#include #include #include #include #include #include #include #include "log.h" #include "config_engine.h" #include "libuv_dbus.h" #define PROCESS_MUTEX_KEY ("/root/config_server.pid") #define CFG_SYNC_TIME_OF_SECONDS (1) static PCFG_ITEM __cfgAddItem(const char *pKeyName, const char *pKeyValue, int iType, int overWrite, int saveToDB, int* pErr); typedef struct { char keyName[MAX_CFG_KEY_NAME]; uint32_t tmCached; UT_hash_handle hh; ///< UT Hash handle } CFG_CACHE_ITEM, *PCFG_CACHE_ITEM; static sqlite3* g_pSqlFileDB = NULL; static PCFG_ITEM g_pCfgItems = NULL; static PCFG_CACHE_ITEM g_pCfgCacheItems = NULL; static int g_bIsCfgSvr = FALSE; static uv_rwlock_t g_uvHashRwLock; static uv_rwlock_t g_uvCacheRwLock; static uv_timer_t g_uvSyncSvr; #if 0 #define INT_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS integer(" \ "keyName TEXT PRIMARY KEY NOT NULL," \ "keyValue INTEGER NOT NULL," \ "keyModule INTEGER NOT NULL," \ "CreatedTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));") #define STRING_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS string(" \ "keyName TEXT PRIMARY KEY NOT NULL," \ "keyValue TEXT NOT NULL," \ "keyModule INTEGER NOT NULL," \ "CreatedTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));") #define FLOAT_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS double(" \ "keyName TEXT PRIMARY KEY NOT NULL," \ "keyValue NUMERIC NOT NULL," \ "keyModule INTEGER NOT NULL," \ "CreatedTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));") #endif #define FIRMWARE_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS %s (" \ "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ "keyName TEXT UNIQUE NOT NULL," \ "keyValue TEXT NOT NULL," \ "keyType INTEGER NOT NULL);") static const char* __cfgGetKeyTypeString(int keyType) { switch(keyType) { case 0: return ("string"); case 1: return ("integer"); case 2: return ("double"); } return ("Unknown Type"); } static int __cfgItem2CfgRsp(PCFG_ITEM pCfgItem, PCFG_API_RSP pRsp) { if(pCfgItem == NULL || pRsp == NULL) { return (-ERR_INPUT_PARAMS); } memset(pRsp->keyValue, 0, MAX_CFG_KEY_VALUE); pRsp->keyType = pCfgItem->keyType; if(pCfgItem->keyType == CFG_TYPE_STRING) { strncpy(pRsp->keyValue, pCfgItem->pStrValue, MAX_CFG_KEY_VALUE); } else if(pCfgItem->keyType == CFG_TYPE_INT) { sprintf(pRsp->keyValue, "%d", pCfgItem->intValue); } else if(pCfgItem->keyType == CFG_TYPE_DOUBLE) { sprintf(pRsp->keyValue, "%f", pCfgItem->doubleValue); } pRsp->errNo = 0; return (0); } static int __cfgMsg2CfgItem(int keyType, const char *pKeyName, const char *pKeyValue, PCFG_ITEM pCfgItem) { int iValue; double dValue; char *pEndPtr = NULL; if(pKeyName == NULL || pKeyValue == NULL || pCfgItem == NULL) { return (-ERR_INPUT_PARAMS); } strcpy(pCfgItem->pKeyName, pKeyName); pCfgItem->keyType = keyType; pCfgItem->keyModule = DBusLibuvGetRuntime()->modName; switch(keyType) { case CFG_TYPE_STRING: strcpy(pCfgItem->pStrValue, pKeyValue); break; case CFG_TYPE_INT: iValue = strtol(pKeyValue, NULL, 10); if(errno == ERANGE || errno == EINVAL) { return (-ERR_STR_CONVERT); } else { pCfgItem->intValue = iValue; } break; case CFG_TYPE_DOUBLE: dValue = strtod(pKeyValue, &pEndPtr); if((errno == ERANGE) || (dValue == 0 && (strcmp(pKeyValue, pEndPtr) == 0))) { return (-ERR_STR_CONVERT); } else { pCfgItem->doubleValue = dValue; } break; default : return (-ERR_UNKNOWN_TYPE); } return (0); } static int __cfgMsg2CfgItemV2(int keyType, const char *pKeyName, const char *pKeyValue, PCFG_ITEM* pItem) { int iSize; PCFG_ITEM pCfgItem = (PCFG_ITEM)malloc(sizeof(CFG_ITEM)); char* pCache = NULL; if(pKeyName == NULL || pKeyValue == NULL || pCfgItem == NULL) { free(pCfgItem); return (-ERR_INPUT_PARAMS); } switch(keyType) { case CFG_TYPE_STRING: iSize += strlen(pKeyValue) + 1; pCache = (char*)malloc(iSize); memset(pCache, 0, iSize); pCfgItem->pKeyName = pCache; pCfgItem->pStrValue = pCache + strlen(pKeyName) + 1; __cfgMsg2CfgItem(pCfgItem->keyType, pKeyName, pKeyValue, pCfgItem);; break; case CFG_TYPE_INT: pCfgItem->pKeyName = (char*)malloc(iSize); memset(pCfgItem->pKeyName, 0, iSize); strcpy(pCfgItem->pKeyName, pKeyName); __cfgMsg2CfgItem(pCfgItem->keyType, pKeyName, pKeyValue, pCfgItem);; break; case CFG_TYPE_DOUBLE: pCfgItem->pKeyName = (char*)malloc(iSize); memset(pCfgItem->pKeyName, 0, iSize); strcpy(pCfgItem->pKeyName, pKeyName); __cfgMsg2CfgItem(pCfgItem->keyType, pKeyName, pKeyValue, pCfgItem);; break; default: free(pCfgItem); return -ERR_UNKNOWN_TYPE; } *pItem = pCfgItem; return 0; } int Sqlite3SyncDB(sqlite3* pSqlMemory, const char* pMemDbName, const char* pDBFilePath, const char* pFileDbName, int isSave) { int rc; sqlite3* pSqlFile; sqlite3_backup* pSqlBackup; sqlite3* pSyncDest; sqlite3* pSyncSrc; rc = sqlite3_open(pDBFilePath, &pSqlFile); if(rc != SQLITE_OK) { return -ERR_OPEN_SQLITE3_DB; } if(pDBFilePath == NULL || strlen(pDBFilePath) == 0) { pMemDbName = "main"; } if(pFileDbName == NULL || strlen(pFileDbName) == 0) { pFileDbName = "main"; } pSyncSrc = isSave ? pSqlMemory : pSqlFile; pSyncDest = isSave ? pSqlFile : pSqlMemory; pSqlBackup = sqlite3_backup_init(pSyncDest, pMemDbName, pSyncSrc, pFileDbName); if(pSqlBackup != NULL) { #if 1 do { rc = sqlite3_backup_step(pSqlBackup, 10); if(rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED) { sqlite3_sleep(100); } } while (rc == SQLITE_OK || rc == SQLITE_BUSY || rc == SQLITE_LOCKED); #else sqlite3_backup_step(pSqlBackup, -1); #endif sqlite3_backup_finish(pSqlBackup); } else { LOG_EX(LOG_Error, "Backup Database Error\n"); } rc = sqlite3_errcode(pSyncDest); return rc; } static int __sqlite3LoadCb(void* data, int argc, char** argv, char** azColName) { if(argc == 4) { int iSize; PCFG_ITEM pCfgItem = (PCFG_ITEM)malloc(sizeof(CFG_ITEM)); char* pCache = NULL; int ret = 0; pCfgItem->keyType = atoi(argv[3]); pCfgItem->keyModule = *(int*)data; iSize = strlen(argv[1]) + 1; switch(pCfgItem->keyType) { case CFG_TYPE_STRING: iSize += strlen(argv[2]) + 1; pCache = (char*)malloc(iSize); memset(pCache, 0, iSize); pCfgItem->pKeyName = pCache; pCfgItem->pStrValue = pCache + strlen(argv[1]) + 1; ret = __cfgMsg2CfgItem(pCfgItem->keyType, argv[1], argv[2], pCfgItem);; break; case CFG_TYPE_INT: pCfgItem->pKeyName = (char*)malloc(iSize); memset(pCfgItem->pKeyName, 0, iSize); strcpy(pCfgItem->pKeyName, argv[1]); ret = __cfgMsg2CfgItem(pCfgItem->keyType, argv[1], argv[2], pCfgItem);; break; case CFG_TYPE_DOUBLE: pCfgItem->pKeyName = (char*)malloc(iSize); memset(pCfgItem->pKeyName, 0, iSize); strcpy(pCfgItem->pKeyName, argv[1]); ret = __cfgMsg2CfgItem(pCfgItem->keyType, argv[1], argv[2], pCfgItem);; break; default: free(pCfgItem); return -ERR_UNKNOWN_TYPE; } uv_rwlock_wrlock(&g_uvHashRwLock); HASH_ADD_STR(g_pCfgItems, pKeyName, pCfgItem); uv_rwlock_wrunlock(&g_uvHashRwLock); if(ret == 0) { CfgItemPrint("Load Configure: ", pCfgItem); } } else { LOG_EX(LOG_Error, "argc = %d\n", argc); } return 0; } static int __cfgLoadGlobalConfig(void) { int rc = 0; char* pErrMsg = NULL; char sqlCmd[1024]; PLIBUV_DBUS_PARAMS pContext = DBusLibuvGetRuntime(); memset(sqlCmd, 0, 1024); sprintf(sqlCmd, "SELECT * FROM %s", MODULE_ALIAS_NAME(MODULE_CONFIGURE)); // get global configure rc = sqlite3_exec(g_pSqlFileDB, sqlCmd, __sqlite3LoadCb, (void*)MODULE_CONFIGURE, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQLite3 Query Error: %s\n", pErrMsg); return -ERR_SQL_QUERY; } if(pContext->modName != MODULE_CONFIGURE) { memset(sqlCmd, 0, 1024); sprintf(sqlCmd, "SELECT * FROM %s", MODULE_ALIAS_NAME(pContext->modName)); // get local configure rc = sqlite3_exec(g_pSqlFileDB, sqlCmd, __sqlite3LoadCb, (void*)&pContext->modName, &pErrMsg); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "SQLite3 Query Error: %s\n", pErrMsg); sqlite3_free(pErrMsg); return -ERR_SQL_QUERY; } } return 0; } void CfgItemPrint(const char* pPrefix, PCFG_ITEM pCfgItem) { if(pCfgItem == NULL) { fprintf(stderr, "CfgItemPrint: NULL\n"); return; } switch(pCfgItem->keyType) { case 0: LOG_EX(LOG_Debug, "%s[%s] = \"%s\", \ttype = %s, \tmodule = %s\n", pPrefix ? pPrefix : "", pCfgItem->pKeyName, pCfgItem->pStrValue, __cfgGetKeyTypeString(pCfgItem->keyType), ModuleNameToString(pCfgItem->keyModule)); break; case 1: LOG_EX(LOG_Debug, "%s[%s] = %d, \ttype = %s, \tmodule = %s\n", pPrefix ? pPrefix : "", pCfgItem->pKeyName, pCfgItem->intValue, __cfgGetKeyTypeString(pCfgItem->keyType), ModuleNameToString(pCfgItem->keyModule)); break; case 2: LOG_EX(LOG_Debug, "%s[%s] = %f, \ttype = %s, \tmodule = %s\n", pPrefix ? pPrefix : "", pCfgItem->pKeyName, pCfgItem->doubleValue, __cfgGetKeyTypeString(pCfgItem->keyType), ModuleNameToString(pCfgItem->keyModule)); break; default: LOG_EX(LOG_Error, "Unknown type = %d\n", pCfgItem->keyType); break; } } int CfgAddGlobalConfig(const char *pKeyName, const char *pKeyValue, CFG_DATA_TYPE keyType) { CFG_API_REQ req; int ret; if(pKeyName == NULL || pKeyValue == NULL || strlen(pKeyName) == 0 || strlen(pKeyValue) == 0) { return (-ERR_INPUT_PARAMS); } if(keyType < 0 || keyType > CFG_TYPE_DOUBLE) { return (-ERR_INPUT_PARAMS); } memset(&req, 0, sizeof(CFG_API_REQ)); strncpy(req.keyName, pKeyName, MAX_CFG_KEY_NAME); strncpy(req.keyValue, pKeyValue, MAX_CFG_KEY_VALUE); ret = DBusJsonSendToCommand(NULL, g_pModInfoTable[MODULE_CONFIGURE].modAliase, CMD_CFG_ADD_REQ, JSON_ENGINE_CFG_REQ, &req, TRUE); if(ret == 0) { return (-ERR_CFG_WAIT_RSP); } else { return (ret); } } int CfgAddKeyValue(const char *pKeyName, PCFG_ITEM pItem, int saveToDB) { int err = 0; PCFG_ITEM pCfgItem = NULL; if(pItem == NULL || pKeyName == NULL || strlen(pKeyName) == 0) { return (-ERR_INPUT_PARAMS); } uv_rwlock_rdlock(&g_uvHashRwLock); HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem); uv_rwlock_rdunlock(&g_uvHashRwLock); if(pCfgItem != NULL) { return (-ERR_CFG_ITEM_EXIST); } if(pItem->keyType == CFG_TYPE_STRING) { __cfgAddItem(pKeyName, (const char*)pItem->pStrValue, pItem->keyType, FALSE, saveToDB, &err); } else { char buf[256]; memset(buf, 0, 256); if(pItem->keyType == CFG_TYPE_INT) { sprintf(buf, "%d", pItem->intValue); } else if(pItem->keyType == CFG_TYPE_DOUBLE) { sprintf(buf, "%f", pItem->doubleValue); } __cfgAddItem(pKeyName, (const char*)buf, pItem->keyType, FALSE, saveToDB, &err); } return (err); } int CfgChangeKeyValue(const char *pKeyName, PCFG_ITEM pItem, int saveToDB) { int err = 0; PCFG_ITEM pCfgItem = NULL; if(pItem == NULL || pKeyName == NULL || strlen(pKeyName) == 0) { return (-ERR_INPUT_PARAMS); } uv_rwlock_rdlock(&g_uvHashRwLock); HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem); uv_rwlock_rdunlock(&g_uvHashRwLock); if(pCfgItem == NULL) { return (-ERR_CFG_NOITEM); } HASH_DEL(g_pCfgItems, pCfgItem); if(pItem->keyType == CFG_TYPE_STRING) { __cfgAddItem(pKeyName, (const char*)pItem->pStrValue, pItem->keyType, FALSE, saveToDB, &err); } else { char buf[256]; memset(buf, 0, 256); if(pItem->keyType == CFG_TYPE_INT) { sprintf(buf, "%d", pItem->intValue); } else if(pItem->keyType == CFG_TYPE_DOUBLE) { sprintf(buf, "%f", pItem->doubleValue); } __cfgAddItem(pKeyName, (const char*)buf, pItem->keyType, FALSE, saveToDB, &err); } return (err); } int CfgGetKeyValue(const char* pKeyName, PCFG_ITEM* pItem) { PCFG_ITEM pCfgItem = NULL; PLIBUV_DBUS_PARAMS pContext = DBusLibuvGetRuntime(); if(pItem == NULL || pKeyName == NULL || strlen(pKeyName) == 0) { return (-ERR_INPUT_PARAMS); } uv_rwlock_rdlock(&g_uvHashRwLock); HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem); uv_rwlock_rdunlock(&g_uvHashRwLock); if(pCfgItem == NULL) { if(pContext->modName == MODULE_CONFIGURE) { return (-ERR_CFG_NOITEM); } else { CFG_API_REQ req; int ret = 0; memset(&req, 0, sizeof(CFG_API_REQ)); strncpy(req.keyName, pKeyName, MAX_CFG_KEY_NAME); ret = DBusJsonSendToCommand(NULL, g_pModInfoTable[MODULE_CONFIGURE].modAliase, CMD_CFG_GET_REQ, JSON_ENGINE_CFG_REQ, &req, TRUE); if(ret == 0) { return (-ERR_CFG_WAIT_RSP); } else { return (ret); } } } *pItem = pCfgItem; return 0; } static int __cfgCreateCfgFile(const char* pCfgFilePath) { /*const char* pSqlIntDB = NULL; const char* pSqlFloatDB = NULL; const char* pSqlStringDB = NULL; */ char* pErrMsg = NULL; int rc = 0; int i = 0; rc = sqlite3_open_v2(pCfgFilePath, &g_pSqlFileDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if(rc) { LOG_EX(LOG_Error, "sqlite3_open_v2 error: %s\n", pCfgFilePath); return -ERR_OPEN_SQLITE3_DB; } for(i = 0; (i < sizeof(g_pModInfoTable) / sizeof(g_pModInfoTable[0])); i++) { char sqlBuf[1024]; memset(sqlBuf, 0, 1024); sprintf(sqlBuf, FIRMWARE_TBL_SQL_CMD, MODULE_ALIAS_NAME(i)); rc = sqlite3_exec(g_pSqlFileDB, sqlBuf, NULL, 0, &pErrMsg); if(rc != SQLITE_OK) { uv_fs_t uvFs; LOG_EX(LOG_Error, "Create Tbl[%d] Error: %s\n", i, pErrMsg); sqlite3_free(pErrMsg); uv_fs_unlink(GetDBusDefaultLoop(), &uvFs, pCfgFilePath, NULL); return -ERR_SQLITE3_CREATE_TABLE; } } return 0; } #if 0 static void onSigTermProgressExit(int sign) { if(g_bIsCfgSvr) { } kill(getpid(), SIGKILL); } static void onProgressExit(void) { onSigTermProgressExit(0); } #endif static int __cfgCheckCfgSvrRun(void) { int rc; int fd = open(PROCESS_MUTEX_KEY, O_CREAT | O_RDWR, 0666); if(fd == -1) { LOG_EX(LOG_Debug, "Open File Error\n"); } rc = flock(fd, LOCK_EX | LOCK_NB); if(rc == -1) { LOG_EX(LOG_Debug, "Configure server running\n"); return FALSE; } else { LOG_EX(LOG_Debug, "Configure server stoped\n"); return TRUE; } } static int __cfgAddToCache(const char *pKeyName) { PCFG_CACHE_ITEM pItem = NULL; uv_rwlock_rdlock(&g_uvCacheRwLock); HASH_FIND_STR(g_pCfgCacheItems, pKeyName, pItem); uv_rwlock_rdunlock(&g_uvCacheRwLock); if(pItem != NULL) { HASH_DEL(g_pCfgCacheItems, pItem); free(pItem); } pItem = (PCFG_CACHE_ITEM)malloc(sizeof(CFG_CACHE_ITEM)); strncpy(pItem->keyName, pKeyName, MAX_CFG_KEY_NAME); pItem->tmCached = LIBUV_CURRENT_TIME_MS(); uv_rwlock_wrlock(&g_uvCacheRwLock); HASH_ADD_STR(g_pCfgCacheItems, keyName, pItem); uv_rwlock_wrunlock(&g_uvCacheRwLock); return (0); } static PCFG_ITEM __cfgAddItem(const char *pKeyName, const char *pKeyValue, int iType, int overWrite, int saveToDB, int* pErr) { PCFG_ITEM pCfgItem = NULL; int iSize = 0; char *pCache = NULL; uv_rwlock_rdlock(&g_uvHashRwLock); HASH_FIND_STR(g_pCfgItems, pKeyName, pCfgItem); uv_rwlock_rdunlock(&g_uvHashRwLock); if(pCfgItem != NULL) { if(overWrite) { HASH_DEL(g_pCfgItems, pCfgItem); free(pCfgItem->pKeyName); free(pCfgItem); } else { if(pErr) { *pErr = -ERR_CFG_NOITEM; } return NULL; } } if(iType == CFG_TYPE_STRING) { iSize = strlen(pKeyName) + strlen(pKeyValue) + 2; } else { iSize = strlen(pKeyName) + 1; } pCache = (char *)malloc(iSize); memset(pCache, 0, iSize); pCfgItem = (PCFG_ITEM)malloc(sizeof(CFG_ITEM)); pCfgItem->pKeyName = pCache; if(iType == CFG_TYPE_STRING) { pCfgItem->pStrValue = pCache + strlen(pKeyName) + 1; } __cfgMsg2CfgItem(iType, pKeyName, pKeyValue, pCfgItem); uv_rwlock_wrlock(&g_uvHashRwLock); HASH_ADD_STR(g_pCfgItems, pKeyName, pCfgItem); uv_rwlock_wrunlock(&g_uvHashRwLock); // if need save this configure item to database if(saveToDB) { __cfgAddToCache(pKeyName); } if(pErr) { *pErr = 0; } return (pCfgItem); } static void __cfgSyncServer(void) { if(HASH_COUNT(g_pCfgCacheItems) > 0) { PCFG_CACHE_ITEM pItem = NULL, pTemp = NULL; sqlite3_exec(g_pSqlFileDB, "BEGIN TRANSACTION;", NULL, NULL, NULL); HASH_ITER(hh, g_pCfgCacheItems, pItem, pTemp) { PCFG_ITEM pCfgItem = NULL; if(CfgGetKeyValue(pItem->keyName, &pCfgItem) == 0) { char* pSqlInsertCmd = (char*)malloc(1024 * 4); char* pSqlUpgradeCmd = (char*)malloc(1024 * 4); memset(pSqlInsertCmd, 0, 1024 * 4); memset(pSqlUpgradeCmd, 0, 1024 * 4); if(pCfgItem->keyType == CFG_TYPE_STRING) { sprintf(pSqlInsertCmd, "INSERT OR IGNORE INTO %s (keyName, keyValue, keyType) VALUES (\'%s\', \'%s\', %d)", MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pKeyName, pCfgItem->pStrValue, pCfgItem->keyType); sprintf(pSqlUpgradeCmd, "UPDATE %s SET keyValue = \'%s\', keyType = %d WHERE keyName = \'%s\'", MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pStrValue, pCfgItem->keyType, pCfgItem->pKeyName); } else if(pCfgItem->keyType == CFG_TYPE_INT) { sprintf(pSqlInsertCmd, "INSERT OR IGNORE INTO %s (keyName, keyValue, keyType) VALUES (\'%s\', \'%d\', %d)", MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pKeyName, pCfgItem->intValue, pCfgItem->keyType); sprintf(pSqlUpgradeCmd, "UPDATE %s SET keyValue = \'%d\', keyType = %d WHERE keyName = \'%s\'", MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->intValue, pCfgItem->keyType, pCfgItem->pKeyName); } else if(pCfgItem->keyType == CFG_TYPE_DOUBLE) { sprintf(pSqlInsertCmd, "INSERT OR IGNORE INTO %s (keyName, keyValue, keyType) VALUES (\'%s\', \'%f\', %d)", MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->pKeyName, pCfgItem->doubleValue, pCfgItem->keyType); sprintf(pSqlUpgradeCmd, "UPDATE %s SET keyValue = \'%f\', keyType = %d WHERE keyName = \'%s\'", MODULE_ALIAS_NAME(pCfgItem->keyModule), pCfgItem->doubleValue, pCfgItem->keyType, pCfgItem->pKeyName); } if((sqlite3_exec(g_pSqlFileDB, pSqlInsertCmd, NULL, NULL, NULL) == SQLITE_OK) && (sqlite3_exec(g_pSqlFileDB, pSqlUpgradeCmd, NULL, NULL, NULL) == SQLITE_OK)) { // Delete this Key HASH_DEL(g_pCfgCacheItems, pItem); LOG_EX(LOG_Debug, "Sync Configure %s To Database\n", pCfgItem->pKeyName); } else { free(pSqlInsertCmd); free(pSqlUpgradeCmd); return; } free(pSqlInsertCmd); free(pSqlUpgradeCmd); } else { // Delete this Key HASH_DEL(g_pCfgCacheItems, pItem); } } sqlite3_exec(g_pSqlFileDB, "END TRANSACTION;", NULL, NULL, NULL); } } static void __uvThreadSyncCfg(void *pParams) { while(TRUE) { __cfgSyncServer(); sleep(CFG_SYNC_TIME_OF_SECONDS); } pthread_detach(pthread_self()); } static void __cfgStartSyncGlobalCfgSvr(void) { uv_thread_t uvSyncThread; uv_rwlock_init(&g_uvCacheRwLock); uv_thread_create(&uvSyncThread, __uvThreadSyncCfg, NULL); } static PCFG_ITEM __onCMD_CFG_GET_REQ(const char* pKeyName, int* pErr) { PCFG_ITEM pItem = NULL; *pErr = CfgGetKeyValue(pKeyName, &pItem); if(*pErr == 0) { return (pItem); } return (NULL); } static int __onCMD_CFG_ADD_REQ(const char* pKeyName, const char* pKeyValue, int keyType) { PCFG_ITEM pCfgItem = NULL; int ret; if(pKeyName == NULL || pKeyValue == NULL || strlen(pKeyName) == 0 || strlen(pKeyValue) == 0) { return (-ERR_INPUT_PARAMS); } if(keyType < 0 || keyType > CFG_TYPE_DOUBLE) { return (-ERR_INPUT_PARAMS); } ret = __cfgMsg2CfgItemV2(keyType, pKeyName, pKeyValue, &pCfgItem); if(ret != 0) { return (ret); } return CfgAddKeyValue(pKeyName, pCfgItem, TRUE); } static void __cfgSvrProcessCmd(DBUS_CMD cmd, const char* pKeyName, const char* pKeyValue, int keyType, PCFG_API_RSP pRsp) { PCFG_ITEM pItem = NULL; int err; memset(pRsp, 0, sizeof(CFG_API_RSP)); pRsp->errNo = -ERR_UNKNOWN_TYPE; if(pKeyName == NULL) { pRsp->errNo = -ERR_INPUT_PARAMS; return; } strncpy(pRsp->keyName, pKeyName, MAX_CFG_KEY_NAME); switch(cmd) { case CMD_CFG_ADD_REQ: err = __onCMD_CFG_ADD_REQ(pKeyName, pKeyValue, keyType); pRsp->keyType = keyType; pRsp->errNo = err; strncpy(pRsp->keyName, pKeyName, MAX_CFG_KEY_NAME); strncpy(pRsp->keyValue, pKeyValue, MAX_CFG_KEY_VALUE); break; case CMD_CFG_GET_REQ: pItem = __onCMD_CFG_GET_REQ(pKeyName, &err); if(pItem == NULL || err != 0) { pRsp->keyType = -1; pRsp->errNo = err; strncpy(pRsp->keyName, pKeyName, MAX_CFG_KEY_NAME); return; } else { __cfgItem2CfgRsp(pItem, pRsp); return; } break; } return; } int CfgGlobalEnvInit(void) { int rc = 0; uv_rwlock_init(&g_uvHashRwLock); rc = __cfgCreateCfgFile(GLOBAL_CFG_FILE_PATH); if(rc != SQLITE_OK) { return rc; } #if 0 rc = sqlite3_open_v2(":memory:", &g_pSqlMemDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); if(rc != SQLITE_OK) { LOG_EX(LOG_Error, "Create Memory SQLite3 DB Error\n"); return -ERR_CREATE_SQLITE3_DB; } //rc = sqlite3SyncDatabase(g_pSqlMemDB, GLOBAL_CFG_FILE_PATH, 0); #endif rc = __cfgLoadGlobalConfig(); if(rc != SQLITE_OK) { return (-ERR_OPEN_SQLITE3_DB); //sqlite3_close(g_pSqlFileDB); } #if 0 g_bIsCfgSvr = cfgCheckCfgSvrRun(); if(atexit(onProgressExit) != 0) { fprintf(stderr, "atexit error\n"); } signal(SIGINT, onSigTermProgressExit); #endif __cfgStartSyncGlobalCfgSvr(); return 0; } void OnCfgMsgProcess(MODULE_NAME dest, DBUS_CMD busCmd, const char* pJsonStr) { CFG_API_RSP cfgRsp; int err = 0; PCFG_API_REQ pReq = NULL; PCFG_API_RSP pRsp = NULL; PLIBUV_DBUS_PARAMS pParams = DBusLibuvGetRuntime(); switch(busCmd) { case CMD_CFG_ADD_REQ: case CMD_CFG_GET_REQ: pReq = Json2Struct(pJsonStr, JSON_ENGINE_CFG_REQ, TRUE, &err); if(pReq != NULL && err == 0) { pRsp = &cfgRsp; __cfgSvrProcessCmd(busCmd, pReq->keyName, pReq->keyValue, pReq->keyType, pRsp); DBusJsonSendToCommand(NULL, g_pModInfoTable[dest].modAliase, busCmd + 1, JSON_ENGINE_CFG_RSP, pRsp, TRUE); } free(pReq); break; #if 0 case CMD_CFG_GET_REQ: pReq = Json2Struct(pJsonStr, JSON_ENGINE_CFG_REQ, TRUE, &err); if(pReq != NULL && err == 0) { pRsp = &cfgRsp; __cfgSvrProcessCmd(busCmd, pReq->keyName, NULL, pReq->keyType, pRsp); DBusJsonSendToCommand(NULL, g_pModInfoTable[dest].modAliase, CMD_CFG_GET_RSP, JSON_ENGINE_CFG_RSP, pRsp, TRUE); } break; #endif case CMD_CFG_ADD_RSP: case CMD_CFG_GET_RSP: pRsp = Json2Struct(pJsonStr, JSON_ENGINE_CFG_RSP, TRUE, &err); if(pRsp != NULL && err == 0 && pRsp->errNo == 0) { // Add to local Hash Table cache PCFG_ITEM pCfgItem = __cfgAddItem(pRsp->keyName, pRsp->keyValue, pRsp->keyType, TRUE, FALSE, &err); if(err == 0 && pCfgItem != NULL) { if(pParams->onCfgCb) { pParams->onCfgCb(busCmd, pCfgItem, 0); } } else { LOG_EX(LOG_Error, "Add Configure {[%s]<%d> = \"%s\"} Error: %d\n", pRsp->keyName, pRsp->keyValue, pRsp->keyType, err); } } else { if(pParams->onCfgCb) { pParams->onCfgCb(busCmd, NULL, (err == 0) ? pRsp->errNo : err); } LOG_EX(LOG_Error, "pRsp = %p, err = %d, rspErr = %d\n", pRsp, err, pRsp ? pRsp->errNo : -err); } free(pRsp); break; } }