PV1_Comm/Framework/libuvEngine/libuv_dbus.c

1919 lines
49 KiB
C
Raw Normal View History

2018-09-11 06:56:00 +00:00
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <linux/input.h>
#include <sys/shm.h>
#include <sys/msg.h>
#include <sys/sendfile.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/vfs.h>
#include <uthash/utlist.h>
#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;
}