#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "log.h" #include "libuv_dbus.h" #include "json_struct.h" #include "inet_api.h" #include "crypto.h" #include "server_addr.h" #ifdef ENABLE_COUNT_DEBUG #include "monitor.h" #endif #ifdef ENABLE_COUNT_DEBUG #define MON_MSG_PROC_STAT ("Message Process") #define MON_MSG_BST_PROC_STAT ("Boardcast Message Process") #define MON_USER_MSG_PROC_STAT ("User Message Process") #define MON_USER_MSG_BST_PROC_STAT ("User Boardcast Message Process") #endif typedef void (*OnDBusSendError)(int, void*); static void uvOpenKeyEventCb(uv_fs_t* puvFs); typedef struct LOOP_TASK_ARRAY { uv_loop_t* pLoop; int isRunning; struct LOOP_TASK_ARRAY *next, *prev; } *PLOOP_TASK_ARRAY; typedef struct { key_t shmKey; // uint32_t tarMask; // uint32_t tmSend; uint32_t msgSize; UT_hash_handle hh; ///< UT Hash handle } UV_SHM_ITEM, *PUV_SHM_ITEM; typedef struct { long int msgMask; unsigned char pMsgContext[0]; } DBUS_MSG_DATA, *PDBUS_MSG_DATA; typedef struct { DBusConnection* pBus; const char* pBusName; uint32_t busCmd; JSON_ENGINE_TYPE type; void* pStruct; int iSize; OnDBusAsyncSendTo cbSendTo; int enBase64; } DBUS_ASYNC_PARAMS, *PDBUS_ASYNC_PARAMS; static LIBUV_DBUS_PARAMS g_LibuvDBusParam; static uv_idle_t g_uvIdleHandle; static uv_timer_t g_uvTimerPing; static uv_fs_t g_uvKeyEvent; static WORKDAY_INFO g_workDayArray; static WIFI_STATUS g_WifiConnStatus = WIFI_CONNECTED; static PDBUS_MSG_PROC g_pMsgProcList = NULL; static uv_rwlock_t g_uvLoopRwLock; static PLOOP_TASK_ARRAY g_LoopArray = NULL; static unsigned int g_EnHBLExit = TRUE; static uv_rwlock_t g_uvMsgProcRwLock; #if USED_SHM_TO_DBUS static uv_rwlock_t g_uvShmHashRwLock; static PUV_SHM_ITEM g_pShmTbl = NULL; static void __addShmIdToTable(key_t shmKey, uint32_t tmSend, uint32_t tarMask, uint32_t msgSize) { PUV_SHM_ITEM pItem = NULL; uv_rwlock_rdlock(&g_uvShmHashRwLock); HASH_FIND_INT(g_pShmTbl, &shmKey, pItem); uv_rwlock_rdunlock(&g_uvShmHashRwLock); if(pItem == NULL) { pItem = (PUV_SHM_ITEM)malloc(sizeof(UV_SHM_ITEM)); memset(pItem, 0, sizeof(UV_SHM_ITEM)); pItem->shmKey = shmKey; uv_rwlock_wrlock(&g_uvShmHashRwLock); HASH_ADD_INT(g_pShmTbl, shmKey, pItem); uv_rwlock_wrunlock(&g_uvShmHashRwLock); } pItem->tmSend = tmSend; pItem->tarMask = tarMask; pItem->msgSize = msgSize; } static void __removeReqIdFromTable(key_t shmKey) { PUV_SHM_ITEM pItem = NULL; uv_rwlock_rdlock(&g_uvShmHashRwLock); HASH_FIND_INT(g_pShmTbl, &shmKey, pItem); uv_rwlock_rdunlock(&g_uvShmHashRwLock); if(pItem != NULL) { uv_rwlock_wrlock(&g_uvShmHashRwLock); HASH_DEL(g_pShmTbl, pItem); uv_rwlock_wrunlock(&g_uvShmHashRwLock); free(pItem); } } static void __uvShmTblTaskThreadCb(void *pParam) { struct timeval tv; PUV_SHM_ITEM pItem = NULL, pTmpItem = NULL; while(TRUE) { gettimeofday(&tv, NULL); HASH_ITER(hh, g_pShmTbl, pItem, pTmpItem) { int msgId; if(tv.tv_sec - pItem->tmSend <= 60) { continue; } msgId = shmget((key_t)pItem->shmKey, pItem->msgSize, 0666 | IPC_CREAT); if(msgId == -1) { continue; } // Not Boardcast Message if((pItem->tarMask & 0xFFFF0000) != 0xFFFF0000) { PDBUS_MSG_DATA pData = (PDBUS_MSG_DATA)shmat(msgId, NULL, 0); if(pData == (void*)-1) { continue; } // Nevery Recevied By Anyone if(pData->msgMask == pItem->tarMask) { continue; } shmdt(pData); shmctl(msgId, IPC_RMID, 0); __removeReqIdFromTable((key_t)pItem->shmKey); } } sleep(1); } pthread_detach(pthread_self()); } #endif PLIBUV_DBUS_PARAMS DBusLibuvGetRuntime(void) { if(g_LibuvDBusParam.pBus == NULL || g_LibuvDBusParam.pLoop == NULL) { return NULL; } return &g_LibuvDBusParam; } MODULE_NAME DBusLibGetModName(void) { return g_LibuvDBusParam.modName; } uv_loop_t* GetDBusDefaultLoop(void) { if(g_LibuvDBusParam.pBus == NULL || g_LibuvDBusParam.pLoop == NULL) { return uv_default_loop(); } return g_LibuvDBusParam.pLoop; } static void uvAsyncCb(uv_async_t* pAsync) { DBusConnection* pConn = (DBusConnection*)pAsync->data; dbus_connection_read_write(pConn, 0); while(dbus_connection_dispatch(pConn) == DBUS_DISPATCH_DATA_REMAINS); } static void uvTimeoutCb(uv_timer_t* pTimer) { DBusTimeout* timeout = (DBusTimeout*)pTimer->data; dbus_timeout_handle(timeout); } static void uvPollCb(uv_poll_t* pPoll, int status, int events) { DBusWatch* watch = (DBusWatch*)pPoll->data; unsigned int uvFlags = 0; if(events & UV_READABLE) { uvFlags |= DBUS_WATCH_READABLE; } if(events & UV_WRITABLE) { uvFlags |= DBUS_WATCH_WRITABLE; } dbus_watch_handle(watch, uvFlags); } static void uvIdleCb(uv_idle_t* phuvIdle) { usleep(1000); } static void uvFsAccessCb(uv_fs_t* puvFs) { if(puvFs->result != 0) { IHW_EnableLogLevel((LOG_LEVEL)(LOG_Fatal | LOG_Error | LOG_Warn | LOG_Debug | LOG_Info), 1); } uv_fs_req_cleanup(puvFs); free(puvFs); } static void uvReadKeyEventCb(uv_fs_t* puvFs) { if(puvFs->result < 0) { uv_fs_req_cleanup(puvFs); return; } else if(puvFs->result == 0) { uv_fs_t uvClose; uv_fs_close(g_LibuvDBusParam.pLoop, &uvClose, g_uvKeyEvent.result, NULL); } else { uv_buf_t* puvIov = (uv_buf_t*)puvFs->data; if(puvIov->len == sizeof(struct input_event)) { struct input_event* pKeyEvt = (struct input_event*)puvIov->base; if(g_LibuvDBusParam.onKeyCb) { // LOG_EX(LOG_Info, "type = %u, code = %u, value = %u\n", pKeyEvt->type, pKeyEvt->code, pKeyEvt->value); g_LibuvDBusParam.onKeyCb(pKeyEvt->type, pKeyEvt->code, pKeyEvt->value); } } } uv_fs_req_cleanup(puvFs); usleep(1000); uv_fs_open(g_LibuvDBusParam.pLoop, &g_uvKeyEvent, R16_TINA_KEY_EVENT_PATH, O_RDONLY, 0, uvOpenKeyEventCb); } static void uvOpenKeyEventCb(uv_fs_t* puvFs) { static uv_buf_t uvIoV; static struct input_event keyEvent; if(puvFs->result < 0) { LOG_EX(LOG_Error, "Open Key Event File[%s] Error: %d\n", R16_TINA_KEY_EVENT_PATH, puvFs->result); uv_fs_req_cleanup(puvFs); return; } uvIoV = uv_buf_init((void*)&keyEvent, sizeof(struct input_event)); puvFs->data = (void*)&uvIoV; uv_fs_read(g_LibuvDBusParam.pLoop, &g_uvKeyEvent, puvFs->result, &uvIoV, 1, -1, uvReadKeyEventCb); uv_fs_req_cleanup(puvFs); return; } static void DBusAsyncFreeCb(void* pData) { uv_async_t* pAsync = (uv_async_t*)pData; if(pAsync) { pAsync->data = NULL; uv_close((uv_handle_t*)pAsync, (uv_close_cb)free); } } static void DBusPollFreeCb(void* pData) { uv_poll_t* pPoll = (uv_poll_t*)pData; if(pPoll) { pPoll->data = NULL; uv_ref((uv_handle_t*)pPoll); uv_poll_stop(pPoll); uv_close((uv_handle_t*)pPoll, (uv_close_cb)free); } } static dbus_bool_t DBusAddWatchCb(DBusWatch* pWatch, void* pData) { static int isCreate = 0; int fdDBus, uvPollFlags = 0; unsigned int dBusWatchFlags; uv_poll_t* pPoll = NULL; uv_loop_t* pLoop = (uv_loop_t*)pData; if(!dbus_watch_get_enabled(pWatch) || dbus_watch_get_data(pWatch) != NULL || isCreate != 0) { return TRUE; } fdDBus = dbus_watch_get_unix_fd(pWatch); dBusWatchFlags = dbus_watch_get_flags(pWatch); if(dBusWatchFlags & DBUS_WATCH_READABLE) { uvPollFlags |= UV_READABLE; } if(dBusWatchFlags & DBUS_WATCH_WRITABLE) { uvPollFlags |= UV_WRITABLE; } pPoll = (uv_poll_t*)malloc(sizeof(uv_poll_t)); pPoll->data = (void*)pWatch; uv_poll_init(pLoop, pPoll, fdDBus); uv_poll_start(pPoll, uvPollFlags, uvPollCb); LOG_EX(LOG_Debug, "Create POOL by FD: %d\n", fdDBus); uv_unref((uv_handle_t*)pPoll); dbus_watch_set_data(pWatch, (void*)pPoll, DBusPollFreeCb); isCreate = 1; return TRUE; } static void DBusRemoveWatchCb(DBusWatch* pWatch, void* pData) { uv_poll_t* pPoll = (uv_poll_t*)dbus_watch_get_data(pWatch); if(pPoll) { dbus_watch_set_data(pWatch, NULL, NULL); } } static void DBusNotifyWatchCb(DBusWatch* pWatch, void* pData) { if(dbus_watch_get_enabled(pWatch)) { DBusAddWatchCb(pWatch, pData); } else { DBusRemoveWatchCb(pWatch, pData); } } static void DBusTimeoutFreeCb(void* pData) { uv_timer_t* pTimer = (uv_timer_t*)pData; if(pTimer == NULL) { return; } pTimer->data = NULL; uv_timer_stop(pTimer); uv_unref((uv_handle_t*)pTimer); uv_close((uv_handle_t*)pTimer, (uv_close_cb)free); } static dbus_bool_t DBusAddTimeoutCb(DBusTimeout* pTimeout, void* pData) { uv_timer_t* pTimer = NULL; uv_loop_t* pLoop = (uv_loop_t*)pData; if(!dbus_timeout_get_enabled(pTimeout) || dbus_timeout_get_data(pTimeout) != NULL) { return TRUE; } pTimer = (uv_timer_t*)malloc(sizeof(uv_timer_t)); pTimer->data = pTimeout; uv_timer_init(pLoop, pTimer); uv_timer_start(pTimer, uvTimeoutCb, dbus_timeout_get_interval(pTimeout), 0); dbus_timeout_set_data(pTimeout, (void*)pTimer, DBusTimeoutFreeCb); return TRUE; } static void DBusRemoveTimeoutCb(DBusTimeout* pTimeout, void* pData) { uv_timer_t* pTimer = (uv_timer_t*)dbus_timeout_get_data(pTimeout); if(pTimer) { dbus_timeout_set_data(pTimeout, NULL, NULL); } } static void DBusNotifyTimeoutCb(DBusTimeout* pTimeout, void* pData) { if(dbus_timeout_get_enabled(pTimeout)) { DBusAddTimeoutCb(pTimeout, pData); } else { DBusRemoveTimeoutCb(pTimeout, pData); } } static void DBusWakeupMainLoopCb(void* pData) { uv_async_t* pAsync = (uv_async_t*)pData; uv_async_send(pAsync); } static void FreeDBusOnMsgCb(uv_work_t* pWork, int status) { PDBUS_MSG_PACK pMsg = (PDBUS_MSG_PACK)pWork->data; if(pMsg) { free(pMsg); } free(pWork); } #if 0 static void DBusOnBoardcastMsgWorkCb(uv_work_t* pWork) #else static int DBusOnBoardcastMsgWorkCb(PDBUS_MSG_PACK pMsg) #endif { pMsg->isBstMsg = TRUE; // Message context on dbus message pad if(pMsg->msgSize < DBUS_MSG_MAX_PAD_SIZE) { if(pMsg->busCmd == CMD_WIFI_STATE_NTF) { int err = 0; PWIFI_STATUS_PRO pWifiInfo = (PWIFI_STATUS_PRO)Json2Struct((const char *)pMsg->pMsg, JSON_WIFI_STATUS_NOTIFY, FALSE, &err); //LOG_EX(LOG_Debug, "pWifiInfo: %s\n", pMsg->pMsg); if(pWifiInfo && err == 0) { if(pWifiInfo->wifi_evt == 0) { g_WifiConnStatus = WIFI_CONNECTED; } else { g_WifiConnStatus = WIFI_DISCONNECTED; } } if(pWifiInfo) { free(pWifiInfo); } } else if(pMsg->busCmd == CMD_CFG_UPG_NOTIFY) { } else if(pMsg->busCmd == CMD_LOG_CONFIG) { int err = 0; PLOG_CFG_PROTOCOL pCfgInfo = (PLOG_CFG_PROTOCOL)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_LOG_CFG_CMD, FALSE, &err); //LOG_EX(LOG_Debug, "pCfgInfo: %s\n", pMsg->pMsg); if(pCfgInfo && err == 0) { UpgradLogConfigure(pCfgInfo); } if(pCfgInfo) { free(pCfgInfo); } } else if(pMsg->busCmd != CMD_MISC_PING) { pMsg->msgDests = 0xFFFFFFFF; if(g_LibuvDBusParam.onMsgCb) { g_LibuvDBusParam.onMsgCb(g_LibuvDBusParam.pLoop, g_LibuvDBusParam.pBus, pMsg); } return 1; } } return 0; } #if 0 static void DBusOnMsgWorkAPICb(uv_work_t* pWork) #else static int DBusOnMsgWorkAPICb(PDBUS_MSG_PACK pMsg) #endif { int err = 0; pMsg->isBstMsg = FALSE; // Message context on dbus message pad if(pMsg->msgSize < DBUS_MSG_MAX_PAD_SIZE) { if(pMsg->busCmd >= CMD_CFG_ADD_REQ && pMsg->busCmd < CMD_CFG_UPG_NOTIFY) { OnCfgMsgProcess(pMsg->msgSrc, pMsg->busCmd, pMsg->pMsg); } else if(pMsg->busCmd == CMD_LOG_CONFIG) { PLOG_CFG_PROTOCOL pCfgInfo = (PLOG_CFG_PROTOCOL)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_LOG_CFG_CMD, FALSE, &err); //LOG_EX(LOG_Debug, "pCfgInfo: %s\n", pMsg->pMsg); if(pCfgInfo && err == 0) { UpgradLogConfigure(pCfgInfo); } if(pCfgInfo) { free(pCfgInfo); } } else if(pMsg->busCmd == CMD_WORKDAY_DB_RSP) { PWORKDAY_INFO pWorkDayInfo = (PWORKDAY_INFO)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_WORKDAY_REQ, FALSE, &err); //LOG_EX(LOG_Debug, "WorkDay: %s\n", pMsg->pMsg); if(pWorkDayInfo && err == 0) { memcpy(&g_workDayArray, pWorkDayInfo, sizeof(WORKDAY_INFO)); g_workDayArray.isReady = TRUE; LOG_EX(LOG_Debug, "Sync Alarm Database: %s\n", pMsg->pMsg); } //LOG_EX2(LOG_Debug, "Database: %s\n", pMsg->pMsg); if(pWorkDayInfo) { free(pWorkDayInfo); } } else if(pMsg->busCmd != CMD_MISC_PING) { if(g_LibuvDBusParam.onMsgCb) { g_LibuvDBusParam.onMsgCb(g_LibuvDBusParam.pLoop, g_LibuvDBusParam.pBus, pMsg); } return 1; } } else // More than 4K size used Share Memory { LOG_EX(LOG_Error, "Receive Message Error Size: %d\n", pMsg->msgSize); #if 0 PDBUS_MSG_DATA pData = NULL; int key = strtol(pMsg->pMsg, NULL, 10); int msgId = shmget((key_t)key, pMsg->msgSize, 0666 | IPC_CREAT); if(msgId == -1) { return; } pData = (PDBUS_MSG_DATA)shmat(msgId, NULL, 0); if(pData == (void*)-1) { return; } //print_hex_dump_bytes("send_", 2, pData, pMsg->msgSize); pMsg->pMsg = pData->pMsgContext; pMsg->msgSize -= sizeof(long int); if(pMsg->busCmd != CMD_MISC_PING) { g_LibuvDBusParam.onMsgCb(g_LibuvDBusParam.pLoop, g_LibuvDBusParam.pBus, pMsg); } pData->msgMask &= ~(1 << g_LibuvDBusParam.modName); // Cleanup Share Memory if(pData->msgMask == 0) { shmctl(msgId, IPC_RMID, 0); #if USED_SHM_TO_DBUS __removeReqIdFromTable((key_t)key); #endif } shmdt(pData); #endif } return 0; } static DBusHandlerResult DBusOnMsgCb(DBusConnection* pConn, DBusMessage* pMsg, void* user_data) { #if 0 struct timeval tmBegin, tmEnd; long long diffTm; #endif DBusError error; PDBUS_MSG_PROC pMsgProc = NULL; PDBUS_MSG_PACK pMsgPack = (PDBUS_MSG_PACK)malloc(sizeof(DBUS_MSG_PACK)); if(pMsgPack == NULL) { LOG_EX(LOG_Error, "Receive Message: No Memory\n"); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } memset(pMsgPack, 0, sizeof(DBUS_MSG_PACK)); dbus_error_init(&error); if(dbus_message_is_signal(pMsg, DBUS_MESSAGE_INTERFACE_NAME, "Notify")) { if(dbus_message_get_args(pMsg, &error, DBUS_TYPE_UINT32, &pMsgPack->msgSrc, // from DBUS_TYPE_UINT32, &pMsgPack->msgDests, // to -1 means all except it's self #if USED_SHM_TO_DBUS DBUS_TYPE_UINT32, &pMsgPack->tmTickMSec, // timestamp for msecond #endif DBUS_TYPE_UINT32, &pMsgPack->busCmd, // command type DBUS_TYPE_STRING, &pMsgPack->pMsg, // message context if had DBUS_TYPE_INVALID)) { pMsgPack->msgSize = strlen((char*)pMsgPack->pMsg); // reset timeout timer if(g_LibuvDBusParam.onHblCb && pMsgPack->msgSrc != g_LibuvDBusParam.modName) { HeartDaemonUpgrade(pMsgPack->msgSrc); } // Dispatch message except from it's self if(pMsgPack->msgSrc != g_LibuvDBusParam.modName && pMsgPack->msgDests & (1 << g_LibuvDBusParam.modName)) { if(g_LibuvDBusParam.onMsgCb == NULL) { pMsgProc = (PDBUS_MSG_PROC)malloc(sizeof(struct DBUS_MSG_PROC)); if(pMsgProc == NULL) { LOG_EX(LOG_Error, "Receive Message: No Memory\n"); free(pMsgPack); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } memset(pMsgProc, 0, sizeof(struct DBUS_MSG_PROC)); memcpy(&pMsgProc->msgContent, pMsgPack, sizeof(DBUS_MSG_PACK)); pMsgProc->msgContent.pMsg = strdup(pMsgPack->pMsg); pMsgProc->msgFrom = 0; uv_rwlock_wrlock(&g_uvMsgProcRwLock); DL_APPEND(g_pMsgProcList, pMsgProc); uv_rwlock_wrunlock(&g_uvMsgProcRwLock); } else { DBusOnBoardcastMsgWorkCb(pMsgPack); } } } else { LOG_EX(LOG_Error, "Receive Notify Message Error: %s\n", error.message); dbus_error_free(&error); } free(pMsgPack); return DBUS_HANDLER_RESULT_HANDLED; } else if(dbus_message_is_method_call(pMsg, DBUS_MESSAGE_INTERFACE_NAME, "API")) { if(dbus_message_get_args(pMsg, &error, DBUS_TYPE_UINT32, &pMsgPack->msgSrc, // from DBUS_TYPE_UINT32, &pMsgPack->msgDests, // to -1 means all except it's self #if USED_SHM_TO_DBUS DBUS_TYPE_UINT32, &pMsgPack->tmTickMSec, // timestamp for msecond #endif DBUS_TYPE_UINT32, &pMsgPack->busCmd, // command type DBUS_TYPE_UINT32, &pMsgPack->msgSize, // message size(in bytes) DBUS_TYPE_STRING, &pMsgPack->pMsg, // message context if had DBUS_TYPE_INVALID)) { // reset timeout timer if(g_LibuvDBusParam.onHblCb && pMsgPack->msgSrc != g_LibuvDBusParam.modName) { HeartDaemonUpgrade(pMsgPack->msgSrc); } // Dispatch message except from it's self if(pMsgPack->msgSrc != g_LibuvDBusParam.modName && pMsgPack->msgDests == (1 << g_LibuvDBusParam.modName)) { if(g_LibuvDBusParam.onMsgCb == NULL) { pMsgProc = (PDBUS_MSG_PROC)malloc(sizeof(struct DBUS_MSG_PROC)); if(pMsgProc == NULL) { LOG_EX(LOG_Error, "Receive Message: No Memory\n"); free(pMsgPack); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } memset(pMsgProc, 0, sizeof(struct DBUS_MSG_PROC)); memcpy(&pMsgProc->msgContent, pMsgPack, sizeof(DBUS_MSG_PACK)); pMsgProc->msgContent.pMsg = strdup(pMsgPack->pMsg); pMsgProc->msgFrom = 1; uv_rwlock_wrlock(&g_uvMsgProcRwLock); DL_APPEND(g_pMsgProcList, pMsgProc); uv_rwlock_wrunlock(&g_uvMsgProcRwLock); } else { DBusOnMsgWorkAPICb(pMsgPack); } } } else { LOG_EX(LOG_Error, "Receive API Message Error: %s\n", error.message); dbus_error_free(&error); } free(pMsgPack); return DBUS_HANDLER_RESULT_HANDLED; } free(pMsgPack); return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } static void freeSHMResource(int shmId, void* pData) { // Cleanup Share Memory if(pData) { shmdt(pData); } shmctl(shmId, IPC_RMID, 0); } static void FreeDBusSendToAsyncCb(uv_work_t* pWork, int status) { PDBUS_ASYNC_PARAMS pParam = (PDBUS_ASYNC_PARAMS)pWork->data; free(pParam->pStruct); free(pParam); free(pWork); } static void DBusSendToAsyncCb(uv_work_t* pWork) { int err = 0; PDBUS_ASYNC_PARAMS pParam = (PDBUS_ASYNC_PARAMS)pWork->data; const char *pJsonStr = Struct2Json(pParam->pStruct, pParam->type, pParam->enBase64, &err); if(pJsonStr == NULL || err != 0) { pParam->cbSendTo(err); return; } err = DBusSendToCommand(pParam->pBus, pParam->pBusName, pParam->busCmd, pJsonStr); free((void*)pJsonStr); pParam->cbSendTo(err); } int DBusJsonSendToCommandAsync(DBusConnection* pBus, const char* pBusName, uint32_t busCmd, JSON_ENGINE_TYPE type, void* pStruct, int iSize, OnDBusAsyncSendTo cbSendTo, int enBase64) { PDBUS_ASYNC_PARAMS pParam = NULL; uv_work_t* puvWork = NULL; if(cbSendTo == NULL) { return 0; } pParam = (PDBUS_ASYNC_PARAMS)malloc(sizeof(DBUS_ASYNC_PARAMS)); puvWork = (uv_work_t*)malloc(sizeof(uv_work_t)); pParam->pBus = pBus; pParam->pBusName = pBusName; pParam->busCmd = busCmd; pParam->type = type; pParam->iSize = iSize; pParam->pStruct = malloc(iSize); pParam->cbSendTo = cbSendTo; pParam->enBase64 = enBase64; memcpy(pParam->pStruct, pStruct, iSize); puvWork->data = (void*)pParam; uv_queue_work(g_LibuvDBusParam.pLoop, puvWork, DBusSendToAsyncCb, FreeDBusSendToAsyncCb); return 0; } int DBusJsonSendToCommand(DBusConnection* pBus, const char* pBusName, uint32_t busCmd, JSON_ENGINE_TYPE type, void* pStruct, int enBase64) { int ret, err = 0; const char* pJsonStr = Struct2Json(pStruct, type, enBase64, &err); if(pJsonStr == NULL || err != 0) { return err; } ret = DBusSendToCommand(pBus, pBusName, busCmd, pJsonStr); free((void*)pJsonStr); return ret; } int DBusJsonBoardcastCommand(DBusConnection* pBus, uint32_t msgToMask, uint32_t busCmd, JSON_ENGINE_TYPE type, void* pStruct, int enBase64) { int ret, err = 0; const char* pJsonStr = Struct2Json(pStruct, type, enBase64, &err); if(pJsonStr == NULL || err != 0) { return err; } ret = DBusBoardcastCommand(pBus, msgToMask, busCmd, pJsonStr); free((void*)pJsonStr); return ret; } static unsigned int __getShmReqId(void) { static unsigned int g_shmReqId = 1; unsigned int iReqId; if(g_shmReqId >= 0xFFFF - 1) { g_shmReqId = 1; } iReqId = __sync_fetch_and_add(&g_shmReqId, 1); return (iReqId & 0xFFFF) | (g_LibuvDBusParam.modName << 16); } int DBusSendToCommand(DBusConnection* pBus, const char* pBusName, uint32_t busCmd, const char* pContext) { #if USED_SHM_TO_DBUS struct timeval tv; #endif int i; int msgId; //char msgContext[DBUS_MSG_MAX_PAD_SIZE]; DBusMessage* pMsg = NULL; uint32_t msgLen = 0; uint32_t msgToMask = 0; OnDBusSendError pErrorCb = NULL; uint8_t* pMsgInfo = NULL; PDBUS_MSG_DATA pShmData = NULL; const char* pPath = NULL; char* pMsgContent = NULL; #if 0 if(pContext == NULL || (msgLen = strlen(pContext)) <= 0) { return (-ERR_INPUT_PARAMS); } #else if(pContext == NULL) { pContext = ""; msgLen = 0; } else { msgLen = strlen(pContext); } #endif pMsgContent = (char*)malloc(msgLen + 1); if(pMsgContent == NULL) { LOG_EX(LOG_Error, "Malloc memory %d error\n", msgLen + 1); return -ERR_MALLOC_MEMORY; } pMsgInfo = (uint8_t*)pMsgContent; memset(pMsgContent, 0, msgLen + 1); if(pBus == NULL) { pBus = g_LibuvDBusParam.pBus; } for(i = 0; (i < sizeof(g_pModInfoTable) / sizeof(g_pModInfoTable[0])); i++) { // Skip match it'self if(strcmp(g_pModInfoTable[i].modAliase, pBusName) == 0) { msgToMask = 1 << i; pPath = g_pModInfoTable[i].modPath; break; } } pMsg = dbus_message_new_method_call(pBusName, pPath, DBUS_MESSAGE_INTERFACE_NAME, "API"); if(pMsg == NULL) { free(pMsgContent); LOG_EX(LOG_Error, "DBus Create Message Error\n"); return -ERR_DBUS_CREATE_MSG; } dbus_message_set_no_reply(pMsg, TRUE); #if USED_SHM_TO_DBUS gettimeofday(&tv, NULL); #endif if(msgLen < DBUS_MSG_MAX_PAD_SIZE) { strcpy(pMsgContent, pContext); } else { #if 0 int msgKey = __getShmReqId(); msgLen += sizeof(long int); // Make message with Memory Share msgId = shmget((key_t)msgKey, msgLen, 0666 | IPC_CREAT); if(msgId == -1) { perror("shmget_"); return (-ERR_CREATE_SHM); } else { pShmData = (PDBUS_MSG_DATA)shmat(msgId, NULL, 0); if(pShmData == (void*)-1) { return -ERR_MAP_SHM; } pShmData->msgMask = msgToMask; memcpy(pShmData->pMsgContext, pContext, msgLen); sprintf(pMsgInfo, "%d", msgKey); shmdt(pShmData); //print_hex_dump_bytes("send_", 2, pShmData, msgLen); //strcpy(pMsgInfo, (void*)&msgKey, sizeof(key_t)); #if USED_SHM_TO_DBUS __addShmIdToTable((key_t)msgKey, tv.tv_sec, msgToMask, msgLen); #endif pErrorCb = freeSHMResource; } //#else #endif free(pMsgContent); LOG_EX(LOG_Error, "Send Message size %d more than DBUS_MSG_MAX_PAD_SIZE, busCmd = %u, pBusName = %s\n", msgLen, busCmd, pBusName); return -ERR_INPUT_PARAMS; } dbus_message_append_args(pMsg, DBUS_TYPE_UINT32, &g_LibuvDBusParam.modName, // from DBUS_TYPE_UINT32, &msgToMask, // to -1 means all except it's self #if USED_SHM_TO_DBUS DBUS_TYPE_UINT32, &tv.tv_sec, // timestamp for msecond #endif DBUS_TYPE_UINT32, &busCmd, // command type DBUS_TYPE_UINT32, &msgLen, // message size(in bytes) DBUS_TYPE_STRING, &pMsgInfo, // msgLen[0, 512): pad to message; msgLen[512, ~): memory map key, //DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &pMsgInfo, (msgLen < DBUS_MSG_MAX_PAD_SIZE) ? msgLen : sizeof(key_t), DBUS_TYPE_INVALID); free(pMsgContent); if(!dbus_connection_send(pBus, pMsg, NULL)) { LOG_EX(LOG_Error, "Send Message Error\n"); if(pErrorCb) { pErrorCb(msgId, pShmData); } return -ERR_BUS_SEND_MSG; } //dbus_connection_flush(pBus); dbus_message_unref(pMsg); usleep(100); return 0; } int DBusBoardcastCommand(DBusConnection* pBus, uint32_t msgToMask, uint32_t busCmd, const char* pContext) { #if USED_SHM_TO_DBUS struct timeval tv; #endif DBusMessage* pMsg = NULL; if(pContext == NULL) { pContext = ""; } if(strlen(pContext) >= DBUS_MSG_MAX_PAD_SIZE) { LOG_EX(LOG_Error, "Msg size = %u more than DBUS_MSG_MAX_PAD_SIZE\n", strlen(pContext)); return -ERR_DBUS_MSG_TO_LARGE; } if(pBus == NULL) { pBus = g_LibuvDBusParam.pBus; } pMsg = dbus_message_new_signal(g_LibuvDBusParam.pBusPath, DBUS_MESSAGE_INTERFACE_NAME, "Notify"); if(pMsg == NULL) { return -ERR_DBUS_CREATE_MSG; } dbus_message_set_no_reply(pMsg, TRUE); #if USED_SHM_TO_DBUS gettimeofday(&tv, NULL); #endif dbus_message_append_args(pMsg, DBUS_TYPE_UINT32, &g_LibuvDBusParam.modName, // from DBUS_TYPE_UINT32, &msgToMask, // to -1 means all except it's self #if USED_SHM_TO_DBUS DBUS_TYPE_UINT32, &tv.tv_sec, // timestamp for msecond #endif DBUS_TYPE_UINT32, &busCmd, // command type DBUS_TYPE_STRING, &pContext, DBUS_TYPE_INVALID); if(!dbus_connection_send(pBus, pMsg, NULL)) { return -ERR_BUS_SEND_MSG; } //dbus_connection_flush(pBus); dbus_message_unref(pMsg); usleep(100); return 0; } static void __addNewLoopTask(uv_loop_t* pLoop) { PLOOP_TASK_ARRAY pItem = NULL; PLOOP_TASK_ARRAY pTask = NULL; if(pLoop == NULL) { return; } uv_rwlock_wrlock(&g_uvLoopRwLock); LL_FOREACH(g_LoopArray, pItem) { if(pItem->pLoop == pLoop) { LOG_EX(LOG_Warn, "Loop %p is added\n", pLoop); uv_rwlock_wrunlock(&g_uvLoopRwLock); return; } } pTask = (PLOOP_TASK_ARRAY)malloc(sizeof(struct LOOP_TASK_ARRAY)); if(pTask == NULL) { LOG_EX(LOG_Error, "Malloc Memory Error\n"); return; } memset(pTask, 0, sizeof(struct LOOP_TASK_ARRAY)); pTask->pLoop = pLoop; pTask->isRunning = FALSE; LL_APPEND(g_LoopArray, pTask); uv_rwlock_wrunlock(&g_uvLoopRwLock); } static void __uvLoopRuntime(void *pParam) { uv_loop_t* pLoop = (uv_loop_t*)pParam; if(pLoop) { while(TRUE) { uv_run(pLoop, UV_RUN_DEFAULT); usleep(1000); } } pthread_detach(pthread_self()); } static void __runUVLoopTask(uv_loop_t* pLoop, void* pCallback) { uv_thread_t uvThread; if(pLoop == NULL) { return; } uv_thread_create(&uvThread, __uvLoopRuntime, pLoop); } void RunUVLoop(uv_loop_t *pLoop) { #if 1 int more; while(TRUE) { more = uv_run(g_LibuvDBusParam.pLoop, UV_RUN_ONCE); if(more == FALSE) { more = uv_loop_alive(g_LibuvDBusParam.pLoop); if(uv_run(g_LibuvDBusParam.pLoop, UV_RUN_NOWAIT) != 0) { more = TRUE; } } } #else int more; do { if(pLoop && pLoop != g_LibuvDBusParam.pUserLoop) { more = uv_run(pLoop, UV_RUN_ONCE); if(more == FALSE) { more = uv_loop_alive(pLoop); if(uv_run(pLoop, UV_RUN_NOWAIT) != 0) { more = TRUE; } } } if(g_LibuvDBusParam.pUserLoop) { more = uv_run(g_LibuvDBusParam.pUserLoop, UV_RUN_ONCE); if(more == FALSE) { more = uv_loop_alive(g_LibuvDBusParam.pUserLoop); if(uv_run(g_LibuvDBusParam.pUserLoop, UV_RUN_NOWAIT) != 0) { more = TRUE; } } } if(g_LibuvDBusParam.pLoop) { more = uv_run(g_LibuvDBusParam.pLoop, UV_RUN_ONCE); if(more == FALSE) { more = uv_loop_alive(g_LibuvDBusParam.pLoop); if(uv_run(g_LibuvDBusParam.pLoop, UV_RUN_NOWAIT) != 0) { more = TRUE; } } } } while(TRUE); //#else //__runUVLoopTask(pLoop, NULL); //__addNewLoopTask(pLoop); #endif } static void __uvDBusRecvProc(void *pParams) { while(TRUE) { DBusMessage* pMsg = NULL; dbus_connection_read_write(g_LibuvDBusParam.pBus, 0); pMsg = dbus_connection_pop_message(g_LibuvDBusParam.pBus); if(pMsg != NULL) { DBusOnMsgCb(g_LibuvDBusParam.pBus, pMsg, NULL); } usleep(100); } } void DBusMsgCleanup(PDBUS_MSG_PACK pMsg) { if(pMsg) { if(pMsg->pMsg) { free(pMsg->pMsg); } free(pMsg); } } PDBUS_MSG_PACK DBusGetMessage(void) { int iCount, ret = 0; PDBUS_MSG_PACK pMsg = NULL; PDBUS_MSG_PROC pItem = NULL, pTmp = NULL; if(g_LibuvDBusParam.onMsgCb) { return NULL; } DL_COUNT(g_pMsgProcList, pItem, iCount); if(iCount == 0) { return pMsg; } pItem = NULL; uv_rwlock_wrlock(&g_uvMsgProcRwLock); DL_FOREACH_SAFE(g_pMsgProcList, pItem, pTmp) { if(pItem->msgFrom == 0) { ret = DBusOnBoardcastMsgWorkCb(&pItem->msgContent); } else { ret = DBusOnMsgWorkAPICb(&pItem->msgContent); } if(ret != 0) { pMsg = (PDBUS_MSG_PACK)malloc(sizeof(DBUS_MSG_PACK)); if(pMsg) { memset(pMsg, 0, sizeof(DBUS_MSG_PACK)); memcpy(pMsg, &pItem->msgContent, sizeof(DBUS_MSG_PACK)); pMsg->pMsg = strdup(pItem->msgContent.pMsg); } } DL_DELETE(g_pMsgProcList, pItem); free(pItem->msgContent.pMsg); free(pItem); break; } uv_rwlock_wrunlock(&g_uvMsgProcRwLock); return pMsg; } #if 0 static void __uvMsgProc(void *pParams) { #ifdef ENABLE_COUNT_DEBUG struct timeval tmBegin, tmEnd; long long diffTm; #endif while(TRUE) { int iMaxProcMsg = 100; PDBUS_MSG_PROC pItem = NULL, pTmp = NULL; uv_rwlock_wrlock(&g_uvMsgProcRwLock); DL_FOREACH_SAFE(g_pMsgProcList, pItem, pTmp) { if(--iMaxProcMsg == 0) { break; } #ifdef ENABLE_COUNT_DEBUG gettimeofday(&tmBegin, NULL); #endif if(pItem->msgFrom == 0) { DBusOnBoardcastMsgWorkCb(&pItem->msgContent); #ifdef ENABLE_COUNT_DEBUG gettimeofday(&tmEnd, NULL); diffTm = (tmEnd.tv_sec * 1000000 + tmEnd.tv_usec) - (tmBegin.tv_sec * 1000000 + tmBegin.tv_usec); MonUpgradeStatistical(MON_MSG_BST_PROC_STAT, diffTm); #endif } else { DBusOnMsgWorkAPICb(&pItem->msgContent); #ifdef ENABLE_COUNT_DEBUG gettimeofday(&tmEnd, NULL); diffTm = (tmEnd.tv_sec * 1000000 + tmEnd.tv_usec) - (tmBegin.tv_sec * 1000000 + tmBegin.tv_usec); MonUpgradeStatistical(MON_MSG_PROC_STAT, diffTm); #endif } if(pItem->msgContent.pMsg) { free(pItem->msgContent.pMsg); } DL_DELETE(g_pMsgProcList, pItem); free(pItem); } uv_rwlock_wrunlock(&g_uvMsgProcRwLock); usleep(1000); } pthread_detach(pthread_self()); } #endif void SetHBLAutoExit(int flag) { g_EnHBLExit = flag ? TRUE : FALSE; } static void __dBusDeameonCb(MODULE_NAME modName, int status) { LOG_EX(status == 0 ? LOG_Info : LOG_Error, "Daemon %s(%d) Msg: [%s]\n", ModuleNameToString(modName), modName, status == 0 ? "Connect" : "Disconnect"); if(status != 0 && modName == MODULE_CONTROLLER && g_EnHBLExit) { sleep(1); //exit(0); } } static void __waitUDISKMount(void) { #ifdef PLATFORM_R16 const char* pDoneStat = "done"; const char* pBootStatFile = "/tmp/booting_state"; char buf[5]; FILE* pFile; // wait system create setup status file fprintf(stdout, "Wait boot status file create ......\n"); while(access(pBootStatFile, F_OK) != 0) { usleep(10000); } pFile = fopen(pBootStatFile, "rb"); if(pFile == NULL) { fprintf(stdout, "Open boot status file error\n"); return; } fprintf(stdout, "Wait boot status done ......\n"); // when UDISK mount, file /tmp/booting_state content is "done" do { fseek(pFile, 0, SEEK_SET); memset(buf, 0, 5); fread(buf, 1, 4, pFile); // read 4 bytes status tags usleep(10000); } while(strncmp(buf, pDoneStat, strlen(pDoneStat)) != 0); fclose(pFile); fprintf(stdout, "Boot status done ......\n"); #endif } int GetServerModeFromCC(int defValue, int* pErr) { char* pSvrMode = NULL; int iValue = defValue; GetShellExecResult("curl --silent http://localhost:1705/httpenv/999 | grep 'env:' | awk '{print $3}'", &pSvrMode); if(pSvrMode == NULL) { if(pErr) { *pErr = -ERR_NO_ITEMS; } return defValue; } iValue = strtol(pSvrMode, NULL, 10); free(pSvrMode); if(errno == EINVAL || errno == ERANGE) { if(pErr) { *pErr = -ERR_STR_CONVERT; } return defValue; } if(pErr) { *pErr = 0; } return iValue; } DBusConnection* DBusWithLibuvInit(uv_loop_t* pUserLoop, const char* pBusName, OnDBusMessage cbOnMsg, OnDaemonMsg cbOnHbl, OnKeyEvent cbOnKey, int* pErrno) { int i, ret = 0; DBusError error; SERVER_MODULE_TYPE svrMode; uv_async_t* pAsync = NULL; DBusConnection* pBus = NULL; uv_fs_t* puvFsReq; //uv_thread_t uvMsgProcThread; //uv_thread_t uvMsgRecvThread; //uv_thread_t uvLoopThread; char rule[DBUS_MAXIMUM_MATCH_RULE_LENGTH - 1]; #if USED_SHM_TO_DBUS uv_thread_t uvSyncThread; #endif //uv_loop_t *pLoop = uv_loop_new(); uv_loop_t *pLoop = pUserLoop; memset(&g_LibuvDBusParam, 0, sizeof(LIBUV_DBUS_PARAMS)); for(i = 0; (i < sizeof(g_pModInfoTable) / sizeof(g_pModInfoTable[0])); i++) { // Skip match it'self if(strcmp(g_pModInfoTable[i].modAliase, pBusName) == 0) { g_LibuvDBusParam.modName = g_pModInfoTable[i].modName; g_LibuvDBusParam.pBusName = g_pModInfoTable[i].modAliase; g_LibuvDBusParam.pBusPath = g_pModInfoTable[i].modPath; break; } } memset(&g_workDayArray, 0, sizeof(WORKDAY_INFO)); srand(time(NULL)); if(pLoop == NULL || pBusName == NULL || pErrno == NULL) { if(pErrno) { *pErrno = -ERR_INPUT_PARAMS; } LOG_EX(LOG_Error, "Input params error: pLoop = %p, pBusName = %p, pErrno = %p\n", pLoop, pBusName, pErrno); return NULL; } puvFsReq = (uv_fs_t*)malloc(sizeof(uv_fs_t)); // wait UDISK mount, configure file save in UDISK partition __waitUDISKMount(); CfgFileInit(); IHW_InitLOG(strrchr(pBusName, '.') + 1, NULL, TRUE); IHW_EnableLogLevel(LOG_Fatal | LOG_Error | LOG_Warn | LOG_Debug | LOG_Info, 1); IHW_RunLogService(); APP_BUILD_INFO(strrchr(pBusName, '.') + 1, GetCurrentVersion()); i = 0; do { svrMode = CfgGetIntValueV1("Global.ServerMode", PUBLISH_MODE, &ret); if(ret != 0) { sleep(1); } else { usleep(1000); } LOG_EX(LOG_Debug, "ServerMode = %d, Error = %d\n", svrMode, ret); } while (ret != 0 && i++ <= 3); if(ret != 0) { LOG_EX(LOG_Error, "Read Server Mode Error: ret = %d\n", ret); svrMode = CfgGetIntValueV2("ServerMode", PUBLISH_MODE, &ret); if(ret == 0) { LOG_EX(LOG_Warn, "Recovery Server Mode OK: ServerMode = %d\n", svrMode); } else { LOG_EX(LOG_Error, "CfgGetInvValueV2 Read Server Mode Error: ret = %d\n", ret); svrMode = GetServerModeFromCC(PUBLISH_MODE, &ret); if(ret == 0) { LOG_EX(LOG_Warn, "Netease Controller Server Mode OK: ServerMode = %d\n", svrMode); } else { svrMode = PUBLISH_MODE; LOG_EX(LOG_Error, "GetServerModeFromCC Read Server Mode Error: " "ret = %d, Set to default: PUBLISH_MODE\n", ret); } } } SetCurrentServerMode(svrMode); DumpCurServerAddr("Default"); #if USED_SHM_TO_DBUS uv_rwlock_init(&g_uvShmHashRwLock); #endif uv_rwlock_init(&g_uvMsgProcRwLock); uv_rwlock_init(&g_uvLoopRwLock); uv_fs_access(pLoop, puvFsReq, "/mnt/UDISK/debug.dbg", F_OK, uvFsAccessCb); memset(rule, 0, DBUS_MAXIMUM_MATCH_RULE_LENGTH - 1); srand(time(NULL)); //setenv("UV_THREADPOOL_SIZE", "128", 1); dbus_error_init(&error); pBus = dbus_bus_get(DBUS_BUS_SESSION, &error); if (dbus_error_is_set(&error)) { LOG_EX(LOG_Error, "dbus: Could not acquire the session bus\n"); dbus_error_free(&error); *pErrno = -ERR_GET_BUS; return NULL; } ret = dbus_bus_request_name(pBus, pBusName, DBUS_NAME_FLAG_REPLACE_EXISTING, &error); if(dbus_error_is_set(&error)) { LOG_EX(LOG_Error, "dbus: Could not request dbus name\n"); dbus_error_free(&error); *pErrno = -ERR_REQUEST_BUS_NAME; return NULL; } if(ret != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { LOG_EX(LOG_Error, "dbus: Could not request dbus name\n"); dbus_error_free(&error); *pErrno = -ERR_REQUEST_BUS_NAME; return NULL; } #if 1 if(!dbus_connection_set_watch_functions(pBus, DBusAddWatchCb, DBusRemoveWatchCb, DBusNotifyWatchCb, (void*)pLoop, NULL)) { LOG_EX(LOG_Error, "dbus: Could not set watch function\n"); *pErrno = -ERR_SET_WATCH_FUNCTION; return NULL; } if(!dbus_connection_set_timeout_functions(pBus, DBusAddTimeoutCb, DBusRemoveTimeoutCb, DBusNotifyTimeoutCb, (void*)pLoop, NULL)) { LOG_EX(LOG_Error, "dbus: Could not set watch function\n"); *pErrno = -ERR_SET_TIMEOUT_FUNCTION; return NULL; } #endif pAsync = malloc(sizeof(uv_async_t)); pAsync->data = (void*)pBus; uv_async_init(pLoop, pAsync, uvAsyncCb); uv_unref((uv_handle_t*)pAsync); #if 1 dbus_connection_set_wakeup_main_function(pBus, DBusWakeupMainLoopCb, (void*)pAsync, DBusAsyncFreeCb); #endif sprintf(rule, "type='signal', interface='%s'", DBUS_MESSAGE_INTERFACE_NAME); dbus_bus_add_match(pBus, rule, &error); if(dbus_error_is_set(&error)) { LOG_EX(LOG_Error, "dbus_bus_add_match [%s] error: %s\n", DBUS_MESSAGE_INTERFACE_NAME, error.message); dbus_error_free(&error); *pErrno = -ERR_BUS_MATCH; return NULL; } #if 1 if(!dbus_connection_add_filter(pBus, DBusOnMsgCb, pLoop, NULL)) { LOG_EX(LOG_Error, "dbus_connection_add_filter error\n"); *pErrno = -ERR_BUS_SET_MSG_CB; return NULL; } #endif uv_idle_init(pLoop, &g_uvIdleHandle); g_uvIdleHandle.data = pBus; uv_idle_start(&g_uvIdleHandle, uvIdleCb); if(cbOnKey) { uv_fs_open(pLoop, &g_uvKeyEvent, R16_TINA_KEY_EVENT_PATH, O_RDONLY, 0, uvOpenKeyEventCb); g_LibuvDBusParam.onKeyCb = cbOnKey; } g_LibuvDBusParam.pLoop = pLoop; g_LibuvDBusParam.pUserLoop = pUserLoop; g_LibuvDBusParam.pBus = pBus; g_LibuvDBusParam.onMsgCb = cbOnMsg; #if 0 if(cbOnHbl) { g_LibuvDBusParam.onHblCb = cbOnHbl; HeartDaemonInit(g_LibuvDBusParam.modName, HEART_LOST_DELAY, cbOnHbl); } #else g_LibuvDBusParam.onHblCb = __dBusDeameonCb; HeartDaemonInit(g_LibuvDBusParam.modName, HEART_LOST_DELAY, __dBusDeameonCb); #endif #if USED_SHM_TO_DBUS uv_thread_create(&uvSyncThread, __uvShmTblTaskThreadCb, NULL); #endif #ifdef ENABLE_COUNT_DEBUG MonitorInit(); MonAddNewItem(MON_MSG_PROC_STAT, 100000); MonAddNewItem(MON_MSG_BST_PROC_STAT, 100000); MonAddNewItem(MON_USER_MSG_PROC_STAT, 100000); MonAddNewItem(MON_USER_MSG_BST_PROC_STAT, 100000); #endif InetInit(); EvpSystemInit(); #if 0 if(g_LibuvDBusParam.onMsgCb) { uv_thread_create(&uvMsgProcThread, __uvMsgProc, NULL); } #endif return pBus; } int DBusWithLibuvCfgInit(OnCfgMsg cbOnCfgMsg) { CfgGlobalEnvInit(); if(cbOnCfgMsg == NULL) { return (-ERR_INPUT_PARAMS); } g_LibuvDBusParam.onCfgCb = cbOnCfgMsg; return (0); } static int __reqWorkDayInfo(int year) { int ret = 0; WORKDAY_INFO reqInfo; memset(&reqInfo, 0, sizeof(WORKDAY_INFO)); if(year <= 0) { struct tm localTime; time_t tmStamp = time((time_t*)NULL); localtime_r(&tmStamp, &localTime); reqInfo.year = localTime.tm_year; } else { reqInfo.year = year; } if(reqInfo.year < (2018 - 1900)) { return 0; } ret = DBusJsonSendToCommand(NULL, g_pModInfoTable[MODULE_CONTROLLER].modAliase, CMD_WORKDAY_DB_REQ, JSON_ENGINE_WORKDAY_REQ, &reqInfo, FALSE); return (ret); } int IsHolidayDBSynced(void) { return g_workDayArray.isReady; } int CurrentIsWorkDay(int year, int day) { static unsigned int i = 0; if(year != 0) { LOG_EX(LOG_Debug, "CurrentIsWorkDay: year = %d, day = %d\n", year, day); } if(day > 365) { LOG_EX(LOG_Error, "Error Input Params: day = %d\n", day); return (-ERR_INPUT_PARAMS); } if(g_workDayArray.year <= 0) { __reqWorkDayInfo(year); if(i++ % 10 == 0) { LOG_EX(LOG_Error, "Unsync Database: year = %d\n", year); } return (-ERR_UNINIT_ITEM); } if(day < 0 || year <= 0) { struct tm localTime; time_t tmStamp = time((time_t*)NULL); localtime_r(&tmStamp, &localTime); if(day < 0) { day = localTime.tm_yday; } if(year <= 0) { year = localTime.tm_year; } } if(year != g_workDayArray.year - 1900) { __reqWorkDayInfo(year); LOG_EX(LOG_Error, "Have No Current Year Database: year = %d, g_workDayArray.year = %d\n", year, g_workDayArray.year); return (-ERR_NO_ITEMS); } // 0 work day, 1 holiday return (g_workDayArray.days[day] == 0); } WIFI_STATUS GetCurrWIFIConnStatus(void) { return g_WifiConnStatus; }