diff --git a/app/LogCtrlTools/Makefile b/app/LogCtrlTools/Makefile new file mode 100644 index 0000000..7ce3ca1 --- /dev/null +++ b/app/LogCtrlTools/Makefile @@ -0,0 +1,47 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common +include $(TOPDIR)/rules.mk + +PKG_NAME:=log_ctrl +PKG_RELEASE:=1 +PKG_VERSION:=0.0.1 + +PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME) + +include $(BUILD_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=utils + CATEGORY:=Netease + TITLE:=Log Control tools + MAINTAINER:=Huang xin + DEPENDS:=+libreadline +libncurses $(MAKE_COMMON_DEPEND) +endef + +define Package/$(PKG_NAME)/description + $(PKG_NAME) This tools used to control module's log actions from dbus bus. For example: enable/disable logs, set udp log server ip and port, and so on. +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) -d ./src/ $(PKG_BUILD_DIR)/ +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR)/src \ + ARCH="$(TARGET_ARCH)" \ + AR="$(TARGET_AR)" \ + CC="$(TARGET_CC)" \ + CXX="$(TARGET_CXX)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \ + TARGET_NAME=$(PKG_NAME) \ + all +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/app/LogCtrlTools/src/Makefile b/app/LogCtrlTools/src/Makefile new file mode 100644 index 0000000..d60ae72 --- /dev/null +++ b/app/LogCtrlTools/src/Makefile @@ -0,0 +1,24 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common +TARGET := log_ctrl + +commonSources := log_ctrl.c + +local_CFLAGS := -DPLATFROM_R16 +local_LDFLAGS := -lreadline -lncurses $(BUILD_COMMON_LIB) + +OBJS = $(patsubst %.c, %.c.o, $(commonSources)) + +$(TARGET):$(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(local_LDFLAGS) -o $@ $^ + +$(OBJS):%.c.o:%.c + $(CC) $(CFLAGS) $(LDFLAGS) $(local_CFLAGS) -c $^ -o $@ + +clean: + -rm $(OBJS) $(TARGET) + +install: + mkdir -p $(INSTALL_PREFIX)/usr/bin + cp $(TARGET) $(INSTALL_PREFIX)/usr/bin/ + +all: $(TARGET) install diff --git a/app/LogCtrlTools/src/log_ctrl.c b/app/LogCtrlTools/src/log_ctrl.c new file mode 100644 index 0000000..ce94a86 --- /dev/null +++ b/app/LogCtrlTools/src/log_ctrl.c @@ -0,0 +1,323 @@ + #include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PLATFORM_R16) || defined (PLATFORM_CPU) +#include "log.h" +#include "libuv_dbus.h" +#include "json_struct.h" + +#else +#include +#include +#include +#endif + +static MOD_INFO_TABLE g_ModInfo; + + +static PDBUS_MSG_PACK DBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, PDBUS_MSG_PACK pMsg) +{ + //int i, ret, err; + //uint32_t tm = LIBUV_CURRENT_TIME_US(); + + if(!pMsg || !pLoop || !pConn) + { + return NULL; + } + + //LOG_EX(LOG_Info, "Process Message(%u --> 0x%08X) at [%lu.%06lu]: cmd = %u, size = %u, key = %d, msg(%d) = [%s]\n", + // pMsg->msgSrc, pMsg->msgDests, tm / 1000000, tm % 1000000, pMsg->busCmd, pMsg->msgSize, pMsg->msgKey, pMsg->msgSize, pMsg->pMsg); + + return NULL; +} + +static void __logCtrlProc(void *pParams) +{ + int i = 0; + //int ret; + + LOG_LEVEL logLevelInfo[] = { + LOG_Fatal, LOG_Error, LOG_Warn, LOG_Debug, LOG_Info, + LOG_Test, LOG_Call, LOG_Devp, LOG_Step, LOG_Unknown, LOG_All, LOG_Close + }; + + const char* g_Menu[] = { + "Usage: enable/disable [params1] [params2]\n" + " help\n", + " quit\n", + }; + + const char* pOptMenu[] = { + "\n operation:\n" + " |--------------------------------------------------------------------------|\n", + " | command | operation | params1 | params2 |\n", + " |--------------------------------------------------------------------------|\n", + " | enable | | | |\n", + " |----------| 0: Set log level | Log level | Unused |\n", + " | disable | | | |\n", + " |----------|---------------------|-----------------------|-----------------|\n", + " | enable | | | |\n", + " |----------| 1: Print to file | Unused | Unused |\n", + " | disable | | | |\n", + " |----------|---------------------|-----------------------|-----------------|\n", + " | enable | | | |\n", + " |----------| 2: Backup to email | Unused | Unused |\n", + " | disable | | | |\n", + " |----------|---------------------|-----------------------|-----------------|\n", + " | enable | | Log server ip address | Log server port |\n", + " |----------| 3: Send to network |-----------------------|-----------------|\n", + " | disable | | Unused | Unused |\n", + " |--------------------------------------------------------------------------|\n", + " | enable | | | |\n", + " |----------| 4: Backup to Server | Unused | Unused |\n", + " | disable | | | |\n", + " |----------|---------------------|-----------------------|-----------------|\n", + }; + + while(TRUE) + { + char *pInput = NULL; + char *pCmd = NULL; + + for(i = 0; i < sizeof(g_Menu) / sizeof(g_Menu[0]); i++) + { + LOG_EX2(LOG_Info, "%s", g_Menu[i]); + } + + pInput = readline("Enter Command:"); + + if(pInput == NULL) + { + continue; + } + + pCmd = strtok(pInput, " "); + i = 0; + + while(pCmd != NULL) + { + if(strcmp(pCmd, "help") == 0) + { + for(i = 0; i < sizeof(g_pModInfoTable) / sizeof(g_pModInfoTable[0]); i++) + { + if(i == 0) + { + LOG_EX2(LOG_Info, " modName : %-2d --> %s\n", + i, ModuleNameToString(g_pModInfoTable[i].modName)); + } + else + { + LOG_EX2(LOG_Info, "%15s%-2d --> %s\n", "", + i, ModuleNameToString(g_pModInfoTable[i].modName)); + } + } + + for(i = 0; i < sizeof(logLevelInfo) / sizeof(logLevelInfo[0]); i++) + { + if(i == 0) + { + LOG_EX2(LOG_Info, "\n Log Level: %-2d --> %s\n", i, LogLeveToString(logLevelInfo[i])); + } + else + { + LOG_EX2(LOG_Info, "%15s%-2d --> %s\n", "", i, LogLeveToString(logLevelInfo[i])); + } + } + + for(i = 0; i < sizeof(pOptMenu) / sizeof(pOptMenu[0]); i++) + { + LOG_EX2(LOG_Info, "%s", pOptMenu[i]); + } + } + else if(strcmp(pCmd, "enable") == 0 + || strcmp(pCmd, "disable") == 0) + { + LOG_CFG_PROTOCOL logItem; + int iCmd, iMod; + char *pParams1 = NULL, *pParams2 = NULL; + char* pMod = strtok(NULL, " "); + char* pOperat = strtok(NULL, " "); + + if(pMod == NULL || strlen(pMod) == 0) + { + LOG_EX(LOG_Error, "Input error, see help\n"); + break; + } + + if(pOperat == NULL || strlen(pOperat) == 0) + { + LOG_EX(LOG_Error, "Input error, see help\n"); + break; + } + + iMod = strtol(pMod, NULL, 10); + + if(iMod < 0 || iMod >= MODULE_MAX) + { + LOG_EX(LOG_Error, "Input error: %s(%d)\n", pMod, iMod); + break; + } + + iCmd = strtol(pOperat, NULL, 10); + + memset(&logItem, 0, sizeof(LOG_CFG_PROTOCOL)); + + switch(iCmd) + { + case 0: + pParams1 = strtok(NULL, " "); + if(pParams1 && strlen(pParams1) > 0) + { + int logLevel = strtol(pParams1, NULL, 10); + + if(logLevel >= 0 && logLevel < sizeof(logLevelInfo) / sizeof(logLevelInfo[0])) + { + LOG_EX2(LOG_Info, "%s %d 0x%08X\n", pCmd, iCmd, logLevelInfo[logLevel]); + + logItem.cfgCmd = CMD_LOG_LEVEL; + logItem.iParams2 = (strcmp(pCmd, "disable") == 0) ? FALSE : TRUE; + logItem.iParams1 = logLevelInfo[logLevel]; + + DBusJsonSendToCommand(NULL, + g_pModInfoTable[iMod].modAliase, + CMD_LOG_CONFIG, + JSON_ENGINE_LOG_CFG_CMD, + &logItem, TRUE); + } + else + { + LOG_EX(LOG_Error, "Input error, see help\n"); + } + } + else + { + LOG_EX(LOG_Error, "Input error, see help\n"); + } + break; + + case 1: + logItem.cfgCmd = CMD_LOG_FILE; + logItem.iParams1 = (strcmp(pCmd, "disable") == 0) ? FALSE : TRUE; + DBusJsonSendToCommand(NULL, + g_pModInfoTable[iMod].modAliase, + CMD_LOG_CONFIG, + JSON_ENGINE_LOG_CFG_CMD, + &logItem, TRUE); + break; + + case 2: + logItem.cfgCmd = CMD_LOG_MAIL; + logItem.iParams1 = (strcmp(pCmd, "disable") == 0) ? FALSE : TRUE; + DBusJsonSendToCommand(NULL, + g_pModInfoTable[iMod].modAliase, + CMD_LOG_CONFIG, + JSON_ENGINE_LOG_CFG_CMD, + &logItem, TRUE); + break; + + case 3: + pParams1 = strtok(NULL, " "); + + logItem.cfgCmd = CMD_LOG_NETWORK; + if(pParams1 == NULL || strlen(pParams1) == 0) + { + + logItem.iParams1 = 0; + DBusJsonSendToCommand(NULL, + g_pModInfoTable[iMod].modAliase, + CMD_LOG_CONFIG, + JSON_ENGINE_LOG_CFG_CMD, + &logItem, TRUE); + } + else + { + pParams2 = strtok(NULL, " "); + + if(pParams2 != NULL && strlen(pParams2) > 0) + { + logItem.iParams1 = inet_addr(pParams1); + logItem.iParams2 = strtol(pParams2, NULL, 10); + DBusJsonSendToCommand(NULL, + g_pModInfoTable[iMod].modAliase, + CMD_LOG_CONFIG, + JSON_ENGINE_LOG_CFG_CMD, + &logItem, TRUE); + } + else + { + LOG_EX(LOG_Error, "Input error, pParams2 = %s\n", + SAFE_STRING_VALUE(pParams2)); + } + } + + break; + + case 4: + logItem.cfgCmd = CMD_LOG_SERVER; + logItem.iParams1 = (strcmp(pCmd, "disable") == 0) ? FALSE : TRUE; + DBusJsonSendToCommand(NULL, + g_pModInfoTable[iMod].modAliase, + CMD_LOG_CONFIG, + JSON_ENGINE_LOG_CFG_CMD, + &logItem, TRUE); + break; + + default: + LOG_EX(LOG_Error, "Unknown operation(0-3) %s, see help\n", pOperat); + break; + } + } + else if(strcmp(pCmd, "quit") == 0) + { + return; + } + + pCmd = strtok(NULL, " "); + } + + usleep(1000); + } + + pthread_detach(pthread_self()); +} + +int main(int argc, char **argv) +{ + int ret = 0; + DBusConnection* pBus = NULL; + uv_thread_t uvThread; + uv_loop_t* pLoop = GetDBusDefaultLoop(); + + memcpy(&g_ModInfo, &g_pModInfoTable[MODULE_LOG_CTRL], sizeof(MOD_INFO_TABLE)); + + pBus = DBusWithLibuvInit(pLoop, g_ModInfo.modAliase, + DBusOnMessage, + NULL, + NULL, + &ret); + + if(pBus == NULL) + { + fprintf(stderr, "DBusWithLibuvInit Error: %d\n", ret); + return 0; + } + + uv_thread_create(&uvThread, __logCtrlProc, NULL); + + RunUVLoop(pLoop); + + while(TRUE) + { + usleep(1000); + } + + return (0); +} + diff --git a/app/alarm/Makefile b/app/alarm/Makefile new file mode 100644 index 0000000..3403741 --- /dev/null +++ b/app/alarm/Makefile @@ -0,0 +1,52 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common +include $(TOPDIR)/rules.mk + +PKG_NAME:=alarmer +PKG_RELEASE:=1 +PKG_VERSION:=0.0.1 + +PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME) + +include $(BUILD_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=utils + CATEGORY:=Netease + TITLE:=Alarmer + MAINTAINER:=Huang xin + DEPENDS:=$(MAKE_COMMON_DEPEND) +endef + +define Package/$(PKG_NAME)/description + $(PKG_NAME) alarm and reaminder +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) -d ./src/ $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef +define Build/InstallDev +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR)/src \ + ARCH="$(TARGET_ARCH)" \ + AR="$(TARGET_AR)" \ + CC="$(TARGET_CC)" \ + CXX="$(TARGET_CXX)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \ + TARGET_NAME=$(PKG_NAME) \ + all +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/app/alarm/src/Makefile b/app/alarm/src/Makefile new file mode 100644 index 0000000..1d2783e --- /dev/null +++ b/app/alarm/src/Makefile @@ -0,0 +1,25 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common + +TARGET := alarmer + +commonSources := assistant.c + +local_CFLAGS := +local_LDFLAGS := $(BUILD_COMMON_LIB) + +OBJS = $(patsubst %.c, %.c.o, $(commonSources)) + +$(TARGET):$(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(local_LDFLAGS) -o $@ $^ + +$(OBJS):%.c.o:%.c + $(CC) $(CFLAGS) $(LDFLAGS) $(local_CFLAGS) -c $^ -o $@ + +clean: + -rm $(OBJS) $(TARGET) + +install: + mkdir -p $(INSTALL_PREFIX)/usr/bin + cp $(TARGET) $(INSTALL_PREFIX)/usr/bin/ + +all: $(TARGET) install diff --git a/app/alarm/src/assistant.c b/app/alarm/src/assistant.c new file mode 100644 index 0000000..90b404e --- /dev/null +++ b/app/alarm/src/assistant.c @@ -0,0 +1,863 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PLATFORM_R16) || defined (PLATFORM_CPU) || defined(PLATFORM_R311) +#include "log.h" +#include "libuv_dbus.h" +#include "crypto.h" +#include "json_struct.h" +#include "config_engine.h" +#include "assistant.h" +#else +#include +#include +#include +#include +#include +#include +#endif + +#define SYNC_TIME_DELAY (1) + +static PASSISTANT_ARRAY_INFO g_pAlarmArray = NULL, + g_pRemaindArray = NULL, + g_pSessionArray = NULL; + +static uv_rwlock_t g_uvListRwLock; +static unsigned char g_syncFlags = 0; +static unsigned int g_sessionId = 0; + +static void __onAlarmCb(unsigned int tmId, unsigned int status, void *pUserData); + +static int __getTimerPriorty(ASSISTANT_TYPE itemType) +{ + switch(itemType) + { + case ASSISTANT_TYPE_CLOCK: + return (2); + + case ASSISTANT_TYPE_REMAIND: + return (3); + + case ASSISTANT_TYPE_SESSION: + return (1); + } + + return (0); +} + +static void __addTaskToTimer(PASSISTANT_ARRAY_INFO pItem) +{ + int ret = 0; + unsigned int alarmId; + + pItem->alarmItem.second = 0; + + alarmId = AlarmTimerAdd(pItem->alarmItem.year, + pItem->alarmItem.month, + pItem->alarmItem.day, + pItem->alarmItem.hour, + pItem->alarmItem.minute, + pItem->alarmItem.second, + pItem->alarmItem.weekDay, + pItem->alarmItem.repeatMode, + __onAlarmCb, + __getTimerPriorty(pItem->alarmItem.itemType), + &pItem->alarmItem, + &ret); + + if(alarmId != 0xFFFFFFFF && ret == 0) + { + pItem->alarmItem.timerId = alarmId; + } + else + { + pItem->alarmItem.timerId = 0xFFFFFFFF; + } +} + +static int __assistantRspStatus(int cmd, int val) +{ + int ret = 0; + ASSISTANT_RSP_STATUS oStatus; + + memset(&oStatus, 0, sizeof(ASSISTANT_RSP_STATUS)); + + oStatus.cmd = cmd; + oStatus.val = val; + + ret = DBusJsonSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ASSISTANT_STATUS, + JSON_ENGINE_ASSISTANT_STATUS, + &oStatus, TRUE); + + return (ret); +} + +static int __assistantRunningEvent(PASSISTANT_ITEM_INFO pInfo) +{ + int ret = 0; + + ret = DBusJsonSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ASSISTANT_RUNNING, + JSON_ENGINE_ASSISTANT_RUNNING, + pInfo, FALSE); + + return (ret); +} + +static int __assistantNotifyChange(int cmdNotify, int nItems, ASSISTANT_TYPE nType, PASSISTANT_ITEM_INFO pInfo) +{ + int ret = 0; + ASSISTANT_NOTIFY_INFO notifyInfo; + + memset(¬ifyInfo, 0, sizeof(ASSISTANT_NOTIFY_INFO)); + + notifyInfo.type = nType; + notifyInfo.cmd = cmdNotify; + + if(pInfo) + { + notifyInfo.nItems = nItems; + for(int i = 0; i < nItems; i++) + { + notifyInfo.ids[i] = pInfo[i].itemId; + } + } + + ret = DBusJsonSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ASSISTANT_NOTIFY, + JSON_ENGINE_ASSISTANT_NOTIFY, + ¬ifyInfo, TRUE); + + return (ret); +} + +static int __assistantArrayNotifyChange(int cmdNotify, int nItems, ASSISTANT_TYPE nType, unsigned long long* pArray) +{ + int ret = 0; + ASSISTANT_NOTIFY_INFO notifyInfo; + + memset(¬ifyInfo, 0, sizeof(ASSISTANT_NOTIFY_INFO)); + + notifyInfo.type = nType; + notifyInfo.cmd = cmdNotify; + + if(pArray) + { + notifyInfo.nItems = nItems; + for(int i = 0; i < nItems; i++) + { + notifyInfo.ids[i] = pArray[i]; + } + } + + ret = DBusJsonSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ASSISTANT_NOTIFY, + JSON_ENGINE_ASSISTANT_NOTIFY, + ¬ifyInfo, TRUE); + + return (ret); +} + +static void __cleanupAlarmArray(void) +{ + PASSISTANT_ARRAY_INFO pItem = NULL, pTmp = NULL; + + uv_rwlock_wrlock(&g_uvListRwLock); + DL_FOREACH_SAFE(g_pAlarmArray, pItem, pTmp) + { + AlarmTimerRemove(pItem->alarmItem.timerId); + DL_DELETE(g_pAlarmArray, pItem); + free(pItem); + } + uv_rwlock_wrunlock(&g_uvListRwLock); +} + +static void __cleanupRemaindArray(void) +{ + PASSISTANT_ARRAY_INFO pItem = NULL, pTmp = NULL; + + uv_rwlock_wrlock(&g_uvListRwLock); + DL_FOREACH_SAFE(g_pRemaindArray, pItem, pTmp) + { + AlarmTimerRemove(pItem->alarmItem.timerId); + DL_DELETE(g_pRemaindArray, pItem); + free(pItem); + } + uv_rwlock_wrunlock(&g_uvListRwLock); +} + +static void __cleanupSessionArray(void) +{ + PASSISTANT_ARRAY_INFO pItem = NULL, pTmp = NULL; + + uv_rwlock_wrlock(&g_uvListRwLock); + DL_FOREACH_SAFE(g_pSessionArray, pItem, pTmp) + { + AlarmTimerRemove(pItem->alarmItem.timerId); + DL_DELETE(g_pSessionArray, pItem); + free(pItem); + } + uv_rwlock_wrunlock(&g_uvListRwLock); +} + +static int __addNewItems(PASSISTANT_SYNC_INFO pInfo) +{ + struct tm localTime; + time_t loclStamp, tmStamp = time((time_t*)NULL); + + localtime_r(&tmStamp, &localTime); + loclStamp = mktime(&localTime); + + for(int i = 0; i < pInfo->nItems; i++) + { + PASSISTANT_ARRAY_INFO pItem = (PASSISTANT_ARRAY_INFO)malloc(sizeof(struct ASSISTANT_ARRAY_INFO)); + + if(pItem == NULL) + { + LOG_EX(LOG_Error, "Malloc Memory Error\n"); + return (-ERR_MALLOC_MEMORY); + } + + memset(pItem, 0, sizeof(struct ASSISTANT_ARRAY_INFO)); + + strcpy(pItem->alarmItem.strTips, pInfo->pAlarmInfo[i].strTips); + strcpy(pItem->alarmItem.resUrl, pInfo->pAlarmInfo[i].resUrl); + strcpy(pItem->alarmItem.voiceRes, pInfo->pAlarmInfo[i].voiceRes); + strcpy(pItem->alarmItem.voiceResType, pInfo->pAlarmInfo[i].voiceResType); + + pItem->alarmItem.itemType = pInfo->pAlarmInfo[i].itemType; + pItem->alarmItem.repeatMode = pInfo->pAlarmInfo[i].repeatMode; + pItem->alarmItem.voiceId = pInfo->pAlarmInfo[i].voiceId; + + pItem->alarmItem.year = pInfo->pAlarmInfo[i].year; + pItem->alarmItem.month = pInfo->pAlarmInfo[i].month; + pItem->alarmItem.day = pInfo->pAlarmInfo[i].day; + pItem->alarmItem.hour = pInfo->pAlarmInfo[i].hour; + pItem->alarmItem.minute = pInfo->pAlarmInfo[i].minute; + pItem->alarmItem.second = pInfo->pAlarmInfo[i].second; + pItem->alarmItem.weekDay = pInfo->pAlarmInfo[i].weekDay; + + if(ASSISTANT_TYPE_SESSION == pItem->alarmItem.itemType) + { + pItem->alarmItem.itemId = g_sessionId++; + } + else + { + pItem->alarmItem.itemId = pInfo->pAlarmInfo[i].itemId; + } + + if(pItem->alarmItem.repeatMode == REPEAT_MODE_NONE) + { + struct tm setTime; + time_t onTimeStamp; + int tmDiff; + + setTime.tm_year = pItem->alarmItem.year; + setTime.tm_mon = pItem->alarmItem.month; + setTime.tm_mday = pItem->alarmItem.day; + setTime.tm_hour = pItem->alarmItem.hour; + setTime.tm_min = pItem->alarmItem.minute; + setTime.tm_sec = pItem->alarmItem.second; + + onTimeStamp = mktime(&setTime); + tmDiff = (int)difftime(loclStamp, onTimeStamp); + + if(tmDiff >= 3) + { + LOG_EX(LOG_Warn, "%llu: Was Expired %d!!!!!!\n", pItem->alarmItem.itemId, tmDiff); + continue; + } + } + + uv_rwlock_wrlock(&g_uvListRwLock); + if(ASSISTANT_TYPE_CLOCK == pItem->alarmItem.itemType) + { + DL_APPEND(g_pAlarmArray, pItem); + } + else if(ASSISTANT_TYPE_REMAIND == pItem->alarmItem.itemType) + { + DL_APPEND(g_pRemaindArray, pItem); + } + else if(ASSISTANT_TYPE_SESSION == pItem->alarmItem.itemType) + { + DL_APPEND(g_pSessionArray, pItem); + } + else + { + LOG_EX(LOG_Error, "Unknown Type: %d\n", pItem->alarmItem.itemType); + } + uv_rwlock_wrunlock(&g_uvListRwLock); + + __addTaskToTimer(pItem); + } + + return (0); +} + +static void __removeAlarmItem(PASSISTANT_NOTIFY_INFO pRemove) +{ + PASSISTANT_ARRAY_INFO pItem = NULL, pTmp = NULL; + + for(int i = 0; i < pRemove->nItems; i++) + { + uv_rwlock_wrlock(&g_uvListRwLock); + DL_FOREACH_SAFE(g_pAlarmArray, pItem, pTmp) + { + if(pItem->alarmItem.itemId == pRemove->ids[i] + && pItem->alarmItem.itemType == pRemove->type) + { + AlarmTimerRemove(pItem->alarmItem.timerId); + DL_DELETE(g_pAlarmArray, pItem); + free(pItem); + } + } + uv_rwlock_wrunlock(&g_uvListRwLock); + } +} + +static void __removeRemaindItem(PASSISTANT_NOTIFY_INFO pRemove) +{ + PASSISTANT_ARRAY_INFO pItem = NULL, pTmp = NULL; + + for(int i = 0; i < pRemove->nItems; i++) + { + uv_rwlock_wrlock(&g_uvListRwLock); + DL_FOREACH_SAFE(g_pRemaindArray, pItem, pTmp) + { + if(pItem->alarmItem.itemId == pRemove->ids[i] + && pItem->alarmItem.itemType == pRemove->type) + { + AlarmTimerRemove(pItem->alarmItem.timerId); + DL_DELETE(g_pRemaindArray, pItem); + free(pItem); + } + } + uv_rwlock_wrunlock(&g_uvListRwLock); + } +} + +static int __alarmItemCmp(PASSISTANT_ARRAY_INFO pSrc, PASSISTANT_ARRAY_INFO pDst) +{ +#if 0 + fprintf(stdout, "id: %llu --> %llu, type: %u --> %u\n", + pSrc->alarmItem.itemId, pDst->alarmItem.itemId, + pSrc->alarmItem.itemType, pDst->alarmItem.itemType); +#endif + if(pSrc->alarmItem.itemId == pDst->alarmItem.itemId + && pSrc->alarmItem.itemType == pDst->alarmItem.itemType) + { + return (0); + } + else + { + return (1); + } +} + +static void __onAlarmCb(unsigned int tmId, unsigned int status, void *pUserData) +{ + PASSISTANT_ITEM_INFO pAlarm = (PASSISTANT_ITEM_INFO)pUserData; + PASSISTANT_ARRAY_INFO pItem = NULL; + struct ASSISTANT_ARRAY_INFO tmpItem; + + struct tm localTime; + time_t tmStamp = time((time_t*)NULL); + + localtime_r(&tmStamp, &localTime); + + LOG_EX(LOG_Debug, "Timer[%lld] %u On at [%04u-%02u-%02u %02u:%02u:%02u], status = %u\n", pAlarm->itemId, tmId, + localTime.tm_year + 1900, localTime.tm_mon + 1, localTime.tm_mday, + localTime.tm_hour, localTime.tm_min, localTime.tm_sec, + status); + + memset(&tmpItem, 0, sizeof(struct ASSISTANT_ARRAY_INFO)); + + tmpItem.alarmItem.itemId = pAlarm->itemId; + tmpItem.alarmItem.itemType = pAlarm->itemType; + + uv_rwlock_rdlock(&g_uvListRwLock); + if(pAlarm->itemType == ASSISTANT_TYPE_CLOCK) + { + DL_SEARCH(g_pAlarmArray, pItem, &tmpItem, __alarmItemCmp); + } + else if(pAlarm->itemType == ASSISTANT_TYPE_REMAIND) + { + DL_SEARCH(g_pRemaindArray, pItem, &tmpItem, __alarmItemCmp); + } + else if(pAlarm->itemType == ASSISTANT_TYPE_SESSION) + { + DL_SEARCH(g_pSessionArray, pItem, &tmpItem, __alarmItemCmp); + } + else + { + LOG_EX(LOG_Error, "Unknown type: %d\n", pAlarm->itemType); + } + uv_rwlock_rdunlock(&g_uvListRwLock); + + if(pItem) + { + pItem->alarmItem.year += 1900; + pItem->alarmItem.month += 1; + + __assistantRunningEvent(&pItem->alarmItem); + + if((pItem->alarmItem.repeatMode & 0xFF) == REPEAT_MODE_NONE) + { + uv_rwlock_wrlock(&g_uvListRwLock); + if(pAlarm->itemType == ASSISTANT_TYPE_CLOCK) + { + DL_DELETE(g_pAlarmArray, pItem); + } + else if(pAlarm->itemType == ASSISTANT_TYPE_REMAIND) + { + DL_DELETE(g_pRemaindArray, pItem); + } + else if(pAlarm->itemType == ASSISTANT_TYPE_SESSION) + { + DL_DELETE(g_pSessionArray, pItem); + } + else + { + LOG_EX(LOG_Error, "Unknown type: %d\n", pAlarm->itemType); + } + uv_rwlock_wrunlock(&g_uvListRwLock); + + free(pItem); + } + } +} + +static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t *pLoop, DBusConnection *pConn, PDBUS_MSG_PACK pMsg) +{ + PASSISTANT_SYNC_INFO pInfo = NULL; + PASSISTANT_NOTIFY_INFO pNotifyInfo = NULL; + int err = 0; + + if(!pMsg || !pLoop || !pConn) + { + return (NULL); + } + + if(pMsg->msgDests == 0xFFFFFFFF) + { + return (NULL); + } + + LOG_EX(LOG_Debug, "JSON(%08X) %s: %s\n", pMsg->busCmd, DBusCmdToString(pMsg->busCmd), (const char *)pMsg->pMsg); + + switch(pMsg->busCmd) + { + case CMD_SESSION_ALARM_SYNC: + if(IsHolidayDBSynced() != TRUE) + { + LOG_EX(LOG_Warn, "CMD_SESSION_ALARM_SYNC: Wait sync holiday database, this is dirty data.\n"); + break; + } + + pInfo = (PASSISTANT_SYNC_INFO)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_ASSISTANT_SYNC_RSP, FALSE, &err); + + if(pInfo) + { + __printAssistantSyncInfo(DBusCmdToString(pMsg->busCmd), pInfo); + + __cleanupSessionArray(); + + if(pInfo->pAlarmInfo && pInfo->nItems > 0) + { + err = __addNewItems(pInfo); + } + + __assistantRspStatus(pMsg->busCmd, err); + + free(pInfo->pAlarmInfo); + free(pInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + break; + + case CMD_ALARM_SYNC_RSP: + if(IsHolidayDBSynced() != TRUE) + { + LOG_EX(LOG_Warn, "CMD_ALARM_SYNC_RSP: Wait sync holiday database, this is dirty data.\n"); + break; + } + + pInfo = (PASSISTANT_SYNC_INFO)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_ASSISTANT_SYNC_RSP, FALSE, &err); + + if(pInfo) + { + g_syncFlags |= 1 << ASSISTANT_TYPE_CLOCK; + + __printAssistantSyncInfo(DBusCmdToString(pMsg->busCmd), pInfo); + + __cleanupAlarmArray(); + + if(pInfo->pAlarmInfo && pInfo->nItems > 0) + { + err = __addNewItems(pInfo); + } + + __assistantRspStatus(pMsg->busCmd, err); + + free(pInfo->pAlarmInfo); + free(pInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + + break; + + case CMD_ALARM_ADD: + pInfo = (PASSISTANT_SYNC_INFO)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_ASSISTANT_SYNC_RSP, TRUE, &err); + + if(pInfo) + { + __printAssistantSyncInfo(DBusCmdToString(pMsg->busCmd), pInfo); + + if(pInfo->pAlarmInfo && pInfo->nItems > 0) + { + err = __addNewItems(pInfo); + __assistantRspStatus(pMsg->busCmd, err); + + if(err == 0) + { + __assistantNotifyChange(pMsg->busCmd, pInfo->nItems, ASSISTANT_TYPE_CLOCK, pInfo->pAlarmInfo); + } + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + + free(pInfo->pAlarmInfo); + free(pInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + break; + + case CMD_ALARM_REMOVE: + pNotifyInfo = (PASSISTANT_NOTIFY_INFO)Json2Struct((const char *)pMsg->pMsg, + JSON_ENGINE_ASSISTANT_NOTIFY, FALSE, &err); + + if(pNotifyInfo) + { + __printAssistantNofifyInfo(DBusCmdToString(pMsg->busCmd), pNotifyInfo); + + if(pNotifyInfo->nItems > 0) + { + __removeAlarmItem(pNotifyInfo); + __assistantRspStatus(pMsg->busCmd, 0); + __assistantArrayNotifyChange(pMsg->busCmd, pNotifyInfo->nItems, ASSISTANT_TYPE_CLOCK, pNotifyInfo->ids); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + + free(pNotifyInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + + break; + + case CMD_ALARM_REMOVEALL: + __cleanupAlarmArray(); + __assistantRspStatus(pMsg->busCmd, 0); + __assistantNotifyChange(pMsg->busCmd, 0, ASSISTANT_TYPE_CLOCK, NULL); + break; + + case CMD_REMAIND_SYNC_RSP: + if(IsHolidayDBSynced() != TRUE) + { + LOG_EX(LOG_Warn, "CMD_REMAIND_SYNC_RSP: Wait sync holiday database, this is dirty data.\n"); + break; + } + + pInfo = (PASSISTANT_SYNC_INFO)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_ASSISTANT_SYNC_RSP, FALSE, &err); + + if(pInfo) + { + g_syncFlags |= 1 << ASSISTANT_TYPE_REMAIND; + + __printAssistantSyncInfo(DBusCmdToString(pMsg->busCmd), pInfo); + + __cleanupRemaindArray(); + + if(pInfo->pAlarmInfo && pInfo->nItems > 0) + { + err = __addNewItems(pInfo); + } + + __assistantRspStatus(pMsg->busCmd, err); + + free(pInfo->pAlarmInfo); + free(pInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + break; + + case CMD_REMAIND_ADD: + pInfo = (PASSISTANT_SYNC_INFO)Json2Struct((const char *)pMsg->pMsg, JSON_ENGINE_ASSISTANT_SYNC_RSP, TRUE, &err); + + if(pInfo) + { + __printAssistantSyncInfo(DBusCmdToString(pMsg->busCmd), pInfo); + + if(pInfo->pAlarmInfo && pInfo->nItems > 0) + { + err = __addNewItems(pInfo); + __assistantRspStatus(pMsg->busCmd, err); + + if(err == 0) + { + __assistantNotifyChange(pMsg->busCmd, pInfo->nItems, ASSISTANT_TYPE_REMAIND, pInfo->pAlarmInfo); + } + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + + free(pInfo->pAlarmInfo); + free(pInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + break; + + case CMD_REMAIND_REMOVE: + pNotifyInfo = (PASSISTANT_NOTIFY_INFO)Json2Struct((const char *)pMsg->pMsg, + JSON_ENGINE_ASSISTANT_NOTIFY, FALSE, &err); + + if(pNotifyInfo) + { + __printAssistantNofifyInfo(DBusCmdToString(pMsg->busCmd), pNotifyInfo); + + if(pNotifyInfo->nItems > 0) + { + __removeRemaindItem(pNotifyInfo); + __assistantRspStatus(pMsg->busCmd, 0); + __assistantArrayNotifyChange(pMsg->busCmd, pNotifyInfo->nItems, ASSISTANT_TYPE_REMAIND, pNotifyInfo->ids); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + + free(pNotifyInfo); + } + else + { + __assistantRspStatus(pMsg->busCmd, -ERR_INPUT_PARAMS); + } + break; + + case CMD_REMAIND_REMOVEALL: + __cleanupRemaindArray(); + __assistantRspStatus(pMsg->busCmd, 0); + __assistantNotifyChange(pMsg->busCmd, 0, ASSISTANT_TYPE_REMAIND, NULL); + break; + } + + return (NULL); +} + +static void __dBusDeameonCb(MODULE_NAME modName, int status) +{ + if(status) + { + LOG_EX(LOG_Error, "Daemon(%d) Msg: [%s]\n", modName, status == 0 ? "Connect" : "Disconnect"); + } + else + { + LOG_EX(LOG_Info, "Daemon(%d) Msg: [%s]\n", modName, status == 0 ? "Connect" : "Disconnect"); + } + +#if 0 + if(modName == MODULE_CONTROLLER && status == 0) + { + int ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ALARM_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_ALARM_SYNC_REQ Command: %d\n", ret); + + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_REMAIND_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_REMAIND_SYNC_REQ Command: %d\n", ret); + } +#endif +} + +static void __assistantSyncThread(void *pParam) +{ + int ret, i = 0, isSynced = -1; + + LOG_EX(LOG_Debug, "Beging Sync holiday Database\n"); + while(TRUE) + { + if(IsHolidayDBSynced() != TRUE) + { + CurrentIsWorkDay(0, 0); + if(i++ % 10 == 0 && i <= 1000) + { + LOG_EX(LOG_Debug, "Retry sync holiday database: %d\n", i); + } + sleep(SYNC_TIME_DELAY); + } + else + { + break; + } + } + LOG_EX(LOG_Debug, "Sync holiday Database Finished\n"); + + LOG_EX(LOG_Debug, "Beging sync ASSISTANT_TYPE_CLOCK\n"); + do + { + if(g_syncFlags & (1 << ASSISTANT_TYPE_CLOCK)) + { + LOG_EX(LOG_Debug, "Sync ASSISTANT_TYPE_CLOCK Finished\n"); + break; + } + + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ALARM_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_ALARM_SYNC_REQ Command: %d\n", ret); + + sleep(SYNC_TIME_DELAY); + } while(TRUE); + + LOG_EX(LOG_Debug, "Beging sync ASSISTANT_TYPE_REMAIND\n"); + do + { + if(g_syncFlags & (1 << ASSISTANT_TYPE_REMAIND)) + { + LOG_EX(LOG_Debug, "Sync ASSISTANT_TYPE_REMAIND Finished\n"); + break; + } + + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_REMAIND_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_REMAIND_SYNC_REQ Command: %d\n", ret); + + sleep(SYNC_TIME_DELAY); + } while(TRUE); + +#if 0 + do + { + if((g_syncFlags & (1 << ASSISTANT_TYPE_CLOCK)) + && (g_syncFlags & (1 << ASSISTANT_TYPE_REMAIND))) + { + LOG_EX(LOG_Debug, "Sync Alarm And Remaind Finished\n"); + break; + } + + if((g_syncFlags & (1 << ASSISTANT_TYPE_CLOCK)) == 0) + { + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ALARM_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_ALARM_SYNC_REQ Command: %d\n", ret); + } + + if((g_syncFlags & (1 << ASSISTANT_TYPE_REMAIND)) == 0) + { + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_REMAIND_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_REMAIND_SYNC_REQ Command: %d\n", ret); + } + + sleep(SYNC_TIME_DELAY); + } while(TRUE); + //while(g_syncFlags != ((1 << ASSISTANT_TYPE_CLOCK) | (1 << ASSISTANT_TYPE_REMAIND))); + + + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_ALARM_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_ALARM_SYNC_REQ Command: %d\n", ret); + + ret = DBusSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_REMAIND_SYNC_REQ, ""); + + LOG_EX(LOG_Debug, "Send CMD_REMAIND_SYNC_REQ Command: %d\n", ret); +#endif + + pthread_detach(pthread_self()); +} + +int main(int argc, char **argv) +{ + int ret = 0; + DBusConnection* pBus; + uv_loop_t* pLoop = GetDBusDefaultLoop(); + uv_thread_t uvSyncThread; + + pBus = DBusWithLibuvInit(pLoop, g_pModInfoTable[MODULE_ALARM].modAliase, + __dBusOnMessage, + __dBusDeameonCb, + NULL, &ret); + + if(pBus == NULL) + { + fprintf(stderr, "DBusWithLibuvInit Error: %d\n", ret); + return 0; + } + + uv_rwlock_init(&g_uvListRwLock); + + AlarmTimerInit(pLoop); + + uv_thread_create(&uvSyncThread, __assistantSyncThread, NULL); + RunUVLoop(pLoop); + + while(TRUE) + { + usleep(1000); + } + + return 0; +} diff --git a/app/libuvdbus/Config.in b/app/libuvdbus/Config.in new file mode 100644 index 0000000..2c6deb0 --- /dev/null +++ b/app/libuvdbus/Config.in @@ -0,0 +1,17 @@ +if PACKAGE_libuvdbus + +comment "Resource Mode Select" + +choice + prompt "Select Resources Work Mode" + default RES_NORMAL_MODE + + config RES_FACTORY_MODE + bool "Used For Factory Mode" + + config RES_NORMAL_MODE + bool "Used For Normal Mode" + +endchoice + +endif diff --git a/app/libuvdbus/Makefile b/app/libuvdbus/Makefile new file mode 100644 index 0000000..890c765 --- /dev/null +++ b/app/libuvdbus/Makefile @@ -0,0 +1,68 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common +include $(TOPDIR)/rules.mk + +PKG_NAME:=libuvdbus +PKG_RELEASE:=1 +PKG_VERSION:=0.0.1 + +PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME) + +include $(BUILD_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=utils + CATEGORY:=Netease + TITLE:=Libuv dubs + MAINTAINER:=Huang xin + DEPENDS:=$(LIB_MAKE_COMMON_DEPEND) +endef + +ifeq ('$(CONFIG_RES_FACTORY_MODE)', 'y') + TARGET_CFLAGS += -DRES_FACTORY_MODE +endif + +define Package/$(PKG_NAME)/description + Libuv + dbus pack! +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) -d ./src/ $(PKG_BUILD_DIR)/ +endef + +define Package/$(PKG_NAME)/config + source "$(SOURCE)/Config.in" +endef + +define Build/Configure +endef + +define Build/InstallDev + $(INSTALL_DIR) $(1)/usr/include/ + $(INSTALL_DIR) $(1)/lib/ + $(CP) \ + $(PKG_BUILD_DIR)/src/include \ + $(1)/usr/include/uvdbus + + $(CP) $(PKG_INSTALL_DIR)/usr/lib/libuvdbus.so $(1)/lib/ +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR)/src \ + ARCH="$(TARGET_ARCH)" \ + AR="$(TARGET_AR)" \ + CC="$(TARGET_CC)" \ + CXX="$(TARGET_CXX)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \ + TARGET_NAME=$(PKG_NAME) \ + all +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/lib + $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/lib/libuvdbus.so $(1)/lib/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/app/libuvdbus/src/Framework/Compress/zlib.c b/app/libuvdbus/src/Framework/Compress/zlib.c new file mode 100644 index 0000000..b78f863 --- /dev/null +++ b/app/libuvdbus/src/Framework/Compress/zlib.c @@ -0,0 +1,110 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "crypto.h" + +#define CHUNK_BLOCK (16384) + +/* Compress from file source to file dest until EOF on source. + def() returns Z_OK on success, Z_MEM_ERROR if memory could not be + allocated for processing, Z_STREAM_ERROR if an invalid compression + level is supplied, Z_VERSION_ERROR if the version of zlib.h and the + version of the library linked do not match, or Z_ERRNO if there is + an error reading or writing the files. */ +int GZipFileCompress(const char* pInput, const char* pOutput) +{ + int ret, isFlush; + unsigned int have; + z_stream strm; + char strPath[256]; + unsigned char in[CHUNK_BLOCK]; + unsigned char out[CHUNK_BLOCK]; + FILE *source, *dest; + + if (pInput == NULL) + { + return (Z_ERRNO); + } + + if(access(pInput, F_OK) != 0) + { + return (Z_ERRNO); + } + + //fprintf(stdout, "in: %s\n", pInput); + + source = fopen(pInput, "r+"); + + memset(strPath, 0, 256); + if (pOutput == NULL || strlen(pOutput) == 0) + { + sprintf(strPath, "%s.gz", pInput); + dest = fopen(strPath, "w+"); + + //fprintf(stdout, "out: %s\n", strPath); + } + else + { + dest = fopen(pOutput, "w+"); + //fprintf(stdout, "out: %s\n", pOutput); + } + + /* allocate deflate state */ + strm.zalloc = Z_NULL; + strm.zfree = Z_NULL; + strm.opaque = Z_NULL; + //ret = deflateInit(&strm, level); + ret = deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, MAX_WBITS + 16, 8, Z_DEFAULT_STRATEGY); + + if (ret != Z_OK) + { + fclose(source); + fclose(dest); + return ret; + } + + /* compress until end of file */ + do { + strm.avail_in = fread(in, 1, CHUNK_BLOCK, source); + if (ferror(source)) { + (void)deflateEnd(&strm); + fclose(source); + fclose(dest); + return Z_ERRNO; + } + isFlush = feof(source) ? Z_FINISH : Z_NO_FLUSH; + strm.next_in = in; + + /* run deflate() on input until output buffer not full, finish + compression if all of source has been read in */ + do { + strm.avail_out = CHUNK_BLOCK; + strm.next_out = out; + ret = deflate(&strm, isFlush); /* no bad return value */ + have = CHUNK_BLOCK - strm.avail_out; + if (fwrite(out, 1, have, dest) != have || ferror(dest)) { + (void)deflateEnd(&strm); + fclose(source); + fclose(dest); + return Z_ERRNO; + } + } while (strm.avail_out == 0); + + /* done when last data in file processed */ + } while (isFlush != Z_FINISH); + + /* clean up and return */ + (void)deflateEnd(&strm); + + fflush(dest); + + fclose(source); + fclose(dest); + return Z_OK; +} + diff --git a/app/libuvdbus/src/Framework/Configure/config_engine.c b/app/libuvdbus/src/Framework/Configure/config_engine.c new file mode 100644 index 0000000..4b5c276 --- /dev/null +++ b/app/libuvdbus/src/Framework/Configure/config_engine.c @@ -0,0 +1,1042 @@ +#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; + } +} diff --git a/app/libuvdbus/src/Framework/Configure/ini_prase.c b/app/libuvdbus/src/Framework/Configure/ini_prase.c new file mode 100644 index 0000000..3542f87 --- /dev/null +++ b/app/libuvdbus/src/Framework/Configure/ini_prase.c @@ -0,0 +1,289 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "libuv_dbus.h" +#include "server_addr.h" + +#ifdef PLATFORM_R16 +#define DEVICE_CFG_FILE ("/mnt/UDISK/dev.conf") +#else +#define DEVICE_CFG_FILE ("./dev.conf") +#endif + +static config_t g_cfgInfo; + +void InitCfgToCfgFile(config_t* pCfg) +{ + config_setting_t *pRoot, *pSetting, *pGlobalgrp, *pLogGrp, *pSubGrp; + + if(pCfg == NULL) + { + return; + } + + pRoot = config_root_setting(pCfg); + + pGlobalgrp = config_setting_add(pRoot, "Global", CONFIG_TYPE_GROUP); + + pSetting = config_setting_add(pGlobalgrp, "ServerMode", CONFIG_TYPE_INT); + config_setting_set_int(pSetting, PUBLISH_MODE); + + pLogGrp = config_setting_add(pGlobalgrp, "Log", CONFIG_TYPE_GROUP); + + pSetting = config_setting_add(pLogGrp, "Enable", CONFIG_TYPE_BOOL); + config_setting_set_bool(pSetting, TRUE); + + pSetting = config_setting_add(pLogGrp, "Level", CONFIG_TYPE_INT); + config_setting_set_format(pSetting, CONFIG_FORMAT_HEX); + config_setting_set_int(pSetting, 0x000003FF); + + pSubGrp = config_setting_add(pLogGrp, "LogToEMail", CONFIG_TYPE_GROUP); + pSetting = config_setting_add(pSubGrp, "Enable", CONFIG_TYPE_BOOL); + config_setting_set_bool(pSetting, FALSE); + pSetting = config_setting_add(pSubGrp, "EMail", CONFIG_TYPE_STRING); + config_setting_set_string(pSetting, "pv1_es2@163.com"); + + pSetting = config_setting_add(pLogGrp, "LogToFile", CONFIG_TYPE_BOOL); + config_setting_set_bool(pSetting, TRUE); + + pSetting = config_setting_add(pLogGrp, "LogToServer", CONFIG_TYPE_BOOL); + config_setting_set_bool(pSetting, TRUE); + + pSubGrp = config_setting_add(pLogGrp, "LogToUDPServer", CONFIG_TYPE_GROUP); + pSetting = config_setting_add(pSubGrp, "Enable", CONFIG_TYPE_BOOL); + config_setting_set_bool(pSetting, FALSE); + pSetting = config_setting_add(pSubGrp, "UdpServerIp", CONFIG_TYPE_STRING); + config_setting_set_string(pSetting, "10.240.84.163"); + pSetting = config_setting_add(pSubGrp, "UdpBasePort", CONFIG_TYPE_INT); + config_setting_set_int(pSetting, 10000); + + + if(!config_write_file(pCfg, DEVICE_CFG_FILE)) + { + LOG_EX(LOG_Error, "Create Configure File %s Error\n", DEVICE_CFG_FILE); + } +} + +int CfgGetIntValueV2(const char* pTags, int defValue, int* pErr) +{ + char* pSvrMode = NULL; + char cmdBuf[MAX_PATH]; + int iValue = defValue; + + memset(cmdBuf, 0, MAX_PATH); + + sprintf(cmdBuf, "cat %s | grep %s | awk '{print $3}' | cut -d \";\" -f 1", + DEVICE_CFG_FILE, + pTags); + + GetShellExecResult(cmdBuf, &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; +} + +int CfgGetIntValueV1(const char* pTags, int defValue, int* pErr) +{ + int iValue = defValue; + + if(pTags == NULL || strlen(pTags) == 0) + { + if(pErr) + { + *pErr = -ERR_INPUT_PARAMS; + } + + return defValue; + } + + if(!config_lookup_int(&g_cfgInfo, pTags, &iValue)) + { + if(pErr) + { + *pErr = -ERR_READ_FILE; + } + + return defValue; + } + + *pErr = 0; + + return iValue; +} + +int CfgGetIntValue(const char* pTags, int defValue) +{ + int iValue = defValue; + + if(pTags == NULL || strlen(pTags) == 0) + { + return defValue; + } + + if(!config_lookup_int(&g_cfgInfo, pTags, &iValue)) + { + return defValue; + } + + return iValue; +} + +void CfgSetIntValue(const char* pTags, int iValue) +{ + config_setting_t *pRoot, *pGlobalgrp, *pSet; + + LOG_EX(LOG_Debug, "Set: %s --> %d\n", pTags, iValue); + + if(pTags == NULL || strlen(pTags) == 0) + { + LOG_EX(LOG_Error, "Input Params error: pTags = [%s]\n", pTags ? pTags : "NULL"); + return; + } + + pRoot = config_root_setting(&g_cfgInfo); + + if(pRoot == NULL) + { + LOG_EX(LOG_Error, "pRoot = NULL\n"); + return; + } + + pGlobalgrp = config_setting_get_member(pRoot, "Global"); + + if(pGlobalgrp == NULL) + { + LOG_EX(LOG_Error, "pGlobalgrp = NULL\n"); + return; + } + + pSet = config_setting_get_member(pGlobalgrp, pTags); + + if(!pSet) + { + pSet = config_setting_add(pGlobalgrp, pTags, CONFIG_TYPE_INT); + } + + if(pSet == NULL) + { + LOG_EX(LOG_Error, "pSet = NULL\n"); + return; + } + + config_setting_set_int(pSet, iValue); + + + if(!config_write_file(&g_cfgInfo, DEVICE_CFG_FILE)) + { + LOG_EX(LOG_Error, "Set %s Value Error\n", pTags); + } +} + +char* CfgGetStringValue(const char* pTags, char* pDefValue) +{ + char* pValue = pDefValue; + + if(pTags == NULL || strlen(pTags) == 0) + { + return pDefValue; + } + + if(!config_lookup_string(&g_cfgInfo, pTags, (const char**)&pValue)) + { + return pDefValue; + } + + return pValue; +} + +double CfgGetFloatValue(const char* pTags, double defValue) +{ + double dValue = defValue; + + if(pTags == NULL || strlen(pTags) == 0) + { + return defValue; + } + + if(!config_lookup_float(&g_cfgInfo, pTags, &dValue)) + { + return defValue; + } + + return dValue; +} + +int CfgGetBoolValue(const char* pTags, int defValue) +{ + int iValue = defValue; + + if(pTags == NULL || strlen(pTags) == 0) + { + return defValue; + } + + if(!config_lookup_bool(&g_cfgInfo, pTags, &iValue)) + { + return defValue; + } + + return iValue; +} + +void CfgFileInit(void) +{ + //config_setting_t *pRoot, *pSetting; + + config_init(&g_cfgInfo); + +#if 0 + config_set_options(&g_cfgInfo, + (CONFIG_OPTION_SEMICOLON_SEPARATORS + | CONFIG_OPTION_COLON_ASSIGNMENT_FOR_GROUPS + | CONFIG_OPTION_OPEN_BRACE_ON_SEPARATE_LINE)); +#endif + + config_set_tab_width(&g_cfgInfo, 4); + + if(access(DEVICE_CFG_FILE, F_OK) != 0) + { + InitCfgToCfgFile(&g_cfgInfo); + } + else if(!config_read_file(&g_cfgInfo, DEVICE_CFG_FILE)) + { + LOG_EX(LOG_Error, "Read Configure File %s Error\n", DEVICE_CFG_FILE); + return; + } +} diff --git a/app/libuvdbus/src/Framework/Crypto/aes.c b/app/libuvdbus/src/Framework/Crypto/aes.c new file mode 100644 index 0000000..afff0ac --- /dev/null +++ b/app/libuvdbus/src/Framework/Crypto/aes.c @@ -0,0 +1,104 @@ +#include +#include +#include +#include + +#include "log.h" +#include "smart_sound.h" +#include "crypto.h" +#include "libuv_dbus.h" + +int EvpAESEncrypto(unsigned char* pInBuf, + int iSize, + unsigned char* pOutBuf, + int* pOutSize, + unsigned char* pKey) +{ + int enBytes = 0; + EVP_CIPHER_CTX ctx; + //int decDataLen = 0; + if(!pInBuf || !pOutBuf || !pOutSize || !pKey) + { + return -ERR_INPUT_PARAMS; + } + + *pOutSize = 0; + //decDataLen = ((iSize + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE; + + EVP_CIPHER_CTX_init(&ctx); + + if(EVP_EncryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, pKey, NULL) == 0) + { + LOG_EX(LOG_Error, "EVP_EncryptInit_ex Error\n"); + return -ERR_EVP_INIT_KEY; + } + + if(EVP_EncryptUpdate(&ctx, pOutBuf, &enBytes, pInBuf, iSize) == 0) + { + LOG_EX(LOG_Error, "EVP_EncryptUpdate Error\n"); + return -ERR_EVP_UPDATE; + } + + pOutBuf += enBytes; + pInBuf += enBytes; + *pOutSize += enBytes; + + if(EVP_EncryptFinal_ex(&ctx, pOutBuf, &enBytes) == 0) + { + LOG_EX(LOG_Error, "EVP_EncryptFinal_ex Error\n"); + return -ERR_EVP_FINALE; + } + + *pOutSize += enBytes; + + EVP_CIPHER_CTX_cleanup(&ctx); + + return 0; +} + +int EvpAESDecrypto(unsigned char* pInBuf, + int iSize, + unsigned char* pOutBuf, + int* pOutSize, + unsigned char* pKey) +{ + int deBytes = 0; + EVP_CIPHER_CTX ctx; + + if(!pInBuf || !pOutBuf || !pOutSize || !pKey) + { + return -ERR_INPUT_PARAMS; + } + + EVP_CIPHER_CTX_init(&ctx); + + *pOutSize = 0; + + if(EVP_DecryptInit_ex(&ctx, EVP_aes_128_ecb(), NULL, pKey, NULL) == 0) + { + LOG_EX(LOG_Error, "EVP_DecryptInit_ex Error\n"); + return -ERR_EVP_INIT_KEY; + } + + if(EVP_DecryptUpdate(&ctx, pOutBuf, &deBytes, pInBuf, iSize) == 0) + { + LOG_EX(LOG_Error, "EVP_EncryptUpdate Error\n"); + return -ERR_EVP_UPDATE; + } + + pOutBuf += deBytes; + pInBuf += deBytes; + *pOutSize += deBytes; + + if(EVP_DecryptFinal_ex(&ctx, pOutBuf, &deBytes) == 0) + { + LOG_EX(LOG_Error, "EVP_EncryptFinal_ex Error\n"); + return -ERR_EVP_FINALE; + } + + *pOutSize += deBytes; + EVP_CIPHER_CTX_cleanup(&ctx); + + return 0; +} + diff --git a/app/libuvdbus/src/Framework/Crypto/base64.c b/app/libuvdbus/src/Framework/Crypto/base64.c new file mode 100644 index 0000000..6941073 --- /dev/null +++ b/app/libuvdbus/src/Framework/Crypto/base64.c @@ -0,0 +1,158 @@ +#include +#include +#include +#include + +#include "log.h" +#include "crypto.h" + +const char* EvpBase64Encode(const char* pSrc) +{ + EVP_ENCODE_CTX ctx; + int enSize = 0; + int sLen, size; + char* pEncode = NULL; + + if(pSrc == NULL || strlen(pSrc) == 0) + { + return (NULL); + } + + sLen = strlen(pSrc); + size = ((sLen / 3) * 4) + 4 + (sLen / 64) + sLen % 64; + + pEncode = (char*)malloc(size); + memset(pEncode, 0, size); + + EVP_EncodeInit(&ctx); + EVP_EncodeUpdate(&ctx, pEncode, &enSize, pSrc, strlen(pSrc)); + EVP_EncodeFinal(&ctx, pEncode + enSize, &enSize); + +// fprintf(stdout, "Src: \n[%s]\n", pSrc); +// fprintf(stdout, "Base64(%d --> %d | %d) Bytes: \n[%s]\n", sLen, size, strlen(pEncode), pEncode); + + return pEncode; +} + +const char* EvpBase64Decode(const char* pBase64) +{ + EVP_ENCODE_CTX ctx; + int enSize = 0; + int size = 0; + char *pDecode = NULL; + + if(pBase64 == NULL || strlen(pBase64) == 0) + { + return (NULL); + } + + size = strlen(pBase64); + pDecode = (char*)malloc(size); + memset(pDecode, 0, size); + + EVP_DecodeInit(&ctx); + EVP_DecodeUpdate(&ctx, pDecode, &enSize, pBase64, strlen(pBase64)); + EVP_DecodeFinal(&ctx, pDecode + enSize, &enSize); + +// fprintf(stdout, "Decode(%d --> %d) Bytes: \n[%s]\n", size, strlen(pDecode), pDecode); + + return pDecode; +} + +const char* EvpBase64EncodeNoAlign(const char* pSrc) +{ + int size, sLen; + char* pEncode = NULL; + + if(pSrc == NULL || strlen(pSrc) == 0) + { + return (NULL); + } + + sLen = strlen(pSrc); + size = ((sLen / 3) * 4) + 4 + (sLen / 64) + sLen % 64; + + pEncode = (char*)malloc(size); + memset(pEncode, 0, size); + + EVP_EncodeBlock(pEncode, (const unsigned char *)pSrc, sLen); +// fprintf(stdout, "Src: \n[%s]\n", pSrc); +// fprintf(stdout, "Base64(%d --> %d | %d) Bytes: \n[%s]\n", sLen, size, strlen(pEncode), pEncode); + + return pEncode; +} + +const char* EvpBase64EncodeNoAlignV2(unsigned char* pSrc, int sLen) +{ + int size; + char* pEncode = NULL; + + if(pSrc == NULL || sLen <= 0) + { + return (NULL); + } + + size = ((sLen / 3) * 4) + 4 + (sLen / 64) + sLen % 64; + + pEncode = (char*)malloc(size); + memset(pEncode, 0, size); + + EVP_EncodeBlock(pEncode, (const unsigned char *)pSrc, sLen); +// fprintf(stdout, "Src: \n[%s]\n", pSrc); +// fprintf(stdout, "Base64(%d --> %d | %d) Bytes: \n[%s]\n", sLen, size, strlen(pEncode), pEncode); + + return pEncode; +} + +const char* EvpBase64DecodeNoAlign(const char *pBase64) +{ + int size = 0; + char *pDecode = NULL; + + if(pBase64 == NULL || strlen(pBase64) == 0) + { + return (NULL); + } + + size = strlen(pBase64); + + pDecode = (char*)malloc(size); + memset(pDecode, 0, size); + + //CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + EVP_DecodeBlock(pDecode, (const unsigned char *)pBase64, size); + //CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + +// fprintf(stdout, "Decode(%d --> %d) Bytes: \n[%s]\n", size, strlen(pDecode), pDecode); + + return pDecode; +} + +unsigned char* EvpBase64DecodeNoAlignV2(const char *pBase64, int* pOutSize) +{ + int size = 0; + unsigned char *pDecode = NULL; + + if(pBase64 == NULL || strlen(pBase64) == 0) + { + return (NULL); + } + + size = strlen(pBase64); + + pDecode = (char*)malloc(size); + memset(pDecode, 0, size); + + //CRYPTO_w_lock(CRYPTO_LOCK_DYNLOCK); + size = EVP_DecodeBlock(pDecode, (const unsigned char *)pBase64, size); + //CRYPTO_w_unlock(CRYPTO_LOCK_DYNLOCK); + +// fprintf(stdout, "Decode(%d --> %d) Bytes: \n[%s]\n", size, strlen(pDecode), pDecode); + + if(pOutSize) + { + *pOutSize = size; + } + + return (pDecode); +} diff --git a/app/libuvdbus/src/Framework/Crypto/crypto.c b/app/libuvdbus/src/Framework/Crypto/crypto.c new file mode 100644 index 0000000..226f1a3 --- /dev/null +++ b/app/libuvdbus/src/Framework/Crypto/crypto.c @@ -0,0 +1,187 @@ +#include +#include +#include +#include + +#include "log.h" +#include "smart_sound.h" +#include "crypto.h" +#include "libuv_dbus.h" + +static uv_mutex_t *pEvpMutex = NULL; +typedef struct +{ + CRYPTO_TYPE type; + unsigned char* pInData; + int iInSize; + unsigned char* pOutData; + unsigned char pKey[EVP_MAX_KEY_LENGTH + 1]; + OnEVPCrypto onEvpEventCb; +} CRYPT_TASK_PARAMS, *PCRYPT_TASK_PARAMS; + +static void FreeEVPWorkCb(uv_work_t* pWork, int status) +{ + PCRYPT_TASK_PARAMS pTask = (PCRYPT_TASK_PARAMS)pWork->data; + free(pTask->pInData); + free(pTask); + free(pWork); +} + +static void OnEVPWorkCb(uv_work_t* pWork) +{ + PCRYPT_TASK_PARAMS pTask = (PCRYPT_TASK_PARAMS)pWork->data; + int iOutSize = 0; + int iError = 0; + + switch(pTask->type) + { + case CRYPTO_AES_ENCRYPT: + iError = EvpAESEncrypto(pTask->pInData, + pTask->iInSize, + pTask->pOutData, + &iOutSize, + pTask->pKey); + break; + + case CRYPTO_AES_DECRYPT: + iError = EvpAESDecrypto(pTask->pInData, + pTask->iInSize, + pTask->pOutData, + &iOutSize, + pTask->pKey); + break; + + case CRYPTO_BASE64_ENCODE: + pTask->pOutData = (unsigned char*)EvpBase64Encode((const char*)pTask->pInData); + iOutSize = strlen((char*)pTask->pOutData); + break; + + case CRYPTO_BASE64_DECODE: + pTask->pOutData = (unsigned char*)EvpBase64Decode((const char*)pTask->pInData); + iOutSize = strlen((char*)pTask->pOutData); + break; + + case CRYPTO_MD5_FILE: + pTask->pOutData = (unsigned char*)EvpMD5HashFile((const char*)pTask->pInData); + iOutSize = strlen((char*)pTask->pOutData); + break; + + default: + iError = -ERR_UNSUP_EVP_TYPE; + } + + if(iError != 0) + { + pTask->onEvpEventCb(pTask->type, pTask->pOutData, 0, pTask->pInData, iError); + } + else + { + pTask->onEvpEventCb(pTask->type, pTask->pOutData, iOutSize, pTask->pInData, 0); + } +} + +int EvpAddCryptoTask(CRYPTO_TYPE type, + unsigned char* pInBuf, + int iSize, + unsigned char* pOutBuf, + char* pKey, + OnEVPCrypto onEvpCryptCb) +{ + uv_work_t* puvWork = NULL; + PCRYPT_TASK_PARAMS pTask = NULL; + PLIBUV_DBUS_PARAMS pContext = DBusLibuvGetRuntime(); + + if(!pContext || !onEvpCryptCb) + { + return -ERR_INPUT_PARAMS; + } + + if(type == CRYPTO_AES_ENCRYPT || type == CRYPTO_AES_DECRYPT) + { + if(pKey == NULL || pOutBuf == NULL) + { + return -ERR_INPUT_PARAMS; + } + + switch(strlen(pKey) * 8) + { + case 128: + case 192: + case 256: + break; + default: + return -ERR_EVP_KEY_SIZE; + } + } + else if(type == CRYPTO_MD5_FILE) + { + uv_fs_t uvFs; + if(uv_fs_access(pContext->pLoop, &uvFs, (const char*)pInBuf, F_OK, NULL) != 0) + { + return -ERR_FILE_NOT_EXISTS; + } + } + + pTask = (PCRYPT_TASK_PARAMS)malloc(sizeof(CRYPT_TASK_PARAMS)); + puvWork = (uv_work_t*)malloc(sizeof(uv_work_t)); + + puvWork->data = (void*)pTask; + + pTask->type = type; + pTask->pInData = (unsigned char*)malloc(iSize + 1); + pTask->iInSize = iSize; + pTask->pOutData = pOutBuf; + pTask->onEvpEventCb = onEvpCryptCb; + + memset(pTask->pInData, 0, iSize + 1); + memset(pTask->pKey, 0, EVP_MAX_KEY_LENGTH + 1); + + if(pKey) + { + strncpy(pTask->pKey, pKey, EVP_MAX_KEY_LENGTH); + } + + memcpy(pTask->pInData, pInBuf, iSize); + + uv_queue_work(pContext->pLoop, puvWork, OnEVPWorkCb, FreeEVPWorkCb); + + return 0; +} + +static void __evpLockCb(int mode, int n, const char *pFile, int line) +{ + if(n >= CRYPTO_num_locks()) + { + return; + } + + if(mode & CRYPTO_LOCK) + { + uv_mutex_lock(&pEvpMutex[n]); + } + else + { + uv_mutex_unlock(&pEvpMutex[n]); + } +} + + +static unsigned long __evpIdCb(void) +{ + return ((unsigned long)uv_thread_self()); +} + +void EvpSystemInit(void) +{ + int i = 0; + + pEvpMutex = (uv_mutex_t *)malloc(CRYPTO_num_locks() * sizeof(uv_mutex_t)); + + for(i = 0; i < CRYPTO_num_locks(); i++) + { + uv_mutex_init(&pEvpMutex[i]); + } + + CRYPTO_set_id_callback(__evpIdCb); + CRYPTO_set_locking_callback(__evpLockCb); +} diff --git a/app/libuvdbus/src/Framework/Crypto/md5.c b/app/libuvdbus/src/Framework/Crypto/md5.c new file mode 100644 index 0000000..655e7b0 --- /dev/null +++ b/app/libuvdbus/src/Framework/Crypto/md5.c @@ -0,0 +1,156 @@ +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "crypto.h" +#include "libuv_dbus.h" + +const char* EvpMD5HashFile(const char* pFileName) +{ + int rdSize = 0; + int fd, size; + uint8_t md5[EVP_MAX_MD_SIZE]; + uint8_t buf[1024]; + EVP_MD_CTX ctx; + char* pString = NULL; + + memset(md5, 0, EVP_MAX_MD_SIZE); + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_md5(), NULL); + + fd = open(pFileName, O_RDONLY); + + if(fd == -1) + { + LOG_EX(LOG_Error, "Open File \'%s\' error\n", pFileName); + return NULL; + } + do + { + rdSize = read(fd, buf, 1024); + + if(rdSize > 0) + { + EVP_DigestUpdate(&ctx, buf, rdSize); + } + } while(rdSize > 0); + + close(fd); + + EVP_DigestFinal_ex(&ctx, md5, &rdSize); + EVP_MD_CTX_cleanup(&ctx); + + size = rdSize * 2 + 1; + + pString = (char*)malloc(size); + memset(pString, 0, size); + + IHW_bin2hex(pString, md5, rdSize); + +// print_hex_dump_bytes("MD5_", DUMP_PREFIX_ADDRESS, md5, rdSize); +// fprintf(stdout, "MD5: [%s]\n", pString); + + return (const char*)pString; +} + +int EvpMD5HashFileV2(const char* pFileName, unsigned char md5[16]) +{ + int rdSize = 0; + int fd; + uint8_t buf[1024]; + EVP_MD_CTX ctx; + //char* pString = NULL; + + memset(md5, 0, 16); + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_md5(), NULL); + + fd = open(pFileName, O_RDONLY); + + if(fd == -1) + { + LOG_EX(LOG_Error, "Open File %s error\n", pFileName); + return (-ERR_OPEN_FILE); + } + do + { + rdSize = read(fd, buf, 1024); + + EVP_DigestUpdate(&ctx, buf, rdSize); + } while(rdSize > 0); + + close(fd); + + EVP_DigestFinal_ex(&ctx, md5, &rdSize); + EVP_MD_CTX_cleanup(&ctx); + + +// print_hex_dump_bytes("MD5_", DUMP_PREFIX_ADDRESS, md5, rdSize); +// fprintf(stdout, "MD5: [%s]\n", pString); + + return 0; +} + +int EvpMD5HashBuf(const unsigned char* pBuf, int iBufLen, unsigned char* pOutBuf, int* pOutSize) +{ + EVP_MD_CTX ctx; + + if(pBuf == NULL || pOutBuf == NULL) + { + return (-ERR_INPUT_PARAMS); + } + + memset(pOutBuf, 0, EVP_MAX_MD_SIZE); + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_md5(), NULL); + EVP_DigestUpdate(&ctx, pBuf, iBufLen); + EVP_DigestFinal_ex(&ctx, pOutBuf, &iBufLen); + EVP_MD_CTX_cleanup(&ctx); + + if(pOutSize) + { + *pOutSize = iBufLen; + } + + //print_hex_dump_bytes("MD5_", DUMP_PREFIX_ADDRESS, pOutBuf, iBufLen); + + return 0; +} + +const char* EvpMD5HashBufV2(const unsigned char* pBuf, int iBufLen) +{ + int size = 0; + EVP_MD_CTX ctx; + uint8_t md5[EVP_MAX_MD_SIZE]; + char* pString = NULL; + + if(pBuf == NULL || iBufLen <= 0) + { + return NULL; + } + + memset(md5, 0, EVP_MAX_MD_SIZE); + EVP_MD_CTX_init(&ctx); + EVP_DigestInit_ex(&ctx, EVP_md5(), NULL); + EVP_DigestUpdate(&ctx, pBuf, iBufLen); + EVP_DigestFinal_ex(&ctx, md5, &iBufLen); + EVP_MD_CTX_cleanup(&ctx); + + //print_hex_dump_bytes("MD5_", DUMP_PREFIX_ADDRESS, pOutBuf, iBufLen); + + size = iBufLen * 2 + 1; + + pString = (char*)malloc(size); + memset(pString, 0, size); + + IHW_bin2hex(pString, md5, iBufLen); + +// print_hex_dump_bytes("MD5_", DUMP_PREFIX_ADDRESS, md5, rdSize); +// fprintf(stdout, "MD5: [%s]\n", pString); + + return (const char*)pString; +} diff --git a/app/libuvdbus/src/Framework/Fifo/fifo.c b/app/libuvdbus/src/Framework/Fifo/fifo.c new file mode 100644 index 0000000..5fd3753 --- /dev/null +++ b/app/libuvdbus/src/Framework/Fifo/fifo.c @@ -0,0 +1,554 @@ +/* + * A generic kernel FIFO implementation + * + * Copyright (C) 2009/2010 Stefani Seibold + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#if 0 +#include +#include +#include +#include +#include +#include +#include +#endif + +#include +#include +#include +#include + +#include "fifo.h" + +#define is_power_of_2(x) ((x) != 0 && (((x) & ((x) - 1)) == 0)) +#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d)) +#define min(x,y) ({ \ + typeof(x) _x = (x); \ + typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x < _y ? _x : _y; }) + +#define max(x,y) ({ \ + typeof(x) _x = (x); \ + typeof(y) _y = (y); \ + (void) (&_x == &_y); \ + _x > _y ? _x : _y; }) + +//#define EINVAL (1) +//#define ENOMEM (2) + +static inline int fls(int x); + +#if defined(PLATFORM_R16) || defined(PLATFORM_R311) +static inline int constant_fls(int x) +{ + int r = 32; + + if (!x) + return 0; + if (!(x & 0xffff0000u)) { + x <<= 16; + r -= 16; + } + if (!(x & 0xff000000u)) { + x <<= 8; + r -= 8; + } + if (!(x & 0xf0000000u)) { + x <<= 4; + r -= 4; + } + if (!(x & 0xc0000000u)) { + x <<= 2; + r -= 2; + } + if (!(x & 0x80000000u)) { + x <<= 1; + r -= 1; + } + return r; +} + +static int fls64(unsigned long long x) +{ + unsigned int h = x >> 32; + if (h) + return fls(h) + 32; + return fls(x); +} + +static inline int fls(int x) +{ + int ret; + + if (__builtin_constant_p(x)) + return constant_fls(x); + + asm("clz\t%0, %1" : "=r" (ret) : "r" (x)); + ret = 32 - ret; + return ret; +} +#endif + +#ifdef PLATFORM_CPU +#define __fls(x) (fls(x) - 1) +static __always_inline int fls64(unsigned long x) +{ + if (x == 0) + return 0; + return __fls(x) + 1; +} + +static inline int fls(int x) +{ + int r; + + long tmp = -1; + asm("bsrl %1,%0" + : "=r" (r) + : "rm" (x), "0" (tmp)); +#if 0 +#ifdef CONFIG_X86_64 + /* + * AMD64 says BSRL won't clobber the dest reg if x==0; Intel64 says the + * dest reg is undefined if x==0, but their CPU architect says its + * value is written to set it to the same as before, except that the + * top 32 bits will be cleared. + * + * We cannot do this on 32 bits because at the very least some + * 486 CPUs did not behave this way. + */ + long tmp = -1; + asm("bsrl %1,%0" + : "=r" (r) + : "rm" (x), "0" (tmp)); +#elif defined(CONFIG_X86_CMOV) + asm("bsrl %1,%0\n\t" + "cmovzl %2,%0" + : "=&r" (r) : "rm" (x), "rm" (-1)); +#else + asm("bsrl %1,%0\n\t" + "jnz 1f\n\t" + "movl $-1,%0\n" + "1:" : "=r" (r) : "rm" (x)); +#endif +#endif + return r + 1; +} +#endif +/* + * internal helper to calculate the unused elements in a fifo + */ +static inline unsigned int kfifo_unused(struct __kfifo *fifo) +{ + return (fifo->mask + 1) - (fifo->in - fifo->out); +} + +static inline unsigned fls_long(unsigned long l) +{ + if (sizeof(l) == 4) + return fls(l); + return fls64(l); +} + +unsigned long roundup_pow_of_two(unsigned long n) +{ + return 1UL << (fls_long(n)); +} + +int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, unsigned int esize) +{ + /* + * round down to the next power of 2, since our 'let the indices + * wrap' technique works only in this case. + */ + if (!is_power_of_2(size)) + size = roundup_pow_of_two(size); + + fprintf(stdout, "+++++++++++kfifo malloc size = %u\n", size); + + fifo->in = 0; + fifo->out = 0; + fifo->esize = esize; + + if (size < 2) { + fifo->data = NULL; + fifo->mask = 0; + return -EINVAL; + } + + fifo->data = malloc(size * esize); + + if (!fifo->data) { + fifo->mask = 0; + return -ENOMEM; + } + fifo->mask = size - 1; + uv_mutex_init(&fifo->lock); + + return 0; +} + +void __kfifo_free(struct __kfifo *fifo) +{ + free(fifo->data); + fifo->in = 0; + fifo->out = 0; + fifo->esize = 0; + fifo->data = NULL; + fifo->mask = 0; +} + +int __kfifo_init(struct __kfifo *fifo, void *buffer, + unsigned int size, unsigned int esize) +{ + size /= esize; + + if (!is_power_of_2(size)) + size = roundup_pow_of_two(size); + + fifo->in = 0; + fifo->out = 0; + fifo->esize = esize; + fifo->data = buffer; + + if (size < 2) { + fifo->mask = 0; + return -EINVAL; + } + fifo->mask = size - 1; + uv_mutex_init(&fifo->lock); + + return 0; +} + +static void kfifo_copy_in(struct __kfifo *fifo, const void *src, + unsigned int len, unsigned int off) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + + off &= fifo->mask; + if (esize != 1) { + off *= esize; + size *= esize; + len *= esize; + } + l = min(len, size - off); + + memcpy(fifo->data + off, src, l); + memcpy(fifo->data, src + l, len - l); + /* + * make sure that the data in the fifo is up to date before + * incrementing the fifo->in index counter + */ +// smp_wmb(); +} + +unsigned int __kfifo_in(struct __kfifo *fifo, + const void *buf, unsigned int len) +{ + unsigned int l; + + l = kfifo_unused(fifo); + if (len > l) + len = l; + + kfifo_copy_in(fifo, buf, len, fifo->in); + fifo->in += len; + return len; +} + +static void kfifo_copy_out(struct __kfifo *fifo, void *dst, + unsigned int len, unsigned int off) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + + off &= fifo->mask; + if (esize != 1) { + off *= esize; + size *= esize; + len *= esize; + } + l = min(len, size - off); + + if (dst) { + memcpy(dst, fifo->data + off, l); + memcpy(dst + l, fifo->data, len - l); + } + /* + * make sure that the data is copied before + * incrementing the fifo->out index counter + */ +// smp_wmb(); +} + +unsigned int __kfifo_out_peek(struct __kfifo *fifo, + void *buf, unsigned int len) +{ + unsigned int l; + + l = fifo->in - fifo->out; + if (len > l) + len = l; + + kfifo_copy_out(fifo, buf, len, fifo->out); + return len; +} + +unsigned int __kfifo_out(struct __kfifo *fifo, + void *buf, unsigned int len) +{ + len = __kfifo_out_peek(fifo, buf, len); + fifo->out += len; + return len; +} + +#if 0 +static unsigned long kfifo_copy_from_user(struct __kfifo *fifo, + const void *from, unsigned int len, unsigned int off, + unsigned int *copied) +{ + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + unsigned int l; + unsigned long ret; + + off &= fifo->mask; + if (esize != 1) { + off *= esize; + size *= esize; + len *= esize; + } + l = min(len, size - off); + + ret = memcpy(fifo->data + off, from, l); + if (unlikely(ret)) + ret = DIV_ROUND_UP(ret + len - l, esize); + else { + ret = memcpy(fifo->data, from + l, len - l); + if (unlikely(ret)) + ret = DIV_ROUND_UP(ret, esize); + } + /* + * make sure that the data in the fifo is up to date before + * incrementing the fifo->in index counter + */ +// smp_wmb(); + *copied = len - ret; + /* return the number of elements which are not copied */ + return ret; +} + +int __kfifo_from_user(struct __kfifo *fifo, const void __user *from, + unsigned long len, unsigned int *copied) +{ + unsigned int l; + unsigned long ret; + unsigned int esize = fifo->esize; + int err; + + if (esize != 1) + len /= esize; + + l = kfifo_unused(fifo); + if (len > l) + len = l; + + ret = kfifo_copy_from_user(fifo, from, len, fifo->in, copied); + if (unlikely(ret)) { + len -= ret; + err = -EFAULT; + } else + err = 0; + fifo->in += len; + return err; +} + +static unsigned long kfifo_copy_to_user(struct __kfifo *fifo, void __user *to, + unsigned int len, unsigned int off, unsigned int *copied) +{ + unsigned int l; + unsigned long ret; + unsigned int size = fifo->mask + 1; + unsigned int esize = fifo->esize; + + off &= fifo->mask; + if (esize != 1) { + off *= esize; + size *= esize; + len *= esize; + } + l = min(len, size - off); + + ret = memcpy(to, fifo->data + off, l); + if (unlikely(ret)) + ret = DIV_ROUND_UP(ret + len - l, esize); + else { + ret = memcpy(to + l, fifo->data, len - l); + if (unlikely(ret)) + ret = DIV_ROUND_UP(ret, esize); + } + /* + * make sure that the data is copied before + * incrementing the fifo->out index counter + */ + //smp_wmb(); + *copied = len - ret; + /* return the number of elements which are not copied */ + return ret; +} + +int __kfifo_to_user(struct __kfifo *fifo, void __user *to, + unsigned long len, unsigned int *copied) +{ + unsigned int l; + unsigned long ret; + unsigned int esize = fifo->esize; + int err; + + if (esize != 1) + len /= esize; + + l = fifo->in - fifo->out; + if (len > l) + len = l; + ret = kfifo_copy_to_user(fifo, to, len, fifo->out, copied); + if (unlikely(ret)) { + len -= ret; + err = -EFAULT; + } else + err = 0; + fifo->out += len; + return err; +} +#endif + +unsigned int __kfifo_max_r(unsigned int len, unsigned int recsize) +{ + unsigned int max = (1 << (recsize << 3)) - 1; + + if (len > max) + return max; + return len; +} + +#define __KFIFO_PEEK(data, out, mask) \ + ((data)[(out) & (mask)]) +/* + * __kfifo_peek_n internal helper function for determinate the length of + * the next record in the fifo + */ +static unsigned int __kfifo_peek_n(struct __kfifo *fifo, unsigned int recsize) +{ + unsigned int l; + unsigned int mask = fifo->mask; + unsigned char *data = fifo->data; + + l = __KFIFO_PEEK(data, fifo->out, mask); + + if (--recsize) + l |= __KFIFO_PEEK(data, fifo->out + 1, mask) << 8; + + return l; +} + +#define __KFIFO_POKE(data, in, mask, val) \ + ( \ + (data)[(in) & (mask)] = (unsigned char)(val) \ + ) + +/* + * __kfifo_poke_n internal helper function for storeing the length of + * the record into the fifo + */ +static void __kfifo_poke_n(struct __kfifo *fifo, unsigned int n, unsigned int recsize) +{ + unsigned int mask = fifo->mask; + unsigned char *data = fifo->data; + + __KFIFO_POKE(data, fifo->in, mask, n); + + if (recsize > 1) + __KFIFO_POKE(data, fifo->in + 1, mask, n >> 8); +} + +unsigned int __kfifo_len_r(struct __kfifo *fifo, unsigned int recsize) +{ + return __kfifo_peek_n(fifo, recsize); +} + +unsigned int __kfifo_in_r(struct __kfifo *fifo, const void *buf, + unsigned int len, unsigned int recsize) +{ + if (len + recsize > kfifo_unused(fifo)) + return 0; + + __kfifo_poke_n(fifo, len, recsize); + + kfifo_copy_in(fifo, buf, len, fifo->in + recsize); + fifo->in += len + recsize; + return len; +} + +static unsigned int kfifo_out_copy_r(struct __kfifo *fifo, + void *buf, unsigned int len, unsigned int recsize, unsigned int *n) +{ + *n = __kfifo_peek_n(fifo, recsize); + + if (len > *n) + len = *n; + + kfifo_copy_out(fifo, buf, len, fifo->out + recsize); + return len; +} + +unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, void *buf, + unsigned int len, unsigned int recsize) +{ + unsigned int n; + + if (fifo->in == fifo->out) + return 0; + + return kfifo_out_copy_r(fifo, buf, len, recsize, &n); +} + +unsigned int __kfifo_out_r(struct __kfifo *fifo, void *buf, + unsigned int len, unsigned int recsize) +{ + unsigned int n; + + if (fifo->in == fifo->out) + return 0; + + len = kfifo_out_copy_r(fifo, buf, len, recsize, &n); + fifo->out += n + recsize; + return len; +} + +void __kfifo_skip_r(struct __kfifo *fifo, unsigned int recsize) +{ + unsigned int n; + + n = __kfifo_peek_n(fifo, recsize); + fifo->out += n + recsize; +} diff --git a/app/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c b/app/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c new file mode 100644 index 0000000..80e190b --- /dev/null +++ b/app/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c @@ -0,0 +1,197 @@ +#include +#include +#include +#include +#include "log.h" +#include "libuv_dbus.h" + +typedef struct +{ + MODULE_NAME modName; + uint32_t hTm[MODULE_MAX]; + int isDaemonWork[MODULE_MAX]; + int isConnected[MODULE_MAX]; + OnDaemonMsg pOnHeartLostCb; +} HEART_DAEMON, *PHEART_DAEMON; + +uint32_t g_hblTout = HEART_LOST_DELAY; ///< nano second: heart lost timeout, default 1s +static uv_loop_t *g_DeamonLoop; +static uv_idle_t g_uvDeamonIdle; +static HEART_DAEMON g_heartDaemon; + +static unsigned int g_Cnt = 0; +static int timerExpire(uint32_t tm, uint32_t tExp) +{ + uint32_t now = LIBUV_CURRENT_TIME_MS(); + int64_t diff = now - tm; + + if(tm == 0 || tExp == 0) + { + return 0; + } + + if(diff > tExp * 1000) + { + return 0; + } + else if(diff >= tExp) + { + return 1; + } + + return (0); +} + +static void RunPingSvr(void) +{ + int ret = 0; + unsigned int tm = LIBUV_CURRENT_TIME_MS(); + PING_MSG pMsg; + struct timeval tv; + + gettimeofday(&tv, NULL); + + pMsg.PING = (double)tm / 1000; + pMsg.tmSec = tv.tv_sec; + pMsg.tmMSec = tv.tv_usec; + + ret = DBusJsonBoardcastCommand(NULL, 0xFFFFFFFF, CMD_MISC_PING, JSON_ENGINE_PING, &pMsg, FALSE); + + if(ret != 0) + { + LOG_EX(LOG_Error, "DBus boardcast message error: %d\n", ret); + } +} + +void HeartDaemonHblCheck(void) +{ + if(g_heartDaemon.modName != MODULE_CONTROLLER) + { + if(g_heartDaemon.isDaemonWork[MODULE_CONTROLLER] && timerExpire(g_heartDaemon.hTm[MODULE_CONTROLLER], g_hblTout)) + { + g_heartDaemon.pOnHeartLostCb(MODULE_CONTROLLER, TRUE); + g_heartDaemon.hTm[MODULE_CONTROLLER] = 0; + g_heartDaemon.isConnected[MODULE_CONTROLLER] = FALSE; + } + } + else + { + int i; + + for(i = 0; i < MODULE_MAX; i++) + { + if(g_heartDaemon.isDaemonWork[i] + && i != MODULE_CONTROLLER + && timerExpire(g_heartDaemon.hTm[i], g_hblTout)) + { + g_heartDaemon.pOnHeartLostCb(i, TRUE); + g_heartDaemon.hTm[i] = 0; + g_heartDaemon.isConnected[i] = FALSE; + } + } + } +} + +void HeartDaemonUpgrade(int iWatcher) +{ + if(iWatcher >= MODULE_MAX) + { + return; + } + + if(g_heartDaemon.hTm[iWatcher] == 0) + { + if(g_heartDaemon.modName == MODULE_CONTROLLER) + { + g_heartDaemon.pOnHeartLostCb(iWatcher, FALSE); + } + else if(iWatcher == MODULE_CONTROLLER) + { + g_heartDaemon.pOnHeartLostCb(iWatcher, FALSE); + } + + g_heartDaemon.isConnected[iWatcher] = TRUE; + RunPingSvr(); + } + + g_heartDaemon.hTm[iWatcher] = LIBUV_CURRENT_TIME_MS(); +} + +static int __isSendPingOnTime(void) +{ + static unsigned int tmPre = 0; + unsigned int tm = LIBUV_CURRENT_TIME_MS(); + unsigned int tmOut = HEART_SEND_DELAY; + + if(g_heartDaemon.modName != MODULE_CONTROLLER + && g_heartDaemon.isConnected[MODULE_CONTROLLER] == FALSE) + { + tmOut = 5000; + } + + if(tmPre != 0 && tm - tmPre < tmOut) + { + return (FALSE); + } + + tmPre = tm; + + return (TRUE); +} + +static void __uvIdleCb(uv_idle_t* phuvIdle) +{ + if(DBusLibuvGetRuntime()->onHblCb + && __isSendPingOnTime()) + { + RunPingSvr(); + } + + HeartDaemonHblCheck(); + sleep(1); +} + +static void __uvThreadDaemon(void *pParams) +{ + g_DeamonLoop = uv_loop_new(); + + uv_idle_init(g_DeamonLoop, &g_uvDeamonIdle); + uv_idle_start(&g_uvDeamonIdle, __uvIdleCb); + + uv_run(g_DeamonLoop, UV_RUN_DEFAULT); + + pthread_detach(pthread_self()); +} + +void HeartDaemonInit(MODULE_NAME mod, int msHblTout, OnDaemonMsg cb) +{ + uv_thread_t uvDaemonThread; + int i; + + memset(&g_heartDaemon, 0, sizeof(HEART_DAEMON)); + + if(msHblTout > 0) + { + g_hblTout = msHblTout; + } + + g_heartDaemon.modName = mod; + + for(i = 0; i < MODULE_MAX; i++) + { + if(mod == MODULE_CONTROLLER) + { + g_heartDaemon.isDaemonWork[i] = (g_pModInfoTable[i].modName != MODULE_CONTROLLER) ? TRUE : FALSE; + } + else + { + g_heartDaemon.isDaemonWork[i] = (g_pModInfoTable[i].modName == MODULE_CONTROLLER) ? TRUE : FALSE; + } + + g_heartDaemon.isConnected[i] = FALSE; + } + + g_heartDaemon.pOnHeartLostCb = cb; + + uv_thread_create(&uvDaemonThread, __uvThreadDaemon, NULL); +} diff --git a/app/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c b/app/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c new file mode 100644 index 0000000..0abd09b --- /dev/null +++ b/app/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c @@ -0,0 +1,181 @@ +#ifndef PLATFORM_CPU +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PLATFORM_R16) || defined (PLATFORM_CPU) || defined(PLATFORM_R311) +#include "log.h" +#include "libuv_dbus.h" +#include "boardlink_iot.h" +#else +#include +#include +#include +#endif + +#define BL_IOT_PROTO (30) +#define BL_MSG_BUF_MAX (1024 * 4) + +static int g_nlSock = -1; +static unsigned char g_MsgSendBuf[BL_MSG_BUF_MAX]; +static BlMsgCb g_blMsgCb = NULL; + +static void __recvMsgThread(void *pParam) +{ + unsigned char msgBuf[BL_MSG_BUF_MAX]; + struct iovec iov = {msgBuf, BL_MSG_BUF_MAX}; + struct nlmsghdr *pMsgHdr; + struct sockaddr_nl fromAddr; + struct msghdr msgHdr = {&fromAddr, sizeof(fromAddr), &iov, 1, NULL, 0, 0};; + + memset(&fromAddr, 0, sizeof(fromAddr)); + fromAddr.nl_family = AF_NETLINK; + fromAddr.nl_pid = 0; + fromAddr.nl_groups = 0; + + while(TRUE) + { + int len = recvmsg(g_nlSock, &msgHdr, 0); + + if(len > 0) + { + for(pMsgHdr = (struct nlmsghdr *)msgBuf; + NLMSG_OK(pMsgHdr, len); + pMsgHdr = NLMSG_NEXT(pMsgHdr, len)) + { + if(pMsgHdr->nlmsg_type == NLMSG_DONE) + { + continue; + } + else if(pMsgHdr->nlmsg_type == NLMSG_ERROR) + { + continue; + } + else + { + PBL_IOT_MSG pMsg = (PBL_IOT_MSG)NLMSG_DATA(pMsgHdr); + //LOG_EX(LOG_Debug, "Recv Message: %s\n", NLMSG_DATA(pMsgHdr)); + print_hex_dump_bytes("Msg", 0, pMsg, BL_IOT_MSG_LEN(pMsg->msglen)); + if(g_blMsgCb) + { + g_blMsgCb(pMsg); + } + } + } + } + + usleep(1000); + } + pthread_detach(pthread_self()); +} + +static int __nlCreateSocket(void) +{ + struct sockaddr_nl srcAddr; + + g_nlSock = socket(AF_NETLINK, SOCK_RAW, BL_IOT_PROTO); + + if(g_nlSock == -1) + { + LOG_EX(LOG_Error, "Create netlink socker error: %s\n", strerror(errno)); + return -ERR_CREATE_SOCKET; + } + + memset(&srcAddr, 0, sizeof(srcAddr)); + srcAddr.nl_family = AF_NETLINK; + srcAddr.nl_pid = getpid(); + srcAddr.nl_groups = 0; + + if(bind(g_nlSock, (struct sockaddr*)&srcAddr, sizeof(srcAddr)) < 0) + { + LOG_EX(LOG_Error, "Bind netlink socket failed: %s", strerror(errno)); + close(g_nlSock); + return -ERR_BIND_SOCKET; + } + + return 0; +} + +static int __sendMessage(unsigned char* pData, unsigned int len) +{ + struct iovec iov; + struct sockaddr_nl dstAddr; + struct nlmsghdr* pMsgHdr = (struct nlmsghdr*)g_MsgSendBuf; + struct msghdr msgHdr = {&dstAddr, sizeof(dstAddr), &iov, 1, NULL, 0, 0}; + + memset(&dstAddr, 0, sizeof(struct sockaddr_nl)); + dstAddr.nl_family = AF_NETLINK; + dstAddr.nl_pid = 0; + dstAddr.nl_groups = 0; + + memset(pMsgHdr, 0, BL_MSG_BUF_MAX); + pMsgHdr->nlmsg_len = len; + pMsgHdr->nlmsg_pid = getpid(); + pMsgHdr->nlmsg_flags = 0; + memcpy(NLMSG_DATA(pMsgHdr), pData, len); + + iov.iov_base = pMsgHdr; + iov.iov_len = NLMSG_SPACE(BL_MSG_BUF_MAX); + + return sendmsg(g_nlSock, &msgHdr, 0); +} + +int BL_SendBLMsg(BL_IOT_MSG_TYPE msgType, unsigned char* pData, unsigned int len) +{ + BL_IOT_MSG blMsg; + + memset(&blMsg, 0, sizeof(BL_IOT_MSG)); + blMsg.msgType = msgType; + blMsg.msglen = len; + strcpy(blMsg.msgTags, BL_IOT_MSG_TAGS); + + if(pData && len > 0) + { + memcpy(blMsg.msgData, pData, len); + } + + return __sendMessage((unsigned char*)&blMsg, BL_IOT_MSG_LEN(len)); +} + +int BL_SendBLMsgTo(BL_IOT_MSG_TYPE msgType, unsigned char* pData, unsigned int len, unsigned char dstMac[ETH_ALEN]) +{ + BL_IOT_MSG blMsg; + + memset(&blMsg, 0, sizeof(BL_IOT_MSG)); + blMsg.msgType = msgType; + blMsg.msglen = len; + memcpy(blMsg.dstMac, dstMac, ETH_ALEN); + strcpy(blMsg.msgTags, BL_IOT_MSG_TAGS); + + if(pData && len > 0) + { + memcpy(blMsg.msgData, pData, len); + } + + return __sendMessage((unsigned char*)&blMsg, BL_IOT_MSG_LEN(len)); +} + +int BL_Init(BlMsgCb cbOnMsg) +{ + int ret = 0; + uv_thread_t uvRecvThread; + + ret = __nlCreateSocket(); + + if(ret != 0) + { + return ret; + } + + g_blMsgCb = cbOnMsg; + + uv_thread_create(&uvRecvThread, __recvMsgThread, NULL); + + return 0; +} +#endif diff --git a/app/libuvdbus/src/Framework/JsonUtils/json_struct.c b/app/libuvdbus/src/Framework/JsonUtils/json_struct.c new file mode 100644 index 0000000..c9be8c3 --- /dev/null +++ b/app/libuvdbus/src/Framework/JsonUtils/json_struct.c @@ -0,0 +1,1218 @@ +#include +#include +#include +#include + +#include "log.h" +#include "smart_sound.h" +#include "libuv_dbus.h" +#include "json_struct.h" +#include "crypto.h" +#include "ota.h" +#include "assistant.h" + +typedef const char* (*StructToJsonCb)(void* pStruct); +typedef void* (*JsonToStructCb)(const char* pJsonStr); +typedef void (*Base64Code)(void *pStruct, int enCode); + +typedef struct +{ + JSON_ENGINE_TYPE typeId; + StructToJsonCb s2jCb; + JsonToStructCb j2sCb; + Base64Code base64Cb; +} JSON_ENGINE, *PJSON_ENGINE; + +static const char* __ping_MSG2Json(void* pData) +{ + PPING_MSG pReq = (PPING_MSG)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, double, PING); + s2j_json_set_basic_element(jObject, pReq, int, tmSec); + s2j_json_set_basic_element(jObject, pReq, int, tmMSec); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +static void* __json2PING_MSG(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, PING_MSG); + + memset(sObject, 0, sizeof(PING_MSG)); + + s2j_struct_get_basic_element(sObject, pJson, double, PING); + s2j_struct_get_basic_element(sObject, pJson, int, tmSec); + s2j_struct_get_basic_element(sObject, pJson, int, tmMSec); + + cJSON_Delete(pJson); + + return sObject; +} + +static const char* __cfg_API_REQ2Json(void* pData) +{ + PCFG_API_REQ pReq = (PCFG_API_REQ)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, string, keyName); + s2j_json_set_basic_element(jObject, pReq, string, keyValue); + s2j_json_set_basic_element(jObject, pReq, int, keyType); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +static void* __json2CFG_API_REQ(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, CFG_API_REQ); + + memset(sObject, 0, sizeof(CFG_API_REQ)); + + s2j_struct_get_basic_element(sObject, pJson, string, keyName); + s2j_struct_get_basic_element(sObject, pJson, string, keyValue); + s2j_struct_get_basic_element(sObject, pJson, int, keyType); + + cJSON_Delete(pJson); + + return sObject; +} + +static void __cfg_API_REQBase64(void *pData, int enCode) +{ + PCFG_API_REQ pReq = (PCFG_API_REQ)pData; + + if(enCode) + { + if(strlen(pReq->keyName) > 0) + { + char* pBase64 = (char *)EvpBase64Encode(pReq->keyName); + memset(pReq->keyName, 0, MAX_CFG_KEY_NAME); + strcpy(pReq->keyName, pBase64); + free(pBase64); + } + + if(strlen(pReq->keyValue) > 0) + { + char* pBase64 = (char *)EvpBase64Encode(pReq->keyValue); + memset(pReq->keyValue, 0, MAX_CFG_KEY_VALUE); + strcpy(pReq->keyValue, pBase64); + free(pBase64); + } + } + else + { + if(strlen(pReq->keyName) > 0) + { + + char *pBase64 = (char *)EvpBase64Decode(pReq->keyName); + memset(pReq->keyName, 0, MAX_CFG_KEY_NAME); + strcpy(pReq->keyName, pBase64); + free(pBase64); + } + + if(strlen(pReq->keyValue) > 0) + { + char *pBase64 = (char *)EvpBase64Decode(pReq->keyValue); + memset(pReq->keyValue, 0, MAX_CFG_KEY_VALUE); + strcpy(pReq->keyValue, pBase64); + free(pBase64); + } + } +} + +static const char* __cfg_API_RSP2Json(void* pData) +{ + PCFG_API_RSP pReq = (PCFG_API_RSP)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, string, keyName); + s2j_json_set_basic_element(jObject, pReq, string, keyValue); + s2j_json_set_basic_element(jObject, pReq, int, keyType); + s2j_json_set_basic_element(jObject, pReq, int, errNo); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +static void* __json2CFG_API_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, CFG_API_RSP); + + memset(sObject, 0, sizeof(CFG_API_RSP)); + + s2j_struct_get_basic_element(sObject, pJson, string, keyName); + s2j_struct_get_basic_element(sObject, pJson, string, keyValue); + s2j_struct_get_basic_element(sObject, pJson, int, keyType); + s2j_struct_get_basic_element(sObject, pJson, int, errNo); + + cJSON_Delete(pJson); + + return sObject; +} + +static void __cfg_API_RSPBase64(void *pData, int enCode) +{ + PCFG_API_RSP pReq = (PCFG_API_RSP)pData; + + if(enCode) + { + if(strlen(pReq->keyName) > 0) + { + char *pBase64 = (char *)EvpBase64Encode(pReq->keyName); + memset(pReq->keyName, 0, MAX_CFG_KEY_NAME); + strcpy(pReq->keyName, pBase64); + free(pBase64); + } + + if(strlen(pReq->keyValue) > 0) + { + char *pBase64 = (char *)EvpBase64Encode(pReq->keyValue); + memset(pReq->keyValue, 0, MAX_CFG_KEY_VALUE); + strcpy(pReq->keyValue, pBase64); + free(pBase64); + } + } + else + { + if(strlen(pReq->keyName) > 0) + { + char *pBase64 = (char *)EvpBase64Decode(pReq->keyName); + memset(pReq->keyName, 0, MAX_CFG_KEY_NAME); + strcpy(pReq->keyName, pBase64); + free(pBase64); + } + + if(strlen(pReq->keyValue) > 0) + { + char *pBase64 = (char *)EvpBase64Decode(pReq->keyValue); + memset(pReq->keyValue, 0, MAX_CFG_KEY_VALUE); + strcpy(pReq->keyValue, pBase64); + free(pBase64); + } + } +} + +static const char* __player_TO_CTRL2Json(void* pData) +{ + PPLAYER_TO_CTRL pP2C = (PPLAYER_TO_CTRL)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pP2C, string, musicUuid); + s2j_json_set_basic_element(jObject, pP2C, int, plySt); + s2j_json_set_basic_element(jObject, pP2C, int, curPos); + s2j_json_set_basic_element(jObject, pP2C, int, duration); + + s2j_json_set_basic_element(jObject, pP2C, int, playerId); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +static void* __json2PLAYER_TO_CTRL(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, PLAYER_TO_CTRL); + + memset(sObject, 0, sizeof(PLAYER_TO_CTRL)); + + s2j_struct_get_basic_element(sObject, pJson, string, musicUuid); + s2j_struct_get_basic_element(sObject, pJson, int, plySt); + s2j_struct_get_basic_element(sObject, pJson, int, curPos); + s2j_struct_get_basic_element(sObject, pJson, int, duration); + + cJSON_Delete(pJson); + + return sObject; +} + +static void __player_TO_CTRLBase64(void *pData, int enCode) +{ + PPLAYER_TO_CTRL pReq = (PPLAYER_TO_CTRL)pData; + + if(enCode) + { + if(strlen(pReq->musicUuid) > 0) + { + char *pBase64 = (char *)EvpBase64Encode(pReq->musicUuid); + memset(pReq->musicUuid, 0, MAX_MUSIC_UUID); + strcpy(pReq->musicUuid, pBase64); + free(pBase64); + } + } + else + { + if(strlen(pReq->musicUuid) > 0) + { + char *pBase64 = (char *)EvpBase64Decode(pReq->musicUuid); + memset(pReq->musicUuid, 0, MAX_MUSIC_UUID); + strcpy(pReq->musicUuid, pBase64); + free(pBase64); + } + } +} + +static const char* __ctrl_TO_PLAYER2Json(void* pData) +{ + PCTRL_TO_PLAYER pC2P = (PCTRL_TO_PLAYER)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pC2P, string, src); + s2j_json_set_basic_element(jObject, pC2P, string, srcUuid); + s2j_json_set_basic_element(jObject, pC2P, string, ttsText); + s2j_json_set_basic_element(jObject, pC2P, int, skTime); + s2j_json_set_basic_element(jObject, pC2P, int, plyMode); + s2j_json_set_basic_element(jObject, pC2P, int, plyListType); + s2j_json_set_basic_element(jObject, pC2P, int, adSrcType); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +static void* __json2CTRL_TO_PLAYER(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, CTRL_TO_PLAYER); + + memset(sObject, 0, sizeof(CTRL_TO_PLAYER)); + + s2j_struct_get_basic_element(sObject, pJson, string, src); + s2j_struct_get_basic_element(sObject, pJson, string, srcUuid); + s2j_struct_get_basic_element(sObject, pJson, string, ttsText); + s2j_struct_get_basic_element(sObject, pJson, int, skTime); + s2j_struct_get_basic_element(sObject, pJson, int, plyMode); + s2j_struct_get_basic_element(sObject, pJson, int, plyListType); + s2j_struct_get_basic_element(sObject, pJson, int, adSrcType); + s2j_struct_get_basic_element(sObject, pJson, int, duration); + s2j_struct_get_basic_element(sObject, pJson, int, volRestoreTime); + s2j_struct_get_basic_element(sObject, pJson, int, volBegin); + s2j_struct_get_basic_element(sObject, pJson, string, fifo); + s2j_struct_get_basic_element(sObject, pJson, int, channel); + s2j_struct_get_basic_element(sObject, pJson, int, bytes); + s2j_struct_get_basic_element(sObject, pJson, int, sampleRate); + s2j_struct_get_basic_element(sObject, pJson, int, playerId); + s2j_struct_get_basic_element(sObject, pJson, double, gain); + s2j_struct_get_basic_element(sObject, pJson, string, backGroundUrl); + + cJSON_Delete(pJson); + + return sObject; +} + +static void __ctrl_TO_PLAYERBase64(void *pData, int enCode) +{ + PCTRL_TO_PLAYER pReq = (PCTRL_TO_PLAYER)pData; + + if(enCode) + { + if(strlen(pReq->src) > 0) + { + char *pBase64 = (char *)EvpBase64Encode(pReq->src); + memset(pReq->src, 0, MAX_MUSIC_UUID); + strcpy(pReq->src, pBase64); + free(pBase64); + } + + if(strlen(pReq->srcUuid) > 0) + { + char *pBase64 = (char *)EvpBase64Encode(pReq->srcUuid); + memset(pReq->srcUuid, 0, MAX_MUSIC_UUID); + strcpy(pReq->srcUuid, pBase64); + free(pBase64); + } + } + else + { + if(strlen(pReq->src) > 0) + { + char *pBase64 = (char *)EvpBase64Decode(pReq->src); + memset(pReq->src, 0, MAX_MUSIC_UUID); + strcpy(pReq->src, pBase64); + free(pBase64); + } + + if(strlen(pReq->srcUuid) > 0) + { + char *pBase64 = (char *)EvpBase64Decode(pReq->srcUuid); + memset(pReq->srcUuid, 0, MAX_MUSIC_UUID); + strcpy(pReq->srcUuid, pBase64); + free(pBase64); + } + } +} + +#if 0 +const char* __ota_Notify_REQ2Json(void* pData) +{ + int i; + POTA_DATA_INFO pReq = (POTA_DATA_INFO)pData; + cJSON* pRoot = NULL; + cJSON* pSubArray = NULL; + const char* pJsonS; + + pRoot = cJSON_CreateObject(); + + cJSON_AddNumberToObject(pRoot, "version", pReq->version); + cJSON_AddNumberToObject(pRoot, "otaMode", pReq->otaMode); + + pSubArray = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "otaFile", pSubArray); + + for(i = 0; i < sizeof(pReq->otaFile) / sizeof(pReq->otaFile[0]); i++) + { + cJSON *pItem = cJSON_CreateObject(); + + cJSON_AddItemToObject(pSubArray, "", pItem); + + + cJSON_AddStringToObject(pItem, "url", pReq->otaFile[i].url); + cJSON_AddStringToObject(pItem, "md5", pReq->otaFile[i].md5); + cJSON_AddNumberToObject(pItem, "size", pReq->otaFile[i].size); + } + + pJsonS = cJSON_Print(pRoot); + cJSON_Delete(pRoot); + + return pJsonS; +} + +void* __json2OTA_Notify_REQ(const char* pJsonS) +{ + POTA_DATA_INFO pInfo; + cJSON* pSubArray = NULL; + cJSON* pItem = NULL; + + cJSON* pRoot = cJSON_Parse(pJsonS); + if(pRoot == NULL) + { + return (NULL); + } + + pSubArray = cJSON_GetObjectItem(pRoot, "otaFile"); + + pInfo = (POTA_DATA_INFO)malloc(sizeof(OTA_DATA_INFO)); + memset(pInfo, 0, sizeof(OTA_DATA_INFO)); + + pItem = cJSON_GetObjectItem(pRoot, "version"); + pInfo->version = pItem->valueint; + + pItem = cJSON_GetObjectItem(pRoot, "otaMode"); + pInfo->otaMode = pItem->valueint; + + if(pSubArray) + { + int i; + cJSON *pList = pSubArray->child; + + for(i = 0; i < cJSON_GetArraySize(pSubArray); i++) + { + strcpy(pInfo->otaFile[i].url, cJSON_GetObjectItem(pList, "url")->valuestring); + strcpy(pInfo->otaFile[i].md5, cJSON_GetObjectItem(pList, "md5")->valuestring); + pInfo->otaFile[i].size = cJSON_GetObjectItem(pList, "size")->valueint; + + pList = pList->next; + } + } + + cJSON_Delete(pRoot); + + return pInfo; +} +#else +const char* __ota_Notify_REQ2Json(void* pData) +{ + POTA_DATA_INFO pReq = (POTA_DATA_INFO)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, version); + s2j_json_set_basic_element(jObject, pReq, int, otaCmd); + s2j_json_set_basic_element(jObject, pReq, int, otaMode); + + s2j_json_set_struct_element(json_otaRes, jObject, struct_otaRes, pReq, OTA_FILE_INFO, otaFileInfo); + s2j_json_set_basic_element(json_otaRes, struct_otaRes, string, url); + s2j_json_set_basic_element(json_otaRes, struct_otaRes, string, md5); + s2j_json_set_basic_element(json_otaRes, struct_otaRes, int, size); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2OTA_Notify_REQ(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, OTA_DATA_INFO); + + memset(sObject, 0, sizeof(OTA_DATA_INFO)); + + s2j_struct_get_basic_element(sObject, pJson, int, version); + s2j_struct_get_basic_element(sObject, pJson, int, otaCmd); + s2j_struct_get_basic_element(sObject, pJson, int, otaMode); + + s2j_struct_get_struct_element(struct_otaRes, sObject, json_otaRes, pJson, OTA_FILE_INFO, otaFileInfo); + s2j_struct_get_basic_element(struct_otaRes, json_otaRes, string, url); + s2j_struct_get_basic_element(struct_otaRes, json_otaRes, string, md5); + s2j_struct_get_basic_element(struct_otaRes, json_otaRes, int, size); + + cJSON_Delete(pJson); + + return sObject; +} +#endif +static void __ota_NotifyBase64(void *pData, int enCode) +{ + POTA_DATA_INFO pReq = (POTA_DATA_INFO)pData; + + if(enCode) + { + if(strlen(pReq->otaFileInfo.url) > 0) + { + char *pBase64 = (char *)EvpBase64EncodeNoAlign(pReq->otaFileInfo.url); + memset(pReq->otaFileInfo.url, 0, SIZE_1K); + strcpy(pReq->otaFileInfo.url, pBase64); + free(pBase64); + } + } + else + { + if(strlen(pReq->otaFileInfo.url) > 0) + { + char *pBase64 = (char *)EvpBase64DecodeNoAlign(pReq->otaFileInfo.url); + memset(pReq->otaFileInfo.url, 0, SIZE_1K); + strcpy(pReq->otaFileInfo.url, pBase64); + free(pBase64); + } + } +} + +const char* __ota_Status_RSP2Json(void* pData) +{ + POTA_RSP_STATUS pReq = (POTA_RSP_STATUS)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, status); + s2j_json_set_basic_element(jObject, pReq, int, val); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2OTA_Status_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, OTA_RSP_STATUS); + + memset(sObject, 0, sizeof(OTA_RSP_STATUS)); + + s2j_struct_get_basic_element(sObject, pJson, int, status); + s2j_struct_get_basic_element(sObject, pJson, int, val); + + cJSON_Delete(pJson); + + return sObject; +} + +const char* __alarm_Run_Event_RSP2Json(void* pData) +{ + const char* pJsonS; + PASSISTANT_ITEM_INFO pReq = (PASSISTANT_ITEM_INFO)pData; + cJSON* pRoot = cJSON_CreateObject(); + cJSON* pSubArray = cJSON_CreateArray(); + + cJSON_AddItemToObject(pRoot, "data", pSubArray); + + cJSON *pItem = cJSON_CreateObject(); + + cJSON_AddItemToObject(pSubArray, "", pItem); + + cJSON_AddNumberToObject(pItem, "alarmId", pReq->itemId); + cJSON_AddNumberToObject(pItem, "itemType", pReq->itemType); + cJSON_AddNumberToObject(pItem, "priority", pReq->priority); + cJSON_AddNumberToObject(pItem, "repeatMode", pReq->repeatMode); + + cJSON_AddNumberToObject(pItem, "year", pReq->year); + cJSON_AddNumberToObject(pItem, "month", pReq->month); + cJSON_AddNumberToObject(pItem, "day", pReq->day); + cJSON_AddNumberToObject(pItem, "hour", pReq->hour); + cJSON_AddNumberToObject(pItem, "minute", pReq->minute); + cJSON_AddNumberToObject(pItem, "second", pReq->second); + cJSON_AddNumberToObject(pItem, "weekDay", pReq->weekDay); + + cJSON_AddNumberToObject(pItem, "voiceId", pReq->voiceId); + cJSON_AddStringToObject(pItem, "strTips", pReq->strTips); + cJSON_AddStringToObject(pItem, "resUrl", pReq->resUrl); + + cJSON_AddStringToObject(pItem, "voiceResType", pReq->voiceResType); + cJSON_AddStringToObject(pItem, "voiceRes", pReq->voiceRes); + + pJsonS = cJSON_Print(pRoot); + cJSON_Delete(pRoot); + + return pJsonS; +} + +static void __getAlarmDateTimeInfo(cJSON* pJson, PASSISTANT_ITEM_INFO pAlarmInfo) +{ + struct tm tmNow; + time_t timep; + + const char *pStrYear = cJSON_GetObjectItem(pJson, "year")->valuestring; + const char *pStrMonth = cJSON_GetObjectItem(pJson, "month")->valuestring; + const char *pStrDay = cJSON_GetObjectItem(pJson, "dayofMonth")->valuestring; + const char *pStrHour = cJSON_GetObjectItem(pJson, "hour")->valuestring; + const char *pStrMinute = cJSON_GetObjectItem(pJson, "minute")->valuestring; + const char *pStrSecond = cJSON_GetObjectItem(pJson, "second")->valuestring; + const char *pStrWeekDay = cJSON_GetObjectItem(pJson, "dayofWeek")->valuestring; + + time(&timep); + localtime_r(&timep, &tmNow); + + if(pStrYear != NULL && strlen(pStrYear) > 0) + { + pAlarmInfo->year = strtoul(pStrYear, NULL, 10) - 1900; + } + else + { + pAlarmInfo->year = -1;//tmNow.tm_year; + } + + if(pStrMonth != NULL && strlen(pStrMonth) > 0) + { + pAlarmInfo->month = strtoul(pStrMonth, NULL, 10) - 1; + } + else + { + pAlarmInfo->month = -1;//tmNow.tm_mon; + } + + if(pStrDay != NULL && strlen(pStrDay) > 0) + { + pAlarmInfo->day = strtoul(pStrDay, NULL, 10); + } + else + { + pAlarmInfo->day = -1; //tmNow.tm_mday; + } + + if(pStrHour != NULL && strlen(pStrHour) > 0) + { + pAlarmInfo->hour = strtoul(pStrHour, NULL, 10); + } + else + { + pAlarmInfo->hour = -1; + } + + if(pStrMinute != NULL && strlen(pStrMinute) > 0) + { + pAlarmInfo->minute = strtoul(pStrMinute, NULL, 10); + } + else + { + pAlarmInfo->minute = -1; + } + + if(pStrSecond != NULL && strlen(pStrSecond) > 0) + { + pAlarmInfo->second = strtoul(pStrSecond, NULL, 10); + } + else + { + pAlarmInfo->second = -1; + } + + if(pStrWeekDay != NULL && strlen(pStrWeekDay) > 0) + { + if(strchr(pStrWeekDay, '7') != NULL) + { + pAlarmInfo->weekDay |= 1; + } + + if(strchr(pStrWeekDay, '1') != NULL) + { + pAlarmInfo->weekDay |= 1 << 1; + } + + if(strchr(pStrWeekDay, '2') != NULL) + { + pAlarmInfo->weekDay |= 1 << 2; + } + + if(strchr(pStrWeekDay, '3') != NULL) + { + pAlarmInfo->weekDay |= 1 << 3; + } + + if(strchr(pStrWeekDay, '4') != NULL) + { + pAlarmInfo->weekDay |= 1 << 4; + } + + if(strchr(pStrWeekDay, '5') != NULL) + { + pAlarmInfo->weekDay |= 1 << 5; + } + + if(strchr(pStrWeekDay, '6') != NULL) + { + pAlarmInfo->weekDay |= 1 << 6; + } + } + else + { + pAlarmInfo->weekDay = 0; + } +} + +void* __json2Alarm_sync_RSP(const char *pJsonS) +{ + PASSISTANT_SYNC_INFO pInfo; + cJSON* pSubArray = NULL; + //cJSON* pItem = NULL; + + cJSON* pRoot = cJSON_Parse(pJsonS); + if(pRoot == NULL) + { + return (NULL); + } + + pSubArray = cJSON_GetObjectItem(pRoot, "data"); + + pInfo = (PASSISTANT_SYNC_INFO)malloc(sizeof(ASSISTANT_SYNC_INFO)); + memset(pInfo, 0, sizeof(ASSISTANT_SYNC_INFO)); + + pInfo->pAlarmInfo = NULL; + + if(pSubArray) + { + cJSON *pList = pSubArray->child; + int arraySize = cJSON_GetArraySize(pSubArray); + + if(arraySize > 0) + { + pInfo->pAlarmInfo = (PASSISTANT_ITEM_INFO)malloc(sizeof(ASSISTANT_ITEM_INFO) * arraySize); + + pInfo->nItems = arraySize; + + for(int i = 0; i < arraySize; i++) + { + cJSON* pData = cJSON_GetObjectItem(pList, "vboxDate"); + + memset(&pInfo->pAlarmInfo[i], 0, sizeof(ASSISTANT_ITEM_INFO)); + + if(pData != NULL) + { + cJSON *pItem; + + __getAlarmDateTimeInfo(pData, &pInfo->pAlarmInfo[i]); + + pInfo->pAlarmInfo[i].itemType = cJSON_GetObjectItem(pList, "label")->valueint; + pInfo->pAlarmInfo[i].itemId = cJSON_GetObjectItem(pList, "id")->valueint; + pInfo->pAlarmInfo[i].repeatMode = cJSON_GetObjectItem(pList, "type")->valueint; + pInfo->pAlarmInfo[i].voiceId = cJSON_GetObjectItem(pList, "voiceType")->valueint; + + pItem = cJSON_GetObjectItem(pList, "remark"); + + if(pInfo->pAlarmInfo[i].itemType != ASSISTANT_TYPE_CLOCK && pItem) + { + strcpy(pInfo->pAlarmInfo[i].strTips, pItem->valuestring); + } + + pItem = cJSON_GetObjectItem(pList, "resUrl"); + + if(pItem) + { + strcpy(pInfo->pAlarmInfo[i].resUrl, pItem->valuestring); + } + + pItem = cJSON_GetObjectItem(pList, "voiceRes"); + + if(pItem) + { + strcpy(pInfo->pAlarmInfo[i].voiceRes, pItem->valuestring); + } + + pItem = cJSON_GetObjectItem(pList, "voiceResType"); + + if(pItem) + { + strcpy(pInfo->pAlarmInfo[i].voiceResType, pItem->valuestring); + } + + pList = pList->next; +#if 0 + fprintf(stdout, "%04u-%02u-%02u %02u:%02u:%02u %u\n", + pInfo->pAlarmInfo[i].year, + pInfo->pAlarmInfo[i].month, + pInfo->pAlarmInfo[i].day, + pInfo->pAlarmInfo[i].hour, + pInfo->pAlarmInfo[i].minute, + pInfo->pAlarmInfo[i].second, + pInfo->pAlarmInfo[i].weekDay); +#endif + } + } + } + } + + cJSON_Delete(pRoot); + + return pInfo; +} + +const char* __alarm_Status_RSP2Json(void* pData) +{ + const char* pJsonS; + + PASSISTANT_RSP_STATUS pReq = (PASSISTANT_RSP_STATUS)pData; + + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, cmd); + s2j_json_set_basic_element(jObject, pReq, int, val); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2Alarm_Status_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, ASSISTANT_RSP_STATUS); + + memset(sObject, 0, sizeof(ASSISTANT_RSP_STATUS)); + + s2j_struct_get_basic_element(sObject, pJson, int, cmd); + s2j_struct_get_basic_element(sObject, pJson, int, val); + + cJSON_Delete(pJson); + + return sObject; + +} + +const char* __alarm_change_RSP2Json(void* pData) +{ + const char* pJsonS; + PASSISTANT_NOTIFY_INFO pReq = (PASSISTANT_NOTIFY_INFO)pData; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, cmd); + s2j_json_set_basic_element(jObject, pReq, int, type); + s2j_json_set_array_element(jObject, pReq, double, ids, pReq->nItems); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2Alarm_change_RSP(const char* pJsonS) +{ + PASSISTANT_NOTIFY_INFO pInfo = NULL; + cJSON* pSubArray = NULL; + cJSON* pItem = NULL; + + cJSON* pRoot = cJSON_Parse(pJsonS); + if(pRoot == NULL) + { + return (NULL); + } + + pSubArray = cJSON_GetObjectItem(pRoot, "ids"); + + pInfo = (PASSISTANT_NOTIFY_INFO)malloc(sizeof(ASSISTANT_NOTIFY_INFO)); + memset(pInfo, 0, sizeof(ASSISTANT_NOTIFY_INFO)); + + pItem = cJSON_GetObjectItem(pRoot, "type"); + pInfo->type = pItem->valueint; + +#if 0 + pItem = cJSON_GetObjectItem(pRoot, "cmd"); + pInfo->cmd = pItem->valueint; +#endif + + if(pSubArray) + { + int arraySize = cJSON_GetArraySize(pSubArray); + + if(arraySize > 0) + { + pInfo->nItems = arraySize; + + for(int i = 0; i < arraySize; i++) + { + pInfo->ids[i] = (unsigned long long)(cJSON_GetArrayItem(pSubArray, i)->valuedouble); + } + } + } + + cJSON_Delete(pRoot); + + return pInfo; +} +#if 0 +const char* __alarm_change_RSP2Json(void* pData) +{ + int i = 0; + PALARM_REMOVE_INFO pReq = (PALARM_REMOVE_INFO)pData; + cJSON* pRoot = NULL; + cJSON* pSubArray = NULL; + const char* pJsonS; + + pRoot = cJSON_CreateObject(); + + cJSON_AddNumberToObject(pRoot, "nItems", pReq->nItems); + + pSubArray = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "data", pSubArray); + + for(i = 0; i < pReq->nItems; i++) + { + cJSON *pItem = cJSON_CreateObject(); + + cJSON_AddItemToObject(pSubArray, "", pItem); + + cJSON_AddNumberToObject(pItem, "alarmId", pReq->pItemInfo[i].alarmId); + cJSON_AddNumberToObject(pItem, "itemType", pReq->pItemInfo[i].itemType); + } + + pJsonS = cJSON_Print(pRoot); + cJSON_Delete(pRoot); + + return pJsonS; +} + +void* __json2Alarm_change_RSP(const char* pJsonS) +{ + PALARM_REMOVE_INFO pInfo = NULL; + cJSON* pRoot = cJSON_Parse(pJsonS); + cJSON* pSubArray = NULL; + cJSON* pItem = NULL; + int itemType = 0; + + if(pRoot == NULL) + { + return (NULL); + } + + pSubArray = cJSON_GetObjectItem(pRoot, "data"); + + pInfo = (PALARM_REMOVE_INFO)malloc(sizeof(ALARM_REMOVE_INFO)); + memset(pInfo, 0, sizeof(ALARM_REMOVE_INFO)); + + pItem = cJSON_GetObjectItem(pRoot, "type"); + itemType = pItem->valueint; + + pInfo->pItemInfo = NULL; + + if(pSubArray) + { + int i; + cJSON *pList = pSubArray->child; + int arraySize = cJSON_GetArraySize(pSubArray); + + if(arraySize > 0) + { + pInfo->pItemInfo = (PITEM_INFO)malloc(sizeof(ITEM_INFO) * arraySize); + pInfo->nItems = arraySize; + + for(i = 0; i < arraySize; i++) + { + memset(&pInfo->pItemInfo[i], 0, sizeof(ALARM_ITEM_INFO)); + + pInfo->pItemInfo[i].itemType = itemType; + pInfo->pItemInfo[i].alarmId = cJSON_GetObjectItem(pList, "id")->valueint; + + pList = pList->next; + } + } + } + + cJSON_Delete(pRoot); + + return pInfo; +} +#endif + +const char* __alarm_WorkData_RSP2Json(void* pData) +{ + const char* pJsonS; + PWORKDAY_INFO pReq = (PWORKDAY_INFO)pData; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, year); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2Alarm_WorkData_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, WORKDAY_INFO); + + memset(sObject, 0, sizeof(WORKDAY_INFO)); + + s2j_struct_get_basic_element(sObject, pJson, int, year); + s2j_struct_get_array_element(sObject, pJson, int, days); + + cJSON_Delete(pJson); + + return sObject; +} + + +const char* __logCfg_RSP2Json(void* pData) +{ + PLOG_CFG_PROTOCOL pReq = (PLOG_CFG_PROTOCOL)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, cfgCmd); + s2j_json_set_basic_element(jObject, pReq, int, iParams1); + s2j_json_set_basic_element(jObject, pReq, int, iParams2); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2LogCfg_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, LOG_CFG_PROTOCOL); + + memset(sObject, 0, sizeof(LOG_CFG_PROTOCOL)); + + s2j_struct_get_basic_element(sObject, pJson, int, cfgCmd); + s2j_struct_get_basic_element(sObject, pJson, int, iParams1); + s2j_struct_get_basic_element(sObject, pJson, int, iParams2); + + cJSON_Delete(pJson); + + return sObject; +} + +const char* __wifiStatus_RSP2Json(void* pData) +{ + PWIFI_STATUS_PRO pReq = (PWIFI_STATUS_PRO)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, int, wifi_evt); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +void* __json2WifiStatus_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, WIFI_STATUS_PRO); + + memset(sObject, 0, sizeof(WIFI_STATUS_PRO)); + + s2j_struct_get_basic_element(sObject, pJson, int, wifi_evt); + + cJSON_Delete(pJson); + + return sObject; +} + +void* __json2McuGuideCmd_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, MCU_TEST_GUIDE_CMD); + + memset(sObject, 0, sizeof(MCU_TEST_GUIDE_CMD)); + + s2j_struct_get_basic_element(sObject, pJson, int, red); + s2j_struct_get_basic_element(sObject, pJson, int, green); + s2j_struct_get_basic_element(sObject, pJson, int, blue); + + cJSON_Delete(pJson); + + return sObject; +} + +void* __json2McuMatrixCmd_RSP(const char* pJsonS) +{ + cJSON* pJson = cJSON_Parse(pJsonS); + + s2j_create_struct_obj(sObject, MCU_TEST_MATRIX_CMD); + + memset(sObject, 0, sizeof(MCU_TEST_MATRIX_CMD)); + + s2j_struct_get_basic_element(sObject, pJson, int, level); + + cJSON_Delete(pJson); + + return sObject; +} + +const char* __mcuVersion_RSP2Json(void* pData) +{ + PMCU_TEST_VER_CMD pReq = (PMCU_TEST_VER_CMD)pData; + const char* pJsonS; + + s2j_create_json_obj(jObject); + + s2j_json_set_basic_element(jObject, pReq, string, McuVer); + + pJsonS = cJSON_Print(jObject); + cJSON_Delete(jObject); + + return pJsonS; +} + +static JSON_ENGINE g_jSonEngine[] = +{ + {JSON_ENGINE_P2C, __player_TO_CTRL2Json, __json2PLAYER_TO_CTRL, __player_TO_CTRLBase64}, + {JSON_ENGINE_C2P, __ctrl_TO_PLAYER2Json, __json2CTRL_TO_PLAYER, __ctrl_TO_PLAYERBase64}, + {JSON_ENGINE_CFG_REQ, __cfg_API_REQ2Json, __json2CFG_API_REQ, __cfg_API_REQBase64}, + {JSON_ENGINE_CFG_RSP, __cfg_API_RSP2Json, __json2CFG_API_RSP, __cfg_API_RSPBase64 }, + {JSON_ENGINE_ASSISTANT_SYNC_RSP, NULL, __json2Alarm_sync_RSP, NULL}, + {JSON_ENGINE_ASSISTANT_NOTIFY, __alarm_change_RSP2Json, __json2Alarm_change_RSP, NULL}, + {JSON_ENGINE_ASSISTANT_STATUS, __alarm_Status_RSP2Json, __json2Alarm_Status_RSP, NULL}, + {JSON_ENGINE_ASSISTANT_RUNNING, __alarm_Run_Event_RSP2Json, NULL, NULL}, + {JSON_ENGINE_WORKDAY_REQ, __alarm_WorkData_RSP2Json, __json2Alarm_WorkData_RSP, NULL}, + {JSON_ENGINE_PING, __ping_MSG2Json, __json2PING_MSG, NULL}, + {JSON_ENGINE_OTA_REQ, __ota_Notify_REQ2Json, __json2OTA_Notify_REQ, __ota_NotifyBase64}, + {JSON_ENGINE_OTA_RSP, __ota_Status_RSP2Json, __json2OTA_Status_RSP, NULL}, + {JSON_ENGINE_LOG_CFG_CMD, __logCfg_RSP2Json, __json2LogCfg_RSP, NULL}, + {JSON_WIFI_STATUS_NOTIFY, __wifiStatus_RSP2Json, __json2WifiStatus_RSP, NULL}, + {JSON_MCU_GUIDE_TEST_CMD, NULL, __json2McuGuideCmd_RSP, NULL}, + {JSON_MCU_MATRIX_TEST_CMD, NULL, __json2McuMatrixCmd_RSP, NULL}, + {JSON_MCU_TEST_GET_VER_CMD, __mcuVersion_RSP2Json, NULL, NULL}, +}; + +void* Json2Struct(const char* pJsonStr, JSON_ENGINE_TYPE type, int enBase64, int* pErr) +{ + if(pJsonStr == NULL || pErr == NULL) + { + if(pErr) + { + *pErr = -ERR_INPUT_PARAMS; + } + return NULL; + } + + if(type < 0 || type >= JSON_ENGINE_MAX) + { + *pErr = -ERR_INPUT_PARAMS; + return NULL; + } + + *pErr = 0; + + //LOG_EX(LOG_Debug, "Json:\n%s\n", pJsonStr); + + if(g_jSonEngine[type].j2sCb) + { + void *pStruct = g_jSonEngine[type].j2sCb(pJsonStr); + + if(enBase64 && g_jSonEngine[type].base64Cb) + { + g_jSonEngine[type].base64Cb(pStruct, FALSE); + } + + return (pStruct); + } + else + { + return (NULL); + } +} + +const char* Struct2Json(void* pStruct, JSON_ENGINE_TYPE type, int enBase64, int* pErr) +{ + if(pStruct == NULL || pErr == NULL) + { + if(pErr) + { + *pErr = -ERR_INPUT_PARAMS; + } + return NULL; + } + + if(type < 0 || type >= JSON_ENGINE_MAX) + { + *pErr = -ERR_INPUT_PARAMS; + return NULL; + } + + *pErr = 0; + + if(enBase64 && g_jSonEngine[type].base64Cb) + { + g_jSonEngine[type].base64Cb(pStruct, TRUE); + } + + if(g_jSonEngine[type].s2jCb) + { + const char *pJsongStr = g_jSonEngine[type].s2jCb(pStruct); + + //LOG_EX(LOG_Debug, "Json: \n%s\n", pJsongStr); + return (pJsongStr); + } + else + { + return NULL; + } +} diff --git a/app/libuvdbus/src/Framework/Monitor/monitor.c b/app/libuvdbus/src/Framework/Monitor/monitor.c new file mode 100644 index 0000000..6e78f6b --- /dev/null +++ b/app/libuvdbus/src/Framework/Monitor/monitor.c @@ -0,0 +1,347 @@ +#ifdef ENABLE_COUNT_DEBUG +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "libuv_dbus.h" + +#define LOG_SAVE_TIME (1000) + +typedef struct +{ + long long maxValue; + long long minValue; + long long avgValue; +} STATISTICAL_VALUE, *PSTATISTICAL_VALUE; + +typedef struct +{ + long long curVaule; + long long tolValue; + unsigned int tolCount; + STATISTICAL_VALUE cVal; +} CSTATISTICAL_INFO, *PSTATISTICAL_INFO; + +typedef struct +{ + char* pMonName; + unsigned long nCount; + CSTATISTICAL_INFO nCstInfo; + uv_rwlock_t rwLock; + + uv_timer_t logTimer; + unsigned int logTime; + + UT_hash_handle hh; ///< UT Hash handle +} MONITOR_INFO, *PMONITOR_INFO; + +static uv_rwlock_t g_uvMonRwLock; +static PMONITOR_INFO g_MonTbl = NULL; +static uv_loop_t* g_MonLogLoop = NULL; + +static void __uvMonLogProc(void *pParams) +{ + RunUVLoop(g_MonLogLoop); + + while(TRUE) + { + usleep(1000); + } + + pthread_detach(pthread_self()); +} + +static void __logMonTimerProc(uv_timer_t* pTimer) +{ + PMONITOR_INFO pInfo = (PMONITOR_INFO)pTimer->data; + + if(pInfo && (pInfo->nCount + pInfo->nCstInfo.tolCount > 0)) + { + UT_string* pMsg = NULL; + utstring_new(pMsg); + + uv_rwlock_rdlock(&pInfo->rwLock); + + utstring_printf(pMsg, "%s Statistical Information:\n", pInfo->pMonName); + //LOG_EX(LOG_Debug, "%s Statistical Information:\n", pInfo->pMonName); + + if(pInfo->nCount) + { + UT_string* pMsgCount = NULL; + utstring_new(pMsgCount); + utstring_printf(pMsgCount, " Total Count = %lu\n", pInfo->nCount); + utstring_concat(pMsg, pMsgCount); + utstring_free(pMsgCount); + //LOG_EX(LOG_Debug, " Total Count = %u\n", pInfo->nCount); + } + + if(pInfo->nCstInfo.tolCount > 0) + { + UT_string* pMsgStat = NULL; + utstring_new(pMsgStat); + utstring_printf(pMsgStat, " Max Value = %lld\n" + " Min Value = %lld\n" + " Avg Value = %lld\n" + " ---- Statistical by total %lld of %u times\n", + pInfo->nCstInfo.cVal.maxValue, + pInfo->nCstInfo.cVal.minValue, + pInfo->nCstInfo.cVal.avgValue, + pInfo->nCstInfo.tolValue, + pInfo->nCstInfo.tolCount); + utstring_concat(pMsg, pMsgStat); + utstring_free(pMsgStat); +#if 0 + LOG_EX(LOG_Debug, " Max Value = %lld\n", pInfo->nCstInfo.cVal.maxValue); + LOG_EX(LOG_Debug, " Min Value = %lld\n", pInfo->nCstInfo.cVal.minValue); + LOG_EX(LOG_Debug, " Avg Value = %lld\n", pInfo->nCstInfo.cVal.avgValue); + LOG_EX(LOG_Debug, " ---- Statistical by total %lld of %u times\n", + pInfo->nCstInfo.tolValue, pInfo->nCstInfo.tolCount); +#endif + } + + LOG_EX(LOG_Debug, "%s", utstring_body(pMsg)); + + uv_rwlock_rdunlock(&pInfo->rwLock); + utstring_free(pMsg); + } +} + +int MonitorInit(void) +{ + uv_thread_t uvMonLogThread; + + g_MonLogLoop = uv_loop_new(); + + uv_rwlock_init(&g_uvMonRwLock); + + uv_thread_create(&uvMonLogThread, __uvMonLogProc, NULL); + + return 0; +} + +int MonAddNewItem(const char* pName, int logSaveTime) +{ + PMONITOR_INFO pInfo; + + if(pName == NULL || strlen(pName) == 0) + { + return -ERR_INPUT_PARAMS; + } + + uv_rwlock_rdlock(&g_uvMonRwLock); + HASH_FIND_STR(g_MonTbl, pName, pInfo); + uv_rwlock_rdunlock(&g_uvMonRwLock); + + if(pInfo != NULL) + { + return -ERR_CFG_ITEM_EXIST; + } + + pInfo = (PMONITOR_INFO)malloc(sizeof(MONITOR_INFO)); + + if(pInfo == NULL) + { + return -ERR_MALLOC_MEMORY; + } + + memset(pInfo, 0, sizeof(MONITOR_INFO)); + + pInfo->nCstInfo.cVal.minValue = INT_MAX; + pInfo->logTime = logSaveTime; + pInfo->pMonName = strdup(pName); + + if(pInfo->logTime > 0) + { + pInfo->logTimer.data = pInfo; + uv_timer_init(g_MonLogLoop, &pInfo->logTimer); + uv_timer_start(&pInfo->logTimer, __logMonTimerProc, pInfo->logTime, pInfo->logTime); + } + else + { + pInfo->logTime = 0; + } + + uv_rwlock_init(&pInfo->rwLock); + + uv_rwlock_wrlock(&g_uvMonRwLock); + HASH_ADD_STR(g_MonTbl, pMonName, pInfo); + uv_rwlock_wrunlock(&g_uvMonRwLock); + + return 0; +} + +int MonIncreaseCount(const char* pName) +{ + PMONITOR_INFO pInfo; + + if(pName == NULL || strlen(pName) == 0) + { + return -ERR_INPUT_PARAMS; + } + + uv_rwlock_rdlock(&g_uvMonRwLock); + HASH_FIND_STR(g_MonTbl, pName, pInfo); + uv_rwlock_rdunlock(&g_uvMonRwLock); + + if(pInfo == NULL) + { + return -ERR_CFG_NOITEM; + } + + uv_rwlock_wrlock(&pInfo->rwLock); + pInfo->nCount++; + uv_rwlock_wrunlock(&pInfo->rwLock); + + return 0; +} + +int MonDiffStatistical(const char* pName, long long newVal) +{ + PMONITOR_INFO pInfo; + + if(pName == NULL || strlen(pName) == 0) + { + return -ERR_INPUT_PARAMS; + } + + uv_rwlock_rdlock(&g_uvMonRwLock); + HASH_FIND_STR(g_MonTbl, pName, pInfo); + uv_rwlock_rdunlock(&g_uvMonRwLock); + + if(pInfo == NULL) + { + return -ERR_CFG_NOITEM; + } + + uv_rwlock_wrlock(&pInfo->rwLock); + + if(pInfo->nCstInfo.curVaule != 0) + { + long long diffValue = newVal - pInfo->nCstInfo.curVaule; + + pInfo->nCstInfo.tolValue += diffValue; + pInfo->nCstInfo.tolCount++; + + if(pInfo->nCstInfo.tolCount > 10) + { + pInfo->nCstInfo.cVal.avgValue = pInfo->nCstInfo.tolValue / pInfo->nCstInfo.tolCount; + + if(pInfo->nCstInfo.cVal.maxValue < diffValue) + { + pInfo->nCstInfo.cVal.maxValue = diffValue; + } + + if(pInfo->nCstInfo.cVal.minValue > diffValue) + { + pInfo->nCstInfo.cVal.minValue = diffValue; + } + } + } + + pInfo->nCstInfo.curVaule = newVal; + uv_rwlock_wrunlock(&pInfo->rwLock); + + //fprintf(stdout, "%s value %lld diffValue %lld\n", pName, newVal, diffValue); + return 0; +} + +int MonUpgradeStatistical(const char* pName, long newVal) +{ + PMONITOR_INFO pInfo; + + if(pName == NULL || strlen(pName) == 0) + { + return -ERR_INPUT_PARAMS; + } + + uv_rwlock_rdlock(&g_uvMonRwLock); + HASH_FIND_STR(g_MonTbl, pName, pInfo); + uv_rwlock_rdunlock(&g_uvMonRwLock); + + if(pInfo == NULL) + { + return -ERR_CFG_NOITEM; + } + + uv_rwlock_wrlock(&pInfo->rwLock); + + pInfo->nCstInfo.curVaule = newVal; + pInfo->nCstInfo.tolValue += newVal; + pInfo->nCstInfo.tolCount++; + pInfo->nCstInfo.cVal.avgValue = pInfo->nCstInfo.tolValue / pInfo->nCstInfo.tolCount; + + if(pInfo->nCstInfo.cVal.maxValue < newVal) + { + pInfo->nCstInfo.cVal.maxValue = newVal; + } + + if(pInfo->nCstInfo.cVal.minValue > newVal) + { + pInfo->nCstInfo.cVal.minValue = newVal; + } + + uv_rwlock_wrunlock(&pInfo->rwLock); + + //fprintf(stdout, "%s value %ld\n", pName, newVal); + return 0; +} + +int MonItemLogout(const char* pName) +{ + PMONITOR_INFO pInfo; + + if(pName == NULL || strlen(pName) == 0) + { + return -ERR_INPUT_PARAMS; + } + + uv_rwlock_rdlock(&g_uvMonRwLock); + HASH_FIND_STR(g_MonTbl, pName, pInfo); + uv_rwlock_rdunlock(&g_uvMonRwLock); + + if(pInfo == NULL) + { + return -ERR_CFG_NOITEM; + } + + if(pInfo->nCount + pInfo->nCstInfo.tolCount == 0) + { + LOG_EX(LOG_Debug, "%s Statistical Unchanged\n", pInfo->pMonName); + return 0; + } + + uv_rwlock_rdlock(&pInfo->rwLock); + + LOG_EX(LOG_Debug, "%s Statistical Information:\n", pInfo->pMonName); + + if(pInfo->nCount) + { + LOG_EX(LOG_Debug, " Total Count = %u\n", pInfo->nCount); + } + + if(pInfo->nCstInfo.tolCount > 0) + { + LOG_EX(LOG_Debug, " Max Value = %lld\n", pInfo->nCstInfo.cVal.maxValue); + LOG_EX(LOG_Debug, " Min Value = %lld\n", pInfo->nCstInfo.cVal.minValue); + LOG_EX(LOG_Debug, " Avg Value = %lld\n", pInfo->nCstInfo.cVal.avgValue); + LOG_EX(LOG_Debug, " ---- Statistical by total %lld of %u times\n", + pInfo->nCstInfo.tolValue, pInfo->nCstInfo.tolCount); + } + + uv_rwlock_rdunlock(&pInfo->rwLock); + + return 0; +} +#endif diff --git a/app/libuvdbus/src/Framework/Network/inet_api.c b/app/libuvdbus/src/Framework/Network/inet_api.c new file mode 100644 index 0000000..ee3a9db --- /dev/null +++ b/app/libuvdbus/src/Framework/Network/inet_api.c @@ -0,0 +1,1396 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "inet_api.h" + +#define MAX_TIMEOUT_VALUE (10) +#define SSL_CA_FILE ("/etc/ssl/certs/ca-certificates.crt") + +typedef enum +{ + INET_HTTP_DOWNLOAD_FILE = 0, + INET_HTTP_WEBSERVICE_POST, +} INET_ACCESS_TYPE; + +typedef struct +{ + uv_poll_t uvPool; + curl_socket_t sock; +} CURL_CONTEXT_DATA, *PCURL_CONTEXT_DATA; + +typedef struct +{ + char* pReqUrl; + char sPath[MAX_PATH]; + char sDlPath[MAX_PATH]; + char* pTaskUuid; + INET_ACCESS_TYPE type; + unsigned int dlSize; + unsigned int lastTm; + unsigned int createTm; + uv_fs_t uvFsOpen; + uv_fs_t uvFsWrite; + uv_fs_t uvFsDataSync; + uv_fs_t uvFsClose; + uv_buf_t uvFsBuf; + OnProgressNotify onPrgCb; + OnHttpResponse onRspCb; + int isCancel; + CURL* pCurl; + void* pData; + int errCode; +} HTTP_REQ_PARAMS, *PHTTP_REQ_PARAMS; + +typedef struct +{ + char *pTaskUuid; + unsigned int uRetryTimes; + PHTTP_REQ_PARAMS pCurlItem; + + UT_hash_handle hh; ///< UT Hash handle +} CURL_HANDLE_TBL, *PCURL_HANDLE_TBL; + +static uv_timer_t g_uvCurlTm; +static uv_timer_t g_uvDlTm; +static CURLM* g_pCurl = NULL; +static uv_loop_t* g_pMainLoop = NULL; +static PCURL_HANDLE_TBL g_ReqHandleTbl = NULL; +static uv_rwlock_t g_uvHashRwLock; +static unsigned g_TotalDownloads = 0; + +static void __addReqIdToTable(const char* pTaskUuid, PHTTP_REQ_PARAMS pParams) +{ + PCURL_HANDLE_TBL pItem = NULL; + + HASH_FIND_STR(g_ReqHandleTbl, pTaskUuid, pItem); + + if(pItem == NULL) + { + pItem = (PCURL_HANDLE_TBL)malloc(sizeof(CURL_HANDLE_TBL)); + + memset(pItem, 0, sizeof(CURL_HANDLE_TBL)); + pItem->pTaskUuid = (char*)pTaskUuid; + + uv_rwlock_wrlock(&g_uvHashRwLock); + HASH_ADD_STR(g_ReqHandleTbl, pTaskUuid, pItem); + uv_rwlock_wrunlock(&g_uvHashRwLock); + } + + pItem->pCurlItem = pParams; + pItem->uRetryTimes++; +} + +static void __removeReqIdFromTable(const char* pTaskUuid) +{ + PCURL_HANDLE_TBL pItem = NULL; + + uv_rwlock_wrlock(&g_uvHashRwLock); + HASH_FIND_STR(g_ReqHandleTbl, pTaskUuid, pItem); + if(pItem != NULL) + { + HASH_DEL(g_ReqHandleTbl, pItem); + + if(pItem->pTaskUuid) + { + free(pItem->pTaskUuid); + } + + free(pItem); + } + uv_rwlock_wrunlock(&g_uvHashRwLock); +} + +static void __cancelDownloadTask(PHTTP_REQ_PARAMS pItem) +{ + if(pItem) + { + pItem->isCancel = TRUE; + } +} + +static void __uvFsCloseCb(uv_fs_t *puvFs) +{ + PHTTP_REQ_PARAMS pParams = (PHTTP_REQ_PARAMS)puvFs->data; + + if(puvFs->result < 0) + { + LOG_EX(LOG_Error, "[%s] Error: %d\n", __FUNCTION__, puvFs->result); + } + + uv_fs_req_cleanup(puvFs); + + if(pParams->type == INET_HTTP_DOWNLOAD_FILE) + { + if(strcmp(pParams->sDlPath, pParams->sPath) != 0) + { + CopyFile(pParams->sDlPath, pParams->sPath); + unlink(pParams->sDlPath); + } + + if(pParams->errCode == CURLE_ABORTED_BY_CALLBACK) + { + pParams->errCode = CURLE_OPERATION_TIMEDOUT; + } + + if(pParams->onRspCb && pParams->isCancel == FALSE) + { + pParams->onRspCb(NULL, pParams->dlSize, pParams->pReqUrl, pParams->sPath, + pParams->pTaskUuid, -pParams->errCode, pParams->pData); + } + } + + __removeReqIdFromTable(pParams->pTaskUuid); + + if(pParams->pReqUrl) + { + free(pParams->pReqUrl); + pParams->pReqUrl = NULL; + } + + free(pParams); + pParams = NULL; +} + +static void __uvFsDataSyncCb(uv_fs_t *puvFs) +{ + PHTTP_REQ_PARAMS pParams = (PHTTP_REQ_PARAMS)puvFs->data; + + if(puvFs->result < 0) + { + LOG_EX(LOG_Error, "[%s] Error: %d\n", __FUNCTION__, puvFs->result); + } + + uv_fs_req_cleanup(puvFs); + + uv_fs_close(g_pMainLoop, &pParams->uvFsClose, pParams->uvFsOpen.result, __uvFsCloseCb); +} + +static PCURL_CONTEXT_DATA __createCurlContext(curl_socket_t sock) +{ + PCURL_CONTEXT_DATA pContext = (PCURL_CONTEXT_DATA)malloc(sizeof(CURL_CONTEXT_DATA)); + + pContext->sock = sock; + + if(uv_poll_init_socket(g_pMainLoop, &pContext->uvPool, sock) != 0) + { + LOG_EX(LOG_Error, "uv_poll_init_socket Error\n"); + } + + pContext->uvPool.data = pContext; + + return (pContext); +} + +static void __uvCloseCb(uv_handle_t *puvPoll) +{ + PCURL_CONTEXT_DATA pContext = (PCURL_CONTEXT_DATA)puvPoll->data; + free(pContext); +} + +static void __destoryCurlContext(PCURL_CONTEXT_DATA pContext) +{ + uv_close((uv_handle_t *)&pContext->uvPool, __uvCloseCb); +} + +static void __checkMultiInfoTimeout(void) +{ + PHTTP_REQ_PARAMS pReq; + CURLMsg *pMsg = NULL; + int iPending; + + while((pMsg = curl_multi_info_read(g_pCurl, &iPending))) + { + switch(pMsg->msg) + { + case CURLMSG_DONE: + curl_easy_getinfo(pMsg->easy_handle, CURLINFO_PRIVATE, (void*)&pReq); + + LOG_EX(LOG_Debug, "Cleanup CURL: %p\n", pMsg->easy_handle); + + curl_multi_remove_handle(g_pCurl, pMsg->easy_handle); + curl_easy_cleanup(pMsg->easy_handle); + + if(pReq) + { + if(pReq->type == INET_HTTP_DOWNLOAD_FILE) + { + uv_fs_close(g_pMainLoop, &pReq->uvFsDataSync, pReq->uvFsOpen.result, NULL); + } + + if(pReq->onRspCb && pReq->isCancel == FALSE) + { + pReq->onRspCb(NULL, 0, pReq->pReqUrl, pReq->sPath, pReq->pTaskUuid, + -CURLE_OPERATION_TIMEDOUT, pReq->pData); + } + + if(pReq->pReqUrl) + { + free(pReq->pReqUrl); + pReq->pReqUrl = NULL; + } + + __removeReqIdFromTable(pReq->pTaskUuid); + + free(pReq); + pReq = NULL; + } + + break; + + default: + LOG_EX(LOG_Error, "pMsg->msg(%d) != CURLMSG_DONE\n", pMsg->msg); + return; + } + } +} + +static void __checkMultiInfo(void) +{ + PHTTP_REQ_PARAMS pReq; + CURLMsg *pMsg = NULL; + int iPending; + + while((pMsg = curl_multi_info_read(g_pCurl, &iPending))) + { + switch(pMsg->msg) + { + case CURLMSG_DONE: + curl_easy_getinfo(pMsg->easy_handle, CURLINFO_PRIVATE, (void*)&pReq); + + curl_multi_remove_handle(g_pCurl, pMsg->easy_handle); + LOG_EX(LOG_Debug, "Cleanup CURL: %p\n", pMsg->easy_handle); + curl_easy_cleanup(pMsg->easy_handle); + + if(pReq) + { + if(pReq->type == INET_HTTP_DOWNLOAD_FILE) + { + if(pMsg->data.result != CURLE_OK) + { + pReq->errCode = pMsg->data.result; + } + else + { + pReq->errCode = 0; + } + + uv_fs_fdatasync(g_pMainLoop, &pReq->uvFsDataSync, pReq->uvFsOpen.result, __uvFsDataSyncCb); + } + else if(pReq->type == INET_HTTP_WEBSERVICE_POST) + { + if(pMsg->data.result != CURLE_OK) + { + if(pReq->onRspCb && pReq->isCancel == FALSE) + { + pReq->onRspCb(pReq->uvFsBuf.base, pReq->dlSize, pReq->pReqUrl, pReq->sPath, + pReq->pTaskUuid, -pMsg->data.result, pReq->pData); + } + } + else + { + if(pReq->onRspCb && pReq->isCancel == FALSE) + { + pReq->onRspCb(pReq->uvFsBuf.base, pReq->dlSize, pReq->pReqUrl, pReq->sPath, + pReq->pTaskUuid, 0, pReq->pData); + } + } + + if(pReq->uvFsBuf.base) + { + free(pReq->uvFsBuf.base); + } + + if(pReq->pReqUrl) + { + free(pReq->pReqUrl); + pReq->pReqUrl = NULL; + } + + __removeReqIdFromTable(pReq->pTaskUuid); + + free(pReq); + pReq = NULL; + } + else + { + if(pMsg->data.result != CURLE_OK) + { + if(pReq->onRspCb && pReq->isCancel == FALSE){ + pReq->onRspCb(NULL, 0, pReq->pReqUrl, pReq->sPath, pReq->pTaskUuid, -pMsg->data.result, pReq->pData); + } + } + else + { + if(pReq->onRspCb && pReq->isCancel == FALSE) + { + pReq->onRspCb(NULL, 0, pReq->pReqUrl, pReq->sPath, pReq->pTaskUuid, 0, pReq->pData); + } + } + + if(pReq->pReqUrl) + { + free(pReq->pReqUrl); + pReq->pReqUrl = NULL; + } + + __removeReqIdFromTable(pReq->pTaskUuid); + + free(pReq); + pReq = NULL; + } + } + + break; + + default: + LOG_EX(LOG_Error, "pMsg->msg(%d) != CURLMSG_DONE\n", pMsg->msg); + return; + } + } +} + +static void __onDlTmoutCb(uv_timer_t *pufTimer) +{ + PCURL_HANDLE_TBL pItem = NULL, pTemp = NULL; + unsigned int curTm = (unsigned int)LIBUV_CURRENT_TIME_S(); + + HASH_ITER(hh, g_ReqHandleTbl, pItem, pTemp) + { + int dlTime; + + if(pItem->pCurlItem->isCancel) + { + continue; + } + + dlTime = curTm - pItem->pCurlItem->createTm; + + // 下载时间大于10s且平均下载速度小于10K/s超时 + if((dlTime * 10000 > pItem->pCurlItem->dlSize) && dlTime > 10) + { + LOG_EX(LOG_Error, "Download Speed less than 10k/s: %s (%uK/%ds)\n", + pItem->pTaskUuid, pItem->pCurlItem->dlSize / 1000, dlTime); + + __cancelDownloadTask(pItem->pCurlItem); + if(pItem->pCurlItem->onRspCb) + { + pItem->pCurlItem->onRspCb(NULL, + pItem->pCurlItem->dlSize, + pItem->pCurlItem->pReqUrl, + pItem->pCurlItem->sPath, + pItem->pCurlItem->pTaskUuid, + -CURLE_OPERATION_TIMEDOUT, + pItem->pCurlItem->pData); + } + break; + } + + // 10秒内没有下载任何数据超时 + if(pItem->pCurlItem->lastTm > 0) + { + if(curTm > pItem->pCurlItem->lastTm + MAX_TIMEOUT_VALUE) + { + LOG_EX(LOG_Error, "Download Timeout: %s\n", pItem->pTaskUuid); + __cancelDownloadTask(pItem->pCurlItem); + if(pItem->pCurlItem->onRspCb) + { + pItem->pCurlItem->onRspCb(NULL, + pItem->pCurlItem->dlSize, + pItem->pCurlItem->pReqUrl, + pItem->pCurlItem->sPath, + pItem->pCurlItem->pTaskUuid, + -CURLE_OPERATION_TIMEDOUT, + pItem->pCurlItem->pData); + } + break; + } + } + + // 下载最长时间设置为1800秒(30分钟) + if(dlTime > 1800) + { + LOG_EX(LOG_Error, "Download More than 1800 seconds: %s (%uK/%ds)\n", + pItem->pTaskUuid, pItem->pCurlItem->dlSize/1000, dlTime); + __cancelDownloadTask(pItem->pCurlItem); + if(pItem->pCurlItem->onRspCb) + { + pItem->pCurlItem->onRspCb(NULL, + pItem->pCurlItem->dlSize, + pItem->pCurlItem->pReqUrl, + pItem->pCurlItem->sPath, + pItem->pCurlItem->pTaskUuid, + -CURLE_OPERATION_TIMEDOUT, + pItem->pCurlItem->pData); + } + break; + } + } +} + +static void __onTimeoutCb(uv_timer_t *pufTimer) +{ + int iRun; + + curl_multi_socket_action(g_pCurl, CURL_SOCKET_TIMEOUT, 0, &iRun); + + __checkMultiInfoTimeout(); +} + +static int __curlTimerCb(CURLM *multi, /* multi handle */ + long timeout_ms, /* see above */ + void *userp) /* private callback pointer */ +{ + if(timeout_ms <= 0) + { + timeout_ms = 1; + } + + uv_timer_start(&g_uvCurlTm, __onTimeoutCb, timeout_ms, 0); + + return 0; +} + +static void __curlPollCb(uv_poll_t *pPoll, int status, int events) +{ + int iRun; + int flags; + PCURL_CONTEXT_DATA pContext = NULL; + + uv_timer_stop(&g_uvCurlTm); + + if(events & UV_READABLE) + { + flags = CURL_CSELECT_IN; + } + else if(events & UV_WRITABLE) + { + flags = CURL_CSELECT_OUT; + } + + pContext = (PCURL_CONTEXT_DATA)pPoll; + curl_multi_socket_action(g_pCurl, pContext->sock, flags, &iRun); + __checkMultiInfo(); +} + +static int __curlSockCb(CURL *easy, /* easy handle */ + curl_socket_t s, /* socket */ + int what, /* describes the socket */ + void *userp, /* private callback pointer */ + void *socketp) /* private socket pointer */ +{ + PCURL_CONTEXT_DATA pContext = NULL; + + if(what == CURL_POLL_IN || what == CURL_POLL_OUT) + { + if(socketp) + { + pContext = (PCURL_CONTEXT_DATA)socketp; + } + else + { + pContext = __createCurlContext(s); + } + + curl_multi_assign(g_pCurl, s, (void *)pContext); + } + + switch(what) + { + case CURL_POLL_IN: + uv_poll_start(&pContext->uvPool, UV_READABLE, __curlPollCb); + break; + + case CURL_POLL_OUT: + uv_poll_start(&pContext->uvPool, UV_WRITABLE, __curlPollCb); + break; + + case CURL_POLL_REMOVE: + if(socketp) + { + uv_poll_stop(&((PCURL_CONTEXT_DATA)socketp)->uvPool); + __destoryCurlContext((PCURL_CONTEXT_DATA)socketp); + curl_multi_assign(g_pCurl, s, NULL); + } + break; + + default: + return (0); + } + + return (0); +} + +static size_t __writeDataCb(void *pData, size_t size, size_t nmemb, void *pParams) +{ + PHTTP_REQ_PARAMS pReq = (PHTTP_REQ_PARAMS)pParams; + int iMemSize = size * nmemb; + + //print_hex_dump_bytes("OTA", DUMP_PREFIX_ADDRESS, pData, size * nmemb); + + if(pReq->isCancel) + { + return 0; + } + + pReq->lastTm = LIBUV_CURRENT_TIME_S(); + + if(pReq->type == INET_HTTP_DOWNLOAD_FILE) + { + int wr = 0; + + pReq->uvFsBuf = uv_buf_init(pData, iMemSize); + + wr = uv_fs_write(g_pMainLoop, &pReq->uvFsWrite, pReq->uvFsOpen.result, &pReq->uvFsBuf, 1, -1, NULL); + + if(wr > 0) + { + pReq->dlSize += wr; + } + } + else if(pReq->type == INET_HTTP_WEBSERVICE_POST) + { + int newSize = 0; + + if(pReq->uvFsBuf.base == NULL && pReq->uvFsBuf.len == 0) + { + newSize = iMemSize + 1; + //fprintf(stdout, "size = %d, newsize = %d, dlsize = %d\n", iMemSize, newSize, pReq->dlSize); + pReq->uvFsBuf.base = malloc(newSize); + memcpy(pReq->uvFsBuf.base, pData, iMemSize); + } + else + { + newSize = pReq->dlSize + iMemSize + 1; + //fprintf(stdout, "::size = %d, newsize = %d, dlsize = %d\n", iMemSize, newSize, pReq->dlSize); + pReq->uvFsBuf.base = realloc(pReq->uvFsBuf.base, newSize); + memcpy(pReq->uvFsBuf.base + pReq->dlSize, pData, iMemSize); + } + + pReq->uvFsBuf.base[pReq->dlSize] = 0; + pReq->dlSize += iMemSize; + } + + return (size * nmemb); +} + +static int __progressCb(void* pData, + double total, + double now, + double ultotal, + double ulnow) +{ + PHTTP_REQ_PARAMS pParams = (PHTTP_REQ_PARAMS)pData; + + if(pParams->onPrgCb) + { + if(pParams->type == INET_HTTP_DOWNLOAD_FILE) + { + pParams->onPrgCb(pParams->pReqUrl, pParams->pTaskUuid, (unsigned char)(now * 100.0 / total), pParams->pData); + } + } + + if(pParams->isCancel) + { + LOG_EX(LOG_Debug, "Cancel Download: %s\n", pParams->pTaskUuid); + return (-CURLE_OPERATION_TIMEDOUT); + } + + return (0); +} + +static size_t __getRemoteSizeCb(void *pData, size_t size, size_t nmemb, void *pParams) +{ + return (size * nmemb); +} + +static int __iNetGetRemoteSize(const char* pURL, unsigned int reqId) +{ + double size = 0.0; + CURL *pCurl = curl_easy_init(); + CURLcode res; + + curl_easy_setopt(pCurl, CURLOPT_URL, pURL); + curl_easy_setopt(pCurl, CURLOPT_NOBODY, 1L); + curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, __getRemoteSizeCb); + curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 1L); + + curl_easy_perform(pCurl); + + res = curl_easy_getinfo(pCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &size); + + if(res != CURLE_OK) + { + return (-1); + } + + curl_easy_cleanup(pCurl); + + return (int)(size); +} + +#if 0 +static const char* __restartDlFileAsync(PHTTP_REQ_PARAMS pParams) +{ + CURL *pCurl = curl_easy_init(); + + pParams->type = INET_HTTP_DOWNLOAD_FILE; + pParams->dlSize = 0; + pParams->pCurl = pCurl; + pParams->lastTm = 0; + + uv_fs_open(g_pMainLoop, + &pParams->uvFsOpen, + pParams->sDlPath, + O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR, + NULL); + + curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __writeDataCb); + curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, pParams); + curl_easy_setopt(pCurl, CURLOPT_PRIVATE, pParams); + curl_easy_setopt(pCurl, CURLOPT_URL, pParams->pReqUrl); + + curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(pCurl, CURLOPT_PROGRESSFUNCTION, __progressCb); + curl_easy_setopt(pCurl, CURLOPT_PROGRESSDATA, pParams); + + curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_LIMIT, 10000L); // 10K bytes + curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_TIME, 10L); // 30 seconds + + curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10L); + +#ifdef SKIP_PEER_VERIFICATION + /* + * If you want to connect to a site who isn't using a certificate that is + * signed by one of the certs in the CA bundle you have, you can skip the + * verification of the server's certificate. This makes the connection + * A LOT LESS SECURE. + * + * If you have a CA cert for the server stored someplace else than in the + * default bundle, then the CURLOPT_CAPATH option might come handy for + * you. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L); +#else + curl_easy_setopt(pCurl, CURLOPT_CAINFO, SSL_CA_FILE); + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L); +#endif + +#ifdef SKIP_HOSTNAME_VERIFICATION + /* + * If the site you're connecting to uses a different host name that what + * they have mentioned in their server certificate's commonName (or + * subjectAltName) fields, libcurl will refuse to connect. You can skip + * this check, but this will make the connection less secure. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0L); +#endif + + //LOG_EX(LOG_Debug, "Total Size = %d\n", __iNetGetRemoteSize(pURL, 0)); + + curl_multi_add_handle(g_pCurl, pCurl); + + __addReqIdToTable(pParams->pTaskUuid, pCurl); + + return (pParams->pTaskUuid); +} +#endif + +const char* InetHttpDlFileAsync(const char *pURL, + const char *pPath, + OnHttpResponse onRespCb, + OnProgressNotify onProgressCb, + void* pData) +{ + CURLMcode ret; + uuid_t msgId; + char strMsgId[64]; + PHTTP_REQ_PARAMS pParams = NULL; + CURL *pCurl = NULL; + unsigned long long uMemFreeSize = GetPartitionFreeSize("/tmp/"); + + if(pURL == NULL || strlen(pURL) == 0 || onRespCb == NULL) + { + free(pParams); + return (NULL); + } + + LOG_EX(LOG_Debug, "Begin Download: %s --> %s\n", pURL, pPath); + + pParams = (PHTTP_REQ_PARAMS)malloc(sizeof(HTTP_REQ_PARAMS)); + + memset(pParams, 0, sizeof(HTTP_REQ_PARAMS)); + + pCurl = curl_easy_init(); + + pParams->onRspCb = onRespCb; + pParams->pReqUrl = (char *)malloc(strlen(pURL) + 1); + pParams->type = INET_HTTP_DOWNLOAD_FILE; + pParams->dlSize = 0; + pParams->onPrgCb = onProgressCb; + pParams->pData = pData; + pParams->pCurl = pCurl; + pParams->lastTm = 0; + pParams->isCancel = FALSE; + pParams->createTm = (unsigned int)LIBUV_CURRENT_TIME_S(); + + memset(pParams->pReqUrl, 0, strlen(pURL) + 1); + strcpy(pParams->pReqUrl, pURL); + + uuid_generate_random(msgId); + memset(strMsgId, 0, 64); + uuid_unparse_lower(msgId, strMsgId); + pParams->pTaskUuid = strdup(strMsgId); + + if(pPath == NULL) + { + sprintf(pParams->sPath, "./%s", basename_v2(pURL)); + } + else + { + strcpy(pParams->sPath, pPath); + } + + // Memory Free More Than 100M, Download Temp File To Memory + if(uMemFreeSize >= 100 * 1024 * 1024 && + strncmp(pParams->sPath, "/tmp/", 5) != 0) + { + int ret = system("mkdir /tmp/dl -p"); + sprintf(pParams->sDlPath, "/tmp/dl/%s_%s.dl", basename_v2(pParams->sPath), pParams->pTaskUuid); + } + else + { + strcpy(pParams->sDlPath, pParams->sPath); + } + + pParams->uvFsDataSync.data = pParams; + pParams->uvFsClose.data = pParams; + + uv_fs_open(g_pMainLoop, + &pParams->uvFsOpen, + pParams->sDlPath, + O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR, + NULL); + + curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __writeDataCb); + curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, pParams); + curl_easy_setopt(pCurl, CURLOPT_PRIVATE, pParams); + curl_easy_setopt(pCurl, CURLOPT_URL, pURL); + + curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, 0L); + curl_easy_setopt(pCurl, CURLOPT_PROGRESSFUNCTION, __progressCb); + curl_easy_setopt(pCurl, CURLOPT_PROGRESSDATA, pParams); + + //curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, 1800L); // Max download times (30 minutes)1800s + curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_LIMIT, 10000L); // 10K bytes + curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_TIME, 10L); // 30 seconds + + curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10L); + //curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT_MS, 10L); + + + //curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L); + +#ifdef SKIP_PEER_VERIFICATION + /* + * If you want to connect to a site who isn't using a certificate that is + * signed by one of the certs in the CA bundle you have, you can skip the + * verification of the server's certificate. This makes the connection + * A LOT LESS SECURE. + * + * If you have a CA cert for the server stored someplace else than in the + * default bundle, then the CURLOPT_CAPATH option might come handy for + * you. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L); +#else + curl_easy_setopt(pCurl, CURLOPT_CAINFO, SSL_CA_FILE); + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L); +#endif + +#ifdef SKIP_HOSTNAME_VERIFICATION + /* + * If the site you're connecting to uses a different host name that what + * they have mentioned in their server certificate's commonName (or + * subjectAltName) fields, libcurl will refuse to connect. You can skip + * this check, but this will make the connection less secure. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0L); +#endif + + LOG_EX(LOG_Debug, "Download(%u): %s --> %p\n", g_TotalDownloads++, pParams->pTaskUuid, pCurl); + ret = curl_multi_add_handle(g_pCurl, pCurl); + if(ret == CURLE_OK) + { + __addReqIdToTable(pParams->pTaskUuid, pParams); + return (pParams->pTaskUuid); + } + else + { + free(pParams->pTaskUuid); + LOG_EX(LOG_Error, "Add Handle Error: %d\n", ret); + return NULL; + } +} + +int InetCancelDownload(const char *pTaskUuid) +{ + if(pTaskUuid && strlen(pTaskUuid) > 0) + { + PCURL_HANDLE_TBL pItem = NULL; + + HASH_FIND_STR(g_ReqHandleTbl, pTaskUuid, pItem); + + if(pItem != NULL && pItem->pCurlItem->isCancel != TRUE) + { + __cancelDownloadTask(pItem->pCurlItem); + if(pItem->pCurlItem->onRspCb) + { + pItem->pCurlItem->onRspCb(NULL, + pItem->pCurlItem->dlSize, + pItem->pCurlItem->pReqUrl, + pItem->pCurlItem->sPath, + pItem->pCurlItem->pTaskUuid, + -CURLE_OPERATION_TIMEDOUT, + pItem->pCurlItem->pData); + } + } + } + + return (0); +} + +static size_t __uploadCb(char *d, size_t n, size_t l, void *p) +{ + return n*l; +} + +#ifdef LIBCURL_DEBUG +struct data { + char trace_ascii; /* 1 or 0 */ +}; + +static +void dump(const char *text, + FILE *stream, unsigned char *ptr, size_t size, + char nohex) +{ + size_t i; + size_t c; + + unsigned int width = 0x10; + + if(nohex) + /* without the hex output, we can fit more on screen */ + width = 0x40; + + fprintf(stream, "%s, %10.10ld bytes (0x%8.8lx)\n", + text, (long)size, (long)size); + + for(i = 0; i= 0x20) && (ptr[i + c]<0x80)?ptr[i + c]:'.'); + /* check again for 0D0A, to avoid an extra \n if it's at width */ + if(nohex && (i + c + 2 < size) && ptr[i + c + 1] == 0x0D && + ptr[i + c + 2] == 0x0A) { + i += (c + 3 - width); + break; + } + } + fputc('\n', stream); /* newline */ + } + fflush(stream); +} + +static +int my_trace(CURL *handle, curl_infotype type, + char *data, size_t size, + void *userp) +{ + struct data *config = (struct data *)userp; + const char *text; + (void)handle; /* prevent compiler warning */ + + switch(type) { + case CURLINFO_TEXT: + fprintf(stderr, "== Info: %s", data); + /* FALLTHROUGH */ + default: /* in case a new one is introduced to shock us */ + return 0; + + case CURLINFO_HEADER_OUT: + text = "=> Send header"; + break; + case CURLINFO_DATA_OUT: + text = "=> Send data"; + break; + case CURLINFO_SSL_DATA_OUT: + text = "=> Send SSL data"; + break; + case CURLINFO_HEADER_IN: + text = "<= Recv header"; + break; + case CURLINFO_DATA_IN: + text = "<= Recv data"; + break; + case CURLINFO_SSL_DATA_IN: + text = "<= Recv SSL data"; + break; + } + + dump(text, stderr, (unsigned char *)data, size, config->trace_ascii); + return 0; +} +#endif + +int InetHttpUploadFileSync(const char *pURL, const char* pPath, void* pAttachInfo) +{ + CURL *pCurl = NULL; + int rc = 0; + CURLcode ret; + struct curl_httppost *pPost = NULL, *pLastPtr = NULL; + +#ifdef LIBCURL_DEBUG + struct data config; + config.trace_ascii = 1; /* enable ascii tracing */ +#endif + + if(pURL == NULL || strlen(pURL) == 0) + { + LOG_EX(LOG_Error, "Url: %s(%p)\n", SAFE_STRING_VALUE(pURL), pURL); + return -ERR_INPUT_PARAMS; + } + + if(pPath == NULL || strlen(pPath) == 0) + { + LOG_EX(LOG_Error, "Url: %s(%p)\n", SAFE_STRING_VALUE(pPath), pPath); + return -ERR_INPUT_PARAMS; + } + + curl_formadd(&pPost, &pLastPtr, + CURLFORM_COPYNAME, "file", + CURLFORM_FILE, pPath, + CURLFORM_END); + + if(pAttachInfo) + { + PHTTP_POST_ATTACH pDevInfoArray = (PHTTP_POST_ATTACH)pAttachInfo; + PHTTP_POST_ATTACH pItem = NULL, pTmp = NULL; + + LL_FOREACH_SAFE(pDevInfoArray, pItem, pTmp) + { + curl_formadd(&pPost, &pLastPtr, + CURLFORM_COPYNAME, pItem->keyName, + CURLFORM_COPYCONTENTS, pItem->keyValue, + CURLFORM_END); + } + } + + pCurl = curl_easy_init(); + + if(pCurl == NULL) + { + LOG_EX(LOG_Error, "curl_easy_init() Error\n"); + return -ERR_MALLOC_MEMORY; + } + + curl_easy_setopt(pCurl, CURLOPT_ACCEPT_ENCODING, "gzip, deflate"); + curl_easy_setopt(pCurl, CURLOPT_POST, 1L); + curl_easy_setopt(pCurl, CURLOPT_URL, pURL); + curl_easy_setopt(pCurl, CURLOPT_HTTPPOST, pPost); + curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __uploadCb); + curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, 10L); +#ifdef LIBCURL_DEBUG + curl_easy_setopt(pCurl, CURLOPT_DEBUGFUNCTION, my_trace); + curl_easy_setopt(pCurl, CURLOPT_DEBUGDATA, &config); +#endif + +#ifdef SKIP_PEER_VERIFICATION + /* + * If you want to connect to a site who isn't using a certificate that is + * signed by one of the certs in the CA bundle you have, you can skip the + * verification of the server's certificate. This makes the connection + * A LOT LESS SECURE. + * + * If you have a CA cert for the server stored someplace else than in the + * default bundle, then the CURLOPT_CAPATH option might come handy for + * you. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L); +#else + curl_easy_setopt(pCurl, CURLOPT_CAINFO, SSL_CA_FILE); + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L); +#endif + +#ifdef SKIP_HOSTNAME_VERIFICATION + /* + * If the site you're connecting to uses a different host name that what + * they have mentioned in their server certificate's commonName (or + * subjectAltName) fields, libcurl will refuse to connect. You can skip + * this check, but this will make the connection less secure. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0L); +#endif + + +#ifdef LIBCURL_DEBUG + curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L); +#else + curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 0L); +#endif + + ret = curl_easy_perform(pCurl); + + if(ret != CURLE_OK) + { + LOG_EX(LOG_Error, "Upload %s File %s Error %s(%d)\n", pURL, pPath, curl_easy_strerror(ret), ret); + rc = -ERR_NETWORK_SEND; + } + + curl_easy_cleanup(pCurl); + curl_formfree(pPost); + + return rc; +} + +const char* InetHttpWebServicePostAsync(const char *pURL, const char* pPost, OnHttpResponse onRespCb, void* pData) +{ + uuid_t msgId; + char strMsgId[64]; + PHTTP_REQ_PARAMS pParams = (PHTTP_REQ_PARAMS)malloc(sizeof(HTTP_REQ_PARAMS)); + CURL *pCurl = NULL; + + if(pURL == NULL || strlen(pURL) == 0 || onRespCb == NULL) + { + free(pParams); + return (NULL); + } + + memset(pParams, 0, sizeof(HTTP_REQ_PARAMS)); + + pCurl = curl_easy_init(); + + pParams->onRspCb = onRespCb; + pParams->pReqUrl = (char *)malloc(strlen(pURL) + 1); + pParams->type = INET_HTTP_WEBSERVICE_POST; + pParams->dlSize = 0; + pParams->pData = pData; + pParams->pCurl = pCurl; + pParams->lastTm = 0; + pParams->isCancel = FALSE; + + memset(pParams->pReqUrl, 0, strlen(pURL) + 1); + strcpy(pParams->pReqUrl, pURL); + + uuid_generate_random(msgId); + memset(strMsgId, 0, 64); + uuid_unparse_lower(msgId, strMsgId); + pParams->pTaskUuid = strdup(strMsgId); + + curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, __writeDataCb); + curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, pParams); + curl_easy_setopt(pCurl, CURLOPT_PRIVATE, pParams); + curl_easy_setopt(pCurl, CURLOPT_URL, pURL); + curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, 1L); + curl_easy_setopt(pCurl, CURLOPT_USERAGENT, "libcurl-agent/1.0"); + + if(pPost != NULL && strlen(pPost) > 0) + { + curl_easy_setopt(pCurl, CURLOPT_POSTFIELDS, pPost); + curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE, (long)strlen(pPost)); + } + +#ifdef SKIP_PEER_VERIFICATION + /* + * If you want to connect to a site who isn't using a certificate that is + * signed by one of the certs in the CA bundle you have, you can skip the + * verification of the server's certificate. This makes the connection + * A LOT LESS SECURE. + * + * If you have a CA cert for the server stored someplace else than in the + * default bundle, then the CURLOPT_CAPATH option might come handy for + * you. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0L); +#else + curl_easy_setopt(pCurl, CURLOPT_CAINFO, SSL_CA_FILE); + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 1L); +#endif + +#ifdef SKIP_HOSTNAME_VERIFICATION + /* + * If the site you're connecting to uses a different host name that what + * they have mentioned in their server certificate's commonName (or + * subjectAltName) fields, libcurl will refuse to connect. You can skip + * this check, but this will make the connection less secure. + */ + curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0L); +#endif + + curl_multi_add_handle(g_pCurl, pCurl); + + __addReqIdToTable(pParams->pTaskUuid, pParams); + + return (pParams->pTaskUuid); +} + +#if 0 +static void __curlTaskRuntimeCb(void *pParams) +{ + PCURL_HANDLE_TBL pItem = NULL, pTmpItem = NULL; + + while(TRUE) + { + uv_rwlock_rdlock(&g_uvHashRwLock); + + HASH_ITER(hh, g_ReqHandleTbl, pItem, pTmpItem) + { + if(pItem->pCurlItem->type == INET_HTTP_DOWNLOAD_FILE + && pItem->pCurlItem->lastTm > 0) + { + //unsigned int tmNow = LIBUV_CURRENT_TIME_S(); + + if(pItem->pCurlItem->lastTm > 0) + { + //curl_multi_cleanup(pItem->pCurlItem->pCurl); + curl_multi_remove_handle(g_pCurl, pItem->pCurlItem->pCurl); + + if(pItem->uRetryTimes >= 3) + { + if(pItem->pCurlItem->onRspCb) + { + if(strcmp(pItem->pCurlItem->sPath, pItem->pCurlItem->sDlPath) != 0) + { + unlink(pItem->pCurlItem->sDlPath); + } + + pItem->pCurlItem->onRspCb(NULL, + pItem->pCurlItem->dlSize, + pItem->pCurlItem->pReqUrl, + pItem->pCurlItem->sPath, + pItem->pCurlItem->pTaskUuid, + TRUE, + pItem->pCurlItem->pData); + } + + if(pItem->pCurlItem->pReqUrl) + { + free(pItem->pCurlItem->pReqUrl); + } + } + else + { + __restartDlFileAsync(pItem->pCurlItem); + } + } + } + } + uv_rwlock_rdunlock(&g_uvHashRwLock); + usleep(100000); + } + + pthread_detach(pthread_self()); +} +#endif + +static int __getUsernameFromMail(const char *pMailAddr, char **pUsername) +{ + char *pTail; + + if(pMailAddr == NULL || pUsername == NULL || strlen(pMailAddr) == 0) + { + LOG_EX(LOG_Error, "Input Params Error: pMailAddr = [%s], pUsername = %p\n", + pMailAddr ? pMailAddr : "NULL", pUsername); + return (-ERR_INPUT_PARAMS); + } + + *pUsername = (char *)malloc(strlen(pMailAddr) + 1); + + if(*pUsername == NULL) + { + LOG_EX(LOG_Error, "Error Malloc Memory\n"); + *pUsername = ""; + return (-ERR_MALLOC_MEMORY); + } + + memset(*pUsername, 0, strlen(pMailAddr) + 1); + + pTail = strchr(pMailAddr, '@'); + + if(pTail == NULL) + { + strcpy(*pUsername, pMailAddr); + } + else + { + memcpy(*pUsername, pMailAddr, pTail - pMailAddr); + } + + return (0); +} + +int InetSmtpSendEmail(const char* pFrom, + const char* pTo[], + const char* pCc[], + const char* pTitle, + const char* pMessage, + const char* pAttach[], + PSMTP_MAIL_CONFIG pConfig) +{ + const char *pErrMsg = NULL; + quickmail pMail; + + if(pConfig == NULL) + { + LOG_EX(LOG_Error, "Input Param pConfig = NULL\n"); + return (-ERR_INPUT_PARAMS); + } + + if(pConfig->pPassword == NULL || strlen(pConfig->pPassword) == 0) + { + LOG_EX(LOG_Error, "Input Param Error: pConfig->pPassword = [%s]\n", pConfig->pPassword ? pConfig->pPassword : "NULL"); + return (-ERR_INPUT_PARAMS); + } + + if(pConfig->pUserName == NULL || strlen(pConfig->pUserName) == 0) + { + LOG_EX(LOG_Error, "Input Param Error: pConfig->pUserName = [%s]\n", pConfig->pUserName ? pConfig->pUserName : "NULL"); + return (-ERR_INPUT_PARAMS); + } + + if(pConfig->pSmtpServer == NULL || strlen(pConfig->pSmtpServer) == 0) + { + LOG_EX(LOG_Error, "Input Param Error: pConfig->pUserName = [%s]\n", pConfig->pSmtpServer ? pConfig->pSmtpServer : "NULL"); + return (-ERR_INPUT_PARAMS); + } + + if(pFrom == NULL) + { + LOG_EX(LOG_Error, "Input Param pFrom = NULL\n"); + return (-ERR_INPUT_PARAMS); + } + + if(pTo == NULL && pCc == NULL) + { + LOG_EX(LOG_Error, "Input Param pTo = %p, pCc = %p\n", pTo, pCc); + return (-ERR_INPUT_PARAMS); + } + + if(pTitle == NULL) + { + pTitle = ""; + } + + if(pMessage == NULL) + { + pMessage = ""; + } + + quickmail_initialize(); + + pMail = quickmail_create(pFrom, pTitle); + + if(pMail == NULL) + { + LOG_EX(LOG_Error, "Create Quickmail Object Error\n"); + return (-ERR_MALLOC_MEMORY); + } + + for(const char **pValue = pTo; pTo && *pValue; pValue++) + { + quickmail_add_to(pMail, *pValue); + } + + for(const char **pValue = pCc; pCc && *pValue; pValue++) + { + quickmail_add_cc(pMail, *pValue); + } + + quickmail_add_header(pMail, "Importance: Low"); + quickmail_add_header(pMail, "X-Priority: 5"); + quickmail_add_header(pMail, "X-MSMail-Priority: Low"); + quickmail_add_body_memory(pMail, "text/html", (char*)pMessage, strlen(pMessage), 0); + + for(const char **pValue = pAttach; pAttach && *pValue; pValue++) + { + quickmail_add_attachment_file(pMail, *pValue, NULL); + } + + //quickmail_set_debug_log(pMail, stderr); + + pErrMsg = quickmail_send(pMail, pConfig->pSmtpServer, pConfig->smtpPort, pConfig->pUserName, pConfig->pPassword); + + if(pErrMsg != NULL) + { + LOG_EX(LOG_Error, "Send Mail Error: %s\n", pErrMsg); + return (-ERR_SEND_MAIL); + } + + return (0); +} + +int InetInit(void) +{ + int ret = 0; + + ret = curl_global_init(CURL_GLOBAL_ALL); + + if(ret != 0) + { + LOG_EX(LOG_Error, "curl init error: %d\n", ret); + return ret; + } + + g_pMainLoop = DBusLibuvGetRuntime()->pLoop; + + uv_timer_init(g_pMainLoop, &g_uvCurlTm); + uv_timer_init(g_pMainLoop, &g_uvDlTm); + + g_pCurl = curl_multi_init(); + + curl_multi_setopt(g_pCurl, CURLMOPT_SOCKETFUNCTION, __curlSockCb); + curl_multi_setopt(g_pCurl, CURLMOPT_TIMERFUNCTION, __curlTimerCb); + + uv_rwlock_init(&g_uvHashRwLock); + + uv_timer_start(&g_uvDlTm, __onDlTmoutCb, 1000, 1000); + + return (0); +} + +void InetUnInit(void) +{ + curl_multi_cleanup(g_pCurl); + curl_global_cleanup(); +} + diff --git a/app/libuvdbus/src/Framework/Skins/skin_res_vtbl.c b/app/libuvdbus/src/Framework/Skins/skin_res_vtbl.c new file mode 100644 index 0000000..ae30711 --- /dev/null +++ b/app/libuvdbus/src/Framework/Skins/skin_res_vtbl.c @@ -0,0 +1,320 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "libuv_dbus.h" +#include "skins.h" +#include "log.h" + +typedef struct +{ + sqlite3_vtab vTable; + sqlite3 *pSqlDb; + char *pTblName; +} SKINRES_VTBL, *PSKINRES_VTBL; + +typedef struct +{ + sqlite3_vtab_cursor base; + int count; + int eof; +} SKINRES_CURSOR, *PSKINRES_CURSOR; + +static int __skin_res_destructor(sqlite3_vtab *pVtab) +{ + PSKINRES_VTBL p = (PSKINRES_VTBL)pVtab; + + if(p->pTblName != NULL) + { + free(p->pTblName); + p->pTblName = NULL; + } + sqlite3_free(p); + + return 0; +} + +static int __skin_res_create(sqlite3 *pDb, + void *pAux, + int argc, const char * const *argv, + sqlite3_vtab **pp_vt, + char **pzErr) +{ + UT_string *pSqlCmd; + int rc = SQLITE_OK; + PSKINRES_VTBL pVTbl; + + /* Allocate the sqlite3_vtab/example_vtab structure itself */ + pVTbl = (PSKINRES_VTBL)sqlite3_malloc(sizeof(SKINRES_VTBL)); + + if(pVTbl == NULL) + { + return SQLITE_NOMEM; + } + + pVTbl->pSqlDb = pDb; + pVTbl->pTblName = strdup(argv[2]); + + utstring_new(pSqlCmd); + if(strcmp(argv[0], RES_MODE_NAME) == 0) + { + utstring_printf(pSqlCmd, CREATE_RES_TBL_SQL, ""); + } + else + { + utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL, ""); + } + + /* Declare the vtable's structure */ + rc = sqlite3_declare_vtab(pDb, utstring_body(pSqlCmd)); + utstring_free(pSqlCmd); + + if(rc != SQLITE_OK) + { + __skin_res_destructor((sqlite3_vtab*)pVTbl); + + return SQLITE_ERROR; + } + + /* Success. Set *pp_vt and return */ + *pp_vt = &pVTbl->vTable; + + return SQLITE_OK; +} + +static int __skin_res_connect( sqlite3 *db, void *p_aux, + int argc, const char * const *argv, + sqlite3_vtab **pp_vt, char **pzErr ) +{ + return __skin_res_create(db, p_aux, argc, argv, pp_vt, pzErr); +} + +static int __skin_res_disconnect(sqlite3_vtab *pVtab) +{ + return __skin_res_destructor(pVtab); +} + +static int __skin_res_destroy(sqlite3_vtab *pVtab) +{ + int rc = SQLITE_OK; + //PSKINRES_VTBL p = (PSKINRES_VTBL)pVtab; + + if(rc == SQLITE_OK) + { + rc = __skin_res_destructor(pVtab); + } + + return rc; +} + +static int __skin_res_open(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor) +{ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)sqlite3_malloc(sizeof(SKINRES_CURSOR)); + *ppCursor = (sqlite3_vtab_cursor*)pCur; + + return (pCur ? SQLITE_OK : SQLITE_NOMEM); +} + +static int __skin_res_close(sqlite3_vtab_cursor *cur) +{ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)cur; + sqlite3_free(pCur); + + return SQLITE_OK; +} + +static int __skin_res_eof(sqlite3_vtab_cursor *cur) +{ + return ((PSKINRES_CURSOR)cur)->eof; +} + +static int __skin_res_next(sqlite3_vtab_cursor *pInCur) +{ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; + //PSKINRES_VTBL pvTable = (PSKINRES_VTBL)pInCur->pVtab; + + /* Increment the current row count. */ + pCur->count += 1; + + /* Arbitrary contstraint: when we get to 10 rows, then stop. */ + if(pCur->count >= SkinsDefaultSize()) + { + pCur->eof = 1; + } + + return SQLITE_OK; +} + +static int __skin_res_column(sqlite3_vtab_cursor *pInCur, sqlite3_context *ctx, int iCol) +{ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; + PSKIN_RES_INFO pItem = SkinsItemById(pCur->count); + //PSKINRES_VTBL pvTable = (PSKINRES_VTBL)pInCur->pVtab; + + /* Just return the ordinal of the column requested. */ + switch(iCol) + { + case 0: + sqlite3_result_int(ctx, pCur->count); + break; + + case 1: + sqlite3_result_text(ctx, pItem->pResVer, strlen(pItem->pResVer), SQLITE_STATIC); + break; + + case 2: + sqlite3_result_text(ctx, pItem->pLocalPath, strlen(pItem->pLocalPath), SQLITE_STATIC); + break; + + case 3: + sqlite3_result_text(ctx, pItem->pLocalPath, strlen(pItem->pLocalPath), SQLITE_STATIC); + break; + + case 4: + sqlite3_result_text(ctx, pItem->pMD5Chksum, strlen(pItem->pMD5Chksum), SQLITE_STATIC); + break; + } + + return SQLITE_OK; +} + +static int __skin_cfg_column(sqlite3_vtab_cursor *pInCur, sqlite3_context *ctx, int iCol) +{ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; + PSKIN_RES_INFO pItem = SkinsItemById(pCur->count); + //PSKINRES_VTBL pvTable = (PSKINRES_VTBL)pInCur->pVtab; + + /* Just return the ordinal of the column requested. */ + switch(iCol) + { + case 0: + sqlite3_result_int(ctx, pCur->count); + break; + + case 1: + sqlite3_result_text(ctx, pItem->pKeyName, strlen(pItem->pKeyName), SQLITE_STATIC); + break; + + case 2: + sqlite3_result_int(ctx, pItem->resType); + break; + + case 3: + sqlite3_result_int(ctx, 0); + break; + + case 4: + sqlite3_result_int(ctx, pCur->count); + break; + + case 5: + sqlite3_result_text(ctx, "", 0, SQLITE_STATIC); + break; + } + + return SQLITE_OK; +} + +static int __skin_res_rowid(sqlite3_vtab_cursor *pInCur, sqlite_int64 *p_rowid) +{ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pInCur; + + /* Just use the current row count as the rowid. */ + *p_rowid = pCur->count; + + return SQLITE_OK; +} + +static int __skin_res_filter( sqlite3_vtab_cursor *pVtc, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv ) +{ + //int rc; + //int i; + + /* Initialize the cursor structure. */ + PSKINRES_CURSOR pCur = (PSKINRES_CURSOR)pVtc; + + /* Zero rows returned thus far. */ + pCur->count = 0; + + /* Have not reached end of set. */ + pCur->eof = 0; + + /* Move cursor to first row. */ + return __skin_res_next(pVtc); +} + +/* Pretty involved. We don't implement in this example. */ +static int __skin_res_best_index(sqlite3_vtab *pVTbl, sqlite3_index_info *pIdxInfo) +{ + return SQLITE_OK; +} + +static sqlite3_module g_ResModule = +{ + 0, /* iVersion */ + __skin_res_create, /* xCreate - create a vtable */ + __skin_res_connect, /* xConnect - associate a vtable with a connection */ + __skin_res_best_index, /* xBestIndex - best index */ + __skin_res_disconnect, /* xDisconnect - disassociate a vtable with a connection */ + __skin_res_destroy, /* xDestroy - destroy a vtable */ + __skin_res_open, /* xOpen - open a cursor */ + __skin_res_close, /* xClose - close a cursor */ + __skin_res_filter, /* xFilter - configure scan constraints */ + __skin_res_next, /* xNext - advance a cursor */ + __skin_res_eof, /* xEof - inidicate end of result set*/ + __skin_res_column, /* xColumn - read data */ + __skin_res_rowid, /* xRowid - read data */ + NULL, /* xUpdate - write data */ + NULL, /* xBegin - begin transaction */ + NULL, /* xSync - sync transaction */ + NULL, /* xCommit - commit transaction */ + NULL, /* xRollback - rollback transaction */ + NULL, /* xFindFunction - function overloading */ +}; + +static sqlite3_module g_SkinModule = +{ + 0, /* iVersion */ + __skin_res_create, /* xCreate - create a vtable */ + __skin_res_connect, /* xConnect - associate a vtable with a connection */ + __skin_res_best_index, /* xBestIndex - best index */ + __skin_res_disconnect, /* xDisconnect - disassociate a vtable with a connection */ + __skin_res_destroy, /* xDestroy - destroy a vtable */ + __skin_res_open, /* xOpen - open a cursor */ + __skin_res_close, /* xClose - close a cursor */ + __skin_res_filter, /* xFilter - configure scan constraints */ + __skin_res_next, /* xNext - advance a cursor */ + __skin_res_eof, /* xEof - inidicate end of result set*/ + __skin_cfg_column, /* xColumn - read data */ + __skin_res_rowid, /* xRowid - read data */ + NULL, /* xUpdate - write data */ + NULL, /* xBegin - begin transaction */ + NULL, /* xSync - sync transaction */ + NULL, /* xCommit - commit transaction */ + NULL, /* xRollback - rollback transaction */ + NULL, /* xFindFunction - function overloading */ +}; + +int InitSkinRomDatabase(sqlite3 *pDataBase) +{ + if((sqlite3_create_module(pDataBase, SKIN_MODE_NAME, &g_SkinModule, NULL) == SQLITE_OK) + && (sqlite3_create_module(pDataBase, RES_MODE_NAME, &g_ResModule, NULL) == SQLITE_OK)) + { + return 0; + } + else + { + return -ERR_SQL_REG_MODULE; + } +} + + diff --git a/app/libuvdbus/src/Framework/Skins/skins.c b/app/libuvdbus/src/Framework/Skins/skins.c new file mode 100644 index 0000000..2fc624b --- /dev/null +++ b/app/libuvdbus/src/Framework/Skins/skins.c @@ -0,0 +1,1442 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "crypto.h" +#include "json_struct.h" +#include "config_engine.h" +#include "skins_res.h" +#include "inet_api.h" + +#define MAX_DOWNLOAD_ITEMS (10) + +#define DEBUG_SQL_CMD (0) + +typedef enum +{ + STATUS_CREATE_NEW = 0, + STATUS_DOWNLOADING, + STATUS_DOWNLOADED, +} RES_DOWNLOAD_STATUS; + +typedef enum +{ + UPG_STATUS_ADDNEW = (1 << 0), + UPG_STATUS_DL_NEW = (1 << 1), + UPG_STATUS_DOWNLOADED = (1 << 2), +} UPGRADE_RES_STATUS; + +typedef struct +{ + char* pKeyName; + char* pResPath; + + UT_hash_handle hh; ///< UT Hash handle +} SKINS_CACHE_ITEM, *PSKINS_CACHE_ITEM; +static uv_rwlock_t g_SkinCacheRwLock; + +#ifdef PLATFORM_CPU +#define DOWNLOAD_RES_ROOT_PATH (DEF_SKINS_ROOT_PATH) +#else +#define DOWNLOAD_RES_ROOT_PATH ("/mnt/UDISK/resources/") +#endif + +//select * FROM upgrade_skin WHERE resVersion == 4 ORDER BY resType DESC, RANDOM() LIMIT 1 +//#define SKIN_GET_SQL_CMD ("") + +#define ATTACH_DB_SQL_CMD ("ATTACH \'%s\' AS \'%s\'") +#define UPGRADE_TBL_SQL_CMD ("CREATE TABLE IF NOT EXISTS %supgrade (" \ + "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ + "keyName TEXT NOT NULL," \ + "resType INTEGER NOT NULL," \ + "priority INTEGER NOT NULL DEFAULT (1)," \ + "resVersion TEXT NOT NULL," \ + "localPath TEXT NOT NULL," \ + "serverURL TEXT NOT NULL," \ + "md5Chksum TEXT NOT NULL," \ + "resReadme TEXT NOT NULL DEFAULT (\'\')," \ + "resStatus INTEGER NOT NULL DEFAULT (1)," \ + "dlId TEXT NOT NULL DEFAULT (\'\')," \ + "dlStatus INTEGER NOT NULL DEFAULT (0)," \ + "dlRetrys INTEGER NOT NULL DEFAULT (0)," \ + "dlTime TimeStamp NOT NULL DEFAULT (datetime('now','localtime')));") + +#define CREATE_TMP_TBL_SQL "CREATE TABLE IF NOT EXISTS %stmp (" \ + "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ + "localPath TEXT NOT NULL);" + +static int g_isDlFinished = FALSE; +static unsigned int g_curDlItems = 0; +static sqlite3* g_pMemDb = NULL; +static uv_rwlock_t g_uvSkinRwLock; +static uv_rwlock_t g_uvDlRwLock; +static const unsigned int g_tolDefaultSkins = (sizeof(g_SkinDefaultResTable) / sizeof(g_SkinDefaultResTable[0])); +static PSKINS_CACHE_ITEM g_pSkinCackeTbl = NULL; + +char* TblGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom); +static int __getUpgradeInfo(const char *pUpdFilePath); +static int __reTryDlSkinResCb(void *pData, int argc, char **argv, char **azColName); +extern int InitSkinRomDatabase(sqlite3 *pDataBase); +static int g_isVerifyRes = FALSE; +static int g_isUpgradeRunning = FALSE; + +static int __dumpSkinsInfo(PSKIN_RES_INFO pItem, int nItems) +{ + LOG_EX2(LOG_Debug, "Skins Items Information:\n"); + + LOG_EX2(LOG_Debug, "-------------------------------------------------------------" + "--------------------------------------------------------\n"); + + LOG_EX2(LOG_Debug, "| Key Name | Type | MD5 Checksum |" + " Contexts " + " |\n"); + + LOG_EX2(LOG_Debug, "-------------------------------------------------------------" + "--------------------------------------------------------\n"); + + for(int i = 0; i < nItems && pItem; i++, pItem++) + { + LOG_EX2(LOG_Debug, "| %-8s | %-8s | %-32s | %-80s |\n", + pItem->pKeyName, pItem->pResVer, pItem->pMD5Chksum, pItem->pLocalPath); + } + + LOG_EX2(LOG_Debug, "-------------------------------------------------------------" + "--------------------------------------------------------\n"); +} + +static int __verifyResMD5Chksum(const char* pPath, const char* pChksum, int resType) +{ + const char* pMD5Chksum; + + if(resType == TEXT_RES) + { + return (TRUE); + } + + if(pPath == NULL || pChksum == NULL) + { + return (FALSE); + } + + switch(resType) + { + case IMAGE_RES: + case VOICE_RES: + pMD5Chksum = EvpMD5HashFile(pPath); + + if(pMD5Chksum == NULL) + { + return (FALSE); + } + + if(strcmp(pMD5Chksum, pChksum) != 0) + { + LOG_EX(LOG_Error, "%s MD5 Verify Error: %s -> %s\n", pPath, pMD5Chksum, pChksum); + + free((char*)pMD5Chksum); + return (FALSE); + } + else + { + free((char*)pMD5Chksum); + } + + break; + + default: + return (FALSE); + } + + return (TRUE); +} + +static void __checkRes(sqlite3_context *pContext, int argc, sqlite3_value **argv) +{ + if(access(sqlite3_value_text(argv[0]), F_OK) != 0) + { + sqlite3_result_int(pContext, -1); + } + else if(__verifyResMD5Chksum(sqlite3_value_text(argv[0]), + sqlite3_value_text(argv[1]), + sqlite3_value_int(argv[2])) == FALSE) + { + sqlite3_result_int(pContext, -2); + } + else + { + sqlite3_result_int(pContext, 0); + } +} + +static int __cleanupSkinTbl(void) +{ + int rc; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "DROP TABLE %s.%s", SKIN_USER_DB, SKIN_TBL_NAME); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL, SKIN_USER_DB"."); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_free(pSqlCmd); + return 0; +} + +static int __cleanupResTbl(void) +{ + int rc; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "DROP TABLE %s.%s", SKIN_USER_DB, RES_TBL_NAME); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, CREATE_RES_TBL_SQL, SKIN_USER_DB"."); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_free(pSqlCmd); + return 0; +} + +static int __cleanupUpgTbl(void) +{ + int rc; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "DROP TABLE %s.upgrade", SKIN_USER_DB); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, UPGRADE_TBL_SQL_CMD, SKIN_USER_DB"."); + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_free(pSqlCmd); + return 0; +} + +static int __cleanupTmpTbl(void) +{ + int rc; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "DROP TABLE main.tmp"); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Delete Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, CREATE_TMP_TBL_SQL, "main."); + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_free(pSqlCmd); + return 0; +} + +static int __skinCreateCfgDB(void) +{ + int rc = 0; + char* pErrMsg = NULL; + UT_string *pSqlCmd = NULL; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "CREATE VIRTUAL TABLE main.%s USING %s;" + "CREATE VIRTUAL TABLE main.%s USING %s;", + SKIN_TBL_NAME, SKIN_MODE_NAME, RES_TBL_NAME, RES_MODE_NAME); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_free(pSqlCmd); + + return (0); +} + +static int __skinCreateCfgFile(const char* pCfgFilePath) +{ + char* pErrMsg = NULL; + int rc = 0; + static sqlite3* pSqlFileDB = NULL; + UT_string *pSqlCmd = NULL; + + rc = sqlite3_open(":memory:", &g_pMemDb); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "sqlite3_open memory: %s\n", pCfgFilePath); + return -ERR_OPEN_SQLITE3_DB; + } + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, CREATE_TMP_TBL_SQL, ""); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + unlink(pCfgFilePath); + sqlite3_close(g_pMemDb); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + rc = sqlite3_open_v2(pCfgFilePath, &pSqlFileDB, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "sqlite3_open_v2 error: %s\n", pCfgFilePath); + sqlite3_close(g_pMemDb); + utstring_free(pSqlCmd); + return -ERR_OPEN_SQLITE3_DB; + } + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, CREATE_SKIN_TBL_SQL""CREATE_RES_TBL_SQL, "", ""); + + rc = sqlite3_exec(pSqlFileDB, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + unlink(pCfgFilePath); + sqlite3_close(g_pMemDb); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, UPGRADE_TBL_SQL_CMD, ""); + rc = sqlite3_exec(pSqlFileDB, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Create Tbl %s Error: %s\n", UPGRADE_TBL_SQL_CMD, pErrMsg); + sqlite3_free(pErrMsg); + unlink(pCfgFilePath); + sqlite3_close(g_pMemDb); + utstring_free(pSqlCmd); + return -ERR_SQLITE3_CREATE_TABLE; + } + + sqlite3_close(pSqlFileDB); + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, ATTACH_DB_SQL_CMD, pCfgFilePath, SKIN_USER_DB); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Attach Database %s Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + utstring_free(pSqlCmd); + sqlite3_free(pErrMsg); + unlink(pCfgFilePath); + sqlite3_close(g_pMemDb); + return -ERR_SQLITE3_CREATE_TABLE; + } + + utstring_free(pSqlCmd); + + rc = sqlite3_create_function(g_pMemDb, "ResCheck", 3, SQLITE_UTF8, NULL, __checkRes, NULL, NULL); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Don't Support Resurces Verify Function\n"); + } + + if(InitSkinRomDatabase(g_pMemDb) != 0) + { + sqlite3_close(g_pMemDb); + return (-ERR_SQL_REG_MODULE); + } + + rc = __skinCreateCfgDB(); + + if(rc != 0) + { + sqlite3_close(g_pMemDb); + return rc; + } + + return (0); +} + +static void __onDlFileCb(void *pData, unsigned int size, + const char *pReqUrl, const char* pDlPath, + const char *pTaskUuid, int iFinished, void *pUserData) +{ + char* pId = (char*)pUserData; + UT_string *pSqlCmd = NULL; + int rc = 0; + char* pErrMsg = NULL; + + if(g_curDlItems > 0) + { + g_curDlItems--; + } + + if(iFinished == 0 && pId != NULL) + { + //LOG_EX(LOG_Debug, "Request(%s): [%s] --> [%s] Response: [%u] OK\n", pTaskUuid, pReqUrl, pDlPath, size); + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlStatus = %d, dlRetrys = %d, " + "dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s AND " + "ResCheck(localPath, md5Chksum, resType) = 0", + SKIN_USER_DB, STATUS_DOWNLOADED, 0, pId); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + } + else + { + if(iFinished == 1) + { + LOG_EX(LOG_Error, "Request(%s): [%s] --> [%s] Response: [%u] Error\n", pTaskUuid, pReqUrl, pDlPath, size); + } + else + { + LOG_EX(LOG_Error, "Download %s Error: %d\n", pReqUrl, iFinished); + } + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "SELECT * FROM %s.upgrade WHERE ID = %s AND dlRetrys < 5 ", SKIN_USER_DB, pId); + + //fprintf(stdout, "SQL:\n%s\n", utstring_body(pSqlCmd)); + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __reTryDlSkinResCb, NULL, &pErrMsg); + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL %s Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + } + + if(pId) + { + free(pId); + } +} + +static int __reTryDlSkinResCb(void *pData, int argc, char **argv, char **azColName) +{ + UT_string *pSqlCmd = NULL; + char* pErrMsg = NULL; + + const char* pDlTaskId = InetHttpDlFileAsync(argv[6], + argv[5], + __onDlFileCb, + NULL, + strdup(argv[0])); + + if(pDlTaskId != NULL) + { + int rc = 0; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlId = \'%s\', dlRetrys = dlRetrys + 1, " + "dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s", + SKIN_USER_DB, pDlTaskId, argv[0]); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + } + + return 0; +} + +static int __loadDownloadSkinsCb(void *pData, int argc, char **argv, char **azColName) +{ + const char *pDlTaskId; + char* pItemId = argv[0]; + char* pURL = argv[6]; + char* pDlPath = argv[5]; + char* pDlId = argv[10]; + int dlStatus = strtol(argv[3], NULL, 10); + int dlRetry = strtol(argv[4], NULL, 10) + 1; + + if(dlStatus == STATUS_DOWNLOADING) + { + if(strlen(pDlId) > 0) + { + InetCancelDownload(pDlId); + } + + dlRetry++; + } + + //LOG_EX(LOG_Debug, "Download: %s --> %s\n", pURL, pDlPath); + + pDlTaskId = InetHttpDlFileAsync(pURL, + pDlPath, + __onDlFileCb, + NULL, + strdup(pItemId)); + + if(pDlTaskId) + { + UT_string *pSqlCmd = NULL; + int rc = 0; + char* pErrMsg = NULL; + + g_curDlItems++; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET dlStatus = %d, dlRetrys = %d, " + "dlId = \'%s\', dlTime = datetime(\'now\', \'localtime\') WHERE ID = %s", + SKIN_USER_DB, STATUS_DOWNLOADING, dlRetry, pDlTaskId, pItemId); +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + } + else + { + LOG_EX(LOG_Error, "Download %s error\n", pURL); + } + + return (0); +} + +static void __uvDownloadResThread(void *pParams) +{ + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + LOG_EX(LOG_Debug, "Beging Download Skins\n"); + + while(!g_isDlFinished) + { + int rc = 0; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "SELECT *, STRFTIME(\"%%s\", datetime(\'now\', \'localtime\')) " + "- STRFTIME(\"%%s\", upgrade.dlTime) AS diff FROM %s.upgrade " + "WHERE resStatus = %d AND (dlRetrys < 5 OR diff > 600) " + "AND (dlStatus = %d OR (dlStatus = %d AND diff > 600)) " + "LIMIT 10 - %d", + SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_CREATE_NEW, STATUS_DOWNLOADING, g_curDlItems); +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __loadDownloadSkinsCb, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL Query Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + + sleep(1); + } + + LOG_EX(LOG_Debug, "Download Skins Finished\n"); + + pthread_detach(pthread_self()); +} + +static int __sqlCbRemoveUnusedFile(void *pData, int argc, char **argv, char **azColName) +{ + LOG_EX(LOG_Debug, "Clean up resources: [%s]\n", argv[1]); + + if(access(argv[1], F_OK) == 0 + && strncmp(argv[1], DEF_SKINS_ROOT_PATH, strlen(DEF_SKINS_ROOT_PATH)) != 0) + { + unlink(argv[1]); + } +} + +static int __createResTblCb(void *pData, int argc, char **argv, char **azColName) +{ + int rc = 0; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + //DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName); + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "INSERT INTO %s.%s " + "VALUES (NULL, \'%s\', \'%s\', \'%s\', \'%s\')", + SKIN_USER_DB, RES_TBL_NAME, argv[0], argv[1], argv[2], argv[3]); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -1; + } + + utstring_free(pSqlCmd); + + return 0; +} + +static int __createSkinTblCb(void *pData, int argc, char **argv, char **azColName) +{ + int rc = 0; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + //DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName); + + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, "INSERT INTO %s.%s " + "VALUES (NULL, \'%s\', %s, %s, %s, \'%s\')", + SKIN_USER_DB, SKIN_TBL_NAME, + argv[1], argv[2], argv[3], argv[0], argv[4]); + + //fprintf(stdout, "AutoId: %lld: %s\n", sqlite3_last_insert_rowid(g_pMemDb), argv[3]); + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + return -1; + } + + utstring_free(pSqlCmd); + return 0; +} + +static void __uvSyncResThread(void *pParams) +{ + int tolCnt = 0; + PSKINS_CACHE_ITEM pItem = NULL, pTemp = NULL; + + LOG_EX(LOG_Debug, "Beging Sync Download Skins\n"); + + while(TRUE) + { + UT_string *pSqlCmd = NULL; + int rc = 0; + char* pErrMsg = NULL; + char **pResult = NULL; + int iRow = 0, iCol = 0; + int nItems = 0; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "SELECT COUNT(*) FROM %s.upgrade " + "WHERE resStatus = %d AND dlStatus != %d", + SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + + nItems = strtol(pResult[1], NULL, 10); + sqlite3_free_table(pResult); + + if(tolCnt++ % 20 == 0) + { + LOG_EX(LOG_Debug, "Download: Remain %d\n", nItems); + } + + if(nItems == 0) + { + g_isDlFinished = TRUE; + utstring_new(pSqlCmd); + sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL); + + utstring_printf(pSqlCmd, "INSERT INTO main.tmp " + "SELECT %s.ID, %s.localPath FROM %s.%s " + "LEFT JOIN %s.upgrade on %s.md5Chksum = upgrade.md5Chksum " + "WHERE upgrade.md5Chksum IS NULL;", + RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, + SKIN_USER_DB, RES_TBL_NAME); +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); + utstring_free(pSqlCmd); + break; + } + + __cleanupSkinTbl(); + __cleanupResTbl(); + + utstring_renew(pSqlCmd); + + utstring_printf(pSqlCmd, "SELECT resVersion, localPath, serverURL, md5Chksum, " + "keyName, resType, priority, resReadme, resStatus, dlStatus " + "FROM %s.upgrade WHERE resStatus = %d " + "OR (resStatus = %d AND dlStatus = %d) " + "GROUP BY md5Chksum", + SKIN_USER_DB, UPG_STATUS_DOWNLOADED, + UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __createResTblCb, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); + utstring_free(pSqlCmd); + break; + } + else + { + utstring_renew(pSqlCmd); + utstring_printf(pSqlCmd, "SELECT %s.ID, keyName, resType, priority, " + "resReadme, resStatus, dlStatus, %s.md5Chksum " + "FROM %s.upgrade, %s.res WHERE %s.md5Chksum = upgrade.md5Chksum" + " AND (resStatus = %d OR (resStatus = %d AND dlStatus = %d)) " + "ORDER BY keyName", + RES_TBL_NAME, RES_TBL_NAME, SKIN_USER_DB, SKIN_USER_DB, RES_TBL_NAME, + UPG_STATUS_DOWNLOADED, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __createSkinTblCb, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); + utstring_free(pSqlCmd); + break; + } + else + { + sqlite3_exec(g_pMemDb, "SELECT * FROM main.tmp", __sqlCbRemoveUnusedFile, NULL, NULL); + utstring_free(pSqlCmd); + + if(__cleanupUpgTbl() != 0) + { + sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); + } + else + { + sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL); + break; + } + } + } + } + + sleep(1); + } + + LOG_EX(LOG_Debug, "Sync Download Skins Finished\n"); + + uv_rwlock_wrlock(&g_SkinCacheRwLock); + HASH_ITER(hh, g_pSkinCackeTbl, pItem, pTemp) + { + free(pItem->pKeyName); + free(pItem->pResPath); + free(pItem); + pItem = NULL; + } + + g_pSkinCackeTbl = NULL; + uv_rwlock_wrunlock(&g_SkinCacheRwLock); + + g_isUpgradeRunning = FALSE; + pthread_detach(pthread_self()); +} + +static int __upgStatusTblCb(void *pData, int argc, char **argv, char **azColName) +{ + int rc = 0; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName); + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d WHERE ID = %s", + SKIN_USER_DB, UPG_STATUS_DL_NEW, argv[2]); + + rc = sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, NULL, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "[%s] Query Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return -1; + } + + utstring_free(pSqlCmd); + + return 0; +} + +static int __saveUpgradeInfo(PSKIN_RES_INFO pInfo, int nItems) +{ + int isError = FALSE; + char* pErrMsg = NULL; + UT_string* pSqlCmd = NULL; + + if(pInfo == NULL || nItems <= 0) + { + return (-ERR_INPUT_PARAMS); + } + + utstring_new(pSqlCmd); + + sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL); + __cleanupUpgTbl(); + __cleanupTmpTbl(); + + for(int i = 0; i < nItems; i++) + { + UT_string* pPath = NULL; + PSKIN_RES_INFO pItem = &pInfo[i]; + + utstring_new(pPath); + utstring_renew(pSqlCmd); + +#if 0 + if(pItem->resType == VOICE_RES) + { + utstring_printf(pPath, "%svoice/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath)); + } + + else if(pItem->resType == IMAGE_RES) + { + utstring_printf(pPath, "%simage/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath)); + } + else if(pItem->resType == TEXT_RES) + { + utstring_printf(pPath, "%s", pItem->pLocalPath); + } + else + { + utstring_free(pPath); + continue; + } +#else + utstring_printf(pPath, "%svoice/%s", DOWNLOAD_RES_ROOT_PATH, basename_v2(pItem->pLocalPath)); +#endif + utstring_printf(pSqlCmd, "INSERT INTO %s.upgrade (keyName, resType, resVersion, localPath, serverURL, md5Chksum)" + " SELECT \'%s\', %d, \'%s\', \'%s\', \'%s\', \'%s\' ", + SKIN_USER_DB, pItem->pKeyName, pItem->resType, pItem->pResVer, utstring_body(pPath), + pItem->pLocalPath, pItem->pMD5Chksum); + +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + + if((sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg) != SQLITE_OK)) + { + LOG_EX(LOG_Error, "Add Skins[%d] %s To Database Error: %s\n", i, pItem->pKeyName, utstring_body(pSqlCmd)); + LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + isError = TRUE; + utstring_free(pPath); + break; + } + + utstring_free(pPath); + } + + utstring_renew(pSqlCmd); + + utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d " + "WHERE EXISTS (SELECT %s.keyName, upgrade.md5Chksum FROM main.%s, user_db.upgrade " + "WHERE upgrade.keyName = %s.keyName)", + SKIN_USER_DB, UPG_STATUS_DL_NEW, + SKIN_TBL_NAME, SKIN_TBL_NAME, + SKIN_TBL_NAME); + +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + + if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __upgStatusTblCb, 0, &pErrMsg) != SQLITE_OK) + { + LOG_EX(LOG_Error, "Upgrade Status: %s\n", utstring_body(pSqlCmd)); + LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + isError = TRUE; + } + + utstring_renew(pSqlCmd); + + utstring_printf(pSqlCmd, "UPDATE %s.upgrade SET resStatus = %d " + "WHERE EXISTS (SELECT %s.md5Chksum FROM %s.%s " + "WHERE upgrade.md5Chksum = %s.md5Chksum);" + "UPDATE %s.upgrade SET resStatus = %d, localPath = " + "(SELECT %s.localPath FROM main.%s " + "WHERE upgrade.md5Chksum = %s.md5Chksum) " + "WHERE EXISTS (SELECT %s.md5Chksum FROM main.%s " + "WHERE upgrade.md5Chksum = %s.md5Chksum);", + SKIN_USER_DB, UPG_STATUS_DOWNLOADED, + RES_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, + RES_TBL_NAME, + SKIN_USER_DB, UPG_STATUS_DOWNLOADED, + RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME, + RES_TBL_NAME, RES_TBL_NAME, RES_TBL_NAME); + +#if DEBUG_SQL_CMD + LOG_EX(LOG_Debug, "SQL CMD: [%s]\n", utstring_body(pSqlCmd)); +#endif + + if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), NULL, 0, &pErrMsg) != SQLITE_OK) + { + LOG_EX(LOG_Error, "Upgrade Status: %s\n", utstring_body(pSqlCmd)); + LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + isError = TRUE; + } + + utstring_free(pSqlCmd); + + + if(isError == TRUE) + { + sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); + return (-ERR_SQL_QUERY); + } + else + { + uv_thread_t uvSyncThread, uvDlThread; + sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL); + g_curDlItems = 0; + g_isDlFinished = FALSE; + uv_thread_create(&uvDlThread, __uvDownloadResThread, NULL); + uv_thread_create(&uvSyncThread, __uvSyncResThread, NULL); + } + + return 0; +} + +static int __loadPreUpgradeInfo(void) +{ + UT_string *pSqlCmd = NULL; + int rc = 0; + char* pErrMsg = NULL; + char **pResult = NULL; + int iRow = 0, iCol = 0; + int nItems = 0; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "SELECT COUNT(*) FROM %s.upgrade WHERE resStatus = %d AND dlStatus != %d", + SKIN_USER_DB, UPG_STATUS_DL_NEW, STATUS_DOWNLOADED); + + rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s\n", utstring_body(pSqlCmd), pErrMsg); + sqlite3_free(pErrMsg); + } + + utstring_free(pSqlCmd); + + nItems = strtol(pResult[1], NULL, 10); + sqlite3_free_table(pResult); + + if(nItems > 0) + { + uv_thread_t uvSyncThread, uvDlThread; + g_curDlItems = 0; + g_isDlFinished = FALSE; + g_isUpgradeRunning = TRUE; + uv_thread_create(&uvDlThread, __uvDownloadResThread, NULL); + uv_thread_create(&uvSyncThread, __uvSyncResThread, NULL); + LOG_EX(LOG_Debug, "Load Pre Download Items: %d\n", nItems); + } +} + +static int __getEnumResInfo(void) +{ + __saveUpgradeInfo((PSKIN_RES_INFO)g_emuUpgradeInfo, sizeof(g_emuUpgradeInfo) / sizeof(g_emuUpgradeInfo[0])); +} + +int SkinUpgrade(char* pUpdData) +{ + int nItems = 0; + PSKIN_RES_INFO pUpgResInfo; + cJSON *pRoot, *pList; + +#if 1 + FILE *pFile = fopen("/mnt/UDISK/skinupgrade.txt", "w+"); + fwrite(pUpdData, 1, strlen(pUpdData), pFile); + fclose(pFile); +#endif + + if (pUpdData == NULL || strlen(pUpdData) == 0) + { + LOG_EX(LOG_Error, "Input Params Error\n"); + return (-ERR_INPUT_PARAMS); + } + + LOG_EX(LOG_Debug, "Upgrade Cmd: [%s]\n", pUpdData); + //fprintf(stdout, "%s\n", pUpdData); + + pRoot = cJSON_Parse(pUpdData); + + if(pRoot == NULL) + { + LOG_EX(LOG_Error, "Parse Json Error\n"); + return (-ERR_NO_ITEMS); + } + + nItems = cJSON_GetArraySize(pRoot); + + if(nItems <= 0) + { + LOG_EX(LOG_Error, "Upgrade Item: %d\n", nItems); + cJSON_Delete(pRoot); + return (-ERR_NO_ITEMS); + } + + pUpgResInfo = (PSKIN_RES_INFO)malloc(sizeof(SKIN_RES_INFO) * nItems); + + if(pUpgResInfo == NULL) + { + LOG_EX(LOG_Error, "Malloc %d Memory Error\n", nItems); + cJSON_Delete(pRoot); + return (-ERR_MALLOC_MEMORY); + } + + LOG_EX(LOG_Debug, "Array Size = %d\n", nItems); + + memset(pUpgResInfo, 0, sizeof(SKIN_RES_INFO) * nItems); + pList = pRoot->child; + + for(int i = 0; i < nItems; i++) + { + pUpgResInfo[i].resType = VOICE_RES;//cJSON_GetObjectItem(pList, "resourceType")->valueint; + pUpgResInfo[i].pResVer = strdup(cJSON_GetObjectItem(pList, "resourceVersion")->valuestring); + pUpgResInfo[i].pKeyName = strdup(cJSON_GetObjectItem(pList, "resourceName")->valuestring); + pUpgResInfo[i].pLocalPath = strdup(cJSON_GetObjectItem(pList, "url")->valuestring); + pUpgResInfo[i].pMD5Chksum = strdup(cJSON_GetObjectItem(pList, "md5")->valuestring); + + pList = pList->next; + } + + cJSON_Delete(pRoot); + + g_isUpgradeRunning = TRUE; + __dumpSkinsInfo(pUpgResInfo, nItems); + __saveUpgradeInfo(pUpgResInfo, nItems); + + free(pUpgResInfo); +} + +char* SQLiteGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom) +{ + char *pSkinPath = strdup(""); + int rc = 0; + char* pErrMsg = NULL; + UT_string *pSqlCmd = NULL; + char **pResult = NULL; + int iRow = 0, iCol = 0; + int queCol = 13; + int colPath = 21; + + utstring_new(pSqlCmd); + + if(g_isVerifyRes) + { + utstring_printf(pSqlCmd, "SELECT *, RANDOM() AS rnd, ResCheck(localPath, md5Chksum, resType) as resOK " + "FROM %s.%s, %s.%s\n" + "WHERE %s.keyName = \'%s\' AND resOK = 0 AND %s.resId = %s.ID\n" + "UNION\n" + "SELECT *, RANDOM() AS rnd, ResCheck(localPath, md5Chksum, resType) as resOK " + "FROM main.%s, main.%s\n" + "WHERE %s.keyName = \'%s\' AND resOK = 0 AND %s.resId = %s.ID\n" + "ORDER BY priority DESC, rnd " + "LIMIT 1", + SKIN_USER_DB, SKIN_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, + SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME, + SKIN_TBL_NAME, RES_TBL_NAME, + SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME); + } + else + { + utstring_printf(pSqlCmd, "SELECT *, RANDOM() AS rnd " + "FROM %s.%s, %s.%s\n" + "WHERE %s.keyName = \'%s\' AND %s.resId = %s.ID\n" + "UNION\n" + "SELECT *, RANDOM() AS rnd " + "FROM main.%s, main.%s\n" + "WHERE %s.keyName = \'%s\' AND %s.resId = %s.ID\n" + "ORDER BY priority DESC, rnd " + "LIMIT 1", + SKIN_USER_DB, SKIN_TBL_NAME, SKIN_USER_DB, RES_TBL_NAME, + SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME, + SKIN_TBL_NAME, RES_TBL_NAME, + SKIN_TBL_NAME, pKeyName, SKIN_TBL_NAME, RES_TBL_NAME); + queCol = 12; + colPath = 20; + } + + rc = sqlite3_get_table(g_pMemDb, utstring_body(pSqlCmd), &pResult, &iRow, &iCol, &pErrMsg); + + if(rc != SQLITE_OK) + { + LOG_EX(LOG_Error, "Run SQL \n[%s]\n Error: %s(%d)\n", utstring_body(pSqlCmd), pErrMsg, rc); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return (pSkinPath); + } + + if(iRow == 1 && iCol == queCol) + { + + if(access(pResult[colPath], F_OK) != 0) + { + LOG_EX(LOG_Error, "Res %s --> %s not exists\n", pKeyName, pResult[colPath]); + } + else + { + free(pSkinPath); + pSkinPath = strdup(pResult[colPath]); + } +#if 0 + for(int i = 0; i <= 21; i++) + { + LOG_EX(LOG_Debug, "[%d]: {%s}\n", i, pResult[i]); + } +#endif + } + +#if 0 + int index = iCol; + for(int i = 0; i < iRow; i++) + { + fprintf(stdout, "----------%d[%d, %d]---------\n", i, iRow, iCol); + + for(int j = 0; j < iCol; j++) + { + int tblCol = i * iCol + j; + + fprintf(stdout, "%s(%d, %d) = [%s]\n", pResult[tblCol], j, index, pResult[index]); + index++; + } + } +#endif + + sqlite3_free_table(pResult); + utstring_free(pSqlCmd); + + if(strcmp(pSkinPath, "") == 0) + { + free(pSkinPath); + return TblGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom); + } + else + { + return (pSkinPath); + } +} + +char* TblGetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom) +{ + + for(int i = 0; i < sizeof(g_SkinDefaultResTable) / sizeof(g_SkinDefaultResTable[0]); i++) + { + if(strcmp(g_SkinDefaultResTable[i].pKeyName, pKeyName) == 0) + { + return strdup(g_SkinDefaultResTable[i].pLocalPath); + } + } + + return strdup(""); +} + +char* GetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom) +{ + if(g_isUpgradeRunning) + { + return TblGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom); + } + else + { + return SQLiteGetSkinsResource(pKeyName, pResType, pVersion, pComeFrom); + } +} + +unsigned int SkinsDefaultSize(void) +{ + return (g_tolDefaultSkins + 1); +} + +PSKIN_RES_INFO SkinsItemById(int iId) +{ + if(iId < 0 || iId > g_tolDefaultSkins) + { + return (NULL); + } + + return ((PSKIN_RES_INFO)&g_SkinDefaultResTable[iId - 1]); +} + +static int __verifyResValuableCb(void *pData, int argc, char **argv, char **azColName) +{ + char sqlCmd[256]; + char* pErrMsg = NULL; + + if(argc < 3) + { + return 0; + } + + sqlite3_exec(g_pMemDb, "BEGIN TRANSACTION;", NULL, NULL, NULL); + for(int i = 0; i < argc; i++) + { + if(strcmp(azColName[i], "ID") == 0) + { + LOG_EX(LOG_Error, "Cleanup Bad Resources: %s\n", argv[i + 1]); + + memset(sqlCmd, 0, 256); + sprintf(sqlCmd, "DELETE FROM %s.%s WHERE ID = %s", SKIN_USER_DB, RES_TBL_NAME, argv[i]); + + if(sqlite3_exec(g_pMemDb, sqlCmd, __verifyResValuableCb, 0, &pErrMsg) != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL: %s\nError: %s\n", sqlCmd, pErrMsg); + sqlite3_free(pErrMsg); + sqlite3_exec(g_pMemDb, "ROLLBACK;", NULL, NULL, NULL); + return -1; + } + + unlink(argv[i + 1]); + } + } + sqlite3_exec(g_pMemDb, "END TRANSACTION;", NULL, NULL, NULL); + + return (0); +} + +static void VerifySkinResInfo(void) +{ + UT_string *pSqlCmd = NULL; + char* pErrMsg = NULL; + + utstring_new(pSqlCmd); + utstring_printf(pSqlCmd, "SELECT ID, localPath, md5Chksum FROM %s.%s " + "WHERE ResCheck(localPath, md5Chksum, 1) != 0", SKIN_USER_DB, RES_TBL_NAME); + + if(sqlite3_exec(g_pMemDb, utstring_body(pSqlCmd), __verifyResValuableCb, 0, &pErrMsg) != SQLITE_OK) + { + LOG_EX(LOG_Error, "SQL Error: %s\n", pErrMsg); + sqlite3_free(pErrMsg); + utstring_free(pSqlCmd); + return; + } + + utstring_free(pSqlCmd); +} + +void SkinIsVerifyRes(int isVerify) +{ + g_isVerifyRes = isVerify; +} + +int SkinInit(void) +{ + int rc = 0; + UT_string* pPath = NULL; +#if 0 + int tmUsed = 0; + struct timeval tmStart, tmEnd; + + if(DBusLibuvGetRuntime() == NULL) + { + int ret = 0; + uv_thread_t uvThread; + LOG_EX(LOG_Warn, "+++++++++++++++++++++++System Uninit\n"); + + DBusConnection* pBus = DBusWithLibuvInit(GetDBusDefaultLoop(), + g_pModInfoTable[MODULE_SKINS].modAliase, + __dusOnMsg, + NULL, + NULL, //KeyEventCb, + &ret); + + if(pBus == NULL) + { + LOG_EX(LOG_Error, "DBusWithLibuvInit Error: %d\n", ret); + return -ERR_UNINIT_ITEM; + } + + uv_thread_create(&uvThread, uvLoopProc, NULL); + } +#endif + + uv_rwlock_init(&g_uvSkinRwLock); + uv_rwlock_init(&g_uvDlRwLock); + uv_rwlock_init(&g_SkinCacheRwLock); + + utstring_new(pPath); + + utstring_printf(pPath, "mkdir -p %s/image > /dev/zero", DOWNLOAD_RES_ROOT_PATH); + rc = system(utstring_body(pPath)); + + utstring_renew(pPath); + utstring_printf(pPath, "mkdir -p %s/voice > /dev/zero", DOWNLOAD_RES_ROOT_PATH); + rc = system(utstring_body(pPath)); + + utstring_free(pPath); + + rc = __skinCreateCfgFile(SKINS_DB_PATH); + + if(rc != SQLITE_OK) + { + return rc; + } + + // gettimeofday(&tmStart, NULL); + VerifySkinResInfo(); +// gettimeofday(&tmEnd, NULL); + +// tmUsed = (tmEnd.tv_sec * 1000000 + tmEnd.tv_usec) - (tmStart.tv_sec * 1000000 + tmStart.tv_usec); +// LOG_EX(LOG_Debug, "VerifySkinResInfo used time: %d(us)\n", tmUsed); + + __loadPreUpgradeInfo(); + //__getEnumResInfo(); + //__getUpgradeInfo("./hotfix.txt"); + //__loadDownloadItems(); + + //__dumpSkinsInfo(); +} diff --git a/app/libuvdbus/src/Framework/SvrManager/svr_manager.c b/app/libuvdbus/src/Framework/SvrManager/svr_manager.c new file mode 100644 index 0000000..2a15b1c --- /dev/null +++ b/app/libuvdbus/src/Framework/SvrManager/svr_manager.c @@ -0,0 +1,235 @@ +#include "server_addr.h" +#include "log.h" +#include "config_engine.h" +#include "libuv_dbus.h" + +const char* g_ServerModuleStr[] = +{ + "YUNXIN_MODULE", + "VOICE_MODULE", + "VOICE_AI_MODULE", + "SERVER_MODULE", + "LOG_MODULE", + "MARK_POINT_MODULE", + "TTS_MODULE", + "DC_MODULE", + "UNKNOWN_MODULE" +}; + +const char* g_ServerModeStr[] = +{ + "DEV_MODE", + "TEST_MODE", + "PUBLISH_MODE", + "PUBLISH_PREBUILD", + "UNKNOWN_MODE" +}; + +const char* g_KeyMapStr[] = +{ + "VOICE_APP_KEY", + "VOICE_APP_SECRET", + "UNKNOWN_KEYMAP" +}; + +const char* SvrModuleStr(SERVER_MODULE_TYPE module) +{ + return g_ServerModuleStr[module]; +} + +const char* SvrModeStr(SERVER_MODE_TYPE mode) +{ + return g_ServerModeStr[mode]; +} + +const char* g_VoiceKeyMap[VOICE_MAX][MAX_MODE] = { + { // VOICE_APP_KEY + "vbox-dev", + "vbox-dev", + "vbox-online", + "vbox-online", + }, + { // VOICE_APP_SECRET + "b1ec33c03df80ea3035bc9ccaa4af09c", + "b1ec33c03df80ea3035bc9ccaa4af09c", + "8714d6de1c83f21dda5fc9a905a59ac1", + "8714d6de1c83f21dda5fc9a905a59ac1", + }, +}; + +const char* g_ServerAddr[MAX_MODULE][MAX_MODE] = { + { // YUNXIN_MODULE + "2e37bc56a9b7ec3f6b8f41f60b81eb92", + "2e37bc56a9b7ec3f6b8f41f60b81eb92", + "dbb00213c23ea3709aae12ceb4c4e54e", + "7fc939cdb26ec2fa343b7c47a0617190", + }, + { // VOICE_MODULE + "ws://vbox-test.netease.com/netty/websocket", + "ws://vbox-test.netease.com/netty3/websocket", + "wss://vbox-asr.3.163.com/websocket", + "ws://vbox-test.netease.com/asr/websocket", + }, + { // VOICE_AI_MODULE + "http://api.multimedia.netease.com/imgtest/yqbot31_8686/", + "http://api.multimedia.netease.com/imgtest/yqbot29_8686/", + "https://vbox-smart.3.163.com/ ", + "http://api.multimedia.netease.com/imgtest/yqbot30_8888/", + }, + { // SERVER_MODULE + "http://api.multimedia.netease.com/imgtest/yqbot27_7677/", + "http://api.multimedia.netease.com/imgtest/yqbot31_7676/", + "https://vbox-server.3.163.com/", + "http://api.multimedia.netease.com/imgtest/yqbot22_7678/", + }, + { // LOG_MODULE + "http://vbox-log-test.netease.com/logCollectDev/vbox/logCollect/uploadLog", + "http://vbox-log-test.netease.com/logCollect/vbox/logCollect/uploadLog", + "https://vbox-log.3.163.com/vbox/logCollect/uploadLog", + "http://vbox-log-test.netease.com/logCollectOnline/vbox/logCollect/uploadLog", + }, + { // MARK_POINT_MODULE + "http://vbox-log-test.netease.com/buriedDev/vbox/log/add", + "http://vbox-log-test.netease.com/buriedTest/vbox/log/add", + "https://vbox-log.3.163.com/vbox/log/add", + "http://vbox-log-test.netease.com/buriedOnline/vbox/log/add", + }, + { // TTS_MODULE + "http://api.openai.netease.com/vbox-tts-dev/vbox/tts/transform", + "http://api.openai.netease.com/vbox-tts-test/vbox/tts/transform", + "https://vbox-tts.3.163.com/vbox/tts/transform", + "http://api.openai.netease.com/vbox-tts-online/vbox/tts/transform", + }, + { // DC_MODULE + "http://api.multimedia.netease.com/imgtest/yqbot27_7677/vbox/uploadFile", + "http://api.multimedia.netease.com/imgtest/yqbot31_7676/vbox/uploadFile", + "https://vbox-server.3.163.com/vbox/uploadFile", + "http://api.multimedia.netease.com/imgtest/yqbot22_7678/vbox/uploadFile", + }, +}; + +static unsigned int g_SvrMode = PUBLISH_MODE; + +void DumpCurServerAddr(const char* pTags) +{ + if(pTags && strlen(pTags) > 0) + { + LOG_EX2(LOG_Info, "%s\t Current Server Mode: %s\n", pTags, SvrModeStr(g_SvrMode)); + } + else + { + LOG_EX2(LOG_Info, "Current Server Mode: %s\n", SvrModeStr(g_SvrMode)); + } + +#if 0 + LOG_EX2(LOG_Info, "Voice Key = [%s], Secret = [%s]\n", + GetCurVoiceKeyValue(VOICE_APP_KEY), GetCurVoiceKeyValue(VOICE_APP_SECRET)); + + LOG_EX2(LOG_Info, "--------------------------------------------------------" + "----------------------------------------------\n"); + + LOG_EX2(LOG_Info, "| Module | " + "Server URL |\n"); + + LOG_EX2(LOG_Info, "--------------------------------------------------------" + "----------------------------------------------\n"); + + for(int i = 0; i < MAX_MODULE; i++) + { + LOG_EX2(LOG_Info, "| %-17s | %-78s |\n", SvrModuleStr(i), GetCurServerAddr(i)); + } + + LOG_EX2(LOG_Info, "--------------------------------------------------------" + "----------------------------------------------\n"); +#endif + +} + +SERVER_MODE_TYPE GetCurrentServerMode(void) +{ + return g_SvrMode; +} + +void SetCurrentServerMode(SERVER_MODE_TYPE mode) +{ + if(mode >= 0 && mode < MAX_MODE) + { + if(g_SvrMode != mode) + { + LOG_EX(LOG_Debug, "Change server mode from %s(%d) to %s(%d)\n", + g_ServerModeStr[g_SvrMode], g_SvrMode, g_ServerModeStr[mode], mode); + + g_SvrMode = mode; + + CfgSetIntValue("ServerMode", mode); + } + else + { + LOG_EX(LOG_Warn, "Current mode is %s(%d) yet\n", g_ServerModeStr[mode], mode); + } + } + else + { + LOG_EX(LOG_Error, "Unknown Mode: %d, current mode: %s(%d)\n", + mode, g_ServerModeStr[g_SvrMode], g_SvrMode); + } +} + +char* GetCurServerAddr(SERVER_MODULE_TYPE module) +{ + if(module >= 0 && module < MAX_MODULE) + { + return (char*)g_ServerAddr[module][g_SvrMode]; + } + else + { + LOG_EX(LOG_Error, "Unknown Module: %s(%d)\n", g_ServerModuleStr[module], module); + return ""; + } +} + +char* GetCurVoiceKeyValue(VOICE_KEYMAP_TYPE keyMap) +{ + if(keyMap >= 0 && keyMap < VOICE_MAX) + { + return (char*)g_VoiceKeyMap[keyMap][g_SvrMode]; + } + else + { + LOG_EX(LOG_Error, "Unknown KeyMap Type: %s(%d)\n", g_KeyMapStr[keyMap], keyMap); + return ""; + } +} + +static PDBUS_MSG_PACK __dusOnMsg(uv_loop_t* pLoop, DBusConnection* pConn, PDBUS_MSG_PACK pMsg) +{ + return NULL; +} + +static void uvLoopProc(void *pParams) +{ + RunUVLoop(GetDBusDefaultLoop()); + pthread_detach(pthread_self()); +} + +void ServerManagerInit(void) +{ + int ret = 0; + uv_thread_t uvThread; + LOG_EX(LOG_Warn, "+++++++++++++++++++++++System Uninit\n"); + + DBusConnection* pBus = DBusWithLibuvInit(GetDBusDefaultLoop(), + g_pModInfoTable[MODULE_SKINS].modAliase, + __dusOnMsg, + NULL, + NULL, //KeyEventCb, + &ret); + + if(pBus == NULL) + { + LOG_EX(LOG_Error, "DBusWithLibuvInit Error: %d\n", ret); + return; + } + + uv_thread_create(&uvThread, uvLoopProc, NULL); +} diff --git a/app/libuvdbus/src/Framework/Timer/timer.c b/app/libuvdbus/src/Framework/Timer/timer.c new file mode 100644 index 0000000..0263dd8 --- /dev/null +++ b/app/libuvdbus/src/Framework/Timer/timer.c @@ -0,0 +1,773 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "log.h" +#include "libuv_dbus.h" + +#define TIMER_TIMEOUT (200) + +#define IS_LEAP_YEAR(year) ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + +static unsigned char g_DayOfMonth[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +typedef struct +{ + void* pUserData; + OnAlarmTimer pOnAlarmCb; + unsigned int alarmId; + + struct tm setDateTime; + int setWeekDay; + unsigned int repeatMode; + + struct tm onDateTime; + time_t onTimestamp; + unsigned int timerPriority; + + UT_hash_handle hh; ///< UT Hash handle +} ALARM_ITEM_DATA, *PALARM_ITEM_DATA; + +static uv_timer_t g_uvTimer; +static unsigned int g_iAlarmId = 1; +static struct tm g_LocalTime; +static time_t g_TimeStamp; +static uv_loop_t* g_pMainLoop = NULL; +static uv_rwlock_t g_uvHashRwLock; +static PALARM_ITEM_DATA g_TimerTbl = NULL; + +const char* DumpTimerRepeatModeString(int mode) +{ + switch(mode & 0xFF) + { + case REPEAT_MODE_NONE: return "NONE"; + case REPEAT_MODE_EVERY_DAY: return "EVERY_DAY"; + case REPEAT_MODE_WORKDAY: return "WORKDAY"; + case REPEAT_MODE_HOLIDAY: return ("REPEAT_MODE_HOLIDAY"); + case REPEAT_MODE_WEEKEND: return "WEEKEND"; + case REPEAT_MODE_WEEKDAY: return "WEEKDAY"; + case REPEAT_MODE_EVERY_MONTH_DAY: return "EVERY_MONTH_DAY"; + case REPEAT_MODE_EVERY_YEAR_DAY: return "EVERY_YEAR_DAY"; + case REPEAT_MODE_EVERY_TIME: return ("EVERY_TIME"); + case REPEAT_MODE_MONTH_LAST_DAY: return "REPEAT_MODE_MONTH_LAST_DAY"; + default: return ("Unknown Mode"); + } +} + +static int __timestampSort(PALARM_ITEM_DATA p1, PALARM_ITEM_DATA p2) +{ + if(p1->onTimestamp == p2->onTimestamp) + { + return (p2->timerPriority - p1->timerPriority); + } + else + { + return (p1->onTimestamp - p2->onTimestamp); + } +} + +static int __getNextOnTimestamp(PALARM_ITEM_DATA pInfo) +{ + int ret; + struct tm setTime; + time_t timestamp; + + if(pInfo == NULL) + { + return (-ERR_INPUT_PARAMS); + } + + if(pInfo->repeatMode == REPEAT_MODE_NONE) + { + pInfo->onTimestamp = 0; + return (-ERR_INPUT_PARAMS); + } + + timestamp = pInfo->onTimestamp + 24 * 3600; + pInfo->onTimestamp = timestamp; + localtime_r(×tamp, &setTime); + + switch(pInfo->repeatMode) + { + case REPEAT_MODE_EVERY_DAY: + localtime_r(×tamp, &pInfo->onDateTime); + break; + + case REPEAT_MODE_WORKDAY: + do + { + ret = CurrentIsWorkDay(setTime.tm_year, setTime.tm_yday); + + if(ret == 0) + { + timestamp = mktime(&setTime) + 24 * 3600; + + localtime_r(×tamp, &setTime); + } + } while(ret == 0); + + if(ret < 0) + { + pInfo->onTimestamp = 0; + pInfo->onDateTime.tm_year = -1; + pInfo->onDateTime.tm_mon = -1; + pInfo->onDateTime.tm_mday = -1; + } + else + { + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + } + break; + + case REPEAT_MODE_HOLIDAY: + do + { + ret = CurrentIsWorkDay(setTime.tm_year, setTime.tm_yday); + + if(ret == 0) + { + timestamp = mktime(&setTime) + 24 * 3600; + + localtime_r(×tamp, &setTime); + } + } while(ret == 1); + + if(ret < 0) + { + pInfo->onTimestamp = 0; + pInfo->onDateTime.tm_year = -1; + pInfo->onDateTime.tm_mon = -1; + pInfo->onDateTime.tm_mday = -1; + } + else + { + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + } + break; + + case REPEAT_MODE_WEEKEND: + while(setTime.tm_wday != 0 && setTime.tm_wday != 6) + { + timestamp = mktime(&setTime) + 24 * 3600; + localtime_r(×tamp, &setTime); + } + + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + break; + + case REPEAT_MODE_WEEKDAY: + if(pInfo->setDateTime.tm_wday == 0) + { + pInfo->setDateTime.tm_wday = 1 << 0; + } + else if(pInfo->setDateTime.tm_wday & (1 << 7)) + { + pInfo->setDateTime.tm_wday = 1 << 0; + } + + while(((1 << setTime.tm_wday) & pInfo->setDateTime.tm_wday) == 0) + { + timestamp = mktime(&setTime) + 24 * 3600; + localtime_r(×tamp, &setTime); + } + + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + + break; + + case REPEAT_MODE_EVERY_TIME: + timestamp = mktime(&g_LocalTime); + + if(pInfo->setDateTime.tm_hour > 0) + { + timestamp += pInfo->setDateTime.tm_hour * 3600; + } + + if(pInfo->setDateTime.tm_min > 0) + { + timestamp += pInfo->setDateTime.tm_min * 60; + } + + if(pInfo->setDateTime.tm_sec > 0) + { + timestamp += pInfo->setDateTime.tm_sec; + } + + localtime_r(×tamp, &pInfo->onDateTime); + pInfo->onTimestamp = timestamp; + break; + + case REPEAT_MODE_MONTH_LAST_DAY: + if(pInfo->onDateTime.tm_mon < 11) + { + pInfo->onDateTime.tm_mon++; + } + else + { + pInfo->onDateTime.tm_mon = 0; + pInfo->onDateTime.tm_year++; + } + + pInfo->onDateTime.tm_mday = g_DayOfMonth[pInfo->onDateTime.tm_mon]; + if(IS_LEAP_YEAR(pInfo->onDateTime.tm_year) && (pInfo->onDateTime.tm_mon == 1)) + { + pInfo->onDateTime.tm_mday += 1; + } + + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + break; + } + + return (0); +} + +static int __getOnTimestamp(PALARM_ITEM_DATA pInfo) +{ + int ret = 0; + struct tm setTime; + time_t timestamp; + + if(pInfo == NULL) + { + return (-ERR_INPUT_PARAMS); + } + + if(pInfo->setDateTime.tm_hour == -1) + { + pInfo->onDateTime.tm_hour = g_LocalTime.tm_hour; + } + else + { + pInfo->onDateTime.tm_hour = pInfo->setDateTime.tm_hour; + } + + if(pInfo->setDateTime.tm_min == -1) + { + pInfo->onDateTime.tm_min = g_LocalTime.tm_min; + } + else + { + pInfo->onDateTime.tm_min = pInfo->setDateTime.tm_min; + } + + if(pInfo->setDateTime.tm_sec == -1) + { + pInfo->onDateTime.tm_sec = g_LocalTime.tm_sec; + } + else + { + pInfo->onDateTime.tm_sec = pInfo->setDateTime.tm_sec; + } + + switch(pInfo->repeatMode) + { + case REPEAT_MODE_EVERY_MONTH_DAY: + pInfo->setDateTime.tm_mon = -1; + pInfo->setDateTime.tm_year = -1; + case REPEAT_MODE_EVERY_YEAR_DAY: + pInfo->setDateTime.tm_year = -1; + case REPEAT_MODE_NONE: + if(pInfo->setDateTime.tm_year == -1) + { + pInfo->onDateTime.tm_year = g_LocalTime.tm_year; + } + else + { + pInfo->onDateTime.tm_year = pInfo->setDateTime.tm_year; + } + + if(pInfo->setDateTime.tm_mon == -1) + { + pInfo->onDateTime.tm_mon = g_LocalTime.tm_mon; + } + else + { + pInfo->onDateTime.tm_mon = pInfo->setDateTime.tm_mon; + } + + if(pInfo->setDateTime.tm_mday == -1) + { + pInfo->onDateTime.tm_mday = g_LocalTime.tm_mday; + } + else + { + pInfo->onDateTime.tm_mday = pInfo->setDateTime.tm_mday; + } + break; + + case REPEAT_MODE_EVERY_DAY: + case REPEAT_MODE_WORKDAY: + case REPEAT_MODE_WEEKEND: + case REPEAT_MODE_WEEKDAY: + case REPEAT_MODE_EVERY_TIME: + case REPEAT_MODE_HOLIDAY: + pInfo->onDateTime.tm_year = g_LocalTime.tm_year; + pInfo->onDateTime.tm_mon = g_LocalTime.tm_mon; + pInfo->onDateTime.tm_mday = g_LocalTime.tm_mday; + break; + case REPEAT_MODE_MONTH_LAST_DAY: + pInfo->onDateTime.tm_year = g_LocalTime.tm_year; + pInfo->onDateTime.tm_mon = g_LocalTime.tm_mon; + pInfo->onDateTime.tm_mday = g_DayOfMonth[g_LocalTime.tm_mon]; + if(IS_LEAP_YEAR(g_LocalTime.tm_year) && (g_LocalTime.tm_mon == 1)) + { + pInfo->onDateTime.tm_mday += 1; + } + break; + } + + pInfo->onDateTime.tm_wday = g_LocalTime.tm_wday; + pInfo->onDateTime.tm_yday = g_LocalTime.tm_yday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + + if(pInfo->repeatMode == REPEAT_MODE_NONE) + { + return (0); + } + + memcpy(&setTime, &g_LocalTime, sizeof(struct tm)); + + if(mktime(&setTime) > (pInfo->onTimestamp + 1)) + { + if(pInfo->repeatMode == REPEAT_MODE_EVERY_MONTH_DAY) + { + DEBUG_CODE_LINE(); + if(pInfo->onDateTime.tm_mon < 11) + { + pInfo->onDateTime.tm_mon++; + } + else + { + pInfo->onDateTime.tm_mon = 0; + pInfo->onDateTime.tm_year++; + } + + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + return (0); + } + else if(pInfo->repeatMode == REPEAT_MODE_EVERY_YEAR_DAY) + { + pInfo->onDateTime.tm_year++; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + return (0); + } + else if(pInfo->repeatMode == REPEAT_MODE_MONTH_LAST_DAY) + { + if(pInfo->onDateTime.tm_mon < 11) + { + pInfo->onDateTime.tm_mon++; + } + else + { + pInfo->onDateTime.tm_mon = 0; + pInfo->onDateTime.tm_year++; + } + + pInfo->onDateTime.tm_mday = g_DayOfMonth[pInfo->onDateTime.tm_mon]; + if(IS_LEAP_YEAR(pInfo->onDateTime.tm_year) && (pInfo->onDateTime.tm_mon == 1)) + { + pInfo->onDateTime.tm_mday += 1; + } + + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + return (0); + } + else + { + timestamp = mktime(&setTime) + 24 * 3600; + localtime_r(×tamp, &setTime); + } + } + + switch(pInfo->repeatMode) + { + case REPEAT_MODE_EVERY_DAY: + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + break; + + case REPEAT_MODE_WORKDAY: + do + { + ret = CurrentIsWorkDay(setTime.tm_year, setTime.tm_yday); + + if(ret == 0) + { + timestamp = mktime(&setTime) + 24 * 3600; + + localtime_r(×tamp, &setTime); + } + } while(ret == 0); + + if(ret < 0) + { + pInfo->onTimestamp = 0; + pInfo->onDateTime.tm_year = -1; + pInfo->onDateTime.tm_mon = -1; + pInfo->onDateTime.tm_mday = -1; + } + else + { + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + } + break; + + case REPEAT_MODE_HOLIDAY: + do + { + ret = CurrentIsWorkDay(setTime.tm_year, setTime.tm_yday); + + if(ret == 0) + { + timestamp = mktime(&setTime) + 24 * 3600; + + localtime_r(×tamp, &setTime); + } + } while(ret == 1); + + if(ret < 0) + { + pInfo->onTimestamp = 0; + pInfo->onDateTime.tm_year = -1; + pInfo->onDateTime.tm_mon = -1; + pInfo->onDateTime.tm_mday = -1; + } + else + { + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + } + break; + + case REPEAT_MODE_WEEKEND: + while(setTime.tm_wday != 0 && setTime.tm_wday != 6) + { + timestamp = mktime(&setTime) + 24 * 3600; + localtime_r(×tamp, &setTime); + } + + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + break; + + case REPEAT_MODE_WEEKDAY: + if(pInfo->setDateTime.tm_wday == 0) + { + pInfo->setDateTime.tm_wday = 1 << 0; + } + else if(pInfo->setDateTime.tm_wday & (1 << 7)) + { + pInfo->setDateTime.tm_wday = 1 << 0; + } + + while(((1 << setTime.tm_wday) & pInfo->setDateTime.tm_wday) == 0) + { + timestamp = mktime(&setTime) + 24 * 3600; + localtime_r(×tamp, &setTime); + } + + pInfo->onDateTime.tm_year = setTime.tm_year; + pInfo->onDateTime.tm_mon = setTime.tm_mon; + pInfo->onDateTime.tm_mday = setTime.tm_mday; + pInfo->onTimestamp = mktime(&pInfo->onDateTime); + + break; + + case REPEAT_MODE_EVERY_TIME: + timestamp = mktime(&g_LocalTime); + + if(pInfo->setDateTime.tm_hour > 0) + { + timestamp += pInfo->setDateTime.tm_hour * 3600; + } + + if(pInfo->setDateTime.tm_min > 0) + { + timestamp += pInfo->setDateTime.tm_min * 60; + } + + if(pInfo->setDateTime.tm_sec > 0) + { + timestamp += pInfo->setDateTime.tm_sec; + } + + localtime_r(×tamp, &pInfo->onDateTime); + pInfo->onTimestamp = timestamp; + break; + } + + return (0); +} + +static void __timerout200msCb(uv_timer_t *pTimer) +{ + PALARM_ITEM_DATA pItem = NULL, pTemp = NULL; + + // upgrade current time and timestamp + g_TimeStamp = time((time_t*)NULL); + localtime_r(&g_TimeStamp, &g_LocalTime); + + uv_rwlock_wrlock(&g_uvHashRwLock); + HASH_ITER(hh, g_TimerTbl, pItem, pTemp) + { + // cleanup out of time more than 10s timer + if(g_TimeStamp - pItem->onTimestamp > 10) + { + LOG_EX(LOG_Warn, "Remove out of time timer: %u, %ld, %ld\n", pItem->alarmId, g_TimeStamp, pItem->onTimestamp); + HASH_DEL(g_TimerTbl, pItem); + free(pItem); + + continue; + } + + // timer not on time + if(pItem->onTimestamp != g_TimeStamp) + { + break; + } + + // timer on time, call callback + if(pItem->pOnAlarmCb) + { + pItem->pOnAlarmCb(pItem->alarmId, g_TimeStamp, pItem->pUserData); + } + + //LOG_EX(LOG_Debug, "Timer %d Alarming..................\n", pItem->alarmId); + + // cleanup not repeat timer + if(pItem->repeatMode == REPEAT_MODE_NONE) + { + HASH_DEL(g_TimerTbl, pItem); + free(pItem); + } + else + { + // calc next on time + int ret = __getNextOnTimestamp(pItem); + + if(ret != 0 || pItem->onTimestamp == 0) + { + // some error, remove it + LOG_EX(LOG_Error, "Timer %d repeat error: ret = %d, timestamp = %u\n", pItem->alarmId, ret, pItem->onTimestamp); + HASH_DEL(g_TimerTbl, pItem); + free(pItem); + } + else + { + // resort table by upgrade timestamp + HASH_SORT(g_TimerTbl, __timestampSort); + + // show log + LOG_EX(LOG_Debug, "Readd Timer: %u at [%04u-%02u-%02u %02u:%02u:%02u], repMode = %s, Timestamp = %u\n", + pItem->alarmId, + pItem->onDateTime.tm_year + 1900, + pItem->onDateTime.tm_mon + 1, + pItem->onDateTime.tm_mday, + pItem->onDateTime.tm_hour, + pItem->onDateTime.tm_min, + pItem->onDateTime.tm_sec, + DumpTimerRepeatModeString(pItem->repeatMode), + pItem->onTimestamp); + } + } + } + uv_rwlock_wrunlock(&g_uvHashRwLock); +} + +int AlarmTimerInit(uv_loop_t* pLoop) +{ + g_pMainLoop = pLoop; + uv_rwlock_init(&g_uvHashRwLock); + uv_timer_init(g_pMainLoop, &g_uvTimer); + + g_TimeStamp = time((time_t*)NULL); + localtime_r(&g_TimeStamp, &g_LocalTime); + + g_iAlarmId = 1; + + uv_timer_start(&g_uvTimer, __timerout200msCb, 0, TIMER_TIMEOUT); +} + +int AlarmTimerCleanup(void) +{ + uv_timer_stop(&g_uvTimer); + uv_rwlock_destroy(&g_uvHashRwLock); + + if(g_pMainLoop != NULL) + { + AlarmTimerInit(g_pMainLoop); + } +} + +int AlarmTimerRemove(unsigned int tmId) +{ + PALARM_ITEM_DATA pItem = NULL; + + uv_rwlock_rdlock(&g_uvHashRwLock); + HASH_FIND_INT(g_TimerTbl, &tmId, pItem); + uv_rwlock_rdunlock(&g_uvHashRwLock); + + if(pItem == NULL) + { + LOG_EX(LOG_Error, "Can't find item: %u\n", tmId); + return (-ERR_NO_ITEMS); + } + + uv_rwlock_wrlock(&g_uvHashRwLock); + HASH_DEL(g_TimerTbl, pItem); + uv_rwlock_wrunlock(&g_uvHashRwLock); + free(pItem); + + return (tmId); +} + +unsigned int AlarmTimerAdd(int year, + int month, + int day, + int hour, + int minute, + int second, + int weekDay, + int repMode, + OnAlarmTimer pOnTimerCb, + int priority, + void *pUserData, + int *pError) +{ + int et; + PALARM_ITEM_DATA pAlarmData = NULL; + + if(pOnTimerCb == NULL) + { + LOG_EX(LOG_Error, "Input Params Error: pOnTimerCb = %p\n", pOnTimerCb); + if(pError) + { + *pError = -ERR_INPUT_PARAMS; + } + + return (0xFFFFFFFF); + } + + g_TimeStamp = time((time_t*)NULL); + localtime_r(&g_TimeStamp, &g_LocalTime); + + pAlarmData = (PALARM_ITEM_DATA)malloc(sizeof(ALARM_ITEM_DATA)); + + if(pAlarmData == NULL) + { + LOG_EX(LOG_Error, "Malloc Memory Error\n"); + + if(pError) + { + *pError = -ERR_MALLOC_MEMORY; + } + + return (0xFFFFFFFF); + } + + memset(pAlarmData, 0, sizeof(ALARM_ITEM_DATA)); + + // save input params + pAlarmData->setDateTime.tm_year = year; + pAlarmData->setDateTime.tm_mon = month; + pAlarmData->setDateTime.tm_mday = day; + pAlarmData->setDateTime.tm_hour = hour; + pAlarmData->setDateTime.tm_min = minute; + pAlarmData->setDateTime.tm_sec = second; + pAlarmData->setDateTime.tm_wday = weekDay; + + pAlarmData->repeatMode = repMode; + pAlarmData->pOnAlarmCb = pOnTimerCb; + pAlarmData->pUserData = pUserData; + pAlarmData->timerPriority = priority; + + // get timer on time + __getOnTimestamp(pAlarmData); + + // check on time + et = pAlarmData->onTimestamp - mktime(&g_LocalTime); + + if(et < -1 || pAlarmData->onTimestamp == 0) + { + LOG_EX(LOG_Debug, "Add Timer Error: [%04u-%02u-%02u %02u:%02u:%02u], repMode = %s(%u), %d, %u/%u\n", + pAlarmData->setDateTime.tm_year + 1900, + pAlarmData->setDateTime.tm_mon + 1, + pAlarmData->setDateTime.tm_mday, + pAlarmData->setDateTime.tm_hour, + pAlarmData->setDateTime.tm_min, + pAlarmData->setDateTime.tm_sec, + DumpTimerRepeatModeString(repMode), repMode, + et, pAlarmData->onTimestamp, mktime(&g_LocalTime)); + + if(pError) + { + *pError = -ERR_INPUT_PARAMS; + } + + return (0xFFFFFFFF); + } + + if(pError) + { + *pError = 0; + } + + // upgrade time global id + pAlarmData->alarmId = __sync_fetch_and_add(&g_iAlarmId, 1); + + // save new timer to hash table, and sort it by timestamp + uv_rwlock_wrlock(&g_uvHashRwLock); + HASH_ADD_INT(g_TimerTbl, alarmId, pAlarmData); + HASH_SORT(g_TimerTbl, __timestampSort); + uv_rwlock_wrunlock(&g_uvHashRwLock); + + LOG_EX(LOG_Debug, "Add: %u [%04u-%02u-%02u %02u:%02u:%02u] at [%04u-%02u-%02u %02u:%02u:%02u], repMode = %s, priority = %d, Timestamp = %u\n", + pAlarmData->alarmId, + (pAlarmData->setDateTime.tm_year == -1) ? 1900 : pAlarmData->setDateTime.tm_year + 1900, + (pAlarmData->setDateTime.tm_mon == -1) ? 0 : pAlarmData->setDateTime.tm_mon + 1, + (pAlarmData->setDateTime.tm_mday == -1) ? 0 : pAlarmData->setDateTime.tm_mday, + (pAlarmData->setDateTime.tm_hour == -1) ? 0 : pAlarmData->setDateTime.tm_hour, + (pAlarmData->setDateTime.tm_min == -1) ? 0 : pAlarmData->setDateTime.tm_min, + (pAlarmData->setDateTime.tm_sec == -1) ? 0 : pAlarmData->setDateTime.tm_sec, + pAlarmData->onDateTime.tm_year + 1900, + pAlarmData->onDateTime.tm_mon + 1, + pAlarmData->onDateTime.tm_mday, + pAlarmData->onDateTime.tm_hour, + pAlarmData->onDateTime.tm_min, + pAlarmData->onDateTime.tm_sec, + DumpTimerRepeatModeString(repMode), + pAlarmData->timerPriority, + pAlarmData->onTimestamp); + + return (pAlarmData->alarmId); +} + + diff --git a/app/libuvdbus/src/Framework/WireshartScript/log_pv1.lua b/app/libuvdbus/src/Framework/WireshartScript/log_pv1.lua new file mode 100644 index 0000000..c5edfdd --- /dev/null +++ b/app/libuvdbus/src/Framework/WireshartScript/log_pv1.lua @@ -0,0 +1,93 @@ +pv1_log_proto = Proto("PV1_Log", "PV1 ES2 Log Protocol") + +log_level_str = +{ + [ 1 ] = "[F]", + [ 2 ] = "[E]", + [ 4 ] = "[W]", + [ 8 ] = "[D]", + [ 16 ] = "[I]", + [ 32 ] = "[T]", + [ 64 ] = "[I]", + [ 128 ] = "[V]", + [ 256 ] = "[S]", + [ 512 ] = "[U]", + [ 0xFFFFFFFF ] = "[A]", +} + +local log_content = ProtoField.string("logContent", "Message:\t") +local log_Seq = ProtoField.uint16("logSeq", "Sequence: \t", base.DEC) +local log_pid = ProtoField.uint32("logPid", "PID: \t\t", base.DEC) +local log_datetime = ProtoField.string("logDateTime", "DateTime:\t\t") +local log_time = ProtoField.string("logTime", "Date:\t\t") +local log_level = ProtoField.uint32("logLevel", "Level: \t\t", base.DEC, log_level_str) + +pv1_log_proto.fields = { +log_Seq, log_content, log_pid, log_datetime, log_level +} + +function pv1_log_proto.dissector(buffer, pinfo, tree) + pinfo.cols.protocol:set("LOG") + local offset = 0 + local buf_len = buffer:len() + local logInfoTree = tree:add(pv1_log_proto, buffer(0, 18), "Log Message Information") + + logInfoTree:add(log_Seq, buffer(offset, 2)) + offset = offset + 2 + + local l_pid = buffer(offset, 4):uint() + logInfoTree:add(log_pid, buffer(offset, 4)) + offset = offset + 4 + + local l_second = buffer(offset, 4):uint() + offset = offset + 4 + + local l_nsecond = buffer(offset, 4):uint() + offset = offset + 4 + + logInfoTree:add(log_datetime, "[" .. os.date("%c", l_second) .. "." .. string.format("%03d", l_nsecond / 1000) .. "]") + + local l_level = buffer(offset, 4):uint() + local l_lvStr + + if l_level == 1 then + l_lvStr = "F" + elseif l_level == 2 then + l_lvStr = "E" + elseif l_level == 4 then + l_lvStr = "W" + elseif l_level == 8 then + l_lvStr = "D" + elseif l_level == 16 then + l_lvStr = "I" + elseif l_level == 32 then + l_lvStr = "T" + elseif l_level == 64 then + l_lvStr = "C" + elseif l_level == 128 then + l_lvStr = "V" + elseif l_level == 256 then + l_lvStr = "S" + elseif l_level == 0xFFFFFFFF then + l_lvStr = "A" + else + l_lvStr = "U" + end + + logInfoTree:add(log_level, buffer(offset, 4)) + offset = offset + 4 + + local logInfo = buffer(offset, buf_len - 19):string() + local logMsgTree = tree:add(pv1_log_proto, buffer(18, buf_len - 18), "Log Message Content") + logMsgTree:add(log_content, logInfo) + + if buffer(buf_len - 1, 1):string() == '\n' then + pinfo.cols.info:set("{" .. tostring(l_pid) .. "} [" .. os.date("%X", l_second) .. "." .. string.format("%03d", l_nsecond / 1000) .. "] [" .. tostring(l_lvStr) .. "] " .. buffer(18, buf_len - 19):string()) + else + pinfo.cols.info:set("{" .. tostring(l_pid) .. "} [" .. os.date("%X", l_second) .. "." .. string.format("%03d", l_nsecond / 1000) .. "] [" .. tostring(l_lvStr) .. "] " .. buffer(18, buf_len - 18):string()) + end +end + +local pv1_log_udp_port_table = DissectorTable.get("udp.port") +--local pv1_log_port = 10000 +pv1_log_udp_port_table:add("10000-10020", pv1_log_proto) diff --git a/app/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c b/app/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c new file mode 100644 index 0000000..e73264b --- /dev/null +++ b/app/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c @@ -0,0 +1,2405 @@ +#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); +} + +int GetShellExecResult(const char *pCmd, char **pResult) +{ + FILE *pFile = NULL; + unsigned int uRdSize = 0; + char *pCmdOut; + + *pResult = NULL; + + if(pCmd == NULL || strlen(pCmd) == 0) + { + return (-ERR_INPUT_PARAMS); + } + + pFile = popen(pCmd, "r"); + + if(pFile == NULL) + { + return (-ERR_OPEN_FILE); + } + + *pResult = (char *)malloc(4096); + pCmdOut = *pResult; + + uRdSize = fread(pCmdOut, sizeof(char), 4096, pFile); + + pCmdOut[uRdSize] = 0; + + if(pCmdOut[strlen(pCmdOut) - 1] == '\n') + { + pCmdOut[strlen(pCmdOut) - 1] = 0; + } + + pclose(pFile); + //fprintf(stdout, "%s --> [%s](%u)\n", pCmd, pCmdOut, uRdSize); + return (0); +} + +void SystemSafeReboot(void) +{ + int ret, reTry = 0; +#if 0 + ret = system("sync"); + + ret = system("ubus call system watchdog \'{\"stop\" : true}\'"); + + reTry = 3; + do + { + sleep(1); + } while(reTry--); + + reTry = 0; + + LOG_EX(LOG_Debug, "Reboot System By Power Control Chips\n"); + sleep(1); + + ret = system("echo 3140 > /sys/bus/platform/devices/axp22_board/axp22_reg"); + + sleep(10); +#endif + while(TRUE) + { + LOG_EX(LOG_Debug, "Reboot System: %d times\n", reTry++); + sleep(1); + ret = system("reboot -f"); + sleep(3); + } +} + +char* GetCpuChipId(void) +{ + char* pRet = NULL; +#ifdef PLATFORM_R16 + char* pChipId = NULL; + + GetShellExecResult("cat /proc/cpuinfo | grep Chipid | awk '{print $3}'", &pChipId); + + if(pChipId == NULL) + { + return strdup(""); + } + + pRet = strdup(pChipId); + free(pChipId); + return pRet; +#else + return strdup("Unknown CPU Chip ID"); +#endif +} + +char* GetCpuSerial(void) +{ + char* pRet = NULL; +#ifdef PLATFORM_R16 + char* pSerial = NULL; + + GetShellExecResult("cat /proc/cpuinfo | grep Serial | awk '{print $3}'", &pSerial); + + if(pSerial == NULL) + { + return strdup(""); + } + + pRet = strdup(pSerial); + free(pSerial); + return pRet; +#else + return strdup("Unknown CPU Serial"); +#endif +} + +int CopyFile(const char *pSrc, const char *pDest) +{ + int fdSrc, fdDest; + struct stat st; + ssize_t sz; + + if(stat(pSrc, &st) != 0) + { + LOG_EX(LOG_Error, "Get File %s Size Error\n", pSrc); + return (-ERR_GET_FILE_SIZE); + } + + fdSrc = open(pSrc, O_RDONLY); + + if(fdSrc < 0) + { + LOG_EX(LOG_Error, "Open File %s Error\n", pSrc); + return (-ERR_OPEN_FILE); + } + + fdDest = open(pDest, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); + + if(fdDest < 0) + { + close(fdSrc); + LOG_EX(LOG_Error, "Open File %s Error\n", pDest); + return (-ERR_OPEN_FILE); + } + + sz = sendfile(fdDest, fdSrc, NULL, st.st_size); + + if(sz != st.st_size) + { + LOG_EX(LOG_Error, "Copy File Size Error: %d, %d\n", sz, st.st_size); + close(fdSrc); + close(fdDest); + return (-ERR_COPY_FILE); + } + + fsync(fdDest); + + close(fdSrc); + close(fdDest); + + return (0); +} + +int CopyFileWithSize(const char *pSrc, const char *pDest, int iSize) +{ + int fdSrc, fdDest; + struct stat st; + ssize_t sz; + size_t cpSize = iSize; + + if(iSize <= 0) + { + if(stat(pSrc, &st) != 0) + { + LOG_EX(LOG_Error, "Get File %s Size Error\n", pSrc); + return (-ERR_GET_FILE_SIZE); + } + + cpSize = st.st_size; + } + + fdSrc = open(pSrc, O_RDONLY); + + if(fdSrc < 0) + { + LOG_EX(LOG_Error, "Open File %s Error\n", pSrc); + return (-ERR_OPEN_FILE); + } + + fdDest = open(pDest, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH |S_IWOTH); + + if(fdDest < 0) + { + close(fdSrc); + LOG_EX(LOG_Error, "Open File %s Error\n", pDest); + return (-ERR_OPEN_FILE); + } + + sz = sendfile(fdDest, fdSrc, NULL, cpSize); + + if(sz != cpSize) + { + LOG_EX(LOG_Error, "Copy File Size Error: %d, %d\n", sz, cpSize); + close(fdSrc); + close(fdDest); + return (-ERR_COPY_FILE); + } + + close(fdSrc); + close(fdDest); + + return (0); +} + +int ReadFileToBuf(const char *pSrc, unsigned char *pBuf, int iSize) +{ + int fdSrc; + struct stat st; + ssize_t sz; + size_t cpSize = iSize; + + if(iSize < 0) + { + if(stat(pSrc, &st) != 0) + { + LOG_EX(LOG_Error, "Get File %s Size Error\n", pSrc); + return (-ERR_GET_FILE_SIZE); + } + + cpSize = st.st_size; + } + + fdSrc = open(pSrc, O_RDONLY); + + if(fdSrc < 0) + { + LOG_EX(LOG_Error, "Open File %s Error\n", pSrc); + return (-ERR_OPEN_FILE); + } + + sz = read(fdSrc, pBuf, cpSize); + + if(sz != cpSize) + { + LOG_EX(LOG_Error, "Copy File Size Error: %d, %d\n", sz, cpSize); + close(fdSrc); + return (-ERR_COPY_FILE); + } + + close(fdSrc); + + return (sz); +} + +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); +} + +unsigned long long GetPartitionFreeSize(const char *pPartPath) +{ + struct statfs myStatfs; + unsigned long long freeSize; + + if(statfs(pPartPath, &myStatfs) == -1) + { + return 0; + } + + freeSize = myStatfs.f_bsize * myStatfs.f_bfree; + + //fprintf(stdout, "%s free = %llu bytes\n", pPartPath, freeSize); + + return freeSize; +} + +#ifdef CURRENT_VERSION +char* GetCurrentVersion(void) +{ + return CURRENT_VERSION; +} +#else +char* GetCurrentVersion(void) +{ + return "0.0.1"; +} +#endif + +WIFI_STATUS GetCurrWIFIConnStatus(void) +{ + return g_WifiConnStatus; +} + +const char* ErrcodeToString(int errCode) +{ + switch(errCode) + { + case ERR_INPUT_PARAMS: return "ERR_INPUT_PARAMS"; + case ERR_NO_ITEMS: return "ERR_NO_ITEMS"; + case ERR_GET_BUS: return "ERR_GET_BUS"; + case ERR_DBUS_CONNECTION: return "ERR_DBUS_CONNECTION"; + case ERR_REQUEST_BUS_NAME: return "ERR_REQUEST_BUS_NAME"; + case ERR_SET_WATCH_FUNCTION: return "ERR_SET_WATCH_FUNCTION"; + case ERR_SET_TIMEOUT_FUNCTION: return "ERR_SET_TIMEOUT_FUNCTION"; + case ERR_BUS_MATCH: return "ERR_BUS_MATCH"; + case ERR_BUS_SET_MSG_CB: return "ERR_BUS_SET_MSG_CB"; + case ERR_DBUS_CREATE_MSG: return "ERR_DBUS_CREATE_MSG"; + case ERR_BUS_SEND_MSG: return "ERR_BUS_SEND_MSG"; + case ERR_DBUS_MSG_TO_LARGE: return "ERR_DBUS_MSG_TO_LARGE"; + case ERR_BUS_RCV_MSG: return "ERR_BUS_RCV_MSG"; + case ERR_ADD_TASK: return "ERR_ADD_TASK"; + case ERR_UNSUP_EVP_TYPE: return "ERR_UNSUP_EVP_TYPE"; + case ERR_CREATE_MQ: return "ERR_CREATE_MQ"; + case ERR_MQ_SENDMSG: return "ERR_MQ_SENDMSG"; + case ERR_CREATE_SHM: return "ERR_CREATE_SHM"; + case ERR_MAP_SHM: return "ERR_MAP_SHM"; + case ERR_MALLOC_MEMORY: return "ERR_MALLOC_MEMORY"; + case ERR_EVP_INIT_KEY: return "ERR_EVP_INIT_KEY"; + case ERR_EVP_UPDATE: return "ERR_EVP_UPDATE"; + case ERR_EVP_FINALE: return "ERR_EVP_FINALE"; + case ERR_EVP_KEY_SIZE: return "ERR_EVP_KEY_SIZE"; + case ERR_OPEN_FILE: return "ERR_OPEN_FILE"; + case ERR_READ_FILE: return "ERR_READ_FILE"; + case ERR_WRITE_FILE: return "ERR_WRITE_FILE"; + case ERR_COPY_FILE: return "ERR_COPY_FILE"; + case ERR_FILE_NOT_EXISTS: return "ERR_FILE_NOT_EXISTS"; + case ERR_GET_FILE_SIZE: return "ERR_GET_FILE_SIZE"; + case ERR_UNINIT_ITEM: return "ERR_UNINIT_ITEM"; + case ERR_FILE_EMPTY: return "ERR_FILE_EMPTY"; + case ERR_SEND_MAIL: return "ERR_SEND_MAIL"; + case ERR_NETWORK_SEND: return "ERR_NETWORK_SEND"; + case ERR_NETWORK_NOT_CONNECTED: return "ERR_NETWORK_NOT_CONNECTED"; + case ERR_UNSUPPORT: return "ERR_UNSUPPORT"; + case ERR_NO_INIT_IPL3: return "ERR_NO_INIT_IPL3"; + case ERR_BAD_IPL3: return "ERR_BAD_IPL3"; + case ERR_BAD_FILE_SIZE: return "ERR_BAD_FILE_SIZE"; + case ERR_MD5_FILE: return "ERR_MD5_FILE"; + case ERR_MD5_CHECK_SUM: return "ERR_MD5_CHECK_SUM"; + case ERR_OTA_WRITE_BOOT: return "ERR_OTA_WRITE_BOOT"; + case ERR_OTA_WRITE_ROOTFS: return "ERR_OTA_WRITE_ROOTFS"; + case ERR_OTA_WRITE_IPL3: return "ERR_OTA_WRITE_IPL3"; + case ERR_OTA_WRITE_PARAMS: return "ERR_OTA_WRITE_PARAMS"; + case ERR_OTA_DOWNLOAD_FILE: return "ERR_OTA_DOWNLOAD_FILE"; + case ERR_VERIFY_PARTITION_MD5: return "ERR_VERIFY_PARTITION_MD5"; + case ERR_OTA_PRE_STATR: return "ERR_OTA_PRE_STATR"; + case ERR_OTA_YET_CUR_VER: return "ERR_OTA_YET_CUR_VER"; + case ERR_OTA_NOT_READY: return "ERR_OTA_NOT_READY"; + case ERR_CREATE_CFG_FILE: return "ERR_CREATE_CFG_FILE"; + case ERR_CREATE_SQLITE3_DB: return "ERR_CREATE_SQLITE3_DB"; + case ERR_OPEN_SQLITE3_DB: return "ERR_OPEN_SQLITE3_DB"; + case ERR_SQLITE3_CREATE_TABLE: return "ERR_SQLITE3_CREATE_TABLE"; + case ERR_SYNC_DATABASE: return "ERR_SYNC_DATABASE"; + case ERR_SQL_QUERY: return "ERR_SQL_QUERY"; + case ERR_SQL_DELETE: return "ERR_SQL_DELETE"; + case ERR_UNKNOWN_TYPE: return "ERR_UNKNOWN_TYPE"; + case ERR_PERMISSION_DENIED: return "ERR_PERMISSION_DENIED"; + case ERR_CFG_NOITEM: return "ERR_CFG_NOITEM"; + case ERR_CFG_ITEM_EXIST: return "ERR_CFG_ITEM_EXIST"; + case ERR_CFG_WAIT_RSP: return "ERR_CFG_WAIT_RSP"; + case ERR_CFG_BUSY: return "ERR_CFG_BUSY"; + case ERR_STR_CONVERT: return "ERR_STR_CONVERT"; + case ERR_SQL_REG_MODULE: return "ERR_SQL_REG_MODULE"; + default: return "Unknown Error"; + } +} + +const char* DBusCmdToString(DBUS_CMD cmd) +{ + switch(cmd) + { + case CMD_MISC_PING: return "CMD_MISC_PING"; + case CMD_MISC_OTA: return "CMD_MISC_OTA"; + case CMD_MISC_WEATHER: return "CMD_MISC_WEATHER"; + case CMD_MISC_NOWTIME: return "CMD_MISC_NOWTIME"; + case CMD_MISC_UPGRADE: return "CMD_MISC_UPGRADE"; + case CMD_SYSTEM_STANDBY: return "CMD_SYSTEM_STANDBY"; + case CMD_MISC_QUERY_OTA_STATUS: return "CMD_MISC_QUERY_OTA_STATUS"; + case CMD_MISC_QUERY_DL_STATUS: return "CMD_MISC_QUERY_DL_STATUS"; + case CMD_CALL_DIAL: return "CMD_CALL_DIAL"; + case CMD_CALL_ACCEPI: return "CMD_CALL_ACCEPI"; + case CMD_CALL_HANGUP: return "CMD_CALL_HANGUP"; + case CMD_CALL_MESSAGE: return "CMD_CALL_MESSAGE"; + case CMD_PLAY_MODECHANGE: return "CMD_PLAY_MODECHANGE"; + case CMD_PLAY_PLAY: return "CMD_PLAY_PLAY"; + case CMD_PLAY_PAUSE: return "CMD_PLAY_PAUSE"; + case CMD_PLAY_STOP: return "CMD_PLAY_STOP"; + case CMD_PLAY_SEEKTO: return "CMD_PLAY_SEEKTO"; + case CMD_PLAY_SHOWMODE: return "CMD_PLAY_SHOWMODE"; + case CMD_PLAY_NEXT: return "CMD_PLAY_NEXT"; + case CMD_PLAY_PRE: return "CMD_PLAY_PRE"; + case CMD_PLAY_SHOWLIST: return "CMD_PLAY_SHOWLIST"; + case CMD_PLAY_UPDATELIST: return "CMD_PLAY_UPDATELIST"; + case CMD_PLAY_PREPARE_NEXT: return "CMD_PLAY_PREPARE_NEXT"; + case CMD_PLAY_ADDTOLIST: return "CMD_PLAY_ADDTOLIST"; + case CMD_PLAY_DELETEFROMLIST: return "CMD_PLAY_DELETEFROMLIST"; + case CMD_PLAY_RESETLIST: return "CMD_PLAY_RESETLIST"; + case CMD_PLAY_AUDIO_STOP: return "CMD_PLAY_AUDIO_STOP"; + case CMD_PLAY_AUDIO_PLAY: return "CMD_PLAY_AUDIO_PLAY"; + case CMD_SE_PLAY: return "CMD_SE_PLAY"; + case CMD_PLAY_RET_STATUS: return "CMD_PLAY_RET_STATUS"; + case CMD_CFG_ADD_REQ: return "CMD_CFG_ADD_REQ"; + case CMD_CFG_ADD_RSP: return "CMD_CFG_ADD_RSP"; + case CMD_CFG_CHANGE_REQ: return "CMD_CFG_CHANGE_REQ"; + case CMD_CFG_CHANGE_RSP: return "CMD_CFG_CHANGE_RSP"; + case CMD_CFG_GET_REQ: return "CMD_CFG_GET_REQ"; + case CMD_CFG_GET_RSP: return "CMD_CFG_GET_RSP"; + case CMD_CFG_UPG_NOTIFY: return "CMD_CFG_UPG_NOTIFY"; + case CMD_MSC_MSG_CONTROLLER_RECOG_SUCCESS: return "CMD_MSC_MSG_CONTROLLER_RECOG_SUCCESS"; + case CMD_MSC_MSG_CONTROLLER_RECOG_ERROR: return "CMD_MSC_MSG_CONTROLLER_RECOG_ERROR"; + case CMD_MSC_MSG_CONTROLLER_WAKEUP: return "CMD_MSC_MSG_CONTROLLER_WAKEUP"; + case CMD_MSC_MSG_CONTROLLER_RECOGING: return "CMD_MSC_MSG_CONTROLLER_RECOGING"; + case CMD_CONTROLLER_REQMSG_INITARGS: return "CMD_CONTROLLER_REQMSG_INITARGS"; + case CMD_CONTROLLER_RSPMSG_INITARGS: return "CMD_CONTROLLER_RSPMSG_INITARGS"; + case CMD_CONTROLLER_REQMSG_PLAYERSTATUS: return "CMD_CONTROLLER_REQMSG_PLAYERSTATUS"; + case CMD_CONTROLLER_RSPMSG_PLAYERSTATUS: return "CMD_CONTROLLER_RSPMSG_PLAYERSTATUS"; + case CMD_MSC_REQMSG_MIC_CONTROL: return "CMD_MSC_REQMSG_MIC_CONTROL"; + case CMD_MSC_RSPMSG_MIC_CONTROL: return "CMD_MSC_RSPMSG_MIC_CONTROL"; + case CMD_YUNXIN_RECVMSG: return "CMD_YUNXIN_RECVMSG"; + case CMD_YUNXIN_SENDMSG: return "CMD_YUNXIN_SENDMSG"; + case CMD_YUNXIN_SENDMSG_BYPASS: return "CMD_YUNXIN_SENDMSG_BYPASS"; + case CMD_YUNXIN_SENDMSGCB: return "CMD_YUNXIN_SENDMSGCB"; + case CMD_CONTROLLER_MSG_YUNXIN: return "CMD_CONTROLLER_MSG_YUNXIN"; + case CMD_YUNXIN_STATUS: return "CMD_YUNXIN_STATUS"; + case CMD_YUNXIN_SYSMSG: return "CMD_YUNXIN_SYSMSG"; + case CMD_WIFI_CONF: return "CMD_WIFI_CONF"; + case CMD_WIFI_CONF_RESP: return "CMD_WIFI_CONF_RESP"; + case CMD_WIFI_AUTO_CONN: return "CMD_WIFI_AUTO_CONN"; + case CMD_WIFI_AUTO_CONN_RESP: return "CMD_WIFI_AUTO_CONN_RESP"; + case CMD_WIFI_STATE_REQ: return "CMD_WIFI_STATE_REQ"; + case CMD_WIFI_STATE_RESP: return "CMD_WIFI_STATE_RESP"; + case CMD_WIFI_STATE_NTF: return "CMD_WIFI_STATE_NTF"; + case CMD_BT_NAME_GET_REQ: return "CMD_BT_NAME_GET_REQ"; + case CMD_BT_NAME_GET_RESP: return "CMD_BT_NAME_GET_RESP"; + case CMD_BT_EVT_NTF: return "CMD_BT_EVT_NTF"; + case CMD_KPLAYER_START: return "CMD_KPLAYER_START"; + case CMD_KPLAYER_STOP: return "CMD_KPLAYER_STOP"; + case CMD_KPLAYER_NOTIF_DUR: return "CMD_KPLAYER_NOTIF_DUR"; + case CMD_KPLAYER_HOST_ACTION: return "CMD_KPLAYER_HOST_ACTION"; + case CMD_KPLAYER_CTR_NTF_BASE: return "CMD_KPLAYER_CTR_NTF_BASE"; + case CMD_KPLAYER_CTR_CREATED: return "CMD_KPLAYER_CTR_CREATED"; + case CMD_KPLAYER_CTR_DELED: return "CMD_KPLAYER_CTR_DELED"; + case CMD_KPLAYER_CTR_PLAY: return "CMD_KPLAYER_CTR_PLAY"; + case CMD_KPLAYER_CTR_STOP: return "CMD_KPLAYER_CTR_STOP"; + case CMD_KPLAYER_CTR_PAUSE: return "CMD_KPLAYER_CTR_PAUSE"; + case CMD_KPLAYER_CTR_SEEK: return "CMD_KPLAYER_CTR_SEEK"; + case CMD_KPLAYER_CTR_SET_URL: return "CMD_KPLAYER_CTR_SET_URL"; + case CMD_KPLAYER_CTR_SET_VOLUME: return "CMD_KPLAYER_CTR_SET_VOLUME"; + case CMD_KPLAYER_CTR_SET_MUTE: return "CMD_KPLAYER_CTR_SET_MUTE"; + case CMD_KPLAYER_CTR_SET_NXT_URL: return "CMD_KPLAYER_CTR_SET_NXT_URL"; + case CMD_KPLAYER_CTR_SET_NEXT: return "CMD_KPLAYER_CTR_SET_NEXT"; + case CMD_KPLAYER_CTR_SET_PREV: return "CMD_KPLAYER_CTR_SET_PREV"; + case CMD_ALARM_SYNC_REQ: return "CMD_ALARM_SYNC_REQ"; + case CMD_ALARM_SYNC_RSP: return "CMD_ALARM_SYNC_RSP"; + case CMD_ALARM_ADD: return "CMD_ALARM_ADD"; + case CMD_ALARM_REMOVE: return "CMD_ALARM_REMOVE"; + case CMD_ALARM_REMOVEALL: return "CMD_ALARM_REMOVEALL"; + case CMD_REMAIND_SYNC_REQ: return "CMD_REMAIND_SYNC_REQ"; + case CMD_REMAIND_SYNC_RSP: return "CMD_REMAIND_SYNC_RSP"; + case CMD_REMAIND_ADD: return "CMD_REMAIND_ADD"; + case CMD_REMAIND_REMOVE: return "CMD_REMAIND_REMOVE"; + case CMD_REMAIND_REMOVEALL: return "CMD_REMAIND_REMOVEALL"; + case CMD_ASSISTANT_STATUS: return "CMD_ASSISTANT_STATUS"; + case CMD_ASSISTANT_RUNNING: return "CMD_ASSISTANT_RUNNING"; + case CMD_ASSISTANT_NOTIFY: return "CMD_ASSISTANT_NOTIFY"; + case CMD_SESSION_ALARM_SYNC: return "CMD_SESSION_ALARM_SYNC"; + case CMD_WORKDAY_DB_REQ: return "CMD_WORKDAY_DB_REQ"; + case CMD_WORKDAY_DB_RSP: return "CMD_WORKDAY_DB_RSP"; + case CMD_OTA_NOTIFY: return "CMD_OTA_NOTIFY"; + case CMD_OTA_STATUS: return "CMD_OTA_STATUS"; + case CMD_OTA_RUNNOW: return "CMD_OTA_RUNNOW"; + case CMD_LOG_CONFIG: return "CMD_LOG_CONFIG"; + default: return "Unknown CMD"; + } +} + +const char* ModuleNameToString(MODULE_NAME modName) +{ + switch(modName) + { + case MODULE_CONTROLLER: return "MODULE_CONTROLLER"; + case MODULE_ALARM: return "MODULE_ALARM"; + case MODULE_CALL: return "MODULE_CALL"; + case MODULE_VOICEENGINE: return "MODULE_VOICEENGINE"; + case MODULE_PLAYER: return "MODULE_PLAYER"; + case MODULE_CONFIGURE: return "MODULE_CONFIGURE"; + case MODULE_OTA: return "MODULE_OTA"; + case MODULE_WIFI: return "MODULE_WIFI"; + case MODULE_BT: return "MODULE_BT"; + case MODULE_KPLAYER: return "MODULE_KPLAYER"; + case MODULE_KPLAYER_TEST: return "MODULE_KPLAYER_TEST"; + case MODULE_SPLAYER: return "MODULE_SPLAYER"; + case MODULE_SPLAYER_TEST: return "MODULE_SPLAYER_TEST"; + case MODULE_LIGHT_MCU: return "MODULE_LIGHT_MCU"; + case MODULE_BLUEKC: return "MODULE_BLUEKC"; + case MODULE_BLUEKC_TEST: return "MODULE_BLUEKC_TEST"; + case MODULE_MANUFACTURE: return "MODULE_MANUFACTURE"; + case MODULE_BT_DEMO: return "MODULE_BT_DEMO"; + case MODULE_LOG_CTRL: return "MODULE_LOG_CTRL"; + } + + return "Unknown Module Name"; +} diff --git a/app/libuvdbus/src/Makefile b/app/libuvdbus/src/Makefile new file mode 100644 index 0000000..138edf1 --- /dev/null +++ b/app/libuvdbus/src/Makefile @@ -0,0 +1,50 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common + +GIT_TAG:=$(shell git describe --tags --always --dirty="-dev") +TARGET := libuvdbus.so + +commonSources := \ + log/hexdump.c \ + log/log.c \ + Framework/IoT/Boardlink/boardlink_iot.c \ + Framework/HeartDaemon/heart_daemon.c \ + Framework/Configure/config_engine.c \ + Framework/Configure/ini_prase.c \ + Framework/Crypto/md5.c \ + Framework/Crypto/base64.c \ + Framework/Crypto/crypto.c \ + Framework/Crypto/aes.c \ + Framework/libuvEngine/libuv_dbus.c \ + Framework/JsonUtils/json_struct.c \ + Framework/Network/inet_api.c \ + Framework/Skins/skins.c \ + Framework/Skins/skin_res_vtbl.c \ + Framework/Timer/timer.c \ + Framework/Fifo/fifo.c \ + Framework/Monitor/monitor.c \ + Framework/SvrManager/svr_manager.c \ + Framework/Compress/zlib.c + +local_CFLAGS := -I./include -DPLATFORM_R311 -DCURRENT_VERSION=\"$(GIT_TAG)\" +#local_CFLAGS += -DENABLE_COUNT_DEBUG + +local_LDFLAGS := $(LIB_BUILD_COMMON_LIB) + +OBJS = $(patsubst %.c, %.c.o, $(commonSources)) + +$(TARGET):$(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(local_CFLAGS) -o $@ $^ -fPIC -shared + +$(OBJS):%.c.o:%.c + $(CC) $(CFLAGS) $(LDFLAGS) $(local_CFLAGS) -c $^ -o $@ -fPIC -shared + +all: $(TARGET) install + +clean: + -rm $(OBJS) $(TARGET) +install: + mkdir -p $(INSTALL_PREFIX)/usr/lib + cp $(TARGET) $(INSTALL_PREFIX)/usr/lib + + mkdir -p $(INSTALL_PREFIX)/usr/include + cp -r include/* $(INSTALL_PREFIX)/usr/include diff --git a/app/libuvdbus/src/include/assistant.h b/app/libuvdbus/src/include/assistant.h new file mode 100644 index 0000000..56b28f7 --- /dev/null +++ b/app/libuvdbus/src/include/assistant.h @@ -0,0 +1,168 @@ +#ifndef ASSISTANT_H +#define ASSISTANT_H +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_TIP_LEN (60 * 4 + 1) +#define MAX_ALARM_ITEMS (1024) + +typedef enum +{ + ASSISTANT_TYPE_CLOCK = 0, + ASSISTANT_TYPE_REMAIND, + ASSISTANT_TYPE_SESSION, +} ASSISTANT_TYPE; + +typedef enum +{ + STATUS_IDLE = 0, + STATUS_PREPARE_STANDBY, + STATUS_RUNNING, + STATUS_NOT_IN_USE, + STATUS_REMOVE_ITEM, + STATUS_ADD_ITEM, +} ASSISTANT_STATUS; + +typedef struct +{ + unsigned long long itemId; ///< 提醒、闹钟ID + ASSISTANT_TYPE itemType; ///< 类型: 0 闹钟, 1 提醒 + int priority; ///< 优先级: 暂未使用 + REPEAT_MODE repeatMode; ///< 重复模式 + + int year; ///< 年 + int month; ///< 月 + int day; ///< 日 + int hour; ///< 小时 + int minute; ///< 分钟 + int second; ///< 秒钟 + int weekDay; ///< 星期 + + unsigned int timerId; ///< 关联的定时器ID + unsigned long long voiceId; ///< 闹钟资源ID + char strTips[MAX_TIP_LEN]; ///< 提醒 TTS 文本 + char resUrl[2048]; ///< 资源URL + char voiceRes[32]; ///< 资源声音文件ID + char voiceResType[64]; ///< 资源类型 +} ASSISTANT_ITEM_INFO, *PASSISTANT_ITEM_INFO; + +typedef struct +{ + int nItems; ///< 协议包含的数据个数 + PASSISTANT_ITEM_INFO pAlarmInfo; ///< 提醒、闹钟数据详细信息 +} ASSISTANT_SYNC_INFO, *PASSISTANT_SYNC_INFO; + +typedef struct ASSISTANT_ARRAY_INFO +{ + ASSISTANT_ITEM_INFO alarmItem; + struct ASSISTANT_ARRAY_INFO *next, *prev; +} *PASSISTANT_ARRAY_INFO; + +typedef struct +{ + int cmd; + int nItems; + ASSISTANT_TYPE type; + unsigned long long ids[MAX_ALARM_ITEMS]; +} ASSISTANT_NOTIFY_INFO, *PASSISTANT_NOTIFY_INFO; + +typedef struct +{ + int cmd; + int val; +} ASSISTANT_RSP_STATUS, *PASSISTANT_RSP_STATUS; + +typedef struct +{ + int cmd; + int val; + int errCode; +} ASSISTANT_NOFIFY_EVENT, *PASSISTANT_NOFIFY_EVENT; + +static void __printAssistantNofifyInfo(const char *pTags, PASSISTANT_NOTIFY_INFO pInfo) +{ + int i; + if(pTags && strlen(pTags) > 0) + { + LOG_EX2(LOG_Debug, "%s:\n", pTags); + LOG_EX2(LOG_Debug, "**************************************************************\n"); + } + + LOG_EX2(LOG_Debug, "Sync Items : %d\n", pInfo->nItems); + LOG_EX2(LOG_Debug, "-------------------------\n"); + LOG_EX2(LOG_Debug, "| Alarm Id | Type |\n"); + LOG_EX2(LOG_Debug, "-------------------------\n"); + + for(i = 0; i < pInfo->nItems; i++) + { + LOG_EX2(LOG_Debug, "| %8llu | %11s |\n", + pInfo->ids[i], + (pInfo->type == ASSISTANT_TYPE_REMAIND) ? "Remaind" : "Alarm Clock"); + } + + LOG_EX2(LOG_Debug, "-------------------------\n"); +} + +static void __printAssistantSyncInfo(const char* pTags, PASSISTANT_SYNC_INFO pInfo) +{ + int i; + char buf[MAX_PATH]; + struct tm localTime; + time_t tmStamp; + + if(pTags && strlen(pTags) > 0) + { + LOG_EX2(LOG_Debug, "%s:\n", pTags); + LOG_EX2(LOG_Debug, "**************************************************************\n"); + } + + //fprintf(stdout, "Command : %d(%08X)\n", pInfo->cmd, pInfo->cmd); + LOG_EX2(LOG_Debug, "Sync Items : %d\n", pInfo->nItems); + + LOG_EX2(LOG_Debug, "---------------------------------------------------------------------" + "-----------------------------------------------------------\n"); + + LOG_EX2(LOG_Debug, "| Alarm Id | Type | Priority | Repeat Mode | Week Day |" + " DateTime | Tips | Resource |\n"); + + LOG_EX2(LOG_Debug, "---------------------------------------------------------------------" + "-----------------------------------------------------------\n"); + + for(i = 0; i < pInfo->nItems; i++) + { + memset(buf, 0, MAX_PATH); + + sprintf(buf, "%04u-%02u-%02u %02u:%02u:%02u", + (pInfo->pAlarmInfo[i].year == -1) ? 1900 : pInfo->pAlarmInfo[i].year + 1900, + (pInfo->pAlarmInfo[i].month == -1) ? 0 : pInfo->pAlarmInfo[i].month + 1, + (pInfo->pAlarmInfo[i].day == -1) ? 0 : pInfo->pAlarmInfo[i].day, + (pInfo->pAlarmInfo[i].hour == -1) ? 0 : pInfo->pAlarmInfo[i].hour, + (pInfo->pAlarmInfo[i].minute == -1) ? 0 : pInfo->pAlarmInfo[i].minute, + (pInfo->pAlarmInfo[i].second == -1) ? 0 : pInfo->pAlarmInfo[i].second); + + LOG_EX2(LOG_Debug, "| %8llu | %11s | %8d | %15s | %d%d%d%d %d%d%d%d | %20s | %20s | %8llu |\n", + pInfo->pAlarmInfo[i].itemId, + (pInfo->pAlarmInfo[i].itemType == ASSISTANT_TYPE_REMAIND) ? "Remaind" : "Alarm Clock", + pInfo->pAlarmInfo[i].priority, + DumpTimerRepeatModeString(pInfo->pAlarmInfo[i].repeatMode), + (pInfo->pAlarmInfo[i].weekDay & (1 << 7))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 6))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 5))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 4))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 3))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 2))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 1))? 1 : 0, + (pInfo->pAlarmInfo[i].weekDay & (1 << 0))? 1 : 0, + buf, + pInfo->pAlarmInfo[i].strTips, + pInfo->pAlarmInfo[i].voiceId); + } + + LOG_EX2(LOG_Debug, "---------------------------------------------------------------------" + "-----------------------------------------------------------\n"); +} +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/boardlink_iot.h b/app/libuvdbus/src/include/boardlink_iot.h new file mode 100644 index 0000000..65dd47a --- /dev/null +++ b/app/libuvdbus/src/include/boardlink_iot.h @@ -0,0 +1,44 @@ +#ifndef BOARDLINK_IOT_H +#define BOARDLINK_IOT_H +#ifndef PLATFORM_CPU +#define BL_IOT_MSG_TAGS ("BLNLINK") +#define BL_MAX_MSG (1024) +#define ETH_ALEN (6) + +typedef enum +{ + MSG_IN_DISCOVERY_MODE = 0, + MSG_OUT_DISCOVERY_MODE, + MSG_GET_WLAN_INFO, + MSG_BYPASS_MODE, +} BL_IOT_MSG_TYPE; + +#pragma pack (push) +#pragma pack (1) +typedef struct +{ + unsigned char msgTags[8]; + unsigned char dstMac[ETH_ALEN]; + unsigned char msgType; + unsigned int msglen; + unsigned char msgData[BL_MAX_MSG]; +} BL_IOT_MSG, *PBL_IOT_MSG; + +typedef struct +{ + unsigned char channel; + unsigned char dev_mac[ETH_ALEN]; + unsigned char bssid[ETH_ALEN]; + unsigned char ssid[32]; +} WL_INFO, *PWL_INFO; +#pragma pack (pop) + +#define BL_IOT_MSG_LEN(len) (sizeof(BL_IOT_MSG) - BL_MAX_MSG + len) + +typedef void (*BlMsgCb)(PBL_IOT_MSG pMsg); + +int BL_Init(BlMsgCb cbOnMsg); +int BL_SendBLMsg(BL_IOT_MSG_TYPE msgType, unsigned char* pData, unsigned int len); +int BL_SendBLMsgTo(BL_IOT_MSG_TYPE msgType, unsigned char* pData, unsigned int len, unsigned char dstMac[ETH_ALEN]); +#endif +#endif diff --git a/app/libuvdbus/src/include/config_engine.h b/app/libuvdbus/src/include/config_engine.h new file mode 100644 index 0000000..80dfc49 --- /dev/null +++ b/app/libuvdbus/src/include/config_engine.h @@ -0,0 +1,58 @@ +#ifndef CONFIG_ENGINE_H +#define CONFIG_ENGINE_H +#include +#include + +#include "smart_sound.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define GLOBAL_CFG_FILE_PATH ("/mnt/UDISK/global.db") + + +typedef enum +{ + CFG_TYPE_STRING = 0, + CFG_TYPE_INT = 1, + CFG_TYPE_DOUBLE = 2, +} CFG_DATA_TYPE; + +typedef struct +{ + char* pKeyName; + int keyType; + int keyModule; + + union + { + char* pStrValue; + int intValue; + double doubleValue; + }; + + UT_hash_handle hh; ///< UT Hash handle +} CFG_ITEM, *PCFG_ITEM; + +typedef void (*OnCfgMsg)(DBUS_CMD cmd, PCFG_ITEM pMsg, int err); + +int CfgGlobalEnvInit(void); + +void CfgItemPrint(const char* pPrefix, PCFG_ITEM pCfgItem); + +int CfgGetKeyValue(const char* pKeyName, PCFG_ITEM* pItem); +int CfgChangeKeyValue(const char *pKeyName, PCFG_ITEM pItem, int saveToDB); +int CfgAddKeyValue(const char *pKeyName, PCFG_ITEM pItem, int saveToDB); + +void CfgSetIntValue(const char* pTags, int iValue); + +void OnCfgMsgProcess(MODULE_NAME dest, DBUS_CMD busCmd, const char *pJsonStr); + +int Sqlite3SyncDB(sqlite3* pSqlMemory, const char* pMemDbName, const char* pDBFilePath, const char* pFileDbName, int isSave); + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/app/libuvdbus/src/include/crypto.h b/app/libuvdbus/src/include/crypto.h new file mode 100644 index 0000000..57961f8 --- /dev/null +++ b/app/libuvdbus/src/include/crypto.h @@ -0,0 +1,81 @@ +#ifndef CRYPTO_H +#define CRYPTO_H +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +#define ALIGN_AES_BLOCK(size) (((size + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE) * AES_BLOCK_SIZE) + +#define MD5_VALUE_LEN (16) +#define MD5_STR_VALUE_LEN (MD5_VALUE_LEN * 2) + +typedef enum +{ + CRYPTO_AES_ENCRYPT = 0, + CRYPTO_AES_DECRYPT, + CRYPTO_BASE64_ENCODE, + CRYPTO_BASE64_DECODE, + CRYPTO_MD5_FILE, +} CRYPTO_TYPE; + +void EvpSystemInit(void); + +//***************************************************** +// AES +//***************************************************** +typedef void (*OnEVPCrypto)(CRYPTO_TYPE type, + const unsigned char* pData, + int iSize, + const unsigned char* pSrcData, + int iError); + + + +int EvpAESEncrypto(unsigned char* pInBuf, + int iSize, + unsigned char* pOutBuf, + int* pOutSize, + unsigned char* pKey); + +int EvpAESDecrypto(unsigned char* pInBuf, + int iSize, + unsigned char* pOutBuf, + int* pOutSize, + unsigned char* pKey); + +//***************************************************** +// BASE64 +//***************************************************** +const char* EvpBase64Encode(const char* pSrc); +const char* EvpBase64Decode(const char* pBase64); +const char* EvpBase64EncodeNoAlign(const char *pSrc); +const char* EvpBase64DecodeNoAlign(const char *pBase64); +const char* EvpBase64EncodeNoAlignV2(unsigned char *pSrc, int sLen); +unsigned char* EvpBase64DecodeNoAlignV2(const char *pBase64, int *pOutSize); +//***************************************************** +// MD5 +//***************************************************** +const char* EvpMD5HashFile(const char* pFileName); +int EvpMD5HashFileV2(const char *pFileName, unsigned char md5[16]);; +int EvpMD5HashBuf(const unsigned char *pBuf, int iBufLen, unsigned char *pOutBuf, int *pOutSize); +const char* EvpMD5HashBufV2(const unsigned char *pBuf, int iBufLen); +//***************************************************** +// Async Engine +//***************************************************** +int EvpAddCryptoTask(CRYPTO_TYPE type, + unsigned char* pInBuf, + int iSize, + unsigned char* pOutBuf, + char* pKey, + OnEVPCrypto onEvpCryptCb); + +//***************************************************** +// Compress +//***************************************************** +int GZipFileCompress(const char *pInput, const char *pOutput); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/fifo.h b/app/libuvdbus/src/include/fifo.h new file mode 100644 index 0000000..4ea395b --- /dev/null +++ b/app/libuvdbus/src/include/fifo.h @@ -0,0 +1,724 @@ +/* + * A generic kernel FIFO implementation + * + * Copyright (C) 2009/2010 Stefani Seibold + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#ifndef FIFO_H +#define FIFO_H + +#include + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(*(x))) +#define __must_check __attribute__((warn_unused_result)) +/* + * How to porting drivers to the new generic FIFO API: + * + * - Modify the declaration of the "struct kfifo *" object into a + * in-place "struct kfifo" object + * - Init the in-place object with kfifo_alloc() or kfifo_init() + * Note: The address of the in-place "struct kfifo" object must be + * passed as the first argument to this functions + * - Replace the use of __kfifo_put into kfifo_in and __kfifo_get + * into kfifo_out + * - Replace the use of kfifo_put into kfifo_in_spinlocked and kfifo_get + * into kfifo_out_spinlocked + * Note: the spinlock pointer formerly passed to kfifo_init/kfifo_alloc + * must be passed now to the kfifo_in_spinlocked and kfifo_out_spinlocked + * as the last parameter + * - The formerly __kfifo_* functions are renamed into kfifo_* + */ + +/* + * Note about locking : There is no locking required until only * one reader + * and one writer is using the fifo and no kfifo_reset() will be * called + * kfifo_reset_out() can be safely used, until it will be only called + * in the reader thread. + * For multiple writer and one reader there is only a need to lock the writer. + * And vice versa for only one writer and multiple reader there is only a need + * to lock the reader. + */ + + +struct __kfifo { + unsigned int in; + unsigned int out; + unsigned int mask; + unsigned int esize; + void *data; + uv_mutex_t lock; +}; + +#define __STRUCT_KFIFO_COMMON(datatype, recsize, ptrtype) \ + union { \ + struct __kfifo kfifo; \ + datatype *type; \ + char (*rectype)[recsize]; \ + ptrtype *ptr; \ + const ptrtype *ptr_const; \ + } + +#define __STRUCT_KFIFO(type, size, recsize, ptrtype) \ +{ \ + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[((size < 2) || (size & (size - 1))) ? -1 : size]; \ +} + +#define STRUCT_KFIFO(type, size) \ + struct __STRUCT_KFIFO(type, size, 0, type) + +#define __STRUCT_KFIFO_PTR(type, recsize, ptrtype) \ +{ \ + __STRUCT_KFIFO_COMMON(type, recsize, ptrtype); \ + type buf[0]; \ +} + +#define STRUCT_KFIFO_PTR(type) \ + struct __STRUCT_KFIFO_PTR(type, 0, type) + +/* + * define compatibility "struct kfifo" for dynamic allocated fifos + */ +struct kfifo __STRUCT_KFIFO_PTR(unsigned char, 0, void); + +#define STRUCT_KFIFO_REC_1(size) \ + struct __STRUCT_KFIFO(unsigned char, size, 1, void) + +#define STRUCT_KFIFO_REC_2(size) \ + struct __STRUCT_KFIFO(unsigned char, size, 2, void) + +/* + * define kfifo_rec types + */ +struct kfifo_rec_ptr_1 __STRUCT_KFIFO_PTR(unsigned char, 1, void); +struct kfifo_rec_ptr_2 __STRUCT_KFIFO_PTR(unsigned char, 2, void); + +/* + * helper macro to distinguish between real in place fifo where the fifo + * array is a part of the structure and the fifo type where the array is + * outside of the fifo structure. + */ +#define __is_kfifo_ptr(fifo) (sizeof(*fifo) == sizeof(struct __kfifo)) + +/** + * DECLARE_KFIFO_PTR - macro to declare a fifo pointer object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + */ +#define DECLARE_KFIFO_PTR(fifo, type) STRUCT_KFIFO_PTR(type) fifo + +/** + * DECLARE_KFIFO - macro to declare a fifo object + * @fifo: name of the declared fifo + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + */ +#define DECLARE_KFIFO(fifo, type, size) STRUCT_KFIFO(type, size) fifo + +/** + * INIT_KFIFO - Initialize a fifo declared by DECLARE_KFIFO + * @fifo: name of the declared fifo datatype + */ +#define INIT_KFIFO(fifo) \ +(void)({ \ + typeof(&(fifo)) __tmp = &(fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __kfifo->in = 0; \ + __kfifo->out = 0; \ + __kfifo->mask = __is_kfifo_ptr(__tmp) ? 0 : ARRAY_SIZE(__tmp->buf) - 1;\ + __kfifo->esize = sizeof(*__tmp->buf); \ + __kfifo->data = __is_kfifo_ptr(__tmp) ? NULL : __tmp->buf; \ +}) + +/** + * DEFINE_KFIFO - macro to define and initialize a fifo + * @fifo: name of the declared fifo datatype + * @type: type of the fifo elements + * @size: the number of elements in the fifo, this must be a power of 2 + * + * Note: the macro can be used for global and local fifo data type variables. + */ +#define DEFINE_KFIFO(fifo, type, size) \ + DECLARE_KFIFO(fifo, type, size) = \ + (typeof(fifo)) { \ + { \ + { \ + .in = 0, \ + .out = 0, \ + .mask = __is_kfifo_ptr(&(fifo)) ? \ + 0 : \ + ARRAY_SIZE((fifo).buf) - 1, \ + .esize = sizeof(*(fifo).buf), \ + .data = __is_kfifo_ptr(&(fifo)) ? \ + NULL : \ + (fifo).buf, \ + } \ + } \ + } + + +static inline unsigned int __must_check +__kfifo_uint_must_check_helper(unsigned int val) +{ + return val; +} + +static inline int __must_check +__kfifo_int_must_check_helper(int val) +{ + return val; +} + +/** + * kfifo_initialized - Check if the fifo is initialized + * @fifo: address of the fifo to check + * + * Return %true if fifo is initialized, otherwise %false. + * Assumes the fifo was 0 before. + */ +#define kfifo_initialized(fifo) ((fifo)->kfifo.mask) + +/** + * kfifo_esize - returns the size of the element managed by the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_esize(fifo) ((fifo)->kfifo.esize) + +/** + * kfifo_recsize - returns the size of the record length field + * @fifo: address of the fifo to be used + */ +#define kfifo_recsize(fifo) (sizeof(*(fifo)->rectype)) + +/** + * kfifo_size - returns the size of the fifo in elements + * @fifo: address of the fifo to be used + */ +#define kfifo_size(fifo) ((fifo)->kfifo.mask + 1) + +/** + * kfifo_reset - removes the entire fifo content + * @fifo: address of the fifo to be used + * + * Note: usage of kfifo_reset() is dangerous. It should be only called when the + * fifo is exclusived locked or when it is secured that no other thread is + * accessing the fifo. + */ +#define kfifo_reset(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + __tmp->kfifo.in = __tmp->kfifo.out = 0; \ +}) + +/** + * kfifo_reset_out - skip fifo content + * @fifo: address of the fifo to be used + * + * Note: The usage of kfifo_reset_out() is safe until it will be only called + * from the reader thread and there is only one concurrent reader. Otherwise + * it is dangerous and must be handled in the same way as kfifo_reset(). + */ +#define kfifo_reset_out(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + __tmp->kfifo.out = __tmp->kfifo.in; \ +}) + +/** + * kfifo_len - returns the number of used elements in the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_len(fifo) \ +({ \ + typeof((fifo) + 1) __tmpl = (fifo); \ + __tmpl->kfifo.in - __tmpl->kfifo.out; \ +}) + +/** + * kfifo_is_empty - returns true if the fifo is empty + * @fifo: address of the fifo to be used + */ +#define kfifo_is_empty(fifo) \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + __tmpq->kfifo.in == __tmpq->kfifo.out; \ +}) + +/** + * kfifo_is_full - returns true if the fifo is full + * @fifo: address of the fifo to be used + */ +#define kfifo_is_full(fifo) \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + kfifo_len(__tmpq) > __tmpq->kfifo.mask; \ +}) + +/** + * kfifo_avail - returns the number of unused elements in the fifo + * @fifo: address of the fifo to be used + */ +#define kfifo_avail(fifo) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmpq = (fifo); \ + const unsigned int __recsize = sizeof(*__tmpq->rectype); \ + unsigned int __avail = kfifo_size(__tmpq) - kfifo_len(__tmpq); \ + (__recsize) ? ((__avail <= __recsize) ? 0 : \ + __kfifo_max_r(__avail - __recsize, __recsize)) : \ + __avail; \ +}) \ +) + +/** + * kfifo_skip - skip output data + * @fifo: address of the fifo to be used + */ +#define kfifo_skip(fifo) \ +(void)({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__recsize) \ + __kfifo_skip_r(__kfifo, __recsize); \ + else \ + __kfifo->out++; \ +}) + +/** + * kfifo_peek_len - gets the size of the next fifo record + * @fifo: address of the fifo to be used + * + * This function returns the size of the next fifo record in number of bytes. + */ +#define kfifo_peek_len(fifo) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (!__recsize) ? kfifo_len(__tmp) * sizeof(*__tmp->type) : \ + __kfifo_len_r(__kfifo, __recsize); \ +}) \ +) + +/** + * kfifo_alloc - dynamically allocates a new fifo buffer + * @fifo: pointer to the fifo + * @size: the number of elements in the fifo, this must be a power of 2 + * @gfp_mask: get_free_pages mask, passed to kmalloc() + * + * This macro dynamically allocates a new fifo buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * The fifo will be release with kfifo_free(). + * Return 0 if no error, otherwise an error code. + */ +#define kfifo_alloc(fifo, size) \ +__kfifo_int_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __is_kfifo_ptr(__tmp) ? \ + __kfifo_alloc(__kfifo, size, sizeof(*__tmp->type)) : \ + -EINVAL; \ +}) \ +) + +/** + * kfifo_free - frees the fifo + * @fifo: the fifo to be freed + */ +#define kfifo_free(fifo) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (__is_kfifo_ptr(__tmp)) \ + __kfifo_free(__kfifo); \ +}) + +/** + * kfifo_init - initialize a fifo using a preallocated buffer + * @fifo: the fifo to assign the buffer + * @buffer: the preallocated buffer to be used + * @size: the size of the internal buffer, this have to be a power of 2 + * + * This macro initialize a fifo using a preallocated buffer. + * + * The numer of elements will be rounded-up to a power of 2. + * Return 0 if no error, otherwise an error code. + */ +#define kfifo_init(fifo, buffer, size) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + __is_kfifo_ptr(__tmp) ? \ + __kfifo_init(__kfifo, buffer, size, sizeof(*__tmp->type)) : \ + -EINVAL; \ +}) + +/** + * kfifo_put - put data into the fifo + * @fifo: address of the fifo to be used + * @val: the data to be added + * + * This macro copies the given value into the fifo. + * It returns 0 if the fifo was full. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_put(fifo, val) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof((val) + 1) __val = (val); \ + unsigned int __ret; \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ + __dummy = (typeof(__val))NULL; \ + } \ + if (__recsize) \ + __ret = __kfifo_in_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_full(__tmp); \ + if (__ret) { \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->in & __tmp->kfifo.mask] = \ + *(typeof(__tmp->type))__val; \ + __kfifo->in++; \ + } \ + } \ + __ret; \ +}) + +/** + * kfifo_get - get data from the fifo + * @fifo: address of the fifo to be used + * @val: the var where to store the data to be added + * + * This macro reads the data from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_get(fifo, val) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof((val) + 1) __val = (val); \ + unsigned int __ret; \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) \ + __val = (typeof(__tmp->ptr))0; \ + if (__recsize) \ + __ret = __kfifo_out_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->out & __tmp->kfifo.mask]; \ + __kfifo->out++; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * kfifo_peek - get data from the fifo without removing + * @fifo: address of the fifo to be used + * @val: the var where to store the data to be added + * + * This reads the data from the fifo without removing it from the fifo. + * It returns 0 if the fifo was empty. Otherwise it returns the number + * processed elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_peek(fifo, val) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof((val) + 1) __val = (val); \ + unsigned int __ret; \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) \ + __val = (typeof(__tmp->ptr))NULL; \ + if (__recsize) \ + __ret = __kfifo_out_peek_r(__kfifo, __val, sizeof(*__val), \ + __recsize); \ + else { \ + __ret = !kfifo_is_empty(__tmp); \ + if (__ret) { \ + *(typeof(__tmp->type))__val = \ + (__is_kfifo_ptr(__tmp) ? \ + ((typeof(__tmp->type))__kfifo->data) : \ + (__tmp->buf) \ + )[__kfifo->out & __tmp->kfifo.mask]; \ + } \ + } \ + __ret; \ +}) \ +) + +/** + * kfifo_in - put data into the fifo + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * + * This macro copies the given buffer into the fifo and returns the + * number of copied elements. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_in(fifo, buf, n) \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof((buf) + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr_const) __dummy __attribute__ ((unused)); \ + __dummy = (typeof(__buf))NULL; \ + } \ + (__recsize) ?\ + __kfifo_in_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_in(__kfifo, __buf, __n); \ +}) + +/** + * kfifo_in_spinlocked - put data into the fifo using a spinlock for locking + * @fifo: address of the fifo to be used + * @buf: the data to be added + * @n: number of elements to be added + * @lock: pointer to the spinlock to use for locking + * + * This macro copies the given values buffer into the fifo and returns the + * number of copied elements. + */ +#define kfifo_in_locked(fifo, buf, n) \ +({ \ + unsigned int __ret; \ + uv_mutex_t __lock = ((struct __kfifo*)fifo)->lock; \ + uv_mutex_lock(&__lock); \ + __ret = kfifo_in(fifo, buf, n); \ + uv_mutex_unlock(&__lock); \ + __ret; \ +}) + + +/** + * kfifo_out - get data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get some data from the fifo and return the numbers of elements + * copied. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_out(fifo, buf, n) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof((buf) + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr) __dummy = NULL; \ + __buf = __dummy; \ + } \ + (__recsize) ?\ + __kfifo_out_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_out(__kfifo, __buf, __n); \ +}) \ +) + +/** + * kfifo_out_spinlocked - get data from the fifo using a spinlock for locking + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * @lock: pointer to the spinlock to use for locking + * + * This macro get the data from the fifo and return the numbers of elements + * copied. + */ +#define kfifo_out_locked(fifo, buf, n) \ +__kfifo_uint_must_check_helper( \ +({ \ + unsigned int __ret; \ + uv_mutex_t __lock = ((struct __kfifo*)fifo)->lock; \ + uv_mutex_lock(&__lock); \ + __ret = kfifo_out(fifo, buf, n); \ + uv_mutex_unlock(&__lock); \ + __ret; \ +}) \ +) + +/** + * kfifo_from_user - puts some data from user space into the fifo + * @fifo: address of the fifo to be used + * @from: pointer to the data to be added + * @len: the length of the data to be added + * @copied: pointer to output variable to store the number of copied bytes + * + * This macro copies at most @len bytes from the @from into the + * fifo, depending of the available space and returns -EFAULT/0. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_from_user(fifo, from, len, copied) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + const void __user *__from = (from); \ + unsigned int __len = (len); \ + unsigned int *__copied = (copied); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_from_user_r(__kfifo, __from, __len, __copied, __recsize) : \ + __kfifo_from_user(__kfifo, __from, __len, __copied); \ +}) \ +) + +/** + * kfifo_to_user - copies data from the fifo into user space + * @fifo: address of the fifo to be used + * @to: where the data must be copied + * @len: the size of the destination buffer + * @copied: pointer to output variable to store the number of copied bytes + * + * This macro copies at most @len bytes from the fifo into the + * @to buffer and returns -EFAULT/0. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_to_user(fifo, to, len, copied) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + void __user *__to = (to); \ + unsigned int __len = (len); \ + unsigned int *__copied = (copied); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + (__recsize) ? \ + __kfifo_to_user_r(__kfifo, __to, __len, __copied, __recsize) : \ + __kfifo_to_user(__kfifo, __to, __len, __copied); \ +}) \ +) + +/** + * kfifo_out_peek - gets some data from the fifo + * @fifo: address of the fifo to be used + * @buf: pointer to the storage buffer + * @n: max. number of elements to get + * + * This macro get the data from the fifo and return the numbers of elements + * copied. The data is not removed from the fifo. + * + * Note that with only one concurrent reader and one concurrent + * writer, you don't need extra locking to use these macro. + */ +#define kfifo_out_peek(fifo, buf, n) \ +__kfifo_uint_must_check_helper( \ +({ \ + typeof((fifo) + 1) __tmp = (fifo); \ + typeof((buf) + 1) __buf = (buf); \ + unsigned long __n = (n); \ + const unsigned int __recsize = sizeof(*__tmp->rectype); \ + struct __kfifo *__kfifo = &__tmp->kfifo; \ + if (0) { \ + typeof(__tmp->ptr) __dummy __attribute__ ((unused)) = NULL; \ + __buf = __dummy; \ + } \ + (__recsize) ? \ + __kfifo_out_peek_r(__kfifo, __buf, __n, __recsize) : \ + __kfifo_out_peek(__kfifo, __buf, __n); \ +}) \ +) + +#define kfifo_peek_locked(fifo, buf, n) \ +__kfifo_uint_must_check_helper( \ +({ \ + unsigned int __ret; \ + uv_mutex_t __lock = ((struct __kfifo*)fifo)->lock; \ + uv_mutex_lock(&__lock); \ + __ret = kfifo_out_peek(fifo, buf, n); \ + uv_mutex_unlock(&__lock); \ + __ret; \ +}) \ +) + +extern int __kfifo_alloc(struct __kfifo *fifo, unsigned int size, unsigned int esize); + +extern void __kfifo_free(struct __kfifo *fifo); + +extern int __kfifo_init(struct __kfifo *fifo, void *buffer, + unsigned int size, unsigned int esize); + +extern unsigned int __kfifo_in(struct __kfifo *fifo, + const void *buf, unsigned int len); + +extern unsigned int __kfifo_out(struct __kfifo *fifo, + void *buf, unsigned int len); + +extern unsigned int __kfifo_out_peek(struct __kfifo *fifo, + void *buf, unsigned int len); + +extern unsigned int __kfifo_in_r(struct __kfifo *fifo, + const void *buf, unsigned int len, unsigned int recsize); + +extern unsigned int __kfifo_out_r(struct __kfifo *fifo, + void *buf, unsigned int len, unsigned int recsize); + +extern unsigned int __kfifo_len_r(struct __kfifo *fifo, unsigned int recsize); + +extern void __kfifo_skip_r(struct __kfifo *fifo, unsigned int recsize); + +extern unsigned int __kfifo_out_peek_r(struct __kfifo *fifo, + void *buf, unsigned int len, unsigned int recsize); + +extern unsigned int __kfifo_max_r(unsigned int len, unsigned int recsize); + +#endif diff --git a/app/libuvdbus/src/include/inet_api.h b/app/libuvdbus/src/include/inet_api.h new file mode 100644 index 0000000..c49936d --- /dev/null +++ b/app/libuvdbus/src/include/inet_api.h @@ -0,0 +1,51 @@ +#ifndef INET_API_H +#define INET_API_H + + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_HTTP_POST_SIZE (1024) + +typedef struct HTTP_POST_ATTACH +{ + char keyName[64]; + char keyValue[MAX_HTTP_POST_SIZE]; + + struct HTTP_POST_ATTACH *next, *prev; +} *PHTTP_POST_ATTACH; + +typedef struct +{ + char *pUserName; + char *pPassword; + char *pSmtpServer; + short smtpPort; +} SMTP_MAIL_CONFIG, *PSMTP_MAIL_CONFIG; + +int InetSmtpSendEmail(const char *pFrom, + const char *pTo[], + const char *pCc[], + const char *pTitle, + const char *pMessage, + const char *pAttach[], + PSMTP_MAIL_CONFIG pConfig); +#define InetHttpsDownloadFile(pURL, pPath, onRespCb, onPrgCb) InetHttpDlFileAsync(pURL, pPath, onRespCb, onPrgCb) +#define InetHttpsWebServicePost(pURL, pPost, onRespCb) InetHttpWebServicePostAsync(pURL, pPost, onRespCb) +int InetCancelDownload(const char *pTaskUuid); + +typedef void (*OnHttpResponse)(void* pData, unsigned int size, const char* pReqUrl, const char* pDlPath, const char* pTaskUuid, int iFinished, void* pUserData); +typedef void (*OnProgressNotify)(const char* pReqUrl, const char* pTaskUuid, unsigned char uPercent, void* pUserData); + +int InetInit(void); +void InetUnInit(void); + +const char* InetHttpDlFileAsync(const char*, const char*, OnHttpResponse, OnProgressNotify, void*); +const char* InetHttpWebServicePostAsync(const char *pURL, const char *pPost, OnHttpResponse onRespCb, void *pData); +int InetHttpUploadFileSync(const char *pURL, const char* pPath, void* pAttachInfo); +//int InetSmtpSendEmail(void); +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/json_struct.h b/app/libuvdbus/src/include/json_struct.h new file mode 100644 index 0000000..5664316 --- /dev/null +++ b/app/libuvdbus/src/include/json_struct.h @@ -0,0 +1,150 @@ +#ifndef JSON_STRUCT_H +#define JSON_STRUCT_H +#include + +#include "smart_sound.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#define MAX_MUSIC_UUID (256) +#define MAX_MUSIC_URL (2048) + +typedef enum +{ +//****************************************** +// Player <--> Controller +//****************************************** + JSON_ENGINE_P2C = 0, + JSON_ENGINE_C2P, + +//****************************************** +// Configure Req & Rsp +//****************************************** + JSON_ENGINE_CFG_REQ, + JSON_ENGINE_CFG_RSP, + +//****************************************** +// Alarm Req & Rsp +//****************************************** + JSON_ENGINE_ASSISTANT_SYNC_RSP, + JSON_ENGINE_ASSISTANT_NOTIFY, + JSON_ENGINE_ASSISTANT_STATUS, + JSON_ENGINE_ASSISTANT_RUNNING, + +//****************************************** +// Work Day API Req & Rsp +//****************************************** + JSON_ENGINE_WORKDAY_REQ, + +//****************************************** +// PING Cmd +//****************************************** + JSON_ENGINE_PING, + +//****************************************** +// OTA Cmd +//****************************************** + JSON_ENGINE_OTA_REQ, + JSON_ENGINE_OTA_RSP, + +//****************************************** +// LOG System Configure Cmd +//****************************************** + JSON_ENGINE_LOG_CFG_CMD, + +//****************************************** +// WIFI Status Changed Nofify Cmd +//****************************************** + JSON_WIFI_STATUS_NOTIFY, + +//****************************************** +// mcu test Cmd +//****************************************** + JSON_MCU_GUIDE_TEST_CMD, + JSON_MCU_MATRIX_TEST_CMD, + JSON_MCU_TEST_GET_VER_CMD, + + JSON_ENGINE_MAX, +} JSON_ENGINE_TYPE; + +typedef struct +{ + uint32_t playerId; + char musicUuid[MAX_MUSIC_UUID]; + int plySt; + uint32_t curPos; + uint32_t duration; +} PLAYER_TO_CTRL, *PPLAYER_TO_CTRL; + +typedef struct +{ + uint32_t playerId; + char src[MAX_MUSIC_URL]; + char srcUuid[MAX_MUSIC_URL]; + char ttsText[MAX_MUSIC_UUID * 2]; + int skTime; + int plyMode; + int plyListType; + char adSrcType; + int duration; + int volRestoreTime; + char volBegin; + float gain; + char fifo[MAX_MUSIC_UUID]; + char channel; + char bytes; + int sampleRate; + char backGroundUrl[MAX_MUSIC_URL]; +} CTRL_TO_PLAYER, *PCTRL_TO_PLAYER; + +typedef struct +{ + char keyName[MAX_CFG_KEY_NAME]; + char keyValue[MAX_CFG_KEY_VALUE]; + int keyType; +} CFG_API_REQ, *PCFG_API_REQ; + +typedef struct +{ + int red; + int green; + int blue; +} MCU_TEST_GUIDE_CMD, *PMCU_TEST_GUIDE_CMD; + +typedef struct +{ + int level; +} MCU_TEST_MATRIX_CMD, *PMCU_TEST_MATRIX_CMD; + +typedef struct +{ + char McuVer[16]; +} MCU_TEST_VER_CMD, *PMCU_TEST_VER_CMD; + + +typedef struct +{ + char keyName[MAX_CFG_KEY_NAME]; + char keyValue[MAX_CFG_KEY_VALUE]; + int keyType; + int errNo; +} CFG_API_RSP, *PCFG_API_RSP; + +typedef struct +{ + double PING; + int tmSec; + int tmMSec; +} PING_MSG, *PPING_MSG; + +void* Json2Struct(const char* pJsonStr, JSON_ENGINE_TYPE type, int enBase64, int* pErr); +const char* Struct2Json(void* pStruct, JSON_ENGINE_TYPE type, int enBase64, int* pErr); + + +#ifdef __cplusplus +} +#endif +#endif + diff --git a/app/libuvdbus/src/include/libuv_dbus.h b/app/libuvdbus/src/include/libuv_dbus.h new file mode 100644 index 0000000..e019b8e --- /dev/null +++ b/app/libuvdbus/src/include/libuv_dbus.h @@ -0,0 +1,232 @@ +#ifndef LIBUV_DEBUS_H +#define LIBUV_DEBUS_H +#include "smart_sound.h" + +#include +#include +#include "json_struct.h" +#include "config_engine.h" + +#ifdef __cplusplus +extern "C" { +#endif +#define SAFE_STRING_VALUE(s) (s ? s : "") +#define R16_TINA_KEY_EVENT_PATH ("/dev/input/event2") +#define DBUS_MESSAGE_INTERFACE_NAME "netease.ihw.SmartAudio" + +#define DBUS_PATH_HEAD "/netease/ihw/" +#define DBUS_INTERFACE_HEAD "netease.ihw." + +#define DBUS_MSG_MAX_PAD_SIZE (1024 * 1024 * 2) +#define LIBUV_CURRENT_TIME_S() (uv_hrtime() / 1000000000) +#define LIBUV_CURRENT_TIME_MS() (uv_hrtime() / 1000000) +#define LIBUV_CURRENT_TIME_US() (uv_hrtime() / 1000) +#define MODULE_ALIAS_NAME(i) (strrchr(g_pModInfoTable[i].modAliase, '.') + 1) + +#define HEART_SEND_DELAY (5000) +#define HEART_LOST_DELAY (20000) + +typedef enum +{ + WIFI_CONNECTED = 0, + WIFI_DISCONNECTED = 1, +} WIFI_STATUS; + +typedef struct +{ + int wifi_evt; +} WIFI_STATUS_PRO, *PWIFI_STATUS_PRO; + +typedef struct +{ + int isReady; + int year; + unsigned char days[366]; +} WORKDAY_INFO, *PWORKDAY_INFO; + +typedef struct +{ + int32_t msgSrc; ///< message who send + uint32_t msgDests; ///< who need receive message(not only one) +#if USED_SHM_TO_DBUS + uint32_t tmTickMSec; ///< timestamp of second +#endif + uint32_t busCmd; ///< command of message + uint32_t msgSize; ///< how many bytes of this message + uint32_t msgKey; ///< share key for copy large message + char* pMsg; ///< message context if has + int isBstMsg; +} DBUS_MSG_PACK, *PDBUS_MSG_PACK; + +typedef struct DBUS_MSG_PROC +{ + int msgFrom; ///< 0: Boardcast Msg, 1: P2P Message + DBUS_MSG_PACK msgContent; + + struct DBUS_MSG_PROC *next, *prev; +} *PDBUS_MSG_PROC; + +typedef void (*OnDBusAsyncSendTo)(int err); +typedef PDBUS_MSG_PACK (*OnDBusMessage)(uv_loop_t* pLoop, DBusConnection* pConn, PDBUS_MSG_PACK pMsg); +typedef void (*OnDaemonMsg)(MODULE_NAME modName, int status); +typedef void (*OnKeyEvent)(uint16_t uType, uint16_t uKey, int32_t iValue); + +typedef struct +{ + MODULE_NAME modName; ///< Module Name + const char* modPath; ///< Attach to dbus path + const char* modAliase; ///< Attach to dbus bus name +} MOD_INFO_TABLE, *PMOD_INFO_TABLE; + + +typedef struct +{ + uv_loop_t* pLoop; ///< libuv default main loop + uv_loop_t* pUserLoop; ///< libuv user main loop + DBusConnection* pBus; ///< D-Bus object + MODULE_NAME modName; ///< Process name + const char* pBusName; ///< D-Bus object's interface name + const char* pBusPath; ///< D-Bus object's path name + OnDBusMessage onMsgCb; ///< D-Bus receive message callback + OnKeyEvent onKeyCb; ///< Keyboard event callback + OnDaemonMsg onHblCb; ///< Process HBL event callback + OnCfgMsg onCfgCb; ///< Configure message callback +// unsigned int uDaemon[MODULE_MAX]; ///< Daemon Service +} LIBUV_DBUS_PARAMS, *PLIBUV_DBUS_PARAMS; + +static MOD_INFO_TABLE g_pModInfoTable[] = +{ + {MODULE_CONTROLLER, DBUS_PATH_HEAD"controller", DBUS_INTERFACE_HEAD"controller"}, + {MODULE_ALARM, DBUS_PATH_HEAD"alarm", DBUS_INTERFACE_HEAD"alarm"}, + {MODULE_CALL, DBUS_PATH_HEAD"call", DBUS_INTERFACE_HEAD"call"}, + {MODULE_VOICEENGINE, DBUS_PATH_HEAD"voice_engine", DBUS_INTERFACE_HEAD"voice_engine"}, + {MODULE_PLAYER, DBUS_PATH_HEAD"player", DBUS_INTERFACE_HEAD"player"}, + {MODULE_CONFIGURE, DBUS_PATH_HEAD"config", DBUS_INTERFACE_HEAD"config"}, + {MODULE_OTA, DBUS_PATH_HEAD"ota", DBUS_INTERFACE_HEAD"ota"}, + {MODULE_WIFI, DBUS_PATH_HEAD"wifi", DBUS_INTERFACE_HEAD"wifi"}, + {MODULE_BT, DBUS_PATH_HEAD"bt", DBUS_INTERFACE_HEAD"bt"}, + {MODULE_KPLAYER, DBUS_PATH_HEAD"kplayer", DBUS_INTERFACE_HEAD"kplayer"}, + {MODULE_KPLAYER_TEST, DBUS_PATH_HEAD"kplayerTest", DBUS_INTERFACE_HEAD"kplayerTest"}, + {MODULE_SPLAYER, DBUS_PATH_HEAD"splayer", DBUS_INTERFACE_HEAD"splayer"}, + {MODULE_SPLAYER_TEST, DBUS_PATH_HEAD"splayerTest", DBUS_INTERFACE_HEAD"splayerTest"}, + {MODULE_LIGHT_MCU, DBUS_PATH_HEAD"light_mcu", DBUS_INTERFACE_HEAD"light_mcu"}, + {MODULE_BLUEKC, DBUS_PATH_HEAD"blukc", DBUS_INTERFACE_HEAD"blukc"}, + {MODULE_BLUEKC_TEST, DBUS_PATH_HEAD"bluekcTest", DBUS_INTERFACE_HEAD"bluekcTest"}, + {MODULE_MANUFACTURE, DBUS_PATH_HEAD"manufacture", DBUS_INTERFACE_HEAD"manufacture"}, + {MODULE_BT_DEMO, DBUS_PATH_HEAD"btdemo", DBUS_INTERFACE_HEAD"btdemo"}, + {MODULE_SKINS, DBUS_PATH_HEAD"skins", DBUS_INTERFACE_HEAD"skins"}, + {MODULE_LOG_CTRL, DBUS_PATH_HEAD"logCtrl", DBUS_INTERFACE_HEAD"logCtrl"}, + {MODULE_WIRELESSTEST, DBUS_PATH_HEAD"wirelessTest", DBUS_INTERFACE_HEAD"wirelessTest"}, + {MODULE_WIRELESSTEST_DEMO, DBUS_PATH_HEAD"wirelessTestDemo", DBUS_INTERFACE_HEAD"wirelessTestDemo"}, + {MODULE_MANUFACTURE_CONTROLLER, DBUS_PATH_HEAD"manufacture_controller", DBUS_INTERFACE_HEAD"manufacture_controller"}, + {MODULE_WIFI_DEMO, DBUS_PATH_HEAD"wifiDemo", DBUS_INTERFACE_HEAD"wifiDemo"}, +}; + +PLIBUV_DBUS_PARAMS DBusLibuvGetRuntime(void); +MODULE_NAME DBusLibGetModName(void); +uv_loop_t* GetDBusDefaultLoop(void); + +void RunUVLoop(uv_loop_t *pLoop); + +PDBUS_MSG_PACK DBusGetMessage(void); +void DBusMsgCleanup(PDBUS_MSG_PACK pMsg); + +DBusConnection* DBusWithLibuvInit(uv_loop_t* pUserLoop, + const char* pBusName, + OnDBusMessage cbOnMsg, + OnDaemonMsg cbOnHbl, + OnKeyEvent cbOnKey, + int* pErrno); + +int DBusJsonSendToCommandAsync(DBusConnection* pBus, + const char* pBusName, + uint32_t busCmd, + JSON_ENGINE_TYPE type, + void* pStruct, + int iSize, + OnDBusAsyncSendTo cbSendTo, + int enBase64); + +int DBusJsonSendToCommand(DBusConnection* pBus, + const char* pBusName, + uint32_t busCmd, + JSON_ENGINE_TYPE type, + void* pStruct, + int enBase64); + +int DBusJsonBoardcastCommand(DBusConnection* pBus, + uint32_t msgToMask, + uint32_t busCmd, + JSON_ENGINE_TYPE type, + void* pStruct, + int enBase64); + +int DBusBoardcastCommand(DBusConnection *pBus, + uint32_t msgToMask, + uint32_t busCmd, + const char *pContext); + +int DBusSendToCommand(DBusConnection *pBus, + const char *pBusName, + uint32_t busCmd, + const char *pContext); + +void HeartDaemonUpgrade(int iWatcher); +void HeartDaemonInit(MODULE_NAME mod, int msHblTout, OnDaemonMsg cb); +void HeartDaemonHblCheck(void); + +int DBusWithLibuvCfgInit(OnCfgMsg cbOnCfgMsg); +int GetShellExecResult(const char *pCmd, char **pResult); +int CopyFile(const char *pSrc, const char *pDest); +int CopyFileWithSize(const char *pSrc, const char *pDest, int iSize); +int ReadFileToBuf(const char *pSrc, unsigned char *pBuf, int iSize); +void SystemSafeReboot(void); + +typedef void (*OnAlarmTimer)(unsigned int tmId, unsigned int status, void* pUserData); +int AlarmTimerInit(uv_loop_t *pLoop); +int AlarmTimerCleanup(void); +int AlarmTimerRemove(unsigned int tmId); +#if 0 +unsigned int AlarmTimerAdd(struct tm *pOnTime, unsigned int repMode, OnAlarmTimer pOnTimerCb, void *pUserData, int *pError); +#endif +unsigned int AlarmTimerAdd(int year, + int month, + int day, + int hour, + int minute, + int second, + int weekDay, + int repMode, + OnAlarmTimer pOnTimerCb, + int priority, + void *pUserData, + int *pError); + +int CurrentIsWorkDay(int year, int day); +int IsHolidayDBSynced(void); +const char* DumpTimerRepeatModeString(int mode); +unsigned long long GetPartitionFreeSize(const char *pPartPath); +WIFI_STATUS GetCurrWIFIConnStatus(void); +const char* ErrcodeToString(int errCode); +const char* DBusCmdToString(DBUS_CMD cmd); +const char* ModuleNameToString(MODULE_NAME modName); + +char* GetCpuSerial(void); +char* GetCpuChipId(void); +char* GetCurrentVersion(void); + +void CfgFileInit(void); +int CfgGetIntValue(const char* pTags, int defValue); +int CfgGetIntValueV1(const char* pTags, int defValue, int* pErr); +int CfgGetIntValueV2(const char* pTags, int defValue, int* pErr); +int GetServerModeFromCC(int defValue, int* pErr); +char* CfgGetStringValue(const char* pTags, char* pDefValue); +double CfgGetFloatValue(const char* pTags, double defValue); +int CfgGetBoolValue(const char* pTags, int defValue); +void SetHBLAutoExit(int flag); + +extern char *strptime(const char *s, const char *format, struct tm *tm); +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/log.h b/app/libuvdbus/src/include/log.h new file mode 100644 index 0000000..118d79c --- /dev/null +++ b/app/libuvdbus/src/include/log.h @@ -0,0 +1,233 @@ +/** @file log.h + @brief + @details + @version 1.0.0 +*/ +#ifndef LOG_H_ +#define LOG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef __KERNEL__ +#include +#include +#else +#include +#endif + +#ifndef TRUE +#define TRUE (1) +#endif + +#ifndef FALSE +#define FALSE (0) +#endif + +#ifndef MAX +/** @def MAX + @brief 取最大值 +*/ +#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +/** @def MIN + @brief 取最小值 +*/ +#define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + +#define TIMEZONE_EAST_8H (8 * 3600) + +#ifndef __KERNEL__ +#define DUMP_PREFIX_ADDRESS (1) +#define DUMP_PREFIX_OFFSET (2) +#endif + +#define DEBUG_SQL_CALLBACK_DATA(argc, argv, azColName) do { \ + for(int i = 0; i < argc; i++) { \ + fprintf(stdout, "%s = [%s], ", azColName[i], argv[i]); \ + } \ + fprintf(stdout, "\n"); \ +} while(0); + +#define print(format, ...) fprintf(stdout, format, __VA_ARGS__) + +typedef struct +{ + int cfgCmd; + int iParams1; + int iParams2; +} LOG_CFG_PROTOCOL, *PLOG_CFG_PROTOCOL; + +typedef enum +{ + CMD_LOG_ENABLE = 0, + CMD_LOG_FILE = 1, + CMD_LOG_MAIL = 2, + CMD_LOG_LEVEL = 3, + CMD_LOG_NETWORK = 4, + CMD_LOG_SERVER = 5 +} LOG_CFG_CMD; + +/** @enum _LOG_LEVEL_ + * LOG等级枚举变量 + */ +typedef enum +{ + LOG_Fatal = (1 << 0), + LOG_Error = (1 << 1), + LOG_Warn = (1 << 2), + LOG_Debug = (1 << 3), + LOG_Info = (1 << 4), + LOG_Test = (1 << 5), + LOG_Call = (1 << 6), + LOG_Devp = (1 << 7), + LOG_Step = (1 << 8), + LOG_Unknown = (1 << 9), + LOG_All = (0xFFFFFFFF), + LOG_Close = 0x0, +} LOG_LEVEL; +/** @var typedef _LOG_LEVEL_ LOG_LEVEL + * @brief 错误值枚举类型 + */ + +#ifdef DISABLE_LOG +#define LOG_BUF(level, buf, len) +#define LOG_EX(level, format, args...) +#define LOG_EX2(level, format, args...) +#define LOG_TAG_EX(tag, level, format, args...) +#define DEBUG_CODE_LINE() +#define DEBUG_FUNCTION_BEGIN() +#define DEBUG_FUNCTION_END() +#else +#define LOG_BUF(level, buf, len) do { \ + const char* pFmtBuf = format_hex_buf("", DUMP_PREFIX_ADDRESS, 16, 1, buf, len, 1); \ + IHW_LOG(level, "[%s] - %s(%d): %s[0-%d]:\n%s", basename_v2(__FILE__), __FUNCTION__, __LINE__, \ + #buf, len, pFmtBuf); \ + free((void*)pFmtBuf); \ +} while(0); +/*! \def LOG_EX + \brief 系统日志调试宏标识 +*/ +#define LOG_EX(level, format, args...) (IHW_LOG(level, "[%s] - %s(%d):" format , basename_v2(__FILE__), __FUNCTION__, __LINE__, ##args)) + +/*! \def LOG_TAG_EX + \brief 系统日志调试宏标识 +*/ +#define LOG_TAG_EX(tag, level, format, args...) (IHW_LOG(level, "{%s} [%s] %s(%d):" format , tag, basename_v2(__FILE__), __FUNCTION__, __LINE__, ##args)) + +#define LOG_EX2(level, format, args...) (IHW_LOG_UNTAG(level, format , ##args)) + +/*! @def APP_BUILD_INFO + @brief 应用程序编译信息 +*/ +#define APP_BUILD_INFO(appname, appver) (IHW_LOG(LOG_Info, "%s Ver:%s (Build: %s %s GCC Ver:%s) With %d(bits) OS\n", \ + appname, appver, __DATE__, __TIME__, __VERSION__, sizeof(int*) * 8)) + + +/*! @def DEBUG_CODE_LINE + @brief 输出当前函数名,行号 +*/ +#define DEBUG_CODE_LINE() (LOG_EX(LOG_Info, "\n")) + +/*! @def DEBUG_FUNCTION_BEGIN + @brief 函数入口标志 +*/ +#define DEBUG_FUNCTION_BEGIN() (LOG_EX(LOG_Call, "+++++\n")) + +/*! @def DEBUG_FUNCTION_END + @brief 函数出口标志 +*/ +#define DEBUG_FUNCTION_END() (LOG_EX(LOG_Call, "-----\n")) + +/** + * @brief 输出调试信息 + * @param level 调试信息开关 + * @param pMsg 调试信息内容 + */ +void IHW_LOG(LOG_LEVEL level, const char* pMsg, ...); +void IHW_LOG_UNTAG(LOG_LEVEL level, const char* pMsg, ...); + +void IHW_LogStrWithoutPrint(int level, char* pMsg); +void IHW_LogRawString(int level, char* pMsg); + +/** + * @brief 设置调试等级 + * @param level 调试等级 + * @param iEnable 1 打开调试等级, 0 关闭调试等级 + */ +void IHW_EnableLogLevel(LOG_LEVEL level, int iEnable); + +/** + * @brief 初始化系统日志功能 + * @param pLogTag 系统日志标志 + * @param pPath 系统日志保存路径 + * @param bEnable 打开/关闭调试信息 + */ +void IHW_InitLOG(const char* pLogTag, const char* pPath, int bEnable); + +void IHW_RunLogService(void); + +/** + * @brief 判断文件、路径是否存在 + * @param pPath - 文件路径 + * @return int 存在返回 1, 否则返回 0; + */ +int IHW_IsFileExist(const char* pPath); + +void IHW_EnableLogOut(void); +void IHW_DisableLogOut(void); + +char* IHW_bin2hex(char *p, const unsigned char *cp, int count); + +void UpgradLogConfigure(PLOG_CFG_PROTOCOL pCfg); +//void LogUploadCurLogFile(void); + +/* Return the last part of a pathname */ +static inline const char* basename_v2(const char* path) +{ + const char* tail = strrchr(path, '/'); + return tail ? tail + 1 : path; +} + +static inline int dirname_v2(const char* path, char* dir) +{ + const char* tail = strrchr(path, '/'); + + if(tail) + { + memcpy(dir, path, tail - path); + dir[tail - path] = 0; + } + else + { + strcpy(dir, "./"); + } + + return 0; +} +#endif + +const char* LogLeveToString(LOG_LEVEL lv); + +const char* format_hex_buf(const char* prefix_str, int prefix_type, + int rowsize, int groupsize, + const void* buf, int len, int ascii); +#ifndef __KERNEL__ +void print_hex_dump_bytes(const char* prefix_str, int prefix_type, + const void* buf, int len); +#endif + +int HttpPostLogFile(char* pSession); +//void UploadLogFile(char* pFilePath); +int SysPointMarkUpload(void); +int SysPointMark(char* pMarkInfo); +int SysPointMarkInit(char* pDevId, int iMaxSize, int iPostTime); +#ifdef __cplusplus +} +#endif +#endif //LOG_H_ + diff --git a/app/libuvdbus/src/include/log_info.h b/app/libuvdbus/src/include/log_info.h new file mode 100644 index 0000000..cd24c61 --- /dev/null +++ b/app/libuvdbus/src/include/log_info.h @@ -0,0 +1,13 @@ +#ifndef LOG_INFO_H +#define LOG_INFO_H + +#ifdef __cplusplus +extern "C" { +#endif + + + +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/monitor.h b/app/libuvdbus/src/include/monitor.h new file mode 100644 index 0000000..e5f8513 --- /dev/null +++ b/app/libuvdbus/src/include/monitor.h @@ -0,0 +1,21 @@ +#ifndef _MONITOR_H +#define _MONITOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef ENABLE_COUNT_DEBUG +int MonAddNewItem(const char* pName, int logSaveTime); +int MonIncreaseCount(const char* pName); +int MonUpgradeStatistical(const char* pName, long newVal); +int MonDiffStatistical(const char* pName, long long newVal); +int MonItemLogout(const char* pName); +int MonitorInit(void); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/app/libuvdbus/src/include/ota.h b/app/libuvdbus/src/include/ota.h new file mode 100644 index 0000000..7d4be75 --- /dev/null +++ b/app/libuvdbus/src/include/ota.h @@ -0,0 +1,156 @@ +#ifndef OTA_H +#define OTA_H +#ifdef __cplusplus +extern "C" { +#endif + +#define SIZE_1K (1024) ///< 1K 字节大小 +#define MD5_CHKSUM_LEN (16) ///< MD5校验和长度 +#define MD5_CHKSUM_STR_LEN (MD5_CHKSUM_LEN * 2 + 1) ///< MD5校验和字符串格式长度 +#define NO_OTA_STATUS_VAL_TAG (0) ///< 状态默认值 + + +/** + * 系统启动模式定义 + */ +typedef enum +{ + NORMAL_SETUP = 0x1234, ///< 普通启动模式 + RECOVERY_SETUP, ///< 恢复模式 + SYSTEM_OTA, ///< OTA升级模式 + SYSTEM_OTA_OK, +} SETUP_MODE; + +/** + * OTA状态命令定义 + */ +typedef enum +{ + OTA_CURRENT_VERSION = 0, ///< 当前系统版本号 + OTA_CURRENT_SETUP_MODE, ///< 当前系统启动模式 + OTA_CURRENT_REBOOT_TIME, ///< 当前系统未正常启动次数 + OTA_DOWNLOAD_FILE, ///< OTA升级包下载状态 + OTA_DOWNLOAD_PROGRESS, ///< OTA升级包下载进度 + OTA_VERIFY_FILE, ///< 文件校验结果 + OTA_VERIFY_PARTITION, ///< OTA分区校验结果 + OTA_DECOMPRESS_FILE, ///< OTA当前进度:解压文件 + OTA_UPGRADE_READY, ///< OTA更新准备完成 + OTA_UPGRADE_START, ///< OTA更新开始 + OTA_UPGRADE_PARTITION, ///< OTA写入分区数据 + OTA_RECOVERY_START, ///< OTA恢复模式启动 + OTA_REREQ_OTA_NOW, ///< OTA请求立即执行OTA更新系统 + OTA_REBOOT_SYSTEM, ///< OTA准备重启系统 + OTA_SUCCESED, ///< OTA执行成功 + OTA_UNKNOWN_CMD, ///< 位置OTA状态命令 + OTA_ERR_CODE, ///< OTA过程异常 + OTA_DISK_FULL, ///< 存储空间不足 +} OTA_STATUS_TYPE; + + +/** + * OTA模式 + */ +typedef enum +{ + OTA_MODE_NORMAL = 9029, ///< 普通OTA更新模式 + OTA_MODE_FORCE_NOW, ///< 强制OTA更新模式 + OTA_MODE_RECOVERY, ///< OTA恢复模式 +} OTA_MODE; + + +/** + * OTA操作命令 + */ +typedef enum +{ + OTA_CMD_DOWNLOAD = 1234, ///< 下载OTA升级包 + OTA_CMD_USED_LOCAL_IMAGE, ///< 从上次备份的OTA升级包升级 + OTA_CMD_EXEC, ///< 开始OTA更新系统 +} OTA_CMD; + + + +/** + * OTA级包信息 + * + */ +typedef struct +{ + char url[SIZE_1K]; ///< URL, Base64编码 + char md5[MD5_CHKSUM_STR_LEN]; ///< OTA升级包MD5校验和 + unsigned int size; ///< OTA升级包文件大小 +} OTA_FILE_INFO, *POTA_FILE_INFO; + +/** + * 控制中心控制命令协议 + * + * @see OTA_CMD + * @see OTA_MODE + * @see OTA_FILE_INFO + */ +typedef struct +{ + int version; ///< OTA版本号 + OTA_CMD otaCmd; ///< OTA命令 + OTA_MODE otaMode; ///< OTA模式 + OTA_FILE_INFO otaFileInfo; ///< OTA升级包信息 +} OTA_DATA_INFO, *POTA_DATA_INFO; + +/** + * OTA状态信息协议 + * + * @see OTA_STATUS_TYPE + */ +typedef struct +{ + OTA_STATUS_TYPE status; ///< 状态命令 + int val; ///< 状态值 +} OTA_RSP_STATUS, *POTA_RSP_STATUS; + +static inline const char* otaStatusName(OTA_STATUS_TYPE type) +{ + switch(type) + { + case OTA_CURRENT_VERSION: + return ("OTA_CURRENT_VERSION"); + case OTA_CURRENT_SETUP_MODE: + return ("OTA_CURRENT_SETUP_MODE"); + case OTA_CURRENT_REBOOT_TIME: + return ("OTA_CURRENT_REBOOT_TIME"); + case OTA_DOWNLOAD_FILE: + return ("OTA_DOWNLOAD_FILE"); + case OTA_DOWNLOAD_PROGRESS: + return ("OTA_DOWNLOAD_PROGRESS"); + case OTA_VERIFY_FILE: + return ("OTA_VERIFY_FILE"); + case OTA_VERIFY_PARTITION: + return ("OTA_VERIFY_PARTITION"); + case OTA_DECOMPRESS_FILE: + return ("OTA_DECOMPRESS_FILE"); + case OTA_UPGRADE_READY: + return ("OTA_UPGRADE_READY"); + case OTA_UPGRADE_START: + return ("OTA_UPGRADE_START"); + case OTA_UPGRADE_PARTITION: + return ("OTA_UPGRADE_PARTITION"); + case OTA_RECOVERY_START: + return ("OTA_RECOVERY_START"); + case OTA_REREQ_OTA_NOW: + return ("OTA_REREQ_OTA_NOW"); + case OTA_REBOOT_SYSTEM: + return ("OTA_REBOOT_SYSTEM"); + case OTA_SUCCESED: + return ("OTA_SUCCESED"); + case OTA_UNKNOWN_CMD: + return ("OTA_UNKNOWN_CMD"); + case OTA_ERR_CODE: + return ("OTA_ERR_CODE"); + default: + return ("Unknown Type"); + } +} +#ifdef __cplusplus +} +#endif +#endif + diff --git a/app/libuvdbus/src/include/server_addr.h b/app/libuvdbus/src/include/server_addr.h new file mode 100644 index 0000000..9f5d473 --- /dev/null +++ b/app/libuvdbus/src/include/server_addr.h @@ -0,0 +1,49 @@ +#ifndef SERVER_ADDR_H +#define SERVER_ADDR_H +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum +{ + YUNXIN_MODULE = 0, + VOICE_MODULE = 1, + VOICE_AI_MODULE = 2, + SERVER_MODULE = 3, + LOG_MODULE = 4, + MARK_POINT_MODULE = 5, + TTS_MODULE = 6, + DC_MODULE = 7, + MAX_MODULE +} SERVER_MODULE_TYPE; + +typedef enum +{ + DEV_MODE = 0, + TEST_MODE = 1, + PUBLISH_MODE = 2, + PUBLISH_PREBUILD = 3, + MAX_MODE +} SERVER_MODE_TYPE; + +typedef enum +{ + VOICE_APP_KEY = 0, + VOICE_APP_SECRET = 1, + VOICE_MAX +} VOICE_KEYMAP_TYPE; + +const char* SvrModeStr(SERVER_MODE_TYPE mode); +const char* SvrModuleStr(SERVER_MODULE_TYPE module); +void DumpCurServerAddr(const char* pTags); + +void ServerManagerInit(void); +SERVER_MODE_TYPE GetCurrentServerMode(void); +void SetCurrentServerMode(SERVER_MODE_TYPE mode); + +char* GetCurServerAddr(SERVER_MODULE_TYPE module); +char* GetCurVoiceKeyValue(VOICE_KEYMAP_TYPE keyMap); +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/skins.h b/app/libuvdbus/src/include/skins.h new file mode 100644 index 0000000..1403813 --- /dev/null +++ b/app/libuvdbus/src/include/skins.h @@ -0,0 +1,58 @@ +#ifndef SKINS_H +#define SKINS_H +#ifdef __cplusplus +extern "C" { +#endif + +#define MD5_STR_LEN (36) ///< +#define MAX_KEY_NAME (64) +#define MAX_KEY_PATH (256) + +#define SKIN_MODE_NAME ("ModuleSkin") +#define RES_MODE_NAME ("ModuleRes") +#define RES_TBL_NAME "res" +#define SKIN_TBL_NAME "skin" +#define SKIN_USER_DB "user_db" + +#define CREATE_SKIN_TBL_SQL "CREATE TABLE IF NOT EXISTS %s"SKIN_TBL_NAME" (" \ + "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ + "keyName TEXT NOT NULL," \ + "resType INTEGER NOT NULL," \ + "priority INTEGER NOT NULL," \ + "resID INTEGER NOT NULL," \ + "resReadme TEXT NOT NULL DEFAULT \'\');" + +#define CREATE_RES_TBL_SQL "CREATE TABLE IF NOT EXISTS %s"RES_TBL_NAME" (" \ + "ID INTEGER PRIMARY KEY AUTOINCREMENT," \ + "resVersion TEXT NOT NULL," \ + "localPath TEXT NOT NULL," \ + "serverURL TEXT NOT NULL," \ + "md5Chksum TEXT NOT NULL);" + +typedef enum +{ + VOICE_RES = 1, + IMAGE_RES, + TEXT_RES, +} SKINS_RES_TYPE; + +typedef struct +{ + SKINS_RES_TYPE resType; + const char *pResVer; + const char *pKeyName; + const char *pLocalPath; + const char *pMD5Chksum; +} SKIN_RES_INFO, *PSKIN_RES_INFO; + +int SkinInit(void); +char* GetSkinsResource(char *pKeyName, int *pResType, int *pVersion, char **pComeFrom); +int SkinUpgrade(char *pUpdFilePath); +void SkinIsVerifyRes(int isVerify); +unsigned int SkinsDefaultSize(void); +PSKIN_RES_INFO SkinsItemById(int iId); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/skins_res.h b/app/libuvdbus/src/include/skins_res.h new file mode 100644 index 0000000..742ccda --- /dev/null +++ b/app/libuvdbus/src/include/skins_res.h @@ -0,0 +1,319 @@ +#ifndef SKINS_RES_H +#define SKINS_RES_H + +#include "skins.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef PLATFORM_CPU +#define SKINS_DB_PATH ("./skins.db") +#define DEF_SKINS_ROOT_PATH "/home/hx/MyProjects/release/drivers/skins/" +#else +#define SKINS_DB_PATH ("/mnt/UDISK/skins.db") +#define DEF_SKINS_ROOT_PATH "/usr/share/resource/" +#endif + +#define EMU_HTTP_URL_ROOT "http://10.240.84.163/resource/" + +#if 0 +#define TEXT_WIFIPARING_APPARINGANDCONNECTING ("接收到WIFI配置参数,开始连接,可能时间比较长,请耐心等待") +#define TEXT_BT_WIFIPARING ("进入蓝牙网络配对模式") +#define TEXT_AP_WIFIPARING ("进入AP网络配对模式") +#define TEXT_WIFICONNECTED ("联网成功") +#define TEXT_SYSTEMBOOT ("很高兴遇见你,我是如意") +#define TEXT_NOTRECVINGWIFICONFIG ("没有收到网络配置信息") +#define TEXT_BLE_SUUCCESS_WAIT_CONFIG ("低功耗蓝牙已连接,等待配网") +#define TEXT_AP_WAIT_CONFIG ("当前在AP配网模式,等待配网") +#define TEXT_WIFINOTCONNECT ("网络未连接") +#define TEXT_REQSERVER_ERROR ("服务器请求失败,请重新配网") +#define TEXT_BLE_CONNECT ("ble已连接") +#define TEXT_BLE_DISCONNECT ("ble已断开") +#define TEXT_WIFIPARINGSUCCESS ("网络配对成功") +#define TEXT_BT_ON ("开启传统蓝牙") +#define TEXT_BT_OFF ("关闭传统蓝牙") +#define TEXT_ALARM_REMOVE_ALL ("删除全部闹钟成功") +#define TEXT_ALARM_REMOVE ("删除闹钟成功") +#define TEXT_ALARM_ADD ("闹钟设置成功") +#define TEXT_AP_APP_CONNECTED ("APP已通过wifi连接音箱") +#define TEXT_WIFICONNECT_ERR_REPARING ("wifi联网失败,请重新配网") +#define TEXT_WIFICONNECT_ERR_PASS ("ssid或密码错误,请重新配网") +#define TEXT_WIFIPARING_ERR_SERVERCONNECT ("服务器连接失败,请重新配网") +#define TEXT_NOT_UNSUPPORT ("不支持当前操作") +#define TEXT_BOOT_DONE ("你好,欢迎使用如意音箱") +#define TEXT_WIFIPARING_FIRST_NOTICE ("请使用网易云音乐APP ,进入账号页面 为音箱配网,请下载如意音响APP,为音箱配网") +#endif + +const SKIN_RES_INFO g_SkinDefaultResTable[] = { + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// voice resources + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#ifndef RES_FACTORY_MODE + {VOICE_RES, "0", "v102", DEF_SKINS_ROOT_PATH"voice/Alianwang002.mp3", "c84ee8c2dade8b5d39e36d10ee8e3807"}, +#endif + {VOICE_RES, "0", "v103", DEF_SKINS_ROOT_PATH"voice/Alianwang003.mp3", "33c00781480680a9ea5ef6be1f7ac258"}, + {VOICE_RES, "0", "v104", DEF_SKINS_ROOT_PATH"voice/Alianwang004.mp3", "d8ee9527dd6635f7251b455fcf177723"}, + {VOICE_RES, "0", "v105", DEF_SKINS_ROOT_PATH"voice/Alianwang005.mp3", "87849f3c844a42d765e85631ccfca2eb"}, + {VOICE_RES, "0", "v106", DEF_SKINS_ROOT_PATH"voice/Alianwang006.mp3", "46a63182f73e242fff7f202fc621ef17"}, + {VOICE_RES, "0", "v107", DEF_SKINS_ROOT_PATH"voice/Alianwang007.mp3", "fc02f25d84abfe066fd4ae8c140fe5f7"}, + {VOICE_RES, "0", "v108", DEF_SKINS_ROOT_PATH"voice/Alianwang008.mp3", "da772f7fcec24ebcd85bc3d9fe323f88"}, + {VOICE_RES, "0", "v109", DEF_SKINS_ROOT_PATH"voice/Alianwang009.mp3", "22b8163a5956bb877db55d38f1223cb2"}, + {VOICE_RES, "0", "v110", DEF_SKINS_ROOT_PATH"voice/Alianwang010.mp3", "5d83539bcb59558dd53352b898512227"}, + {VOICE_RES, "0", "v111", DEF_SKINS_ROOT_PATH"voice/Alianwang011.mp3", "58de437b7778885481678cc48bc4b592"}, + {VOICE_RES, "0", "v112", DEF_SKINS_ROOT_PATH"voice/Alianwang012.mp3", "0e1d0afc6663a73c5aa5d9de0072b8df"}, + {VOICE_RES, "0", "v113", DEF_SKINS_ROOT_PATH"voice/Alianwang013.mp3", "f495927bf6b5c67991685e751f2fca40"}, + {VOICE_RES, "0", "v114", DEF_SKINS_ROOT_PATH"voice/Alianwang014.mp3", "06b0f3de13c21c60ab73253ee16f36b3"}, + {VOICE_RES, "0", "v202", DEF_SKINS_ROOT_PATH"voice/Ashiyong002.mp3", "e825e5c5b6989afb88d4084ffe1eff01"}, + {VOICE_RES, "0", "v203", DEF_SKINS_ROOT_PATH"voice/Ashiyong003.mp3", "d7245a20b4a3597894e6af8a83770044"}, + {VOICE_RES, "0", "v204", DEF_SKINS_ROOT_PATH"voice/Ashiyong004.mp3", "d546fe1b69f8ba62c14acd299ae5bc7e"}, + {VOICE_RES, "0", "v205", DEF_SKINS_ROOT_PATH"voice/Ashiyong005.mp3", "79df29d63ac4ea40546f0274b7dd3c84"}, + {VOICE_RES, "0", "v206", DEF_SKINS_ROOT_PATH"voice/Ashiyong006.mp3", "7f47f1796e125078778556d62bd573e2"}, + {VOICE_RES, "0", "v301", DEF_SKINS_ROOT_PATH"voice/S001.mp3", "eee1506b7ed801e5aa6a6ccc18c0c1f1"}, + {VOICE_RES, "0", "v302", DEF_SKINS_ROOT_PATH"voice/S002.mp3", "c90dbc04cda7bdb778a9cb196eb208a2"}, + {VOICE_RES, "0", "v303", DEF_SKINS_ROOT_PATH"voice/S003.mp3", "89340aa9f735d082d9404bae014d7bae"}, + {VOICE_RES, "0", "v304", DEF_SKINS_ROOT_PATH"voice/S004-1.mp3", "2a03648026864291cf0aad7bf6569734"}, + {VOICE_RES, "0", "v3041", DEF_SKINS_ROOT_PATH"voice/S004-2.mp3", "33cafc99de51b53afc97156866e82473"}, + {VOICE_RES, "0", "v3042", DEF_SKINS_ROOT_PATH"voice/S004-3.mp3", "0a1057342a661597730b521427d6097c"}, + {VOICE_RES, "0", "v3043", DEF_SKINS_ROOT_PATH"voice/S004-4.mp3", "c8061b90c50558c155ddc9ffef114e61"}, + {VOICE_RES, "0", "v3044", DEF_SKINS_ROOT_PATH"voice/S004-5.mp3", "97f94d1350bc09c9e974525172ad8fc0"}, + {VOICE_RES, "0", "v305", DEF_SKINS_ROOT_PATH"voice/S005.mp3", "2e7a489501b76c73e5aa4be4f7e7aa5f"}, + {VOICE_RES, "0", "v306", DEF_SKINS_ROOT_PATH"voice/S006.mp3", "437ddb3e99f77696d60c2f28c1b268cb"}, + {VOICE_RES, "0", "v307", DEF_SKINS_ROOT_PATH"voice/S007.mp3", "a6c6be6f702b5b47ddebad61d28eb1ad"}, + {VOICE_RES, "0", "v308", DEF_SKINS_ROOT_PATH"voice/S008.mp3", "5918f635de28b45f2d32e3eb4b05b9ad"}, + {VOICE_RES, "0", "v309", DEF_SKINS_ROOT_PATH"voice/S009.mp3", "f9039012752b3ed2a00f173aa305acf1"}, + {VOICE_RES, "0", "v310", DEF_SKINS_ROOT_PATH"voice/S010.mp3", "446ec757495bdf7aee31a41a9efe8bab"}, + {VOICE_RES, "0", "v311", DEF_SKINS_ROOT_PATH"voice/S011.mp3", "e9fa92d8929dcb2e134f42c1cedf4827"}, + {VOICE_RES, "0", "v400", DEF_SKINS_ROOT_PATH"voice/B-h-60.mp3", "61b24ec25307072464866da912d38287"}, + {VOICE_RES, "0", "v400", DEF_SKINS_ROOT_PATH"voice/B-h-61.mp3", "a231dc24277e25e6d762269efa9a1e07"}, + {VOICE_RES, "0", "v400", DEF_SKINS_ROOT_PATH"voice/B-h-62.mp3", "27402531c6aff9a9cfb5e418267fb41e"}, + {VOICE_RES, "0", "v400", DEF_SKINS_ROOT_PATH"voice/B-h-63.mp3", "f9487a6bf86f82961011920509ae0704"}, + {VOICE_RES, "0", "v400", DEF_SKINS_ROOT_PATH"voice/B-h-64.mp3", "1e67f62e7d8f38dbd8535355cb50fd81"}, + {VOICE_RES, "0", "v400", DEF_SKINS_ROOT_PATH"voice/B-h-65.mp3", "d2e6c99c68e981e6126306cfe8a8058e"}, + {VOICE_RES, "0", "v401", DEF_SKINS_ROOT_PATH"voice/B-h-66.mp3", "cb64153aef2ea8d5d9baeb0fc683fd54"}, + {VOICE_RES, "0", "v401", DEF_SKINS_ROOT_PATH"voice/B-h-67.mp3", "6661a903cd05fdab1ecd5193fb789e51"}, + {VOICE_RES, "0", "v401", DEF_SKINS_ROOT_PATH"voice/B-h-68.mp3", "db32f17dc439c25255d934bbeaec6275"}, + {VOICE_RES, "0", "v401", DEF_SKINS_ROOT_PATH"voice/B-h-69.mp3", "a93fea8d57e37a519f3ee0388cbd6e9a"}, + {VOICE_RES, "0", "v401", DEF_SKINS_ROOT_PATH"voice/B-h-70.mp3", "f91f277864c927fedfee53fb1e9d964a"}, + {VOICE_RES, "0", "v401", DEF_SKINS_ROOT_PATH"voice/B-h-71.mp3", "a4a4ff36d63fa47072c9eb181712e5cb"}, + {VOICE_RES, "0", "v402", DEF_SKINS_ROOT_PATH"voice/b-h-50.mp3", "017b53f7610f6dd99e21b546e6b35605"}, + {VOICE_RES, "0", "v403", DEF_SKINS_ROOT_PATH"voice/b-h-51.mp3", "422b4550253780343b7a9805ca7b629a"}, + {VOICE_RES, "0", "v5011", DEF_SKINS_ROOT_PATH"voice/a-a-01.mp3", "5d9d186ef50b603ab84a9abbfd348630"}, + {VOICE_RES, "0", "v5012", DEF_SKINS_ROOT_PATH"voice/a-a-02.mp3", "837a2222c961824e98c0d3751a234ae6"}, + {VOICE_RES, "0", "v5013", DEF_SKINS_ROOT_PATH"voice/a-a-03.mp3", "0ec34a1f19ee7cea6b139d214e59026d"}, + {VOICE_RES, "0", "v502", DEF_SKINS_ROOT_PATH"voice/a-n-01.mp3", "b1eb13ed8c9afaa2989763c3d379b39a"}, + {VOICE_RES, "0", "v601", DEF_SKINS_ROOT_PATH"voice/b-m-1.mp3", "820cf2c01e03726b95bc4346a2ce8f8b"}, + {VOICE_RES, "0", "v602", DEF_SKINS_ROOT_PATH"voice/b-m-2.mp3", "35a48b8ec586acfb99a612b4fc1ba57a"}, + {VOICE_RES, "0", "v701", DEF_SKINS_ROOT_PATH"voice/B-b-1.mp3", "993810d9cdcdc7ea02c5a069c9a66623"}, + {VOICE_RES, "0", "v702", DEF_SKINS_ROOT_PATH"voice/B-b-2.mp3", "2748a62323e3e004cdc54da7f50b2315"}, + {VOICE_RES, "0", "v703", DEF_SKINS_ROOT_PATH"voice/B-b-3.mp3", "5be4e22fb53180719b5385863a50a7ae"}, + {VOICE_RES, "0", "v801", DEF_SKINS_ROOT_PATH"voice/C-yc-1.mp3", "ea4268b86e2527f79a0f239944645cc9"}, + {VOICE_RES, "0", "v901", DEF_SKINS_ROOT_PATH"voice/IoT-01.mp3", "22a19c8fc7b0a07701d256dde5eb510d"}, + {VOICE_RES, "0", "v902", DEF_SKINS_ROOT_PATH"voice/IoT-02.mp3", "d1187715117c33ffd48788e53cefc5bf"}, + {VOICE_RES, "0", "v903", DEF_SKINS_ROOT_PATH"voice/IoT-03.mp3", "39d829772814e1bd36b3d68863dbb651"}, + {VOICE_RES, "0", "v904", DEF_SKINS_ROOT_PATH"voice/IoT-04.mp3", "3315787b7c9ce5ea3e9e77a4b27f7358"}, + {VOICE_RES, "0", "v905", DEF_SKINS_ROOT_PATH"voice/IoT-05.mp3", "f4e8806c84c532bad54a25a81f983887"}, + {VOICE_RES, "0", "v906", DEF_SKINS_ROOT_PATH"voice/IoT-06.mp3", "a214a9af112c9581353ebfa171f4132e"}, + {VOICE_RES, "0", "v907", DEF_SKINS_ROOT_PATH"voice/IoT-07.mp3", "50b80fb9b4fc1afd96c0118382a25282"}, + {VOICE_RES, "0", "v908", DEF_SKINS_ROOT_PATH"voice/IoT-08.mp3", "ea911086bfe0603256ef4b7b6ab731e2"}, + {VOICE_RES, "0", "v909", DEF_SKINS_ROOT_PATH"voice/IoT-09.mp3", "32461a940f695d80623a05c871a0dcda"}, + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// picture resources + /////////////////////////////////////////////////////////////////////////////////////////////////////////// + {IMAGE_RES, "0", "p001", DEF_SKINS_ROOT_PATH"image/IconChaozuo001.jpg", "0d4aa6351cc71daf2c699e42c1b74cde"}, + {IMAGE_RES, "0", "p005", DEF_SKINS_ROOT_PATH"image/IconChaozuo005.jpg", "1ceca68b9e7d49c537376a08c07a2b88"}, + {IMAGE_RES, "0", "p101", DEF_SKINS_ROOT_PATH"image/IconLianjie001.jpg", "236dbc343bd1d0c5e651f33900a13c07"}, + {IMAGE_RES, "0", "p102", DEF_SKINS_ROOT_PATH"image/IconLianjie002.jpg", "c627364aec00131589fc942c902c65bc"}, + {IMAGE_RES, "0", "p103", DEF_SKINS_ROOT_PATH"image/IconLianjie003.jpg", "edb04af03cf7c7e4d29aee43c332235b"}, + {IMAGE_RES, "0", "p201", DEF_SKINS_ROOT_PATH"image/IconNaozhong001.jpg", "bd5e7a00b4902ca971684d6ee021fb06"}, + {IMAGE_RES, "0", "p302", DEF_SKINS_ROOT_PATH"image/Iconstart002.gif", "90f2b52b1399348debcec2f447dbd383"}, + {IMAGE_RES, "0", "p401", DEF_SKINS_ROOT_PATH"image/IconTixing001.jpg", "feff2fbedffc955b491e0349385ef6c3"}, + {IMAGE_RES, "0", "p500", DEF_SKINS_ROOT_PATH"image/Iconyinliang000.jpg", "a0c29ad20d51cf86e808c83ee90b6510"}, + {IMAGE_RES, "0", "p501", DEF_SKINS_ROOT_PATH"image/Iconyinliang001.jpg", "196ba4082358d3238d0dcb0035764465"}, + {IMAGE_RES, "0", "p502", DEF_SKINS_ROOT_PATH"image/Iconyinliang002.jpg", "196ba4082358d3238d0dcb0035764465"}, + {IMAGE_RES, "0", "p503", DEF_SKINS_ROOT_PATH"image/Iconyinliang003.jpg", "196ba4082358d3238d0dcb0035764465"}, + {IMAGE_RES, "0", "p504", DEF_SKINS_ROOT_PATH"image/Iconyinliang004.jpg", "d3157ec3c194e4cc6dbcbe683fd40d3f"}, + {IMAGE_RES, "0", "p505", DEF_SKINS_ROOT_PATH"image/Iconyinliang005.jpg", "3f857b11062aeddaa6061e7cabfde044"}, + {IMAGE_RES, "0", "p506", DEF_SKINS_ROOT_PATH"image/Iconyinliang006.jpg", "3f857b11062aeddaa6061e7cabfde044"}, + {IMAGE_RES, "0", "p507", DEF_SKINS_ROOT_PATH"image/Iconyinliang007.jpg", "64a461ee34bea341879aa5a08c717705"}, + {IMAGE_RES, "0", "p508", DEF_SKINS_ROOT_PATH"image/Iconyinliang008.jpg", "b932b0b1c7766c6a995ce3e63b2b7422"}, + {IMAGE_RES, "0", "p509", DEF_SKINS_ROOT_PATH"image/Iconyinliang009.jpg", "dce1278710e1831f02d8dd4fd5d0aac6"}, + {IMAGE_RES, "0", "p510", DEF_SKINS_ROOT_PATH"image/Iconyinliang010.jpg", "b9ac1d7469b34d2aabe04d849c4f1112"}, + {IMAGE_RES, "0", "p511", DEF_SKINS_ROOT_PATH"image/Iconyinliang011.jpg", "45e001edc7d973b15434334ad7f77771"}, + {IMAGE_RES, "0", "p512", DEF_SKINS_ROOT_PATH"image/Iconyinliang012.jpg", "c9c22063c381e5cb775c82b105dce0f1"}, + {IMAGE_RES, "0", "p513", DEF_SKINS_ROOT_PATH"image/Iconyinliang013.jpg", "6e06e51e83498185d148070c0643852c"}, + {IMAGE_RES, "0", "p514", DEF_SKINS_ROOT_PATH"image/Iconyinliang014.jpg", "6e06e51e83498185d148070c0643852c"}, + {IMAGE_RES, "0", "p515", DEF_SKINS_ROOT_PATH"image/Iconyinliang015.jpg", "694a1698c16539805ed4ee238f36586c"}, + {IMAGE_RES, "0", "p516", DEF_SKINS_ROOT_PATH"image/Iconyinliang016.jpg", "0e7e847191e429618c6684ae89d30ac6"}, + {IMAGE_RES, "0", "p517", DEF_SKINS_ROOT_PATH"image/Iconyinliang017.jpg", "a18f5107ada535d664b2483b02080e70"}, + {IMAGE_RES, "0", "p518", DEF_SKINS_ROOT_PATH"image/Iconyinliang018.jpg", "d64992577a379c0faed0078dde767fcc"}, + {IMAGE_RES, "0", "p519", DEF_SKINS_ROOT_PATH"image/Iconyinliang019.jpg", "58268a96482df75c97a177371d295bd3"}, + {IMAGE_RES, "0", "p520", DEF_SKINS_ROOT_PATH"image/Iconyinliang020.jpg", "81ffbdc7857790696e3a7e353bd86908"}, + {IMAGE_RES, "0", "p601", DEF_SKINS_ROOT_PATH"image/Iconlianwang001.gif", "9e18565313b6b1769b7c5979a248dbd6"}, + {IMAGE_RES, "0", "p605", DEF_SKINS_ROOT_PATH"image/Iconlianwang005.gif", "ee81f49fe49864d4cbc4f7f9a1ec52c0"}, + {IMAGE_RES, "0", "p703", DEF_SKINS_ROOT_PATH"image/IconZhuangtai003.gif","e2bdf79f8c2825c23ffbb0233328df97"}, + + + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// + /// tts resources + /////////////////////////////////////////////////////////////////////////////////////////////////////////////// +#if 0 + {{TEXT_RES, 0, "wifiparing_apparingandconnecting", ""}, "", TEXT_WIFIPARING_APPARINGANDCONNECTING, ""}, + {{TEXT_RES, 0, "bt_wifiparing", ""}, "", TEXT_BT_WIFIPARING, ""}, + {{TEXT_RES, 0, "ap_wifiparing", ""}, "", TEXT_AP_WIFIPARING, ""}, + {{TEXT_RES, 0, "wificonnected", ""}, "", TEXT_WIFICONNECTED, ""}, + {{TEXT_RES, 0, "systemboot", ""}, "", TEXT_SYSTEMBOOT, ""}, + {{TEXT_RES, 0, "notrecvingwificonfig", ""}, "", TEXT_NOTRECVINGWIFICONFIG, ""}, + {{TEXT_RES, 0, "ble_suuccess_wait_config", ""}, "", TEXT_BLE_SUUCCESS_WAIT_CONFIG, ""}, + {{TEXT_RES, 0, "ap_wait_config", ""}, "", TEXT_AP_WAIT_CONFIG, ""}, + {{TEXT_RES, 0, "wifinotconnect", ""}, "", TEXT_WIFINOTCONNECT, ""}, + {{TEXT_RES, 0, "reqserver_error", ""}, "", TEXT_REQSERVER_ERROR, ""}, + {{TEXT_RES, 0, "ble_connect", ""}, "", TEXT_BLE_CONNECT, ""}, + {{TEXT_RES, 0, "ble_disconnect", ""}, "", TEXT_BLE_DISCONNECT, ""}, + {{TEXT_RES, 0, "wifiparingsuccess", ""}, "", TEXT_WIFIPARINGSUCCESS, ""}, + {{TEXT_RES, 0, "bt_on", ""}, "", TEXT_BT_ON, ""}, + {{TEXT_RES, 0, "bt_off", ""}, "", TEXT_BT_OFF, ""}, + {{TEXT_RES, 0, "alarm_remove_all", ""}, "", TEXT_ALARM_REMOVE_ALL, ""}, + {{TEXT_RES, 0, "alarm_remove", ""}, "", TEXT_ALARM_REMOVE, ""}, + {{TEXT_RES, 0, "alarm_add", ""}, "", TEXT_ALARM_ADD, ""}, + {{TEXT_RES, 0, "ap_app_connected", ""}, "", TEXT_AP_APP_CONNECTED, ""}, + {{TEXT_RES, 0, "wificonnect_err_reparing", ""}, "", TEXT_WIFICONNECT_ERR_REPARING, ""}, + {{TEXT_RES, 0, "wificonnect_err_pass", ""}, "", TEXT_WIFICONNECT_ERR_PASS, ""}, + {{TEXT_RES, 0, "wifiparing_err_serverconnect", ""}, "", TEXT_WIFIPARING_ERR_SERVERCONNECT, ""}, + {{TEXT_RES, 0, "not_unsupport", ""}, "", TEXT_NOT_UNSUPPORT, ""}, + {{TEXT_RES, 0, "boot_done", ""}, "", TEXT_BOOT_DONE, ""}, + {{TEXT_RES, 0, "wifiparing_first_notice", ""}, "", TEXT_WIFIPARING_FIRST_NOTICE, ""}, +#endif +}; + +static const SKIN_RES_INFO g_emuUpgradeInfo[] = { + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"android.txt", "8dc557037b69c69efd5615cdfc06934a"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"applying-patches.txt", "8d65812b01d64c9df1529509083e189d"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"atomic_ops.txt", "0d6a66d951ed4747aeee1aa7ab99d8d3"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"bad_memory.txt", "e81b536c2095eb53f9209e26b914f426"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"basic_profiling.txt", "1c70596bd41eb49077af5e91e16d2967"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"binfmt_misc.txt", "8936b928d685bdf98f83f1b3e86562a4"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"braille-console.txt", "4263bbce1595bdb3923bcb7885f866f5"}, + {VOICE_RES, "1", "v001", EMU_HTTP_URL_ROOT"bt8xxgpio.txt", "3a61d033e71cff3c75c778dad89ac565"}, + {VOICE_RES, "1", "v105", EMU_HTTP_URL_ROOT"btmrvl.txt", "f5ce90fb4a0ef97d23914fef37fba39d"}, + {VOICE_RES, "1", "v105", EMU_HTTP_URL_ROOT"bus-virt-phys-mapping.txt", "23fedac31d1b6ee5dae644ed86cc2c37"}, + {VOICE_RES, "1", "v105", EMU_HTTP_URL_ROOT"cachetlb.txt", "5db6b816869d89822759bca684024430"}, + {VOICE_RES, "1", "v105", EMU_HTTP_URL_ROOT"circular-buffers.txt", "3be2b7f00c13b160d5dba390b2ee8a54"}, + {VOICE_RES, "1", "v105", EMU_HTTP_URL_ROOT"clk.txt", "e60704c45037f922a73f49fc827b5225"}, + {VOICE_RES, "1", "v206", EMU_HTTP_URL_ROOT"coccinelle.txt", "379a83726bbf8f2ffbb12ba454788909"}, + {VOICE_RES, "1", "v206", EMU_HTTP_URL_ROOT"cpu-hotplug.txt", "e3676063c62c556a94ebf3b9296db82f"}, + {VOICE_RES, "1", "v206", EMU_HTTP_URL_ROOT"cpu-load.txt", "d9d096434110f5c017ab27ea397cee1d"}, + {VOICE_RES, "1", "v206", EMU_HTTP_URL_ROOT"cputopology.txt", "4ead2141d532dfaf1057cd2964ced3f4"}, + {VOICE_RES, "1", "v206", EMU_HTTP_URL_ROOT"crc32.txt", "644ff3d58c8ab6ca0c5c721dc78e7343"}, + {VOICE_RES, "1", "v206", EMU_HTTP_URL_ROOT"dcdbas.txt", "ad88b9a2d9b547a81ec3f28006a897bc"}, + {VOICE_RES, "1", "v309", EMU_HTTP_URL_ROOT"debugging-modules.txt", "c3b0d7040e83f85b5593dac628b3ffa5"}, + {VOICE_RES, "1", "v309", EMU_HTTP_URL_ROOT"debugging-via-ohci1394.txt", "a58d95e96be1ca24c5946c6636c4e041"}, + {VOICE_RES, "1", "v309", EMU_HTTP_URL_ROOT"dell_rbu.txt", "d5324f7ddcfbf19eb00e4c81bbb5cb7f"}, + {VOICE_RES, "1", "v309", EMU_HTTP_URL_ROOT"devices.txt", "8aa73c9268a9012eecbbb78fc4e4cc68"}, + {VOICE_RES, "1", "v309", EMU_HTTP_URL_ROOT"digsig.txt", "44b680ee0b743d63f9d0d2849e39d982"}, + {VOICE_RES, "1", "v309", EMU_HTTP_URL_ROOT"DMA-API-HOWTO.txt", "3225970a70a6a79c5112ff29b8f99ec6"}, + {VOICE_RES, "1", "v310", EMU_HTTP_URL_ROOT"DMA-API.txt", "3110d6930bd1c4c692c741f960310810"}, + {VOICE_RES, "1", "v310", EMU_HTTP_URL_ROOT"DMA-attributes.txt", "1ccc7f613bde5312a6a7452e8381d518"}, + {VOICE_RES, "1", "v311", EMU_HTTP_URL_ROOT"dma-buf-sharing.txt", "303f87732efc9effee0d6ed16e89ee37"}, + {VOICE_RES, "1", "v303", EMU_HTTP_URL_ROOT"dmaengine.txt", "80881dc6b0c7c9761be617a8f2e5eee3"}, + {VOICE_RES, "1", "v303", EMU_HTTP_URL_ROOT"DMA-ISA-LPC.txt", "a0b20e82cadca3595c95a9b7909a2120"}, + {VOICE_RES, "1", "v303", EMU_HTTP_URL_ROOT"dynamic-debug-howto.txt", "d15ef07d9fae98de0e096897da1e06ab"}, + {VOICE_RES, "1", "v303", EMU_HTTP_URL_ROOT"edac.txt", "a83b6d68f9e4c2d03ac619f912c13eb9"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"eisa.txt", "cae33ca2a108401d9465a0589503b845"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"email-clients.txt", "a1e6b9470ea752cf97a99ebcb9594aa0"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"feature-removal-schedule.txt", "e45405d2fac3a3bf87b26b3faeaad5de"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"flexible-arrays.txt", "03bfe3a8cb65aecdc96f710a140b8c27"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"futex-requeue-pi.txt", "684984d4f7026c76533ad7f247136ef4"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"gcov.txt", "fb711ca5323092e285f2e0b59a574009"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"gpio.txt", "13417a2589abd22672e8c109e5c57e8e"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"highuid.txt", "1c3e14d700b302d76b1bca29325a4a8e"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"hw_random.txt", "6c78af2ee2fab6ae30aca725c3970da1"}, + {VOICE_RES, "1", "v202", EMU_HTTP_URL_ROOT"hwspinlock.txt", "2ac1e75e3ee30099527e344287340b0a"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"initrd.txt", "c889974503df36fc073c891e6d9b8b0a"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"init.txt", "bdbcc42bf6ae739157092a7fa64aaaac"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"Intel-IOMMU.txt", "e693ef88d3d7d42c7a65a23f3975aa97"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"intel_txt.txt", "9dd22fd4de8b9e718fefc96c15b994c8"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"io-mapping.txt", "a7785b478117c65839749521fc020dc3"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"io_ordering.txt", "f7a404c9794d133f9167ff1a7e2953bb"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"iostats.txt", "4248f808a42956c73b79032686ae77bb"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"IPMI.txt", "8b8bc6bf4528e8d82017113c17d58a37"}, + {VOICE_RES, "1", "v111", EMU_HTTP_URL_ROOT"IRQ-affinity.txt", "d89c8d406a2618cc19db636ba81ce4ca"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"IRQ-domain.txt", "ec9bde5aa997211d7ded9658cfde4fff"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"irqflags-tracing.txt", "b8ca946951177d2cb8099feb9c4587e2"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"IRQ.txt", "0ef9f8f98b9eac9336c0ffb95cfc1d65"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"isapnp.txt", "ab111f0d42d1e748d9745c09e7ff935b"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"java.txt", "fbe28a3d11651fd214ad1d897700fd4f"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kernel-doc-nano-HOWTO.txt", "28579d296e40e460678d0587991e9d48"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kernel-docs.txt", "afc6fd5cdcc8b49ba794bcf5382ff2c3"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kernel-parameters.txt", "2dc9abd6790fd24c3e841f15d0d24a38"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kmemcheck.txt", "b301c758aed537468e98183bd04dc15d"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kmemleak.txt", "b5108533723c0a616e8723e009244d55"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kobject.txt", "d47cf170cd9ce2aaca082fa322b3c271"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kprobes.txt", "7a4c60ba6c646746ca64a311b24a7919"}, + {VOICE_RES, "1", "v110", EMU_HTTP_URL_ROOT"kref.txt", "e6ee109e7185aafc4efe67cad2576352"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"ldm.txt", "3492835c4e3f2340ef0a0d5af464b962"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"local_ops.txt", "809dba9261b3704813557cccaeb3d83d"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"lockdep-design.txt", "b5379d04c39758d7f979d8c6c459285b"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"lockstat.txt", "c672433097ed3823b84bea98cafbb921"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"lockup-watchdogs.txt", "36c72be9bf511bd0e76975f7987f97a2"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"logo.txt", "c12e6a02a126220ed420586143f96d7e"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"magic-number.txt", "2baed34f647a4dab43357718050ded53"}, + {VOICE_RES, "1", "v201", EMU_HTTP_URL_ROOT"mca.txt", "1ea3eab396d5433f30952ad1b30ab133"}, + {VOICE_RES, "1", "v304", EMU_HTTP_URL_ROOT"md.txt", "6cdd602644e47836f0cb357e910a4db7"}, + {VOICE_RES, "1", "v304", EMU_HTTP_URL_ROOT"media-framework.txt", "1f3f9ba9afc6c1323df2c03160b4db4d"}, + {VOICE_RES, "1", "v304", EMU_HTTP_URL_ROOT"memory-barriers.txt", "1b2369bd78d18c2f80c23ca3ab2fb8d8"}, + {VOICE_RES, "1", "v304", EMU_HTTP_URL_ROOT"memory-hotplug.txt", "e9bc23bc43814ef7fbe2bcd89692c55b"}, + {VOICE_RES, "1", "v304", EMU_HTTP_URL_ROOT"memory.txt", "c17ccb89201a46532f3b95fee4adc372"}, + {VOICE_RES, "1", "v304", EMU_HTTP_URL_ROOT"mono.txt", "da6d7823007522089fc4bfefc1752b16"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"mutex-design.txt", "278a8bef9b14c136939715738cc0f0e8"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"nommu-mmap.txt", "9f4e01823e63aec8b42bf523389664fc"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"numastat.txt", "bebd74fc4713e1500702be1a90113f74"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"oops-tracing.txt", "87f1184ede24989279c9a1dfa1ccfae1"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"padata.txt", "bd3486df46e488dd75d1e67b2bb52da9"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"parport-lowlevel.txt", "a7d58201239229037269d4fd7ba720ac"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"parport.txt", "fa8d7291a3e7d5c2afe5a2060a0abb50"}, + {VOICE_RES, "1", "v108", EMU_HTTP_URL_ROOT"pi-futex.txt", "492ac92f69716bfaa0c40a909c992ade"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"pinctrl.txt", "9b7c710bba0b9aaae7e4f3794a548511"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"pnp.txt", "a7338b790fd6b30b4071fcacbfcedc4e"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"preempt-locking.txt", "5b7ed3fd44bb218e897492667b316a56"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"printk-formats.txt", "8eaefbea3500e15cc155045b3d3ef39c"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"prio_tree.txt", "1b079f5eac72227ecee86a7693ae8f69"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"ramoops.txt", "b50016891d7184720439346f362083e3"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"rbtree.txt", "a35e53c01ecfe9fbc534425504b8f408"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"remoteproc.txt", "d9599a6eda47e17ade41491b1106db22"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"rfkill.txt", "d86dc1dc7f27a25692b40cb739a88a09"}, + {VOICE_RES, "1", "v107", EMU_HTTP_URL_ROOT"robust-futex-ABI.txt", "32be0a8a71053b3258c8dc13c8e3f981"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"robust-futexes.txt", "1ac8f369bc00680aa40e8dfd3bc766c3"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"rpmsg.txt", "67b8fcf7e064b15d910e6ef41b944984"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"rtc.txt", "51577c35a6c713e85bc4325dde78f1f9"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"rt-mutex-design.txt", "25703f95e001b8ab0a92ec7e22f85527"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"rt-mutex.txt", "b449bdf78dad3a5ff62eb7a0853c0c99"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"SAK.txt", "bb81ce113927582c1513704f360129fd"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"serial-console.txt", "814e90de90e893f56eb12cc536dc7d42"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"sgi-ioc4.txt", "f4e0584fa5b55907435c3374c6ae6601"}, + {VOICE_RES, "1", "v333", EMU_HTTP_URL_ROOT"sgi-visws.txt", "0bb26ebbfc96a898f54126d5762cd3de"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"SM501.txt", "58ce960675582f8414019f33a27e1260"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"sparse.txt", "8bc3d0ada8ca01475d69431cd9cd4ec0"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"spinlocks.txt", "d903caeac016182fd7bb349af658bb1a"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"stable_api_nonsense.txt", "ca2acd6fd94048b5b03b213922d962b5"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"stable_kernel_rules.txt", "3948439142160832a55510a93746b738"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"static-keys.txt", "6d801dd48021a20394a7eaa82f0b758d"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"svga.txt", "ffc4306708801c3489dc575998ecca43"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"sync.txt", "381c9f8905dfc34f66eef3e3e486f0d1"}, + {VOICE_RES, "1", "v203", EMU_HTTP_URL_ROOT"sysfs-rules.txt", "84cfa60b3ba436be5acd54034bc15c84"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"sysrq.txt", "f24e71d4fed0257178078b820927791b"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"unaligned-memory-access.txt", "a5a387aeec918a0f528f85bcb76bc8c5"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"unicode.txt", "fd815b4b43d0cf5a85ca44d0db76dde7"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"unshare.txt", "a3ca54a1d655c512654510e56b4c8e53"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"vgaarbiter.txt", "802d04a400dfb5959711fe8088c62f01"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"VGA-softcursor.txt", "88c93a1b83277f3fc3fb07de148fd726"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"video-output.txt", "60ab68e5be73008948e8f1426db0941b"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"volatile-considered-harmful.txt", "8983aa37ffb5d56400e7f54ca9aa88d6"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"workqueue.txt", "6fadee709d10fbbdc4ed587020dbb9b7"}, + {VOICE_RES, "1", "v204", EMU_HTTP_URL_ROOT"xz.txt", "4c3cdd3cc9795936719f90c5998e444d"}, + {VOICE_RES, "1", "v904", EMU_HTTP_URL_ROOT"zorro.txt", "5afccd5699a870edbaeeb4842171e637"} +}; +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/include/smart_sound.h b/app/libuvdbus/src/include/smart_sound.h new file mode 100644 index 0000000..8a17142 --- /dev/null +++ b/app/libuvdbus/src/include/smart_sound.h @@ -0,0 +1,528 @@ +#ifndef SMART_SOUND_H +#define SMART_SOUND_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define CMD_BT_AVK_OPEN CMD_BT_BREDR_ENABLE +#define CMD_BT_AVK_CLOSE CMD_BT_BREDR_DISABLE + +//***************************************************************** +//* Global Configure +//***************************************************************** +#define USED_SHM_TO_DBUS (0) // used shm for dbus transfer data +#ifndef MAX_PATH +#define MAX_PATH (256) +#endif + +//************************************************************* + +typedef enum { + MODULE_CONTROLLER = 0, + MODULE_ALARM, + MODULE_CALL, + MODULE_VOICEENGINE, + MODULE_PLAYER, + MODULE_CONFIGURE, + MODULE_OTA, + MODULE_WIFI, + MODULE_BT, + MODULE_KPLAYER, + MODULE_KPLAYER_TEST, + MODULE_SPLAYER, + MODULE_SPLAYER_TEST, + MODULE_LIGHT_MCU, + MODULE_BLUEKC, + MODULE_BLUEKC_TEST, + MODULE_MANUFACTURE, + MODULE_BT_DEMO, + MODULE_SKINS, + MODULE_LOG_CTRL, + MODULE_WIRELESSTEST, + MODULE_WIRELESSTEST_DEMO, + MODULE_MANUFACTURE_CONTROLLER, + MODULE_WIFI_DEMO, + MODULE_MAX, +} MODULE_NAME; + +typedef enum { + CMD_MISC_PING = 0x0000, + CMD_MISC_OTA, + CMD_MISC_WEATHER, + CMD_MISC_NOWTIME, + CMD_MISC_UPGRADE, + CMD_SYSTEM_STANDBY, + CMD_MISC_QUERY_OTA_STATUS, + CMD_MISC_QUERY_DL_STATUS, + CMD_MISC_CHANGE2TEST, + CMD_MISC_CHANGE2ONLINE, + + CMD_SEARCH_PLAYER_REQ, + CMD_SEARCH_PLAYER_RESP, + + CMD_PROCESS_START, + + CMD_CALL_DIAL = 0x0300, + CMD_CALL_ACCEPI, + CMD_CALL_HANGUP, + CMD_CALL_MESSAGE, + + CMD_PLAY_MODECHANGE = 0x0600, + CMD_PLAY_PLAY, + CMD_PLAY_PAUSE, + CMD_PLAY_STOP, + CMD_PLAY_SEEKTO, + CMD_PLAY_SHOWMODE, + CMD_PLAY_NEXT, + CMD_PLAY_PRE, + CMD_PLAY_SEEKTO_PLAY, + CMD_PLAY_SHOWLIST, + CMD_PLAY_UPDATELIST, + CMD_PLAY_PREPARE_NEXT, + CMD_PLAY_ADDTOLIST, + CMD_PLAY_DELETEFROMLIST, + CMD_PLAY_RESETLIST, + CMD_PLAY_VOL_SET, + CMD_PLAY_VOL_RESTORE, + CMD_PLAY_MAX, + + CMD_PLAY_AUDIO_STOP = 0x0700, + CMD_PLAY_AUDIO_PLAY, + CMD_PLAY_AUDIO_MAX, + + CMD_SE_PLAY = 0x0780, + CMD_SE_PLAYER_STATE_NTF, + + CMD_MUSIC_PCM_PLAY = 0X0790, + CMD_MUSIC_PCM_PAUSE = 0X0791, + CMD_MUSIC_PCM_STOP = 0X0792, + CMD_MUSIC_PCM_MAX, + + CMD_PLAYER_MAX = 0X07FF, + + CMD_PLAY_RET_STATUS = 0x0800, + + CMD_CFG_ADD_REQ = 0x0900, + CMD_CFG_ADD_RSP, + CMD_CFG_CHANGE_REQ, + CMD_CFG_CHANGE_RSP, + CMD_CFG_GET_REQ, + CMD_CFG_GET_RSP, + CMD_CFG_UPG_NOTIFY, + + CMD_MSC_MSG_CONTROLLER_RECOG_SUCCESS = 0x0a00, + CMD_MSC_MSG_CONTROLLER_RECOG_ERROR, + CMD_MSC_MSG_CONTROLLER_WAKEUP, + CMD_MSC_MSG_CONTROLLER_SESSION_BEGIN, + CMD_MSC_MSG_CONTROLLER_RECOGING, + CMD_CC_MSC_BEGIN_SESSION, + CMD_CC_MSC_END_SESSION, + CMD_CONTROLLER_REQMSG_INITARGS, + CMD_CONTROLLER_RSPMSG_INITARGS, + CMD_CONTROLLER_REQMSG_PLAYERSTATUS, + CMD_CONTROLLER_RSPMSG_PLAYERSTATUS, + CMD_MSC_REQMSG_MIC_CONTROL, + CMD_MSC_RSPMSG_MIC_CONTROL, + CMD_NDUILITE_FESPA_SET_ARG, + CMD_NDUILITE_SDK_REINIT, + CMD_YUNXIN_RECVMSG, + CMD_YUNXIN_SENDMSG, + CMD_YUNXIN_SENDMSG_BYPASS, + CMD_YUNXIN_SENDMSGCB, + CMD_CONTROLLER_MSG_YUNXIN, + CMD_YUNXIN_STATUS, + CMD_YUNXIN_SYSMSG, + + CMD_WIFI_CONF = 0x0b00, + CMD_WIFI_CONF_RESP, + CMD_WIFI_AUTO_CONN, + CMD_WIFI_AUTO_CONN_RESP, + CMD_WIFI_AUTO_CONN_OUT, + CMD_WIFI_STATE_REQ, + CMD_WIFI_STATE_RESP, + CMD_WIFI_STATE_NTF, + CMD_WIFI_CHANGE_VALID_AP, + CMD_WIFI_CHANGE_VALID_AP_OUT, + CMD_WIFI_CHANGE_VALID_AP_RESP, + + CMD_WIFI_BL_CMD_START, + CMD_WIFI_BL_CONF, + CMD_WIFI_BL_CONF_ABORT, + CMD_WIFI_BL_DEV_INFO_NTF, + CMD_WIFI_BL_CLOUD_CHALLENGE_SIGNATURE, + CMD_WIFI_BL_DEV_SIGNATURE, + CMD_WIFI_BL_CLOUD_SHAREDKEY, + CMD_WIFI_BL_DEV_TOKEN, + CMD_WIFI_BL_DEV_TOKEN_BOUND, + CMD_WIFI_BL_CONF_FAILED, + CMD_WIFI_BL_CMD_END, + + CMD_BT_NAME_GET_REQ, + CMD_BT_NAME_GET_RESP, + CMD_BT_EVT_NTF, + CMD_BT_CREATED, + + CMD_BT_RESET, + CMD_BT_BREDR_ENABLE, // 0xb10 + CMD_BT_BREDR_DISABLE, // 0xb11 + + CMD_BT_AVK_SOUND_OPEN, + CMD_BT_AVK_SOUND_CLOSE, + + CMD_BT_AVK_CON_EVT, + CMD_BT_AVK_DISC_EVT, + + CMD_BT_AVK_CON_DEV, + CMD_BT_AVK_DISC_DEV, + CMD_BT_AVK_PLAY, + CMD_BT_AVK_PAUSE, + CMD_BT_AVK_STOP, + CMD_BT_AVK_PRE, + CMD_BT_AVK_NEXT, + CMD_BT_AVK_VOL_UP, + CMD_BT_AVK_VOL_DOWN, + + CMD_BT_AVK_SOUND_START_EVT, // 0xb1f + CMD_BT_AVK_SOUND_STOP_EVT, // 0xb20 + + CMD_BT_LE_ENABLE, // 0xb21 + CMD_BT_LE_DISABLE, + CMD_BT_LE_NEVSPS_DISC, + + CMD_BT_AVK_CRTED, + CMD_BT_AVK_DELETED, + + CMD_BT_AVK_RC_PLAY, + CMD_BT_AVK_RC_PAUSE, + + CMD_WIFI_UNBIND_ACCOUNT, + CMD_BT_VOL_CHANGE, + + CMD_BT_BREDR_REBOOT_CLOSE, + CMD_BT_AVK_DEV_CON_CONFLICT, + CMD_WIFI_ON, + CMD_WIFI_OFF, + CMD_WIFI_ON_RESP, + CMD_WIFI_OFF_RESP, + + CMD_KPLAYER_START = 0x1b00, + CMD_KPLAYER_STOP, + CMD_KPLAYER_NOTIF_DUR, + CMD_KPLAYER_HOST_ACTION, + CMD_KPLAYER_CTR_NTF_BASE = 0x1c00, + CMD_KPLAYER_CTR_CREATED, + CMD_KPLAYER_CTR_DELED, + CMD_KPLAYER_CTR_PLAY, + CMD_KPLAYER_CTR_STOP, + CMD_KPLAYER_CTR_PAUSE, + CMD_KPLAYER_CTR_SEEK, + CMD_KPLAYER_CTR_SET_URL, + CMD_KPLAYER_CTR_SET_VOLUME, + CMD_KPLAYER_CTR_SET_MUTE, + CMD_KPLAYER_CTR_SET_NXT_URL, + CMD_KPLAYER_CTR_SET_NEXT, + CMD_KPLAYER_CTR_SET_PREV, + + CMD_SPLAYER_SFIFO_TEST = 0x1d00, + CMD_SPLAYER_START, + CMD_SPLAYER_STOP, + CMD_SPLAYER_HOST_ACTION, + + CMD_SPLAYER_CTR_NTF_BASE = 0x1e00, + CMD_SPLAYER_MSG_TYPE_CREATE, + CMD_SPLAYER_MSG_TYPE_DEL, + CMD_SPALYER_MSG_TYPE_START, + CMD_SPLAYER_MSG_TYPE_STOP, + CMD_SPLAYER_MSG_TYPE_SET_VOLUME, + CMD_SPLAYER_MSG_TYPE_STREAMING, + CMD_SPLAYER_MSG_TYPE_DESTRY, + CMD_SPLAYER_MSG_TYPE_DURATION, + CMD_SPLAYER_MSG_TYPE_STREAM_NTF, + CMD_SPLAYER_MSG_TYPE_STREAM_PLAYPAUSE, + + CMD_BLUEKC_POOL_TEST = 0x1f00, + CMD_BLUEKC_LOG_DEBUG, + CMD_BLUEKC_LOG_RESTORE, + + // 厂测 + CMD_TEST_GET_VER_REQ = 0X2000, + CMD_TEST_GET_VER_RESP, + CMD_TEST_GET_MCU_VER_REQ, + CMD_TEST_GET_MCU_VER_RESP, + CMD_TEST_KNOB_REQ, + CMD_TEST_KNOB_RESP, + CMD_TEST_BUTTON_REQ, + CMD_TEST_BUTTON_RESP, + CMD_TEST_GET_VOLUME_REQ, + CMD_TEST_GET_VOLUME_RESP, + CMD_TEST_SET_VOLUME_REQ, + CMD_TEST_SET_VOLUME_RESP, + CMD_TEST_BT_ADDR_REQ, + CMD_TEST_BT_ADDR_RESP, + CMD_TEST_BT_PARRING_REQ, + CMD_TEST_BT_PARRING_RESP, + CMD_TEST_GET_CPLD_REQ, + + // RF cmd---> + + CMD_TEST_RF_BASE = 0x2100, + CMD_TEST_RF_BT_ENTER, + CMD_TEST_RF_BT_ENTER_RESP, + CMD_TEST_RF_EXIT_TO_NORNAL, + CMD_TEST_RF_EXIT_TO_NORNAL_RESP, + + CMD_TEST_RF_BT_TX = 0x2200, + CMD_TEST_RF_BT_TX_RESP, + CMD_TEST_RF_BT_TX_2402_1DH1, + CMD_TEST_RF_BT_TX_2402_1DH1_RESP, + CMD_TEST_RF_BT_TX_2440_1DH1, + CMD_TEST_RF_BT_TX_2440_1DH1_RESP, + CMD_TEST_RF_BT_TX_2480_1DH1, + CMD_TEST_RF_BT_TX_2480_1DH1_RESP, + CMD_TEST_RF_BT_TX_2402_2DH3, + CMD_TEST_RF_BT_TX_2402_2DH3_RESP, + CMD_TEST_RF_BT_TX_2440_2DH3, + CMD_TEST_RF_BT_TX_2440_2DH3_RESP, + CMD_TEST_RF_BT_TX_2480_2DH3, + CMD_TEST_RF_BT_TX_2480_2DH3_RESP, + CMD_TEST_RF_BT_TX_2402_3DH5, + CMD_TEST_RF_BT_TX_2402_3DH5_RESP, + CMD_TEST_RF_BT_TX_2440_3DH5, + + CMD_TEST_RF_BT_TX_2440_3DH5_RESP, + CMD_TEST_RF_BT_TX_2480_3DH5, + CMD_TEST_RF_BT_TX_2480_3DH5_RESP, + + // varible extend---> + CMD_TEST_RF_BT_TX_VARIABLE = 0x22f0, + CMD_TEST_RF_BT_TX_VARIABLE_RESP, + //<----varible extend + + CMD_TEST_RF_BT_RX = 0x2300, + CMD_TEST_RF_BT_RX_RESP, + CMD_TEST_RF_BT_RX_2402_1DH1, + CMD_TEST_RF_BT_RX_2402_1DH1_RESP, + CMD_TEST_RF_BT_RX_2440_1DH1, + CMD_TEST_RF_BT_RX_2440_1DH1_RESP, + CMD_TEST_RF_BT_RX_2480_1DH1, + CMD_TEST_RF_BT_RX_2480_1DH1_RESP, + CMD_TEST_RF_BT_RX_2402_2DH3, + CMD_TEST_RF_BT_RX_2402_2DH3_RESP, + CMD_TEST_RF_BT_RX_2440_2DH3, + CMD_TEST_RF_BT_RX_2440_2DH3_RESP, + CMD_TEST_RF_BT_RX_2480_2DH3, + CMD_TEST_RF_BT_RX_2480_2DH3_RESP, + CMD_TEST_RF_BT_RX_2402_3DH5, + CMD_TEST_RF_BT_RX_2402_3DH5_RESP, + CMD_TEST_RF_BT_RX_2440_3DH5, + + CMD_TEST_RF_BT_RX_2440_3DH5_RESP, + CMD_TEST_RF_BT_RX_2480_3DH5, + CMD_TEST_RF_BT_RX_2480_3DH5_RESP, + + // varible extend---> + CMD_TEST_RF_BT_RX_VARIABLE = 0x23f0, + CMD_TEST_RF_BT_RX_VARIABLE_RESP, + //<----varible extend + + CMD_TEST_RF_BT_EXIT = 0x2400, + CMD_TEST_RF_BT_EXIT_RESP, + + CMD_TEST_RF_WIFI_ENTER = 0x2500, + CMD_TEST_RF_WIFI_ENTER_RESP, + + CMD_TEST_RF_WIFI_TX = 0x2600, + CMD_TEST_RF_WIFI_TX_RESP, + + CMD_TEST_RF_WIFI_TX_CHANNEL1, + CMD_TEST_RF_WIFI_TX_CHANNEL1_RESP, + CMD_TEST_RF_WIFI_TX_CHANNEL7, + CMD_TEST_RF_WIFI_TX_CHANNEL7_RESP, + CMD_TEST_RF_WIFI_TX_CHANNEL13, + CMD_TEST_RF_WIFI_TX_CHANNEL13_RESP, + + // varible extend---> + CMD_TEST_RF_WIFI_TX_VARIABLE = 0x26f0, + CMD_TEST_RF_WIFI_TX_VARIABLE_RESP, + //<----varible extend + + CMD_TEST_RF_WIFI_RX = 0x2700, + CMD_TEST_RF_WIFI_RX_RESP, + + CMD_TEST_RF_WIFI_RX_CHANNEL1, + CMD_TEST_RF_WIFI_RX_CHANNEL1_RESP, + CMD_TEST_RF_WIFI_RX_CHANNEL1_RET, + CMD_TEST_RF_WIFI_RX_CHANNEL1_RET_RESP, + CMD_TEST_RF_WIFI_RX_CHANNEL7, + CMD_TEST_RF_WIFI_RX_CHANNEL7_RESP, + CMD_TEST_RF_WIFI_RX_CHANNEL7_RET, + CMD_TEST_RF_WIFI_RX_CHANNEL7_RET_RESP, + CMD_TEST_RF_WIFI_RX_CHANNEL13, + CMD_TEST_RF_WIFI_RX_CHANNEL13_RESP, + CMD_TEST_RF_WIFI_RX_CHANNEL13_RET, + CMD_TEST_RF_WIFI_RX_CHANNEL13_RET_RESP, + + // varible extend---> + CMD_TEST_RF_WIFI_RX_VARIABLE = 0x27f0, + CMD_TEST_RF_WIFI_RX_VARIABLE_RESP, + //<----varible extend + + CMD_TEST_RF_WIFI_EXIT = 0x2800, + CMD_TEST_RF_WIFI_EXIT_RESP, + + CMD_TEST_MCU_LED_GUIDE = 0X2900, + CMD_TEST_MCU_LED_GUIDE_RSP, + CMD_TEST_MCU_LED_MATRIX, + CMD_TEST_MCU_LED_MATRIX_RSP, + //<-----RF cmd + + CMD_TEST_RELEASE_SYSTEM, + + CMD_ALARM_SYNC_REQ = 0xF000, + CMD_ALARM_SYNC_RSP, + CMD_ALARM_ADD, + CMD_ALARM_REMOVE, + CMD_ALARM_REMOVEALL, + + CMD_REMAIND_SYNC_REQ, + CMD_REMAIND_SYNC_RSP, + CMD_REMAIND_ADD, + CMD_REMAIND_REMOVE, + CMD_REMAIND_REMOVEALL, + + CMD_ASSISTANT_STATUS, + CMD_ASSISTANT_RUNNING, + CMD_ASSISTANT_NOTIFY, + + CMD_SESSION_ALARM_SYNC, + + CMD_WORKDAY_DB_REQ = 0xF100, + CMD_WORKDAY_DB_RSP, + + CMD_OTA_NOTIFY = 0xF200, + CMD_OTA_STATUS, + CMD_OTA_RUNNOW, + + CMD_LOG_CONFIG = 0xF300, + + CMD_DEMO_PERFORM_TEST = 0xff00, + +} DBUS_CMD; + +typedef enum { + ERR_INPUT_PARAMS = 1, + ERR_NO_ITEMS, + ERR_GET_BUS, + ERR_DBUS_CONNECTION, + ERR_REQUEST_BUS_NAME, + ERR_SET_WATCH_FUNCTION, + ERR_SET_TIMEOUT_FUNCTION, + ERR_BUS_MATCH, + ERR_BUS_SET_MSG_CB, + ERR_DBUS_CREATE_MSG, + ERR_BUS_SEND_MSG, + ERR_DBUS_MSG_TO_LARGE, + ERR_BUS_RCV_MSG, + ERR_ADD_TASK, + ERR_UNSUP_EVP_TYPE, + + ERR_CREATE_MQ, + ERR_MQ_SENDMSG, + ERR_CREATE_SHM, + ERR_MAP_SHM, + ERR_MALLOC_MEMORY, + + ERR_EVP_INIT_KEY, + ERR_EVP_UPDATE, + ERR_EVP_FINALE, + ERR_EVP_KEY_SIZE, + + ERR_OPEN_FILE, + ERR_READ_FILE, + ERR_WRITE_FILE, + ERR_COPY_FILE, + ERR_FILE_NOT_EXISTS, + ERR_GET_FILE_SIZE, + ERR_UNINIT_ITEM, + ERR_FILE_EMPTY, + + ERR_SEND_MAIL, + ERR_NETWORK_SEND, + ERR_NETWORK_NOT_CONNECTED, + + ERR_CREATE_SOCKET, + ERR_BIND_SOCKET, + + ERR_UNSUPPORT, +} DBUS_WITH_LIBUV_ERROR; + +/** + * 错误码 + */ +typedef enum { + ERR_NO_INIT_IPL3 = 2000, ///< (0xF101) 未初始化OTA参数 + ERR_BAD_IPL3, ///< OTA参数异常 + ERR_BAD_FILE_SIZE, ///< 文件大小不正确 + ERR_MD5_FILE, ///< 计算文件MD5校验和异常 + ERR_MD5_CHECK_SUM, ///< MD5校验和不正确 + ERR_OTA_WRITE_BOOT, ///< 写入BOOT分区异常 + ERR_OTA_WRITE_ROOTFS, ///< 写入ROOTFS分区异常 + ERR_OTA_WRITE_IPL3, ///< 写入IPL3分区异常 + ERR_OTA_WRITE_PARAMS, ///< 写入OTA参数异常 + ERR_OTA_DOWNLOAD_FILE, ///< 下载文件失败 + ERR_VERIFY_PARTITION_MD5, ///< 校验分区MD5异常 + ERR_OTA_PRE_STATR, ///< 先前已经启动了一个未完成的OTA任务 + ERR_OTA_YET_CUR_VER, ///< 当前版本已经更新 + ERR_OTA_NOT_READY, ///< OTA未准备好,暂时不能进行OTA升级 +} OTA_ERROR; + +typedef enum { + ERR_CREATE_CFG_FILE = 1000, + ERR_CREATE_SQLITE3_DB, + ERR_OPEN_SQLITE3_DB, + ERR_SQLITE3_CREATE_TABLE, + ERR_SYNC_DATABASE, + ERR_SQL_QUERY, + ERR_SQL_DELETE, + ERR_UNKNOWN_TYPE, + ERR_PERMISSION_DENIED, + ERR_CFG_NOITEM, + ERR_CFG_ITEM_EXIST, + ERR_CFG_WAIT_RSP, + ERR_CFG_BUSY, + ERR_STR_CONVERT, + ERR_SQL_REG_MODULE, +} CONFIG_MODE_ERRCODE; + +typedef enum { + REPEAT_MODE_NONE = 1, + REPEAT_MODE_EVERY_DAY = 2, + REPEAT_MODE_WORKDAY = 3, + REPEAT_MODE_WEEKEND = 4, + REPEAT_MODE_WEEKDAY = 5, + REPEAT_MODE_EVERY_MONTH_DAY = 6, + REPEAT_MODE_EVERY_YEAR_DAY = 7, + REPEAT_MODE_EVERY_TIME = 8, + REPEAT_MODE_MONTH_LAST_DAY = 9, + REPEAT_MODE_HOLIDAY = 10, +} REPEAT_MODE; + +#define MAX_CFG_KEY_NAME (256) +#define MAX_CFG_KEY_VALUE (1024) +#define DATA_TIME_STR_LEN (20) + +#define GET_FILE_SIZE(path, size) \ + do { \ + struct stat st; \ + memset(&st, 0, sizeof(struct stat)); \ + if (stat(path, &st) != 0) { \ + size = -1; \ + } else { \ + size = st.st_size; \ + } \ + } while (0) +#ifdef __cplusplus +} +#endif +#endif diff --git a/app/libuvdbus/src/log/hexdump.c b/app/libuvdbus/src/log/hexdump.c new file mode 100644 index 0000000..0217b34 --- /dev/null +++ b/app/libuvdbus/src/log/hexdump.c @@ -0,0 +1,326 @@ +#ifndef __KERNEL__ +#include +#include +#include +#include +#include + +#include "log.h" + +static const char hex_asc[] = "0123456789abcdef"; + +#define hex_asc_lo(x) hex_asc[((x) & 0x0f)] +#define hex_asc_hi(x) hex_asc[((x) & 0xf0) >> 4] + +char* IHW_bin2hex(char *p, const unsigned char *cp, int count) +{ + while (count) { + unsigned char c = *cp++; + /* put lowercase hex digits */ + *p++ = 0x20 | hex_asc[c >> 4]; + *p++ = 0x20 | hex_asc[c & 0xf]; + count--; + } + + return p; +} + +/** + * hex_to_bin - convert a hex digit to its real value + * @ch: ascii character represents hex digit + * + * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad + * input. + */ +int hex_to_bin(char ch) +{ + if((ch >= '0') && (ch <= '9')) + { + return ch - '0'; + } + + ch = tolower(ch); + + if((ch >= 'a') && (ch <= 'f')) + { + return ch - 'a' + 10; + } + + return -1; +} + +/** + * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory + * @buf: data blob to dump + * @len: number of bytes in the @buf + * @rowsize: number of bytes to print per line; must be 16 or 32 + * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) + * @linebuf: where to put the converted data + * @linebuflen: total size of @linebuf, including space for terminating NUL + * @ascii: include ASCII after the hex output + * + * hex_dump_to_buffer() works on one "line" of output at a time, i.e., + * 16 or 32 bytes of input data converted to hex + ASCII output. + * + * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data + * to a hex + ASCII dump at the supplied memory location. + * The converted output is always NUL-terminated. + * + * E.g.: + * hex_dump_to_buffer(frame->data, frame->len, 16, 1, + * linebuf, sizeof(linebuf), true); + * + * example output buffer: + * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO + */ +void hex_dump_to_buffer(const void* buf, int len, int rowsize, + int groupsize, char* linebuf, size_t linebuflen, + int ascii) +{ + const unsigned char* ptr = (const unsigned char *)buf; + unsigned char ch; + int j, lx = 0; + int ascii_column; + + if(rowsize != 16 && rowsize != 32) + { + rowsize = 16; + } + + if(!len) + { + goto nil; + } + + if(len > rowsize) /* limit to one line at a time */ + { + len = rowsize; + } + + if((len % groupsize) != 0) /* no mixed size output */ + { + groupsize = 1; + } + + switch(groupsize) + { + case 8: + { + const unsigned long long* ptr8 = (const unsigned long long *)buf; + int ngroups = len / groupsize; + + for(j = 0; j < ngroups; j++) + lx += snprintf(linebuf + lx, linebuflen - lx, + "%s%16.16llx", j ? " " : "", + (unsigned long long) * (ptr8 + j)); + + ascii_column = 17 * ngroups + 2; + break; + } + + case 4: + { + const unsigned int* ptr4 = (const unsigned int *)buf; + int ngroups = len / groupsize; + + for(j = 0; j < ngroups; j++) + lx += snprintf(linebuf + lx, linebuflen - lx, + "%s%8.8x", j ? " " : "", *(ptr4 + j)); + + ascii_column = 9 * ngroups + 2; + break; + } + + case 2: + { + const unsigned short* ptr2 = (const unsigned short *)buf; + int ngroups = len / groupsize; + + for(j = 0; j < ngroups; j++) + lx += snprintf(linebuf + lx, linebuflen - lx, + "%s%4.4x", j ? " " : "", *(ptr2 + j)); + + ascii_column = 5 * ngroups + 2; + break; + } + + default: + for(j = 0; (j < len) && (lx + 3) <= linebuflen; j++) + { + ch = ptr[j]; + linebuf[lx++] = hex_asc_hi(ch); + linebuf[lx++] = hex_asc_lo(ch); + linebuf[lx++] = ' '; + } + + if(j) + { + lx--; + } + + ascii_column = 3 * rowsize + 2; + break; + } + + if(!ascii) + { + goto nil; + } + + while(lx < (linebuflen - 1) && lx < (ascii_column - 1)) + { + linebuf[lx++] = ' '; + } + + for(j = 0; (j < len) && (lx + 2) < linebuflen; j++) + { + ch = ptr[j]; + linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.'; + } + +nil: + linebuf[lx++] = '\0'; +} + +/** + * print_hex_dump - print a text hex dump to syslog for a binary blob of data + * @level: kernel log level (e.g. KERN_DEBUG) + * @prefix_str: string to prefix each line with; + * caller supplies trailing spaces for alignment if desired + * @prefix_type: controls whether prefix of an offset, address, or none + * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) + * @rowsize: number of bytes to print per line; must be 16 or 32 + * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1) + * @buf: data blob to dump + * @len: number of bytes in the @buf + * @ascii: include ASCII after the hex output + * + * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump + * to the kernel log at the specified kernel log level, with an optional + * leading prefix. + * + * print_hex_dump() works on one "line" of output at a time, i.e., + * 16 or 32 bytes of input data converted to hex + ASCII output. + * print_hex_dump() iterates over the entire input @buf, breaking it into + * "line size" chunks to format and print. + * + * E.g.: + * print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS, + * 16, 1, frame->data, frame->len, true); + * + * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode: + * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f @ABCDEFGHIJKLMNO + * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode: + * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c pqrstuvwxyz{|}~. + */ +void print_hex_dump(const char* prefix_str, int prefix_type, + int rowsize, int groupsize, + const void* buf, int len, int ascii) +{ + const unsigned char* ptr = (const unsigned char *)buf; + int i, remaining = len; + unsigned char linebuf[32 * 3 + 2 + 32 + 1]; + + if(rowsize != 16 && rowsize != 32) + { + rowsize = 16; + } + + for(i = 0; i < len; i += rowsize) + { + int linelen = MIN(remaining, rowsize); + remaining -= rowsize; + + hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, + (char *)linebuf, sizeof(linebuf), ascii); + + switch(prefix_type) + { + case DUMP_PREFIX_ADDRESS: + print("%s%p: %s\n", + prefix_str, ptr + i, linebuf); + break; + + case DUMP_PREFIX_OFFSET: + print("%s%.8x: %s\n", prefix_str, i, linebuf); + break; + + default: + print("%s%.8x: %s\n", prefix_str, i, linebuf); + break; + } + } + + print("%s", "\n"); +} + +/** + * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params + * @prefix_str: string to prefix each line with; + * caller supplies trailing spaces for alignment if desired + * @prefix_type: controls whether prefix of an offset, address, or none + * is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE) + * @buf: data blob to dump + * @len: number of bytes in the @buf + * + * Calls print_hex_dump(), with log level of KERN_DEBUG, + * rowsize of 16, groupsize of 1, and ASCII output included. + */ +void print_hex_dump_bytes(const char* prefix_str, int prefix_type, + const void* buf, int len) +{ + print_hex_dump(prefix_str, prefix_type, 16, 1, + buf, len, 1); +} + +const char* format_hex_buf(const char* prefix_str, int prefix_type, + int rowsize, int groupsize, + const void* buf, int len, int ascii) +{ + UT_string* pLogStr = NULL; + const char* pFormatStr; + const unsigned char* ptr = (const unsigned char *)buf; + int i, remaining = len; + unsigned char linebuf[32 * 3 + 2 + 32 + 1]; + + if(rowsize != 16 && rowsize != 32) + { + rowsize = 16; + } + + utstring_new(pLogStr); + + for(i = 0; i < len; i += rowsize) + { + int linelen = MIN(remaining, rowsize); + remaining -= rowsize; + + hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize, + (char *)linebuf, sizeof(linebuf), ascii); + + switch(prefix_type) + { + case DUMP_PREFIX_ADDRESS: + utstring_printf(pLogStr, "%s%p: %s\n", + prefix_str, ptr + i, linebuf); + break; + + case DUMP_PREFIX_OFFSET: + utstring_printf(pLogStr, "%s%.8x: %s\n", + prefix_str, i, linebuf); + break; + + default: + utstring_printf(pLogStr, "%s%.8x: %s\n", + prefix_str, i, linebuf); + break; + } + } + + pFormatStr = strdup(utstring_body(pLogStr)); + utstring_free(pLogStr); + + return pFormatStr; +} + +#endif diff --git a/app/libuvdbus/src/log/log.c b/app/libuvdbus/src/log/log.c new file mode 100644 index 0000000..0802634 --- /dev/null +++ b/app/libuvdbus/src/log/log.c @@ -0,0 +1,1332 @@ +/** @file log.c + @brief 系统日志接口文件 + @version 1.0.0 +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef PLATFORM_R16 +#include +#endif + +#include "log.h" +#include "smart_sound.h" +#include "inet_api.h" +#include "crypto.h" +#include "libuv_dbus.h" +#include "server_addr.h" + +#define SHOW_CONSOLE_RED ("\033[31;48m\033[1m%s\033[0m%c") +#define SHOW_CONSOLE_YELLOW ("\033[33;48m\033[1m%s\033[0m%c") +#define SHOW_CONSOLE_GREEN ("\033[32;48m\033[1m%s\033[0m%c") +#define SHOW_CONSOLE_BLUE ("\033[34;48m\033[1m%s\033[0m%c") + +#ifdef PLATFORM_CPU +#define LOG_FILE_BASEDIR (".") +#else +#define LOG_FILE_BASEDIR ("/tmp") +#endif + +#ifdef PLATFORM_R16 +#define NIC_NAME ("wlan0") +#else +#define NIC_NAME ("enp3s0") +#endif + +#define MAX_LOG_ITEM (1000) +#define MAX_LOG_FILE_SIZE (1024 * 1024) +#define LOG_PRE_SIZE (512) + +#if 0 +#define LOG_MAIL_USERNAME ("pv1_es2@hotmail.com") +#define LOG_MAIL_PASSWORD ("netEase163") +#define LOG_MAIL_SERVER ("smtp://smtp-mail.outlook.com") +#define LOG_MAIL_PORT (587) +#else +#define LOG_MAIL_USERNAME ("pv1_es2@163.com") +#define LOG_MAIL_LOGPASSWD ("netEase163") +#define LOG_MAIL_PASSWORD ("pv1Dev163") +#define LOG_MAIL_SERVER ("smtp.163.com") +#define LOG_MAIL_PORT (25) +#endif + +#define LOG_MAIL_RECEIVER ("pv1_es2@163.com") + +#define SYS_POINT_UPLOAD_TIME (600) + +typedef struct +{ + char* pDeviceId; + char savePath[MAX_PATH]; + int iMaxCacheSize; + int iEveryUploadTime; + time_t lastPostTime; + time_t lastMarkTime; + FILE* pMarkFile; + uv_rwlock_t uvRwLock; + uv_thread_t uvIOThread; +} SYSPOINT_INFO, *PSYSPOINT_INFO; + +typedef struct SYSPOINT_ITEM +{ + char* pContent; + struct SYSPOINT_ITEM *next, *prev; +} *PSYSPOINT_ITEM; + +typedef struct LOG_ITEM +{ + LOG_LEVEL level; + int isPrinted; + int isAddTags; + struct timeval timestamp; + char *pLogContent; + struct LOG_ITEM *next, *prev; +}*PLOG_ITEM; + +typedef struct LOG_BACKUP +{ + time_t timestamp; + char *plogFilePath; + char *pGzFilePath; + unsigned int sendTimes; + unsigned int tolLogs; + struct LOG_BACKUP *next, *prev; +} *PLOG_BACKUP; + +typedef struct +{ + pid_t pid; + char* pChipId; + char* pChipSerial; + char exeName[MAX_PATH]; + char logFilePath[MAX_PATH]; + FILE *pLogFile; +} LOG_PROCESS_INFO, *PLOG_PROCESS_INFO; + +static int g_bEnableLog = FALSE; // 是否启用 Log 功能 +static int g_bEnMailBackup = FALSE; +static char* g_pEmailBox = NULL; +static int g_bEnLogToFile = TRUE; +static int g_bEnLogToServer = TRUE; +static char g_strLogTag[32]; // Log 标志 +static unsigned int g_LogRdPos = 0; +static pthread_t g_logThreadId; +static pthread_t g_backupThreadId; +static LOG_PROCESS_INFO g_LogProcessInfo; +static uv_rwlock_t g_uvLogLock; +static uv_rwlock_t g_uvLogBackLock; +static PLOG_ITEM g_pLogItemList = NULL; +static PLOG_BACKUP g_pLogBackupList = NULL; +static int g_logSock = -1; +struct sockaddr_in g_logAddr; + +static SYSPOINT_INFO g_SysPonitInfo; +static PSYSPOINT_ITEM g_pSysPointArray = NULL; +static PHTTP_POST_ATTACH g_pLogParamsArray = NULL; + + +static int g_iMinLevel = LOG_Fatal | LOG_Error | LOG_Warn | LOG_Debug | LOG_Info | LOG_Step; + +/** + * @brief Log 调试等级转字符串 + * @param level 调试等级 + * @return 调试等级对应的字符串 + */ +const char* LogLevelToStr(LOG_LEVEL level) +{ + switch(level) + { + case LOG_Test: + return "T"; + + case LOG_Info: + return "I"; + + case LOG_Call: + return "C"; + + case LOG_Debug: + return "D"; + + case LOG_Warn: + return "W"; + + case LOG_Error: + return "E"; + + case LOG_Fatal: + return "F"; + + case LOG_Step: + return "S"; + + case LOG_Devp: + return "V"; + + case LOG_Unknown: + return "U"; + + case LOG_All: + return "A"; + + default: + return "?"; + } + + return "U"; +} + +#pragma pack (push) +#pragma pack (1) +typedef struct +{ + unsigned short logSeq; + unsigned int pid; + unsigned int timeStamp; + unsigned int nanotime; + unsigned int logLevel; + char logContent[0]; +} LOG_PROTO_CONTENT, *PLOG_PROTO_CONTENT; +#pragma pack (pop) + +static struct HTTP_POST_ATTACH g_PostLogParams[] = +{ + {"CPUID", "", NULL, NULL}, + {"MAC", "", NULL, NULL}, + {"Version", "", NULL, NULL}, + {"BuildTime", "", NULL, NULL}, + {"SerialNumber", "", NULL, NULL}, + {"Datetime", "", NULL, NULL}, + {"content", "", NULL, NULL}, +}; + +static void __initPostLogParams(void) +{ + char *pMacAddr = NULL; + struct tm localTime; + time_t timeStamp = time((time_t*)NULL); + + GetShellExecResult("ifconfig wlan0 | grep HWaddr | awk \'{print $5}\'", &pMacAddr); + + localtime_r(&timeStamp, &localTime); + + strncpy(g_PostLogParams[0].keyValue, g_LogProcessInfo.pChipId, MAX_HTTP_POST_SIZE); + strncpy(g_PostLogParams[1].keyValue, (pMacAddr && strlen(pMacAddr) > 0) ? pMacAddr : "00:00:00:00:00:00", MAX_HTTP_POST_SIZE); + strncpy(g_PostLogParams[2].keyValue, GetCurrentVersion(), MAX_HTTP_POST_SIZE); + sprintf(g_PostLogParams[3].keyValue, "Build: %s %s", __DATE__, __TIME__); + strncpy(g_PostLogParams[4].keyValue, g_LogProcessInfo.pChipSerial, MAX_HTTP_POST_SIZE); + + for(int i = 0; i < sizeof(g_PostLogParams) / sizeof(g_PostLogParams[0]); i++) + { + LL_APPEND(g_pLogParamsArray, &g_PostLogParams[i]); + } + + if(pMacAddr) + { + free(pMacAddr); + } +} + +int HttpPostLogFile(char* pSession) +{ + int ret; + struct tm localTime; + const char* pFileName = "/tmp/backuplog.tar.gz"; + const char* pLastFile = "/mnt/UDISK/backuplog_nand.tar.gz"; + char* pLogServerURL = GetCurServerAddr(LOG_MODULE); + time_t timeStamp = time((time_t*)NULL); + + ret = system(" /usr/sbin/backuplocalfiles.sh"); + + if(access(pFileName, F_OK) != 0 + && access(pLastFile, F_OK) != 0) + { + return -ERR_FILE_NOT_EXISTS; + } + + localtime_r(&timeStamp, &localTime); + + memset(g_PostLogParams[5].keyValue, 0, MAX_HTTP_POST_SIZE); + sprintf(g_PostLogParams[5].keyValue, "%04u-%02u-%02u %02u:%02u:%02u", + localTime.tm_year + 1900, + localTime.tm_mon + 1, + localTime.tm_mday, + localTime.tm_hour, + localTime.tm_min, + localTime.tm_sec); + + memset(g_PostLogParams[6].keyValue, 0, MAX_HTTP_POST_SIZE); + + if(pSession && strlen(pSession) >= 2) + { + strncpy(g_PostLogParams[6].keyValue, pSession, MAX_HTTP_POST_SIZE); + } + else + { + strncpy(g_PostLogParams[6].keyValue, "{}", MAX_HTTP_POST_SIZE); + } + + if(access(pFileName, F_OK) == 0) + { + ret = InetHttpUploadFileSync(pLogServerURL, pFileName, g_pLogParamsArray); + + if(ret == 0) + { + LOG_EX(LOG_Debug, "Upload Log Data [%s] To Server [%s]\n", pFileName, pLogServerURL); + unlink(pFileName); + } + else + { + LOG_EX(LOG_Error, "Upload Log Data [%s] To Server [%s]\n", pFileName, pLogServerURL); + } + } + + if(access(pLastFile, F_OK) == 0) + { + ret = InetHttpUploadFileSync(pLogServerURL, pLastFile, g_pLogParamsArray); + + if(ret == 0) + { + LOG_EX(LOG_Debug, "Upload Log Data [%s] To Server [%s]\n", pLastFile, pLogServerURL); + unlink(pLastFile); + } + else + { + LOG_EX(LOG_Error, "Upload Log Data [%s] To Server [%s]\n", pLastFile, pLogServerURL); + } + } + + //fprintf(stdout, "Upload Log Data [%s] To Server [%s], size = %d\n", pFileName, UPL_HTTP_URL, fileSize); + + return ret; +} + +static int __logNetworkSend(PLOG_ITEM pItem) +{ + PLOG_PROTO_CONTENT pLogInfo; + unsigned char *pBuf; + int ret, totalSize = 0; + static unsigned short sendSeq = 0; + + if(pItem == NULL || pItem->pLogContent == NULL || strlen(pItem->pLogContent) == 0) + { + return (-ERR_INPUT_PARAMS); + } + + totalSize = sizeof(LOG_PROTO_CONTENT) + strlen(pItem->pLogContent); + + pBuf = (unsigned char *)malloc(totalSize); + + if(pBuf == NULL) + { + return (-ERR_MALLOC_MEMORY); + } + + memset(pBuf, 0, totalSize); + + pLogInfo = (PLOG_PROTO_CONTENT)pBuf; + + pLogInfo->logSeq = htons(sendSeq++); + pLogInfo->timeStamp = htonl(pItem->timestamp.tv_sec); + pLogInfo->nanotime = htonl(pItem->timestamp.tv_usec); + pLogInfo->pid = htonl(g_LogProcessInfo.pid); + pLogInfo->logLevel = htonl(pItem->level); + + memcpy(pLogInfo->logContent, pItem->pLogContent, strlen(pItem->pLogContent)); + + ret = sendto(g_logSock, pBuf, totalSize, 0, + (struct sockaddr *)&g_logAddr, sizeof(g_logAddr)); + + if(ret == totalSize) + { + return (0); + } + else + { + //LOG_EX(LOG_Error, "Send %d bytes, need %d bytes\n", ret, totalSize); + return (-ERR_NETWORK_SEND); + } +} + +static void __cleanupBackupItem(PLOG_BACKUP pItem) +{ + if(pItem) + { + LL_DELETE(g_pLogBackupList, pItem); + + if(pItem->plogFilePath) + { + if(access(pItem->plogFilePath, F_OK) == 0) + { + unlink(pItem->plogFilePath); + } + + free(pItem->plogFilePath); + } + + if(pItem->pGzFilePath) + { + if(access(pItem->pGzFilePath, F_OK) == 0) + { + unlink(pItem->pGzFilePath); + } + + free(pItem->pGzFilePath); + } + + free(pItem); + } +} + +static void* __uvLogBackupProc(void *pParams) +{ + SMTP_MAIL_CONFIG smtpCfg; + char gzLogPath[MAX_PATH]; + struct tm localTime; + const char *pFrom = LOG_MAIL_USERNAME; + const char *pTo[] = {g_pEmailBox, NULL}; + char *pMacAddr = NULL; + + //const char *pCc[] = {"xajhuang@qq.com", "xajhuang@163.com", NULL}; + + memset(&smtpCfg, 0, sizeof(SMTP_MAIL_CONFIG)); + + smtpCfg.pUserName = LOG_MAIL_USERNAME; + smtpCfg.pPassword = LOG_MAIL_PASSWORD; + smtpCfg.pSmtpServer = LOG_MAIL_SERVER; + smtpCfg.smtpPort = LOG_MAIL_PORT; + +#ifdef PLATFORM_CPU + GetShellExecResult("ifconfig enp3s0 | grep HWaddr | awk \'{print $5}\'", &pMacAddr); +#else + GetShellExecResult("ifconfig wlan0 | grep HWaddr | awk \'{print $5}\'", &pMacAddr); +#endif + + if(pMacAddr == NULL || strlen(pMacAddr) == 0) + { + pMacAddr = strdup("00:00:00:00:00:00"); + } + + while(TRUE) + { + PLOG_BACKUP pItem = NULL, pTmp = NULL; + time_t timeStamp = time((time_t*)NULL); + localtime_r(&timeStamp, &localTime); + + uv_rwlock_wrlock(&g_uvLogBackLock); + + LL_FOREACH_SAFE(g_pLogBackupList, pItem, pTmp) + { + const char *pAttact[2]; + UT_string *pTitle, *pMessage, *pDatetime; + char* pMD5Val; + + pAttact[1] = NULL; + + if(pItem->plogFilePath == NULL || strlen(pItem->plogFilePath) == 0) + { + __cleanupBackupItem(pItem); + continue; + } + + if(timeStamp - pItem->timestamp >= 3600) + { + __cleanupBackupItem(pItem); + continue; + } + + if(pItem->sendTimes >= 3) + { + __cleanupBackupItem(pItem); + continue; + } +#if 0 + if(g_bEnLogToServer) + { + __logHttpPostFile(pItem->plogFilePath); + //InetHttpUploadFileSync(UPL_HTTP_URL, pItem->pGzFilePath, NULL); + } +#endif + if(pItem->pGzFilePath == NULL) + { + memset(gzLogPath, 0, MAX_PATH); + sprintf(gzLogPath, "%s/%d_%s_%u.log.gz", + LOG_FILE_BASEDIR, g_LogProcessInfo.pid, g_LogProcessInfo.exeName, pItem->tolLogs); + + if(GZipFileCompress(pItem->plogFilePath, gzLogPath) != 0) + { + LOG_EX(LOG_Error, "Create Gzip File Error: %s\n", gzLogPath); + continue; + } + else + { + pItem->pGzFilePath = strdup(gzLogPath); + } + } + + pMD5Val = (char*)EvpMD5HashFile(pItem->pGzFilePath); + + utstring_new(pTitle); + utstring_new(pMessage); + utstring_new(pDatetime); + + utstring_printf(pDatetime, "%04u-%02u-%02u %02u:%02u:%02u", + localTime.tm_year + 1900, + localTime.tm_mon + 1, + localTime.tm_mday, + localTime.tm_hour, + localTime.tm_min, + localTime.tm_sec); + + utstring_printf(pTitle, "Log [%s]-[%s]-[%s]", + g_LogProcessInfo.exeName, + g_LogProcessInfo.pChipSerial, + utstring_body(pDatetime)); + + utstring_printf(pMessage, "\r\n" + "

Summary information:

" + "


" + "

" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "" + "
Items
%u
Process PID
%d
Process Name
%s
CPU ID
%s
Serial
%s
Mac Address
%s
File Checksum
%s
Log Level
0x%08X
Datetime
%s
" + "

" + "\r\n", + pItem->tolLogs, + g_LogProcessInfo.pid, + g_LogProcessInfo.exeName, + g_LogProcessInfo.pChipId, + g_LogProcessInfo.pChipSerial, + pMacAddr, + SAFE_STRING_VALUE(pMD5Val), + g_iMinLevel, + utstring_body(pDatetime)); + + pAttact[0] = pItem->pGzFilePath; +#if 0 + if(g_bEnMailBackup && + InetSmtpSendEmail(pFrom, pTo, NULL, utstring_body(pTitle), + utstring_body(pMessage), pAttact, &smtpCfg) == 0) + { + __cleanupBackupItem(pItem); + } + else + { + LOG_EX(LOG_Error, "Send email error: %s\n", pItem->pGzFilePath); + } +#endif + pItem->sendTimes++; + + if(pMD5Val) + { + free(pMD5Val); + } + + utstring_free(pTitle); + utstring_free(pMessage); + utstring_free(pDatetime); + } + + uv_rwlock_wrunlock(&g_uvLogBackLock); + + sleep(1); + } + + free(pMacAddr); + pthread_detach(pthread_self()); + return (NULL); +} + +static void __logColorOutput(const char* pColFmt, UT_string* pLog) +{ + if(pLog == NULL) + { + return; + } + + if(pColFmt == NULL) + { + print("%s", utstring_body(pLog)); + } + else + { + if(utstring_find(pLog, -1, "\n", 1) == utstring_len(pLog) - 1) + { + char* pLogArray = utstring_body(pLog); + pLogArray[utstring_len(pLog) - 1] = 0; + + print(pColFmt, pLogArray, '\n'); + + strcat(pLogArray, "\n"); + } + else + { + print(pColFmt, utstring_body(pLog), '\0'); + } + } +} + +static void* __logOutputThread(void *p) +{ + while(TRUE) + { + int isWriteLog = FALSE; + PLOG_ITEM pItem = NULL, pTmp = NULL; + + uv_rwlock_wrlock(&g_uvLogLock); + + LL_FOREACH_SAFE(g_pLogItemList, pItem, pTmp) + { + UT_string *pLogStr; + struct tm lTime; + int logFileSize = 0; + + if(++g_LogRdPos % 100 == 0) + { + GET_FILE_SIZE(g_LogProcessInfo.logFilePath, logFileSize); + } + + localtime_r(&(pItem->timestamp.tv_sec), &lTime); + + utstring_new(pLogStr); + + if(pItem->isAddTags) + { + utstring_printf(pLogStr, "[%04d-%02d-%02d %02d:%02d:%02d.%03ld] [%s] %s", + lTime.tm_year + 1900, lTime.tm_mon + 1, lTime.tm_mday, + lTime.tm_hour, lTime.tm_min, lTime.tm_sec, pItem->timestamp.tv_usec / 1000, + LogLevelToStr(pItem->level), pItem->pLogContent); + } + else + { + utstring_printf(pLogStr, "%s", pItem->pLogContent); + } + + if(pItem->isPrinted == FALSE) + { + if(pItem->level & LOG_Error + || pItem->level & LOG_Fatal) + { + __logColorOutput(SHOW_CONSOLE_RED, pLogStr); + } + else if(pItem->level & LOG_Warn + || pItem->level & LOG_Unknown) + { + __logColorOutput(SHOW_CONSOLE_YELLOW, pLogStr); + } + else if(pItem->level & LOG_Test + || pItem->level & LOG_Call) + { + __logColorOutput(SHOW_CONSOLE_BLUE, pLogStr); + } + else if(pItem->level & LOG_Devp) + { + __logColorOutput(SHOW_CONSOLE_GREEN, pLogStr); + } + else + { + print("%s", utstring_body(pLogStr)); + } + + pItem->isPrinted = TRUE; + } + + if(g_logSock != -1 && GetCurrWIFIConnStatus() == WIFI_CONNECTED) + { + __logNetworkSend(pItem); + } + + if(g_LogProcessInfo.pLogFile != NULL && g_bEnLogToFile) + { + if(logFileSize >= MAX_LOG_FILE_SIZE) + { + fflush(g_LogProcessInfo.pLogFile); + fclose(g_LogProcessInfo.pLogFile); +#if 0 + if(g_bEnMailBackup) + { + PLOG_BACKUP pBackup = (PLOG_BACKUP)malloc(sizeof(struct LOG_BACKUP)); + char path[MAX_PATH]; + + memset(path, 0, MAX_PATH); + sprintf(path, "%s/%s.bak_%u.log", + LOG_FILE_BASEDIR, + basename_v2(g_LogProcessInfo.logFilePath), + g_LogRdPos); + rename(g_LogProcessInfo.logFilePath, path); + + if(pBackup) + { + memset(pBackup, 0, sizeof(struct LOG_BACKUP)); + pBackup->timestamp = time(NULL); + pBackup->plogFilePath = strdup(path); + pBackup->sendTimes = 0; + pBackup->tolLogs = g_LogRdPos - 1; + + uv_rwlock_wrlock(&g_uvLogBackLock); + LL_APPEND(g_pLogBackupList, pBackup); + uv_rwlock_wrunlock(&g_uvLogBackLock); + } + } +#endif + g_LogProcessInfo.pLogFile = fopen(g_LogProcessInfo.logFilePath, "w+"); + } + + if(g_LogProcessInfo.pLogFile) + { + fwrite(utstring_body(pLogStr), 1, utstring_len(pLogStr), g_LogProcessInfo.pLogFile); + } + + isWriteLog = TRUE; + } + + LL_DELETE(g_pLogItemList, pItem); + + utstring_free(pLogStr); + free(pItem->pLogContent); + free(pItem); + + if(g_LogRdPos % 100 == 0) + { + break; + } + } + + uv_rwlock_wrunlock(&g_uvLogLock); + + usleep(1000); + if(g_LogProcessInfo.pLogFile != NULL && isWriteLog) + { + fflush(g_LogProcessInfo.pLogFile); + } + } + + pthread_detach(pthread_self()); + return (NULL); +} + +/** + * @brief 设置调试等级 + * @param level 调试等级 + * @param iEnable 1 打开调试等级, 0 关闭调试等级 + */ +void IHW_EnableLogLevel(LOG_LEVEL level, int iEnable) +{ + if(iEnable > 0) + { + g_iMinLevel |= level; + } + else + { + g_iMinLevel &= ~(level); + } +} + +static int __getCfgFromCfgFile(void) +{ + int ret = 0; + g_bEnableLog = CfgGetBoolValue("Global.Log.Enable", g_bEnableLog); + g_iMinLevel = CfgGetIntValue("Global.Log.Level", g_iMinLevel); + g_bEnMailBackup = CfgGetBoolValue("Global.Log.LogToEMail.Enable", g_bEnMailBackup); + g_pEmailBox = CfgGetStringValue("Global.Log.LogToEMail.EMail", LOG_MAIL_RECEIVER); + g_bEnLogToFile = CfgGetBoolValue("Global.Log.LogToFile", g_bEnLogToFile); + g_bEnLogToServer = CfgGetBoolValue("Global.Log.LogToServer", g_bEnLogToServer); + +#if 0 + LOG_EX(LOG_Debug, "g_bEnableLog = %d\n", g_bEnableLog); + LOG_EX(LOG_Debug, "g_iMinLevel = 0x%X\n", g_iMinLevel); + LOG_EX(LOG_Debug, "g_bEnMailBackup = %d\n", g_bEnMailBackup); + LOG_EX(LOG_Debug, "g_pEmailBox = %s\n", g_pEmailBox); + LOG_EX(LOG_Debug, "g_bEnLogToFile = %d\n", g_bEnLogToFile); + LOG_EX(LOG_Debug, "g_bEnLogToServer = %d\n", g_bEnLogToServer); +#endif + + ret = CfgGetBoolValue("Global.Log.LogToUDPServer.Enable", FALSE); + + if(ret) + { + char *pIpAddr = NULL; + int udpPortBase = CfgGetBoolValue("Global.Log.LogToUDPServer.UdpBasePort", 10000); + int port = udpPortBase + DBusLibGetModName(); + + if(g_logSock != -1) + { + close(g_logSock); + g_logSock = -1; + } + + pIpAddr = CfgGetStringValue("Global.Log.LogToUDPServer.UdpServerIp", NULL); + + LOG_EX(LOG_Debug, "UDP Ipaddr = %s, port = %d\n", pIpAddr, port); + + if(pIpAddr) + { + memset(&g_logAddr, 0, sizeof(g_logAddr)); + g_logAddr.sin_family = AF_INET; + g_logAddr.sin_port = htons(port); + g_logAddr.sin_addr.s_addr = inet_addr(pIpAddr); + + g_logSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + } + } +} +/** + * @brief 初始化系统日志功能 + * @param pLogTag 系统日志标志 + * @param pPath 系统日志保存路径 + * @param bEnable 打开/关闭调试信息 + */ +void IHW_InitLOG(const char* pLogTag, const char* pPath, int bEnable) +{ + int ret; + char strPath[MAX_PATH]; + + memset(&g_logAddr, 0, sizeof(g_logAddr)); + uv_rwlock_init(&g_uvLogLock); + g_LogRdPos = 0; + memset(g_strLogTag, 0, 32); + + memset(&g_LogProcessInfo, 0, sizeof(LOG_PROCESS_INFO)); + + if(pLogTag == NULL) + { + strcpy(g_strLogTag, ""); + } + else + { + strncpy(g_strLogTag, pLogTag, 31); + } + + memset(strPath, 0, MAX_PATH); + + g_LogProcessInfo.pid = getpid(); + if(readlink("/proc/self/exe", strPath, MAX_PATH) == -1) + { + strcpy(g_LogProcessInfo.exeName, pLogTag); + } + else + { + char *pExeName = strrchr(strPath, '/'); + + if(pExeName == NULL) + { + strncpy(g_LogProcessInfo.exeName, strPath, MAX_PATH - 1); + } + else + { + strncpy(g_LogProcessInfo.exeName, pExeName + 1, MAX_PATH - 1); + } + } + + //fprintf(stdout, "pid = %d, name = %s\n", g_LogProcessInfo.pid, g_LogProcessInfo.exeName); + g_LogProcessInfo.pChipId = GetCpuChipId(); + g_LogProcessInfo.pChipSerial = GetCpuSerial(); + memset(g_LogProcessInfo.logFilePath, 0, MAX_PATH); + sprintf(g_LogProcessInfo.logFilePath, "%s/%s_%d.log", LOG_FILE_BASEDIR, g_LogProcessInfo.exeName, g_LogProcessInfo.pid); + + memset(strPath, 0, MAX_PATH); + sprintf(strPath, "rm -f %s/%s_*.log > /dev/zero", LOG_FILE_BASEDIR, g_LogProcessInfo.exeName); + ret = system(strPath); + + g_LogProcessInfo.pLogFile = fopen(g_LogProcessInfo.logFilePath, "w+"); + + g_bEnableLog = bEnable; + + __getCfgFromCfgFile(); + +#if 0 + LOG_CFG_PROTOCOL logCfg; + + memset(&logCfg, 0, sizeof(LOG_CFG_PROTOCOL)); + logCfg.cfgCmd = CMD_LOG_NETWORK; + logCfg.iParams1 = inet_addr("10.240.84.163"); + logCfg.iParams2 = htons(10000); + UpgradLogConfigure(&logCfg); +#endif + + __initPostLogParams(); +} + +void IHW_RunLogService(void) +{ + pthread_create(&g_logThreadId, NULL, __logOutputThread, NULL); + pthread_create(&g_backupThreadId, NULL, __uvLogBackupProc, NULL); +} + +static void __logTo(LOG_LEVEL level, int isAddTag, char* pMsg, int isPrint) +{ + PLOG_ITEM pLogItem; + + pLogItem = (PLOG_ITEM)malloc(sizeof(struct LOG_ITEM)); + + if(pLogItem == NULL) + { + return; + } + + pLogItem->pLogContent = strdup(pMsg); + pLogItem->isPrinted = isPrint ? FALSE : TRUE; + pLogItem->level = level; + pLogItem->isAddTags = isAddTag ? TRUE : FALSE; + gettimeofday(&(pLogItem->timestamp), NULL); + + uv_rwlock_wrlock(&g_uvLogLock); + LL_APPEND(g_pLogItemList, pLogItem); + uv_rwlock_wrunlock(&g_uvLogLock); +} + +void IHW_LogStrWithoutPrint(int level, char* pMsg) +{ + __logTo(level, TRUE, pMsg, FALSE); +} + +void IHW_LogRawString(int level, char* pMsg) +{ + __logTo(level, TRUE, pMsg, TRUE); +} + +/** + * @brief 输出调试信息 + * @param cFlag 调试信息开关 + * @param pMsg 调试信息内容 + */ +void IHW_LOG_UNTAG(LOG_LEVEL level, const char* pMsg, ...) +{ + va_list arg_ptr; + UT_string *pLogContent; + + if(!g_bEnableLog) + { + return; + } + + // 检查调试等级 + if(!(g_iMinLevel & level)) + { + return; + } + + utstring_new(pLogContent); + va_start(arg_ptr, pMsg); + utstring_printf_va(pLogContent, pMsg, arg_ptr); + va_end(arg_ptr); + + __logTo(level, FALSE, utstring_body(pLogContent), TRUE); + + utstring_free(pLogContent); +} + +/** + * @brief 输出调试信息 + * @param cFlag 调试信息开关 + * @param pMsg 调试信息内容 + */ +void IHW_LOG(LOG_LEVEL level, const char* pMsg, ...) +{ + UT_string* pLogContent = NULL; + va_list arg_ptr; + + if(!g_bEnableLog) + { + return; + } + + // 检查调试等级 + if(!(g_iMinLevel & level)) + { + return; + } + + utstring_new(pLogContent); + va_start(arg_ptr, pMsg); + utstring_printf_va(pLogContent, pMsg, arg_ptr); + va_end(arg_ptr); + + __logTo(level, TRUE, utstring_body(pLogContent), TRUE); + + utstring_free(pLogContent); +} + +void IHW_DisableLogOut(void) +{ + g_bEnableLog = FALSE; +} + +void IHW_EnableLogOut(void) +{ + g_bEnableLog = TRUE; +} + +#if 0 +void LogUploadCurLogFile(void) +{ + UT_string *pFn = NULL, *pCmd = NULL; + utstring_new(pFn); + utstring_new(pCmd); + + utstring_printf(pFn, "/tmp/%s_%s.bak.log", g_LogProcessInfo.exeName, g_LogProcessInfo.pChipId); + utstring_printf(pCmd, "cp %s %s", g_LogProcessInfo.logFilePath, utstring_body(pFn)); + + __logHttpPostFile(utstring_body(pFn)); + //InetHttpUploadFileSync(UPL_HTTP_URL, utstring_body(pFn), NULL); + + utstring_free(pFn); + utstring_free(pCmd); +} +#endif + +#if 0 +void UploadLogFile(char* pFilePath) +{ + int fileSize = 0; + + if(pFilePath == NULL || strlen(pFilePath) == 0) + { + return; + } + + GET_FILE_SIZE(pFilePath, fileSize); + + if(fileSize <= 0) + { + LOG_EX(LOG_Warn, "File Size Error: %d\n", fileSize); + return; + } + + __logHttpPostFile(pFilePath); +} +#endif + +void UpgradLogConfigure(PLOG_CFG_PROTOCOL pCfg) +{ + switch(pCfg->cfgCmd) + { + case CMD_LOG_ENABLE: + g_bEnableLog = pCfg->iParams1; + break; + + case CMD_LOG_FILE: + if(pCfg->iParams1 == FALSE) + { + g_bEnMailBackup = g_bEnLogToFile = FALSE; + } + else + { + g_bEnLogToFile = TRUE; + } + break; + + case CMD_LOG_MAIL: + g_bEnMailBackup = pCfg->iParams1; + break; + + case CMD_LOG_LEVEL: + if(pCfg->iParams2 == FALSE) + { + if(pCfg->iParams1 == 0) + { + g_iMinLevel = LOG_Fatal | LOG_Error | LOG_Devp; + } + else + { + g_iMinLevel &= ~(pCfg->iParams1); + } + } + else + { + g_iMinLevel |= pCfg->iParams1; + } + break; + + case CMD_LOG_NETWORK: + if(pCfg->iParams1 == 0) + { + memset(&g_logAddr, 0, sizeof(g_logAddr)); + close(g_logSock); + g_logSock = -1; + } + else + { + if(g_logSock != -1) + { + close(g_logSock); + } + + memset(&g_logAddr, 0, sizeof(g_logAddr)); + g_logAddr.sin_family = AF_INET; + g_logAddr.sin_port = htons((pCfg->iParams2 & 0xFFFF)); + g_logAddr.sin_addr.s_addr = (pCfg->iParams1); + + g_logSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + } + break; + + case CMD_LOG_SERVER: + g_bEnLogToServer = pCfg->iParams1; + break; + + default: break; + } +} + +const char* LogLeveToString(LOG_LEVEL lv) +{ + switch(lv) + { + case LOG_Fatal: return "LOG_Fatal"; + case LOG_Error: return "LOG_Error"; + case LOG_Warn: return "LOG_Warn"; + case LOG_Debug: return "LOG_Debug"; + case LOG_Info: return "LOG_Info"; + case LOG_Test: return "LOG_Test"; + case LOG_Call: return "LOG_Call"; + case LOG_Devp: return "LOG_Devp"; + case LOG_Step: return "LOG_Step"; + case LOG_Unknown: return "LOG_Unknown"; + case LOG_All: return "LOG_All"; + case LOG_Close: return "LOG_Close"; + } + + return "Unknown"; +} + +static void __uvSysPointIOProc(void *pParams) +{ + while(TRUE) + { + PSYSPOINT_ITEM pItem = NULL, pTmp = NULL; + int iFileSize; + time_t tmNow = time(NULL); + + if(g_SysPonitInfo.pMarkFile) + { + uv_rwlock_wrlock(&g_SysPonitInfo.uvRwLock); + LL_FOREACH_SAFE(g_pSysPointArray, pItem, pTmp) + { + fwrite(pItem->pContent, 1, strlen(pItem->pContent), g_SysPonitInfo.pMarkFile); + free(pItem->pContent); + LL_DELETE(g_pSysPointArray, pItem); + free(pItem); + } + uv_rwlock_wrunlock(&g_SysPonitInfo.uvRwLock); + } + + GET_FILE_SIZE(g_SysPonitInfo.savePath, iFileSize); + + if(g_SysPonitInfo.lastPostTime == 0 || tmNow < g_SysPonitInfo.lastPostTime) + { + g_SysPonitInfo.lastPostTime = g_SysPonitInfo.lastMarkTime = tmNow; + tmNow = 0; + } +#if 0 + LOG_EX(LOG_Debug, "iFile = %d, MaxSize = %d, upTime = %d\n", + iFileSize, g_SysPonitInfo.iMaxCacheSize, g_SysPonitInfo.iEveryUploadTime); + + LOG_EX(LOG_Debug, "tm = %d, last = %d\n", tmNow, g_SysPonitInfo.lastPostTime); +#endif + if(iFileSize > g_SysPonitInfo.iMaxCacheSize + || tmNow - g_SysPonitInfo.lastPostTime > g_SysPonitInfo.iEveryUploadTime) + { + int fileSize = 0; + + GET_FILE_SIZE(g_SysPonitInfo.savePath, fileSize); + + if(fileSize > 0) + { + SysPointMarkUpload(); + g_SysPonitInfo.lastPostTime = tmNow; + } + + if(tmNow - g_SysPonitInfo.lastPostTime > g_SysPonitInfo.iEveryUploadTime) + { + SysPointMarkUpload(); + g_SysPonitInfo.lastPostTime = tmNow; + } + } + + if(g_SysPonitInfo.pMarkFile) + { + fflush(g_SysPonitInfo.pMarkFile); + } + + sleep(1); + } + + pthread_detach(pthread_self()); +} + +int SysPointMarkInit(char* pDevId, int iMaxSize, int iPostTime) +{ + LOG_EX(LOG_Debug, "pDevId = %s, iMaxSize = %d, iPostTime = %d\n", pDevId, iMaxSize, iPostTime); + + if(g_SysPonitInfo.pDeviceId != NULL) + { + if(pDevId && strlen(pDevId) > 0) + { + free(g_SysPonitInfo.pDeviceId); + g_SysPonitInfo.pDeviceId = strdup(pDevId); + } + + if(iMaxSize > 0) + { + g_SysPonitInfo.iMaxCacheSize = iMaxSize; + } + else + { + g_SysPonitInfo.iMaxCacheSize = 1024 * 10; + } + + if(iPostTime > 0) + { + g_SysPonitInfo.iEveryUploadTime = iPostTime; + } + else + { + g_SysPonitInfo.iEveryUploadTime = SYS_POINT_UPLOAD_TIME; + } + } + else + { + memset(&g_SysPonitInfo, 0, sizeof(SYSPOINT_INFO)); + + if(pDevId && strlen(pDevId) > 0) + { + g_SysPonitInfo.pDeviceId = strdup(pDevId); + } + + if(iMaxSize > 0) + { + g_SysPonitInfo.iMaxCacheSize = iMaxSize; + } + else + { + g_SysPonitInfo.iMaxCacheSize = 1024 * 1024; + } + + if(iPostTime > 0) + { + g_SysPonitInfo.iEveryUploadTime = iPostTime; + } + else + { + g_SysPonitInfo.iEveryUploadTime = SYS_POINT_UPLOAD_TIME; + } + + sprintf(g_SysPonitInfo.savePath, "%s/sys_point_mark.log", LOG_FILE_BASEDIR); + + g_SysPonitInfo.pMarkFile = fopen(g_SysPonitInfo.savePath, "w+"); + + if(g_SysPonitInfo.pMarkFile == NULL) + { + LOG_EX(LOG_Error, "Create File: %s Error\n", g_SysPonitInfo.savePath); + return -ERR_OPEN_FILE; + } + + uv_rwlock_init(&g_SysPonitInfo.uvRwLock); + + uv_thread_create(&g_SysPonitInfo.uvIOThread, __uvSysPointIOProc, NULL); + } + + return 0; +} + +int SysPointMark(char* pMarkInfo) +{ + PSYSPOINT_ITEM pItem; + + if(pMarkInfo == NULL || strlen(pMarkInfo) == 0) + { + return -ERR_INPUT_PARAMS; + } + + if(g_SysPonitInfo.iMaxCacheSize <= 0) + { + return -ERR_UNSUPPORT; + } + + pItem = (PSYSPOINT_ITEM)malloc(sizeof(struct SYSPOINT_ITEM)); + + if(pItem == NULL) + { + return -ERR_MALLOC_MEMORY; + } + + pItem->pContent = strdup(pMarkInfo); + g_SysPonitInfo.lastMarkTime = time(NULL); + + uv_rwlock_wrlock(&g_SysPonitInfo.uvRwLock); + LL_APPEND(g_pSysPointArray, pItem); + uv_rwlock_wrunlock(&g_SysPonitInfo.uvRwLock); + + //LOG_EX(LOG_Debug, "SysMark: %s\n", pItem->pContent); + + return 0; +} + +int SysPointMarkUpload(void) +{ + int ret, size = 0; + char path[MAX_PATH]; + + memset(path, 0, MAX_PATH); + sprintf(path, "%s.txt", g_SysPonitInfo.savePath); + + if(access(path, F_OK) == 0) + { + unlink(path); + } + + GET_FILE_SIZE(g_SysPonitInfo.savePath, size); + + if(size <= 0) + { + LOG_EX(LOG_Debug, "Upload System Mark Data [%s] Is Empty, Skip......\n", g_SysPonitInfo.savePath); + return 0; + } + + rename(g_SysPonitInfo.savePath, path); + + fclose(g_SysPonitInfo.pMarkFile); + g_SysPonitInfo.pMarkFile = fopen(g_SysPonitInfo.savePath, "w+"); + + size = 0; + + do + { + ret = InetHttpUploadFileSync(GetCurServerAddr(MARK_POINT_MODULE), path, NULL); + sleep(1); + } while(ret != 0 && ++size < 3); + + LOG_EX(LOG_Debug, "Upload System Mark Data [%s] To Server [%s]\n", path, GetCurServerAddr(MARK_POINT_MODULE)); + + unlink(path); + + return 0; +} + diff --git a/app/ota_r311/Makefile b/app/ota_r311/Makefile new file mode 100644 index 0000000..a5e3c43 --- /dev/null +++ b/app/ota_r311/Makefile @@ -0,0 +1,52 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common +include $(TOPDIR)/rules.mk + +PKG_NAME:=ota +PKG_RELEASE:=1 +PKG_VERSION:=0.0.1 + +PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME) + +include $(BUILD_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=utils + CATEGORY:=Netease + TITLE:=OTA tools + MAINTAINER:=Huang xin + DEPENDS:=$(MAKE_COMMON_DEPEND) +endef + +define Package/$(PKG_NAME)/description + $(PKG_NAME) PV1 Device OTA Tools +endef + +define Build/Prepare + mkdir -p $(PKG_BUILD_DIR) + $(CP) -d ./src/ $(PKG_BUILD_DIR)/ +endef + +define Build/Configure +endef +define Build/InstallDev +endef + +define Build/Compile + $(MAKE) -C $(PKG_BUILD_DIR)/src \ + ARCH="$(TARGET_ARCH)" \ + AR="$(TARGET_AR)" \ + CC="$(TARGET_CC)" \ + CXX="$(TARGET_CXX)" \ + CFLAGS="$(TARGET_CFLAGS)" \ + LDFLAGS="$(TARGET_LDFLAGS)" \ + INSTALL_PREFIX="$(PKG_INSTALL_DIR)" \ + TARGET_NAME=$(PKG_NAME) \ + all +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/bin + $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/$(PKG_NAME) $(1)/usr/bin/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/app/ota_r311/src/Makefile b/app/ota_r311/src/Makefile new file mode 100644 index 0000000..c0b48f7 --- /dev/null +++ b/app/ota_r311/src/Makefile @@ -0,0 +1,24 @@ +include $(TINA_BUILD_TOP)/package/netease/Makefile.common +TARGET := ota + +commonSources := ota_r311.c + +local_CFLAGS := +local_LDFLAGS := $(BUILD_COMMON_LIB) + +OBJS = $(patsubst %.c, %.c.o, $(commonSources)) + +$(TARGET):$(OBJS) + $(CC) $(CFLAGS) $(LDFLAGS) $(local_LDFLAGS) -o $@ $^ + +$(OBJS):%.c.o:%.c + $(CC) $(CFLAGS) $(LDFLAGS) $(local_CFLAGS) -c $^ -o $@ + +clean: + -rm $(OBJS) $(TARGET) + +install: + mkdir -p $(INSTALL_PREFIX)/usr/bin + cp $(TARGET) $(INSTALL_PREFIX)/usr/bin/ + +all: $(TARGET) install diff --git a/app/ota_r311/src/ota_r311.c b/app/ota_r311/src/ota_r311.c new file mode 100644 index 0000000..c19fceb --- /dev/null +++ b/app/ota_r311/src/ota_r311.c @@ -0,0 +1,1067 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(PLATFORM_R311) || defined (PLATFORM_CPU) +#include "log.h" +#include "libuv_dbus.h" +#include "crypto.h" +#include "json_struct.h" +#include "config_engine.h" +#include "inet_api.h" +#include "ota.h" +#else +#include +#include +#include +#include +#include +#include +#include +#endif + +#define MD5_CHKSUM_LEN (16) +#define MD5_STR_LEN (32 + 4) + +#define GET_STA_CNT(s) (s & 0xFF) +#define SET_STA_CNT(s, v) (s = (s & 0xFFFFFF00) | ((v) & 0xFF)) + +#define GET_STA_CMD(s) ((s >> 8) & 0xFF) +#define SET_STA_CMD(s, v) (s = (s & 0xFFFF00FF) | (((v) & 0xFF) << 8)) + +#define GET_STA_FLAG(s) ((s >> 16) & 0xFF) +#define SET_STA_FLAG(s, v) (s = (s & 0xFF00FFFF) | (((v) & 0xFF) << 16)) + +#define GET_STA_ERR(s) ((s >> 24) & 0xFF) +#define SET_STA_ERR(s, v) (s = (s & 0x00FFFFFF) | (((v) & 0xFF) << 24)) + +#define OTA_PARAMS_PARTITION ("/dev/by-name/ota_info") +#define OTA_PARAMS_TAG ("OTA163\0") +#define BOOT_IMG_FILE_NAME ("boot.img") +#define ROOTFS_IMG_FILE_NAME ("rootfs.img") +#define OTA_TEMP_DIR ("/mnt/UDISK/ota/unzip") +#define OTA_FILE_DOWNLOAD_DIR ("/mnt/UDISK/ota/dl") + +typedef struct +{ + char tags[8]; + unsigned int otaStatus; + char otaVer[MD5_STR_LEN]; + char bootChksum[MD5_STR_LEN]; + unsigned int bootfileSize; + char rootfsChksum[MD5_STR_LEN]; + unsigned int rootfsfileSize; + char paramsChksum[MD5_STR_LEN]; +} OTA_PARAMS, *POTA_PARAMS; + +typedef enum +{ + CMD_RUN_OTA = 1, + CMD_RUN_BOOT, + CMD_RUN_VERIFY, +} OTA_COMMAND; + +typedef enum +{ + FLAG_NORMAL = 0, + FLAG_EXEC_OTA = 1, +} OTA_FLAG; + + + +typedef struct +{ + unsigned int fileSize; + unsigned char md5sum[MD5_CHKSUM_LEN]; + int reserved[4]; +} IPL_DATA_ITEM, *PIPL_DATA_ITEM; + +typedef struct +{ + OTA_FILE_INFO fileInfo; + + char pPath[MAX_PATH]; + int dlStatus; + int retCode; + uv_barrier_t* puvBarrier; +} DOWNLOAD_TASK_INFO, *PDOWNLOAD_TASK_INFO; + +static char g_otaDownloadPath[MAX_PATH]; +static SETUP_MODE g_sSetupStatus = NORMAL_SETUP; + +static unsigned int g_IsOTAMode = 0; +static uv_barrier_t g_otaBarrier; +static uv_loop_t* g_pMainLoop = NULL; +static int g_isDownloading = FALSE; +static OTA_PARAMS g_otaParams; + +static void __ota_print_params(POTA_PARAMS pInfo, const char* pTips) +{ + LOG_EX2(LOG_Debug, "%s--------------------------\n", pTips ? pTips : ""); + LOG_EX2(LOG_Debug, "tags: %s\n", pInfo->tags); + LOG_EX2(LOG_Debug, "status: 0x%08X\n", pInfo->otaStatus); + LOG_EX2(LOG_Debug, "version: %s\n", pInfo->otaVer); + LOG_EX2(LOG_Debug, "boot_ver: %s\n", pInfo->bootChksum); + LOG_EX2(LOG_Debug, "boot_size: %u\n", pInfo->bootfileSize); + LOG_EX2(LOG_Debug, "rootfs_ver: %s\n", pInfo->rootfsChksum); + LOG_EX2(LOG_Debug, "rootfs_size: %u\n", pInfo->rootfsfileSize); + LOG_EX2(LOG_Debug, "params_chksum: %s\n", pInfo->paramsChksum); +} + +static void __printfOTANotifyCmd(const char* pTags, POTA_DATA_INFO pInfo) +{ + if(pTags && strlen(pTags) > 0) + { + LOG_EX2(LOG_Debug, "%s:\n", pTags); + LOG_EX2(LOG_Debug, "**************************************************************\n"); + } + + LOG_EX2(LOG_Debug, "Version : %d\n", pInfo->version); + LOG_EX2(LOG_Debug, "OTA Command : %d(0x%08X)\n", pInfo->otaCmd, pInfo->otaCmd); + LOG_EX2(LOG_Debug, "OTA Type : %d(0x%08X)\n", pInfo->otaMode, pInfo->otaMode); + + LOG_EX2(LOG_Debug, "---------------------------------------------------------\n"); + LOG_EX2(LOG_Debug, "\tURL : %s\n", pInfo->otaFileInfo.url); + LOG_EX2(LOG_Debug, "\tMD5 : %s\n", pInfo->otaFileInfo.md5); + LOG_EX2(LOG_Debug, "\tsize : %u\n", pInfo->otaFileInfo.size); +} + +static int __otaRspStatus(OTA_STATUS_TYPE type, int val) +{ + int ret = 0; + OTA_RSP_STATUS oStatus; + + if(OTA_ERR_CODE == type && val != 0) + { + g_IsOTAMode = FALSE; + } + + memset(&oStatus, 0, sizeof(OTA_RSP_STATUS)); + + oStatus.status = type; + oStatus.val = val; + + LOG_EX(LOG_Debug, "Rsponse: %d --> %d\n", type, val); + + if(type == OTA_UPGRADE_START || type == OTA_REBOOT_SYSTEM || type == OTA_RECOVERY_START) + { + ret = DBusJsonBoardcastCommand(NULL, 0xFFFFFFFF, CMD_OTA_STATUS, JSON_ENGINE_OTA_RSP, &oStatus, FALSE); + } + else + { + ret = DBusJsonSendToCommand(NULL, + g_pModInfoTable[MODULE_CONTROLLER].modAliase, + CMD_OTA_STATUS, + JSON_ENGINE_OTA_RSP, + &oStatus, FALSE); + } + + return (ret); +} + +void __onHttpResponseCb(void* pData, unsigned int size, const char* pReqUrl, const char* pDlPath, const char* pTaskUuid, int iFinished, void* pUserData) +{ + PDOWNLOAD_TASK_INFO pDlInfo = (PDOWNLOAD_TASK_INFO)pUserData; + + if(iFinished == 0) + { + LOG_EX(LOG_Debug, "Request(%s): [%s] --> [%s] Response: [%u] OK\n", pTaskUuid, pReqUrl, pDlPath, size); + } + else if(iFinished == 1) + { + LOG_EX(LOG_Error, "Request(%s): [%s] --> [%s] Response: [%u] Error\n", pTaskUuid, pReqUrl, pDlPath, size); + } + else + { + LOG_EX(LOG_Error, "Download Error Code: %d\n", iFinished); + } + + if(pDlInfo) + { + uv_thread_t uvThread; + pDlInfo->retCode = iFinished; + LOG_EX(LOG_Debug, "Cleanup barrier\n"); + uv_barrier_wait(pDlInfo->puvBarrier); + } + else + { + LOG_EX(LOG_Debug, "pDlInfo == NULL\n"); + } +} + +void __onProgressNotifyCb(const char* pReqUrl, const char* pTaskUuid, unsigned char uPercent, void* pUserData) +{ + static unsigned char preCnt = 0; + + if(preCnt != uPercent && uPercent != 0) + { + preCnt = uPercent; + __otaRspStatus(OTA_DOWNLOAD_PROGRESS, uPercent); + LOG_EX(LOG_Debug, "[%s]: %u%%\n", pReqUrl, uPercent); + } +} + +static int __ota_read_params(POTA_PARAMS pInfo) +{ + uv_fs_t uvOpen, uvRead, uvClose; + int ret, rdSize = 0; + unsigned char md5Buf[MD5_CHKSUM_LEN]; + char md5str[MD5_STR_LEN]; + + uv_loop_t* pLoop = g_pMainLoop; + uv_buf_t uvBuf = uv_buf_init((char*)pInfo, sizeof(OTA_PARAMS)); + + if(pInfo == NULL) + { + return (-ERR_INPUT_PARAMS); + } + + memset(md5str, 0, MD5_STR_LEN); + memset(pInfo, 0, sizeof(OTA_PARAMS)); + + ret = system("sync"); + + if(uv_fs_open(pLoop, &uvOpen, OTA_PARAMS_PARTITION, O_RDWR, 0, NULL) == -1) + { + LOG_EX(LOG_Error, "Open Partition %s Error\n", OTA_PARAMS_PARTITION); + return (-ERR_OPEN_FILE); + } + + if((rdSize = uv_fs_read(pLoop, &uvRead, uvOpen.result, &uvBuf, 1, -1, NULL)) != sizeof(OTA_PARAMS)) + { + LOG_EX(LOG_Error, "Read Partition Error: Read %d Bytes, Need Read %d Bytes %d\n", rdSize, sizeof(OTA_PARAMS)); + return (-ERR_READ_FILE); + } + + uv_fs_close(pLoop, &uvClose, uvOpen.result, NULL); + + if(strncmp(pInfo->tags, OTA_PARAMS_TAG, 8) != 0) + { + LOG_EX(LOG_Error, "Check Magic Head Error: [%s], need [%s]\n", pInfo->tags, OTA_PARAMS_TAG); + return (-ERR_NO_INIT_IPL3); + } + + EvpMD5HashBuf((const unsigned char*)pInfo, sizeof(OTA_PARAMS) - MD5_STR_LEN, md5Buf, &rdSize); + + IHW_bin2hex(md5str, md5Buf, MD5_CHKSUM_LEN); + + if(strcmp(pInfo->paramsChksum, md5str) != 0) + { + LOG_EX(LOG_Error, "Verify MD5 Error: %s --> %s\n", md5str, pInfo->paramsChksum); + return (-ERR_BAD_IPL3); + } + + return (0); +} + +static int __ota_save_params(POTA_PARAMS pInfo) +{ + int ret, wrSize = 0; + uv_fs_t uvOpen, uvWrite, uvSync, uvClose; + unsigned char md5Buf[MD5_CHKSUM_LEN]; + char buf[MAX_PATH]; + char cmd[MAX_PATH]; + char md5str[MD5_STR_LEN]; + + uv_loop_t* pLoop = g_pMainLoop; + uv_buf_t uvBuf = uv_buf_init((char*)pInfo, sizeof(OTA_PARAMS)); + + if(pInfo == NULL) + { + return (-ERR_INPUT_PARAMS); + } + + memset(md5str, 0, MD5_STR_LEN); + + if(strncmp(pInfo->tags, OTA_PARAMS_TAG, 8) != 0) + { + memset(pInfo->tags , 0, 8); + strcpy(pInfo->tags, OTA_PARAMS_TAG); + } + + EvpMD5HashBuf((const unsigned char *)pInfo, sizeof(OTA_PARAMS) - MD5_STR_LEN, md5Buf, &wrSize); + + if(wrSize != MD5_CHKSUM_LEN) + { + LOG_EX(LOG_Error, "Error MD5: size = %d, need %d\n", wrSize, MD5_CHKSUM_LEN); + return (-ERR_BAD_IPL3); + } + + IHW_bin2hex(md5str, md5Buf, MD5_CHKSUM_LEN); + memset(pInfo->paramsChksum, 0, MD5_STR_LEN); + strcpy(pInfo->paramsChksum, md5str); + + memset(buf, 0, MAX_PATH); + ret = system("mkdir -p /tmp/ota_param/"); + sprintf(buf, "/tmp/ota_param/ota_%s.params", pInfo->otaVer); + + if(uv_fs_open(pLoop, &uvOpen, buf, O_RDWR | O_CREAT | O_TRUNC, + S_IRUSR | S_IWUSR, NULL) == -1) + { + LOG_EX(LOG_Error, "Open File %s Error\n", buf); + return (-ERR_OPEN_FILE); + } + + if((wrSize = uv_fs_write(pLoop, &uvWrite, uvOpen.result, &uvBuf, 1, -1, NULL)) != sizeof(OTA_PARAMS)) + { + LOG_EX(LOG_Error, "Write Error: Read %d Bytes, Need Read %d Bytes %d\n", wrSize, sizeof(OTA_PARAMS)); + return (-ERR_READ_FILE); + } + + uv_fs_fdatasync(pLoop, &uvSync, uvOpen.result, NULL); + uv_fs_close(pLoop, &uvClose, uvOpen.result, NULL); + + memset(cmd, 0, MAX_PATH); + sprintf(cmd, "dd if=%s of=/dev/by-name/ota_info bs=4k conv=sync > /dev/zero && sync", buf); + + ret = system(cmd); + + return (0); +} + +static int __otaRunning(char* pCheckSumFile, int ver) +{ + ssize_t rdRet; + size_t rdSize; + unsigned char strMD5[MD5_CHKSUM_STR_LEN]; + char dirPath[MAX_PATH]; + char basePath[MAX_PATH]; + const char *pChkMD5 = NULL; + char *pRdLine = NULL; + char *pChkSumFile = pCheckSumFile; + FILE *pFile = fopen(pChkSumFile, "r"); + int ret, i = 0; + int step = 0; + + if(pFile == NULL) + { + LOG_EX(LOG_Error, "Open File %s Error\n", pChkSumFile); + return (-ERR_OPEN_FILE); + } + + memset(dirPath, 0, MAX_PATH); + dirname_v2(pChkSumFile, dirPath); + + LOG_EX(LOG_Debug, "Step %d: Check OTA image .......\n", step++); + // check download ota file + while((rdRet = getline(&pRdLine, &rdSize, pFile)) != -1) + { + char* pToken = NULL; + char *pItem[2]; + char pMD5Val[MD5_CHKSUM_LEN]; + char pMD5Str[MD5_CHKSUM_STR_LEN]; + int fileSize = 0; + + if(rdSize == 0 || pRdLine == NULL) + { + continue; + } + + if(pRdLine[strlen(pRdLine) - 1] == '\n') + { + pRdLine[strlen(pRdLine) - 1] = 0; + } + + i = 0; + + for(pToken = strtok(pRdLine, " "); pToken != NULL && i <= 1; pToken = strtok(NULL, " "), i++) + { + pItem[i] = pToken; + } + + //fprintf(stdout, "md5 = %s, file = \'%s\'\n", pItem[0], pItem[1]); + + if(pItem[0] == NULL || pItem[1] == NULL || strlen(pItem[0]) != 32 || strlen(pItem[1]) == 0) + { + free(pRdLine); + fclose(pFile); + return (-ERR_MD5_CHECK_SUM); + } + + memset(basePath, 0, MAX_PATH); + sprintf(basePath, "%s/%s", dirPath, pItem[1]); + + LOG_EX(LOG_Debug, "OTA File: %s --> %s\n", basePath, pItem[0]); + + if((ret = EvpMD5HashFileV2(basePath, pMD5Val)) != 0) + { + free(pRdLine); + fclose(pFile); + LOG_EX(LOG_Error, "%s Check MD5 error: %d\n", ret); + return (-ERR_MD5_FILE); + } + + memset(pMD5Str, 0, MD5_CHKSUM_STR_LEN); + IHW_bin2hex(pMD5Str, pMD5Val, MD5_CHKSUM_LEN); + + //LOG_EX(LOG_Debug, "%s Check MD5 Info: [%s] need [%s]\n", basePath, pMD5Str, pItem[0]); + + if(strcmp(pMD5Str, pItem[0]) != 0) + { + free(pRdLine); + fclose(pFile); + LOG_EX(LOG_Error, "%s Check MD5 error: [%s] need [%s]\n", basePath, pMD5Str, pItem[0]); + return (-ERR_MD5_FILE); + } + + if(strcmp(pItem[1], BOOT_IMG_FILE_NAME) == 0) + { + GET_FILE_SIZE(basePath, fileSize); + memset(g_otaParams.bootChksum, 0, MD5_STR_LEN); + strncpy(g_otaParams.bootChksum, pMD5Str, MD5_STR_LEN); + g_otaParams.bootfileSize = fileSize; + } + else if(strcmp(pItem[1], ROOTFS_IMG_FILE_NAME) == 0) + { + GET_FILE_SIZE(basePath, fileSize); + memset(g_otaParams.rootfsChksum, 0, MD5_STR_LEN); + strncpy(g_otaParams.rootfsChksum, pMD5Str, MD5_STR_LEN); + g_otaParams.rootfsfileSize = fileSize; + } + } + + if(pRdLine) + { + free(pRdLine); + } + fclose(pFile); + + __otaRspStatus(OTA_VERIFY_FILE, NO_OTA_STATUS_VAL_TAG); + + LOG_EX(LOG_Debug, "Step %d: Save OTA Information .......\n", step++); + + memset(g_otaParams.otaVer, 0, MD5_STR_LEN); + sprintf(g_otaParams.otaVer, "%d.%d.%d.%d", + (ver >> 24) & 0xFF, + (ver >> 16) & 0xFF, + (ver >> 8) & 0xFF, + ver & 0xFF); + + SET_STA_CMD(g_otaParams.otaStatus, CMD_RUN_OTA); + + ret = __ota_save_params(&g_otaParams); + + if(ret != 0) + { + LOG_EX(LOG_Error, "Save OTA Params Error: %d\n", ret); + return (-ERR_OTA_WRITE_PARAMS); + } + + //print_hex_dump_bytes("IPL3", DUMP_PREFIX_ADDRESS, &g_iplInfo, sizeof(IPL_DATA_INFO)); + __ota_print_params(&g_otaParams, "OTA Finished"); + + LOG_EX(LOG_Debug, "Step %d: Waitting for reboot ......\n", step++); + + return (0); +} + +static void __otaFromLocalImage(void* pParams) +{ + int ret, reTry; + int step = 0; + char buf[MAX_PATH]; + char* pFileName = NULL, *pMD5Val = NULL; + const char* pMD5Chk = NULL; + int version = (int)(intptr_t)pParams; + + LOG_EX(LOG_Debug, "Step %d: Get OTA information .......\n", step++); + memset(buf, 0, MAX_PATH); + sprintf(buf, "%s/ota.md5", g_otaDownloadPath); + + if(access(buf, F_OK) != 0) + { + __otaRspStatus(OTA_ERR_CODE, -ERR_FILE_NOT_EXISTS); + g_IsOTAMode = FALSE; + return; + } + + memset(buf, 0, MAX_PATH); + sprintf(buf, "cat %s/ota.md5 | awk '{print $2}'", g_otaDownloadPath); + + if(GetShellExecResult(buf, &pFileName) != 0) + { + LOG_EX(LOG_Error, "Get File Name Error: %s\n", buf); + __otaRspStatus(OTA_ERR_CODE, -ERR_READ_FILE); + g_IsOTAMode = FALSE; + return; + } + + memset(buf, 0, MAX_PATH); + sprintf(buf, "cat %s/ota.md5 | awk '{print $1}'", g_otaDownloadPath); + + if(GetShellExecResult(buf, &pMD5Val) != 0) + { + LOG_EX(LOG_Error, "Get MD5 Value Error: %s\n", buf); + free(pFileName); + __otaRspStatus(OTA_ERR_CODE, -ERR_READ_FILE); + g_IsOTAMode = FALSE; + return; + } + + LOG_EX(LOG_Debug, "Step %d: Verify OTA image .......\n", step++); + + memset(buf, 0, MAX_PATH); + sprintf(buf, "%s/%s", g_otaDownloadPath, pFileName); + + pMD5Chk = EvpMD5HashFile(buf); + + if(strcmp(pMD5Chk, pMD5Val) != 0) + { + LOG_EX(LOG_Error, "Check %s MD5 Error: %s --> %s\n", buf, pMD5Chk, pMD5Val); + __otaRspStatus(OTA_ERR_CODE, -ERR_MD5_CHECK_SUM); + g_IsOTAMode = FALSE; + return; + } + + free(pMD5Val); + free(pFileName); + free((void*)pMD5Chk); + + LOG_EX(LOG_Debug, "Step %d: Decompress OTA file .......\n", step++); + + pFileName = strdup(buf); + + __otaRspStatus(OTA_DECOMPRESS_FILE, NO_OTA_STATUS_VAL_TAG); + + memset(buf, 0, MAX_PATH); + sprintf(buf, "mkdir -p %s/%d/ && tar -C %s/%d -xvzf %s > /dev/null", + OTA_TEMP_DIR, version, + OTA_TEMP_DIR, version, + pFileName); + free(pFileName); + + ret = system(buf); + + SetHBLAutoExit(FALSE); + __otaRspStatus(OTA_UPGRADE_START, NO_OTA_STATUS_VAL_TAG); + + memset(buf, 0, MAX_PATH); + sprintf(buf, "%s/%d/ota.md5", OTA_TEMP_DIR, version); + + reTry = 3; + while(reTry--) + { + if((ret = __otaRunning(buf, version)) == 0) + { + break; + } + } + + if(ret == 0) + { + ret = system("rm -f /mnt/UDISK/ota/*.img /mnt/UDISK/ota/*.md5 > /dev/null"); + + memset(buf, 0, MAX_PATH); + sprintf(buf, "cp %s/%d/* /mnt/UDISK/ota > /dev/null", OTA_TEMP_DIR, version); + ret = system(buf); + + memset(buf, 0, MAX_PATH); + sprintf(buf, "rm %s/* > /dev/null", g_otaDownloadPath); + ret = system(buf); + } + + if(ret == ERR_OPEN_FILE + || ret == ERR_MD5_FILE + || ret == ERR_MD5_CHECK_SUM + || ret == ERR_OTA_WRITE_BOOT + || ret == ERR_OTA_WRITE_ROOTFS + || ret == ERR_OTA_WRITE_PARAMS) + { + __otaRspStatus(OTA_ERR_CODE, -12345); + } + + __otaRspStatus(OTA_REBOOT_SYSTEM, NO_OTA_STATUS_VAL_TAG); + + reTry = 300; + + while(reTry--) + { + LOG_EX(LOG_Debug, "System force reboot before %d seconds\n", reTry); + sleep(1); + } + + while(TRUE) + { + ret = system("reboot -f"); + sleep(5); + } + + return; +} + +static int __isPreDownloader(POTA_DATA_INFO pInfo) +{ + UT_string* pDlPath = NULL, *pChkPath = NULL; + + char* pFileName = NULL, *pMD5Val = NULL; + const char* pMD5Chk = NULL; + + if(pInfo == NULL) + { + return (-ERR_FILE_NOT_EXISTS); + } + + utstring_new(pDlPath); + utstring_new(pChkPath); + utstring_printf(pDlPath, "%s/tina_r16_ota_%d.tar.gz", g_otaDownloadPath, pInfo->version); + utstring_printf(pChkPath, "%s/ota.md5", g_otaDownloadPath); + + if(access(utstring_body(pDlPath), F_OK) != 0 + || access(utstring_body(pChkPath), F_OK) != 0) + { + utstring_free(pDlPath); + utstring_free(pChkPath); + return (-ERR_FILE_NOT_EXISTS); + } + + utstring_renew(pChkPath); + utstring_printf(pChkPath, "cat %s/ota.md5 | awk '{print $2}'", g_otaDownloadPath); + + if(GetShellExecResult(utstring_body(pChkPath), &pFileName) != 0) + { + LOG_EX(LOG_Error, "Get File Name Error: %s\n", utstring_body(pChkPath)); + utstring_free(pDlPath); + utstring_free(pChkPath); + return -ERR_FILE_NOT_EXISTS; + } + + utstring_renew(pChkPath); + utstring_printf(pChkPath, "cat %s/ota.md5 | awk '{print $1}'", g_otaDownloadPath); + + if(GetShellExecResult(utstring_body(pChkPath), &pMD5Val) != 0) + { + LOG_EX(LOG_Error, "Get MD5 Value Error: %s\n", utstring_body(pChkPath)); + free(pFileName); + utstring_free(pDlPath); + utstring_free(pChkPath); + return -ERR_MD5_CHECK_SUM; + } + + if(strcmp(pMD5Val, pInfo->otaFileInfo.md5) != 0) + { + LOG_EX(LOG_Debug, "Download File Chksum Diff: %s -> %s\n", pMD5Val, pInfo->otaFileInfo.md5); + free(pFileName); + free(pMD5Val); + utstring_free(pDlPath); + utstring_free(pChkPath); + return -ERR_FILE_NOT_EXISTS; + } + + utstring_renew(pChkPath); + utstring_printf(pChkPath, "%s/%s", g_otaDownloadPath, pFileName); + + pMD5Chk = EvpMD5HashFile(utstring_body(pChkPath)); + + if(pMD5Chk == NULL || strcmp(pMD5Chk, pMD5Val) != 0) + { + LOG_EX(LOG_Error, "Check %s MD5 Error: %s --> %s\n", utstring_body(pChkPath), pMD5Chk, pMD5Val); + free(pFileName); + free(pMD5Val); + utstring_free(pDlPath); + utstring_free(pChkPath); + + if(pMD5Chk) + { + free((void*)pMD5Chk); + } + + return -ERR_MD5_CHECK_SUM; + } + + free(pMD5Val); + free(pFileName); + free((void*)pMD5Chk); + utstring_free(pDlPath); + utstring_free(pChkPath); + + return (0); +} + +static void __otaDownloadImageCb(void* pParams) +{ + POTA_DATA_INFO pInfo = (POTA_DATA_INFO)pParams; + DOWNLOAD_TASK_INFO dlInfo; + char buf[SIZE_1K]; + int ret, reTry = 3; + + g_isDownloading = TRUE; + + // Notify CC Beging Download + __otaRspStatus(OTA_DOWNLOAD_FILE, 2); + + if(__isPreDownloader(pInfo) == 0) + { + g_isDownloading = FALSE; + g_IsOTAMode = FALSE; + __otaRspStatus(OTA_DOWNLOAD_PROGRESS, 100); + __otaRspStatus(OTA_DOWNLOAD_FILE, 0); + + if(pInfo->otaMode == OTA_MODE_FORCE_NOW) + { + g_IsOTAMode = TRUE; + __otaFromLocalImage((void*)(intptr_t)pInfo->version); + g_IsOTAMode = FALSE; + } + + free(pInfo); + pthread_detach(pthread_self()); + return; + } + + while(reTry--) + { + uv_barrier_t uvBarrier; + uv_barrier_init(&uvBarrier, 2); + + memset(buf, 0, SIZE_1K); + sprintf(buf, "rm -rf %s/*", g_otaDownloadPath); + ret = system(buf); + + memset(&dlInfo, 0, sizeof(DOWNLOAD_TASK_INFO)); + sprintf(dlInfo.pPath, "%s/tina_r16_ota_%d.tar.gz", g_otaDownloadPath, pInfo->version); + + memcpy(&dlInfo.fileInfo, &pInfo->otaFileInfo, sizeof(OTA_FILE_INFO)); + + dlInfo.dlStatus = 0; + + dlInfo.puvBarrier = &uvBarrier; + + InetHttpDlFileAsync(dlInfo.fileInfo.url, + dlInfo.pPath, + __onHttpResponseCb, + __onProgressNotifyCb, + &dlInfo); + + LOG_EX(LOG_Debug, ">>>>>>>>>>>>>>>>>>>Wait Download Finished.............\n"); + uv_barrier_wait(&uvBarrier); + uv_barrier_destroy(&uvBarrier); + LOG_EX(LOG_Debug, "<<<<<<<<<<<<<<<<<<otaFileInfo.md5) != 0) + { + LOG_EX(LOG_Error, "Download File MD5 Error: %s --> %s\n", pChkVal, pInfo->otaFileInfo.md5); + dlInfo.retCode = -ERR_MD5_CHECK_SUM; + } + else + { + break; + } + } + } + + if(dlInfo.retCode != 0) + { + ret = system(buf); + g_IsOTAMode = FALSE; + g_isDownloading = FALSE; + + if(dlInfo.retCode > 0) + { + dlInfo.retCode = -dlInfo.retCode; + } + + __otaRspStatus(OTA_DOWNLOAD_FILE, dlInfo.retCode); + pthread_detach(pthread_self()); + free(pInfo); + return; + } + + LOG_EX(LOG_Debug, "Step 1: Download File result: %d\n", dlInfo.retCode); + + memset(buf, 0, SIZE_1K); + sprintf(buf, "echo \"%s %s\" > %s/ota.md5", + dlInfo.fileInfo.md5, basename_v2(dlInfo.pPath), g_otaDownloadPath); + + ret = system(buf); + + LOG_EX(LOG_Debug, "Step 2: Save MD5 File; %d\n", ret); + + g_IsOTAMode = FALSE; + __otaRspStatus(OTA_DOWNLOAD_FILE, 0); + + if(pInfo->otaMode == OTA_MODE_FORCE_NOW) + { + g_IsOTAMode = TRUE; + __otaFromLocalImage((void*)(intptr_t)pInfo->version); + g_IsOTAMode = FALSE; + } + + free(pInfo); + + g_isDownloading = FALSE; + + pthread_detach(pthread_self()); +} + +static PDBUS_MSG_PACK __dBusOnMessage(uv_loop_t* pLoop, DBusConnection* pConn, PDBUS_MSG_PACK pMsg) +{ + int err; + uv_thread_t uvThread; + POTA_DATA_INFO pInfo = NULL; + + if(!pMsg || !pLoop || !pConn) + { + return NULL; + } + + //fprintf(stdout, "Recv: cmd = %u, Json = [%s]\n", pMsg->busCmd, (const char *)pMsg->pMsg); + + switch(pMsg->busCmd) + { + case CMD_OTA_RUNNOW: + if(g_IsOTAMode == 1) + { + LOG_EX(LOG_Info, "Trigger OTA Now.......\n"); + uv_barrier_wait(&g_otaBarrier); + } + else + { + __otaRspStatus(OTA_ERR_CODE, -ERR_OTA_NOT_READY); + LOG_EX(LOG_Error, "Current Not In OTA Mode\n"); + } + + break; + + case CMD_MISC_QUERY_DL_STATUS: + if(g_isDownloading) + { + __otaRspStatus(OTA_DOWNLOAD_FILE, 1); + } + else + { + __otaRspStatus(OTA_DOWNLOAD_FILE, 0); + } + + break; + + case CMD_MISC_QUERY_OTA_STATUS: + if(g_sSetupStatus == SYSTEM_OTA_OK) + { + __otaRspStatus(OTA_SUCCESED, 0); + } + else if(g_sSetupStatus == RECOVERY_SETUP) + { + __otaRspStatus(OTA_SUCCESED, -1); + } + else if(g_sSetupStatus == NORMAL_SETUP) + { + __otaRspStatus(OTA_SUCCESED, 1); + } + + __otaRspStatus(OTA_CURRENT_VERSION, 0); + __otaRspStatus(OTA_CURRENT_SETUP_MODE, g_sSetupStatus); + __otaRspStatus(OTA_CURRENT_REBOOT_TIME, GET_STA_CNT(g_otaParams.otaStatus)); + break; + + case CMD_SYSTEM_STANDBY: + LOG_EX(LOG_Debug, "System Ready ....\n"); + break; + + case CMD_OTA_NOTIFY: + + if(g_IsOTAMode == 0) + { + if(g_sSetupStatus == SYSTEM_OTA) + { + LOG_EX(LOG_Debug, "Current System Mode: SYSTEM_OTA\n"); + } + else if(g_sSetupStatus == RECOVERY_SETUP) + { + LOG_EX(LOG_Debug, "Current System Mode: RECOVERY_SETUP\n"); + } + else if(g_sSetupStatus == SYSTEM_OTA_OK) + { + LOG_EX(LOG_Debug, "Current System Mode: SYSTEM_OTA_OK\n"); + } + else + { + LOG_EX(LOG_Debug, "Current System Mode: NORMAL_SETUP\n"); + } + + if(g_isDownloading) + { + __otaRspStatus(OTA_DOWNLOAD_FILE, 1); + break; + } + + pInfo = (POTA_DATA_INFO)Json2Struct((const char*)pMsg->pMsg, JSON_ENGINE_OTA_REQ, TRUE, &err); + + if(pInfo == NULL) + { + __otaRspStatus(OTA_ERR_CODE, -ERR_INPUT_PARAMS); + } + else + { + unsigned long long uDiskFreeSize = GetPartitionFreeSize("/mnt/UDISK/"); + unsigned long long uUsedSize = 0; + + g_IsOTAMode = TRUE; +#if TEST_OTA_SERVER + memset(&pInfo->otaFileInfo, 0, sizeof(OTA_FILE_INFO)); + strcpy(pInfo->otaFileInfo.md5, "78bcf3236f54543301ee1a2f74282917"); + strcpy(pInfo->otaFileInfo.url, "http://10.240.84.163/tina_r16_ota_2.tar.gz"); + pInfo->otaFileInfo.size = 57106052; +#endif + __printfOTANotifyCmd("On OTA Notify Command++", pInfo); + + uUsedSize = pInfo->otaFileInfo.size + (1024 * 1024 * 10); + + if(uUsedSize > uDiskFreeSize) + { + LOG_EX(LOG_Error, "Error: File Size = %u bytes, Need %llu bytes, UDISK Free %llu bytes\n", + pInfo->otaFileInfo.size, uUsedSize, uDiskFreeSize); + + g_IsOTAMode = FALSE; + __otaRspStatus(OTA_DISK_FULL, pInfo->otaCmd); + break; + } + + switch(pInfo->otaCmd) + { + case OTA_CMD_DOWNLOAD: + if(strlen(pInfo->otaFileInfo.md5) == 0 + || strlen(pInfo->otaFileInfo.url) == 0) + { + g_IsOTAMode = FALSE; + LOG_EX(LOG_Error, "OTA Information Error\n"); + } + else + { + err = uv_thread_create(&uvThread, __otaDownloadImageCb, pInfo); + + if(err != 0) + { + LOG_EX(LOG_Error, "Create Thread Error: %d\n", err); + } + } + + break; + + case OTA_CMD_USED_LOCAL_IMAGE: + case OTA_CMD_EXEC: + err = uv_thread_create(&uvThread, __otaFromLocalImage, (void*)(intptr_t)pInfo->version); + + if(err != 0) + { + LOG_EX(LOG_Error, "Create Thread Error: %d\n", err); + } + + free(pInfo); + break; + + default: + __otaRspStatus(OTA_UNKNOWN_CMD, pInfo->otaCmd); + free(pInfo); + break; + } + } + } + else + { + __otaRspStatus(OTA_ERR_CODE, -ERR_OTA_PRE_STATR); + } + + break; + + default: + break; + } + + return NULL; +} + +int main(int argc, char** argv) +{ + int i, ret = 0; + char buf[256]; + DBusConnection* pBus; + int otaCmd, otaFlag, cnt; + + //struct tm *pTm = NULL; + g_pMainLoop = GetDBusDefaultLoop(); + + pBus = DBusWithLibuvInit(g_pMainLoop, + g_pModInfoTable[MODULE_OTA].modAliase, + __dBusOnMessage, + NULL, + NULL, + &ret); + + if(pBus == NULL) + { + fprintf(stderr, "DBusWithLibuvInit Error: %d\n", ret); + return (-1); + } + + g_IsOTAMode = 0; + strcpy(g_otaDownloadPath, OTA_FILE_DOWNLOAD_DIR); + + memset(buf, 0, 256); + sprintf(buf, "mkdir -p %s", OTA_FILE_DOWNLOAD_DIR); + ret = system(buf); + + if(__ota_read_params(&g_otaParams) == 0) + { + __ota_print_params(&g_otaParams, "System setup"); + } + + otaCmd = GET_STA_CMD(g_otaParams.otaStatus); + otaFlag = GET_STA_FLAG(g_otaParams.otaStatus); + ret = GET_STA_ERR(g_otaParams.otaStatus); + cnt = GET_STA_CNT(g_otaParams.otaStatus); + + if(ret != 0) + { + LOG_EX(LOG_Error, "System setup error: code = %d, flag = %d, otaCmd = %d\n", + ret, otaFlag, otaCmd); + } + + if(cnt >= 3) + { + LOG_EX(LOG_Error, "Reboot more than %d times\n", cnt); + } + + if(otaFlag == FLAG_EXEC_OTA) + { + g_sSetupStatus = SYSTEM_OTA_OK; + } + else if(otaFlag == FLAG_NORMAL) + { + g_sSetupStatus = NORMAL_SETUP; + } + + SET_STA_CNT(g_otaParams.otaStatus, 0); + SET_STA_CMD(g_otaParams.otaStatus, CMD_RUN_BOOT); + SET_STA_FLAG(g_otaParams.otaStatus, FLAG_NORMAL); + + __ota_save_params(&g_otaParams); + + // Make sure continue last download task + __otaRspStatus(OTA_DOWNLOAD_FILE, -28); + __otaRspStatus(OTA_CURRENT_VERSION, 0); + + RunUVLoop(g_pMainLoop); + + return (0); +} + diff --git a/res/system_resources/Makefile b/res/system_resources/Makefile new file mode 100644 index 0000000..eec6c19 --- /dev/null +++ b/res/system_resources/Makefile @@ -0,0 +1,34 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=pv1res +PKG_RELEASE:=1 +PKG_VERSION:=0.0.1 + +PKG_BUILD_DIR := $(COMPILE_DIR)/$(PKG_NAME) + +include $(BUILD_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=utils + CATEGORY:=Netease + TITLE:=System Resource Files +endef + +define Package/$(PKG_NAME)/description + $(PKG_NAME) System used sound, picture resources. +endef + +define Build/Configure +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/install + $(INSTALL_DIR) $(1)/usr/share/resource/voice + $(INSTALL_DIR) $(1)/usr/share/resource/image + $(INSTALL_BIN) resource/voice/* $(1)/usr/share/resource/voice/ + $(INSTALL_BIN) resource/image/* $(1)/usr/share/resource/image/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/res/system_resources/resource/image/IconChaozuo001.jpg b/res/system_resources/resource/image/IconChaozuo001.jpg new file mode 100644 index 0000000..ebb781e Binary files /dev/null and b/res/system_resources/resource/image/IconChaozuo001.jpg differ diff --git a/res/system_resources/resource/image/IconChaozuo005.jpg b/res/system_resources/resource/image/IconChaozuo005.jpg new file mode 100644 index 0000000..7e882ad Binary files /dev/null and b/res/system_resources/resource/image/IconChaozuo005.jpg differ diff --git a/res/system_resources/resource/image/IconLianjie001.jpg b/res/system_resources/resource/image/IconLianjie001.jpg new file mode 100644 index 0000000..3d07c05 Binary files /dev/null and b/res/system_resources/resource/image/IconLianjie001.jpg differ diff --git a/res/system_resources/resource/image/IconLianjie002.jpg b/res/system_resources/resource/image/IconLianjie002.jpg new file mode 100644 index 0000000..c64910c Binary files /dev/null and b/res/system_resources/resource/image/IconLianjie002.jpg differ diff --git a/res/system_resources/resource/image/IconLianjie003.jpg b/res/system_resources/resource/image/IconLianjie003.jpg new file mode 100644 index 0000000..b4dc834 Binary files /dev/null and b/res/system_resources/resource/image/IconLianjie003.jpg differ diff --git a/res/system_resources/resource/image/IconNaozhong001.jpg b/res/system_resources/resource/image/IconNaozhong001.jpg new file mode 100644 index 0000000..fe96da0 Binary files /dev/null and b/res/system_resources/resource/image/IconNaozhong001.jpg differ diff --git a/res/system_resources/resource/image/IconTixing001.jpg b/res/system_resources/resource/image/IconTixing001.jpg new file mode 100644 index 0000000..74d323a Binary files /dev/null and b/res/system_resources/resource/image/IconTixing001.jpg differ diff --git a/res/system_resources/resource/image/IconZhuangtai003.gif b/res/system_resources/resource/image/IconZhuangtai003.gif new file mode 100644 index 0000000..5d85a05 Binary files /dev/null and b/res/system_resources/resource/image/IconZhuangtai003.gif differ diff --git a/res/system_resources/resource/image/Iconlianwang001.gif b/res/system_resources/resource/image/Iconlianwang001.gif new file mode 100644 index 0000000..2be79b5 Binary files /dev/null and b/res/system_resources/resource/image/Iconlianwang001.gif differ diff --git a/res/system_resources/resource/image/Iconlianwang005.gif b/res/system_resources/resource/image/Iconlianwang005.gif new file mode 100644 index 0000000..db09b13 Binary files /dev/null and b/res/system_resources/resource/image/Iconlianwang005.gif differ diff --git a/res/system_resources/resource/image/Iconstart002.gif b/res/system_resources/resource/image/Iconstart002.gif new file mode 100644 index 0000000..ca8bd3d Binary files /dev/null and b/res/system_resources/resource/image/Iconstart002.gif differ diff --git a/res/system_resources/resource/image/Iconyinliang000.jpg b/res/system_resources/resource/image/Iconyinliang000.jpg new file mode 100644 index 0000000..b3d321c Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang000.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang001.jpg b/res/system_resources/resource/image/Iconyinliang001.jpg new file mode 100644 index 0000000..6816ea6 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang001.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang002.jpg b/res/system_resources/resource/image/Iconyinliang002.jpg new file mode 100644 index 0000000..6816ea6 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang002.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang003.jpg b/res/system_resources/resource/image/Iconyinliang003.jpg new file mode 100644 index 0000000..6816ea6 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang003.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang004.jpg b/res/system_resources/resource/image/Iconyinliang004.jpg new file mode 100644 index 0000000..a5a5199 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang004.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang005.jpg b/res/system_resources/resource/image/Iconyinliang005.jpg new file mode 100644 index 0000000..9ed8674 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang005.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang006.jpg b/res/system_resources/resource/image/Iconyinliang006.jpg new file mode 100644 index 0000000..9ed8674 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang006.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang007.jpg b/res/system_resources/resource/image/Iconyinliang007.jpg new file mode 100644 index 0000000..549c9b3 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang007.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang008.jpg b/res/system_resources/resource/image/Iconyinliang008.jpg new file mode 100644 index 0000000..ec7406d Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang008.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang009.jpg b/res/system_resources/resource/image/Iconyinliang009.jpg new file mode 100644 index 0000000..e35602a Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang009.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang010.jpg b/res/system_resources/resource/image/Iconyinliang010.jpg new file mode 100644 index 0000000..9663886 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang010.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang011.jpg b/res/system_resources/resource/image/Iconyinliang011.jpg new file mode 100644 index 0000000..8780f8c Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang011.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang012.jpg b/res/system_resources/resource/image/Iconyinliang012.jpg new file mode 100644 index 0000000..a2a5ab7 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang012.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang013.jpg b/res/system_resources/resource/image/Iconyinliang013.jpg new file mode 100644 index 0000000..ddfbea1 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang013.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang014.jpg b/res/system_resources/resource/image/Iconyinliang014.jpg new file mode 100644 index 0000000..ddfbea1 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang014.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang015.jpg b/res/system_resources/resource/image/Iconyinliang015.jpg new file mode 100644 index 0000000..19f3c6f Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang015.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang016.jpg b/res/system_resources/resource/image/Iconyinliang016.jpg new file mode 100644 index 0000000..fbe9353 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang016.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang017.jpg b/res/system_resources/resource/image/Iconyinliang017.jpg new file mode 100644 index 0000000..949048b Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang017.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang018.jpg b/res/system_resources/resource/image/Iconyinliang018.jpg new file mode 100644 index 0000000..f3a75d0 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang018.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang019.jpg b/res/system_resources/resource/image/Iconyinliang019.jpg new file mode 100644 index 0000000..9b0ecab Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang019.jpg differ diff --git a/res/system_resources/resource/image/Iconyinliang020.jpg b/res/system_resources/resource/image/Iconyinliang020.jpg new file mode 100644 index 0000000..6208e15 Binary files /dev/null and b/res/system_resources/resource/image/Iconyinliang020.jpg differ diff --git a/res/system_resources/resource/voice/Alianwang002.mp3 b/res/system_resources/resource/voice/Alianwang002.mp3 new file mode 100644 index 0000000..da381f8 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang002.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang003.mp3 b/res/system_resources/resource/voice/Alianwang003.mp3 new file mode 100644 index 0000000..ff5a6e3 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang003.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang004.mp3 b/res/system_resources/resource/voice/Alianwang004.mp3 new file mode 100644 index 0000000..ed4f40f Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang004.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang005.mp3 b/res/system_resources/resource/voice/Alianwang005.mp3 new file mode 100644 index 0000000..248d1db Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang005.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang006.mp3 b/res/system_resources/resource/voice/Alianwang006.mp3 new file mode 100644 index 0000000..6e91fbd Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang006.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang007.mp3 b/res/system_resources/resource/voice/Alianwang007.mp3 new file mode 100644 index 0000000..cc02636 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang007.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang008.mp3 b/res/system_resources/resource/voice/Alianwang008.mp3 new file mode 100644 index 0000000..2f05a0f Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang008.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang009.mp3 b/res/system_resources/resource/voice/Alianwang009.mp3 new file mode 100644 index 0000000..5c97f58 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang009.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang010.mp3 b/res/system_resources/resource/voice/Alianwang010.mp3 new file mode 100644 index 0000000..fc6b2cb Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang010.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang011.mp3 b/res/system_resources/resource/voice/Alianwang011.mp3 new file mode 100644 index 0000000..3c2576a Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang011.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang012.mp3 b/res/system_resources/resource/voice/Alianwang012.mp3 new file mode 100644 index 0000000..98cf376 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang012.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang013.mp3 b/res/system_resources/resource/voice/Alianwang013.mp3 new file mode 100644 index 0000000..c319dc1 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang013.mp3 differ diff --git a/res/system_resources/resource/voice/Alianwang014.mp3 b/res/system_resources/resource/voice/Alianwang014.mp3 new file mode 100644 index 0000000..c01d566 Binary files /dev/null and b/res/system_resources/resource/voice/Alianwang014.mp3 differ diff --git a/res/system_resources/resource/voice/Ashiyong002.mp3 b/res/system_resources/resource/voice/Ashiyong002.mp3 new file mode 100644 index 0000000..665ae97 Binary files /dev/null and b/res/system_resources/resource/voice/Ashiyong002.mp3 differ diff --git a/res/system_resources/resource/voice/Ashiyong003.mp3 b/res/system_resources/resource/voice/Ashiyong003.mp3 new file mode 100644 index 0000000..c5c0e76 Binary files /dev/null and b/res/system_resources/resource/voice/Ashiyong003.mp3 differ diff --git a/res/system_resources/resource/voice/Ashiyong004.mp3 b/res/system_resources/resource/voice/Ashiyong004.mp3 new file mode 100644 index 0000000..4c1cf62 Binary files /dev/null and b/res/system_resources/resource/voice/Ashiyong004.mp3 differ diff --git a/res/system_resources/resource/voice/Ashiyong005.mp3 b/res/system_resources/resource/voice/Ashiyong005.mp3 new file mode 100644 index 0000000..3d20ee8 Binary files /dev/null and b/res/system_resources/resource/voice/Ashiyong005.mp3 differ diff --git a/res/system_resources/resource/voice/Ashiyong006.mp3 b/res/system_resources/resource/voice/Ashiyong006.mp3 new file mode 100644 index 0000000..f6834db Binary files /dev/null and b/res/system_resources/resource/voice/Ashiyong006.mp3 differ diff --git a/res/system_resources/resource/voice/B-b-1.mp3 b/res/system_resources/resource/voice/B-b-1.mp3 new file mode 100644 index 0000000..ef3b32d Binary files /dev/null and b/res/system_resources/resource/voice/B-b-1.mp3 differ diff --git a/res/system_resources/resource/voice/B-b-2.mp3 b/res/system_resources/resource/voice/B-b-2.mp3 new file mode 100644 index 0000000..17ba47b Binary files /dev/null and b/res/system_resources/resource/voice/B-b-2.mp3 differ diff --git a/res/system_resources/resource/voice/B-b-3.mp3 b/res/system_resources/resource/voice/B-b-3.mp3 new file mode 100644 index 0000000..fdca691 Binary files /dev/null and b/res/system_resources/resource/voice/B-b-3.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-60.mp3 b/res/system_resources/resource/voice/B-h-60.mp3 new file mode 100644 index 0000000..f018703 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-60.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-61.mp3 b/res/system_resources/resource/voice/B-h-61.mp3 new file mode 100644 index 0000000..113a539 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-61.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-62.mp3 b/res/system_resources/resource/voice/B-h-62.mp3 new file mode 100644 index 0000000..9f0d99f Binary files /dev/null and b/res/system_resources/resource/voice/B-h-62.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-63.mp3 b/res/system_resources/resource/voice/B-h-63.mp3 new file mode 100644 index 0000000..bc697b8 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-63.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-64.mp3 b/res/system_resources/resource/voice/B-h-64.mp3 new file mode 100644 index 0000000..a31e9cd Binary files /dev/null and b/res/system_resources/resource/voice/B-h-64.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-65.mp3 b/res/system_resources/resource/voice/B-h-65.mp3 new file mode 100644 index 0000000..31c8819 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-65.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-66.mp3 b/res/system_resources/resource/voice/B-h-66.mp3 new file mode 100644 index 0000000..603970a Binary files /dev/null and b/res/system_resources/resource/voice/B-h-66.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-67.mp3 b/res/system_resources/resource/voice/B-h-67.mp3 new file mode 100644 index 0000000..a14ec87 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-67.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-68.mp3 b/res/system_resources/resource/voice/B-h-68.mp3 new file mode 100644 index 0000000..688bf65 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-68.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-69.mp3 b/res/system_resources/resource/voice/B-h-69.mp3 new file mode 100644 index 0000000..eba486e Binary files /dev/null and b/res/system_resources/resource/voice/B-h-69.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-70.mp3 b/res/system_resources/resource/voice/B-h-70.mp3 new file mode 100644 index 0000000..389a1c5 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-70.mp3 differ diff --git a/res/system_resources/resource/voice/B-h-71.mp3 b/res/system_resources/resource/voice/B-h-71.mp3 new file mode 100644 index 0000000..4982e80 Binary files /dev/null and b/res/system_resources/resource/voice/B-h-71.mp3 differ diff --git a/res/system_resources/resource/voice/C-yc-1.mp3 b/res/system_resources/resource/voice/C-yc-1.mp3 new file mode 100644 index 0000000..b2eb636 Binary files /dev/null and b/res/system_resources/resource/voice/C-yc-1.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-01.mp3 b/res/system_resources/resource/voice/IoT-01.mp3 new file mode 100644 index 0000000..9be261b Binary files /dev/null and b/res/system_resources/resource/voice/IoT-01.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-02.mp3 b/res/system_resources/resource/voice/IoT-02.mp3 new file mode 100644 index 0000000..6f321b3 Binary files /dev/null and b/res/system_resources/resource/voice/IoT-02.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-03.mp3 b/res/system_resources/resource/voice/IoT-03.mp3 new file mode 100644 index 0000000..74a239e Binary files /dev/null and b/res/system_resources/resource/voice/IoT-03.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-04.mp3 b/res/system_resources/resource/voice/IoT-04.mp3 new file mode 100644 index 0000000..e71b6ab Binary files /dev/null and b/res/system_resources/resource/voice/IoT-04.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-05.mp3 b/res/system_resources/resource/voice/IoT-05.mp3 new file mode 100644 index 0000000..57663d5 Binary files /dev/null and b/res/system_resources/resource/voice/IoT-05.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-06.mp3 b/res/system_resources/resource/voice/IoT-06.mp3 new file mode 100644 index 0000000..a66a693 Binary files /dev/null and b/res/system_resources/resource/voice/IoT-06.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-07.mp3 b/res/system_resources/resource/voice/IoT-07.mp3 new file mode 100644 index 0000000..8269ede Binary files /dev/null and b/res/system_resources/resource/voice/IoT-07.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-08.mp3 b/res/system_resources/resource/voice/IoT-08.mp3 new file mode 100644 index 0000000..9f5a7db Binary files /dev/null and b/res/system_resources/resource/voice/IoT-08.mp3 differ diff --git a/res/system_resources/resource/voice/IoT-09.mp3 b/res/system_resources/resource/voice/IoT-09.mp3 new file mode 100644 index 0000000..b4f8c7c Binary files /dev/null and b/res/system_resources/resource/voice/IoT-09.mp3 differ diff --git a/res/system_resources/resource/voice/S001.mp3 b/res/system_resources/resource/voice/S001.mp3 new file mode 100644 index 0000000..c76f587 Binary files /dev/null and b/res/system_resources/resource/voice/S001.mp3 differ diff --git a/res/system_resources/resource/voice/S002.mp3 b/res/system_resources/resource/voice/S002.mp3 new file mode 100644 index 0000000..2a3bf11 Binary files /dev/null and b/res/system_resources/resource/voice/S002.mp3 differ diff --git a/res/system_resources/resource/voice/S003.mp3 b/res/system_resources/resource/voice/S003.mp3 new file mode 100644 index 0000000..45179b6 Binary files /dev/null and b/res/system_resources/resource/voice/S003.mp3 differ diff --git a/res/system_resources/resource/voice/S004-1.mp3 b/res/system_resources/resource/voice/S004-1.mp3 new file mode 100644 index 0000000..f5b99be Binary files /dev/null and b/res/system_resources/resource/voice/S004-1.mp3 differ diff --git a/res/system_resources/resource/voice/S004-2.mp3 b/res/system_resources/resource/voice/S004-2.mp3 new file mode 100644 index 0000000..5b0830e Binary files /dev/null and b/res/system_resources/resource/voice/S004-2.mp3 differ diff --git a/res/system_resources/resource/voice/S004-3.mp3 b/res/system_resources/resource/voice/S004-3.mp3 new file mode 100644 index 0000000..ca0ecd6 Binary files /dev/null and b/res/system_resources/resource/voice/S004-3.mp3 differ diff --git a/res/system_resources/resource/voice/S004-4.mp3 b/res/system_resources/resource/voice/S004-4.mp3 new file mode 100644 index 0000000..86c1a02 Binary files /dev/null and b/res/system_resources/resource/voice/S004-4.mp3 differ diff --git a/res/system_resources/resource/voice/S004-5.mp3 b/res/system_resources/resource/voice/S004-5.mp3 new file mode 100644 index 0000000..d9a9209 Binary files /dev/null and b/res/system_resources/resource/voice/S004-5.mp3 differ diff --git a/res/system_resources/resource/voice/S005.mp3 b/res/system_resources/resource/voice/S005.mp3 new file mode 100644 index 0000000..f33c780 Binary files /dev/null and b/res/system_resources/resource/voice/S005.mp3 differ diff --git a/res/system_resources/resource/voice/S006.mp3 b/res/system_resources/resource/voice/S006.mp3 new file mode 100644 index 0000000..c2f7dff Binary files /dev/null and b/res/system_resources/resource/voice/S006.mp3 differ diff --git a/res/system_resources/resource/voice/S007.mp3 b/res/system_resources/resource/voice/S007.mp3 new file mode 100644 index 0000000..571c25a Binary files /dev/null and b/res/system_resources/resource/voice/S007.mp3 differ diff --git a/res/system_resources/resource/voice/S008.mp3 b/res/system_resources/resource/voice/S008.mp3 new file mode 100644 index 0000000..3166536 Binary files /dev/null and b/res/system_resources/resource/voice/S008.mp3 differ diff --git a/res/system_resources/resource/voice/S009.mp3 b/res/system_resources/resource/voice/S009.mp3 new file mode 100644 index 0000000..aa6f429 Binary files /dev/null and b/res/system_resources/resource/voice/S009.mp3 differ diff --git a/res/system_resources/resource/voice/S010.mp3 b/res/system_resources/resource/voice/S010.mp3 new file mode 100644 index 0000000..9588cb8 Binary files /dev/null and b/res/system_resources/resource/voice/S010.mp3 differ diff --git a/res/system_resources/resource/voice/S011.mp3 b/res/system_resources/resource/voice/S011.mp3 new file mode 100644 index 0000000..839d839 Binary files /dev/null and b/res/system_resources/resource/voice/S011.mp3 differ diff --git a/res/system_resources/resource/voice/a-a-01.mp3 b/res/system_resources/resource/voice/a-a-01.mp3 new file mode 100644 index 0000000..c31ec72 Binary files /dev/null and b/res/system_resources/resource/voice/a-a-01.mp3 differ diff --git a/res/system_resources/resource/voice/a-a-02.mp3 b/res/system_resources/resource/voice/a-a-02.mp3 new file mode 100644 index 0000000..438e974 Binary files /dev/null and b/res/system_resources/resource/voice/a-a-02.mp3 differ diff --git a/res/system_resources/resource/voice/a-a-03.mp3 b/res/system_resources/resource/voice/a-a-03.mp3 new file mode 100644 index 0000000..1992d78 Binary files /dev/null and b/res/system_resources/resource/voice/a-a-03.mp3 differ diff --git a/res/system_resources/resource/voice/a-n-01.mp3 b/res/system_resources/resource/voice/a-n-01.mp3 new file mode 100644 index 0000000..59d6a31 Binary files /dev/null and b/res/system_resources/resource/voice/a-n-01.mp3 differ diff --git a/res/system_resources/resource/voice/b-h-50.mp3 b/res/system_resources/resource/voice/b-h-50.mp3 new file mode 100644 index 0000000..e5cbb4b Binary files /dev/null and b/res/system_resources/resource/voice/b-h-50.mp3 differ diff --git a/res/system_resources/resource/voice/b-h-51.mp3 b/res/system_resources/resource/voice/b-h-51.mp3 new file mode 100644 index 0000000..3a63aa1 Binary files /dev/null and b/res/system_resources/resource/voice/b-h-51.mp3 differ diff --git a/res/system_resources/resource/voice/b-m-1.mp3 b/res/system_resources/resource/voice/b-m-1.mp3 new file mode 100644 index 0000000..91a4dff Binary files /dev/null and b/res/system_resources/resource/voice/b-m-1.mp3 differ diff --git a/res/system_resources/resource/voice/b-m-2.mp3 b/res/system_resources/resource/voice/b-m-2.mp3 new file mode 100644 index 0000000..c5e86be Binary files /dev/null and b/res/system_resources/resource/voice/b-m-2.mp3 differ