From f48cd6cdb7b646e2920ff0e54d12ca4d1c760b6e Mon Sep 17 00:00:00 2001 From: HuangXin Date: Fri, 7 Sep 2018 11:21:53 +0800 Subject: [PATCH] remove old projects --- package/netease/LogCtrlTools/Makefile | 47 - package/netease/LogCtrlTools/src/Makefile | 24 - package/netease/LogCtrlTools/src/log_ctrl.c | 323 --- package/netease/alarm/Makefile | 52 - package/netease/alarm/src/Makefile | 25 - package/netease/alarm/src/assistant.c | 864 ------ package/netease/libuvdbus/Config.in | 17 - package/netease/libuvdbus/Makefile | 68 - .../libuvdbus/src/Framework/Compress/zlib.c | 110 - .../src/Framework/Configure/config_engine.c | 1042 ------- .../src/Framework/Configure/ini_prase.c | 289 -- .../libuvdbus/src/Framework/Crypto/aes.c | 104 - .../libuvdbus/src/Framework/Crypto/base64.c | 158 -- .../libuvdbus/src/Framework/Crypto/crypto.c | 187 -- .../libuvdbus/src/Framework/Crypto/md5.c | 156 -- .../libuvdbus/src/Framework/Fifo/fifo.c | 554 ---- .../src/Framework/HeartDaemon/heart_daemon.c | 197 -- .../Framework/IoT/Boardlink/boardlink_iot.c | 181 -- .../src/Framework/JsonUtils/json_struct.c | 1218 --------- .../libuvdbus/src/Framework/Monitor/monitor.c | 347 --- .../src/Framework/Network/inet_api.c | 1396 ---------- .../src/Framework/Skins/skin_res_vtbl.c | 320 --- .../libuvdbus/src/Framework/Skins/skins.c | 1442 ---------- .../src/Framework/SvrManager/svr_manager.c | 235 -- .../libuvdbus/src/Framework/Timer/timer.c | 773 ------ .../src/Framework/WireshartScript/log_pv1.lua | 93 - .../src/Framework/libuvEngine/libuv_dbus.c | 2405 ----------------- package/netease/libuvdbus/src/Makefile | 50 - .../netease/libuvdbus/src/include/assistant.h | 168 -- .../libuvdbus/src/include/boardlink_iot.h | 44 - .../libuvdbus/src/include/config_engine.h | 58 - .../netease/libuvdbus/src/include/crypto.h | 81 - package/netease/libuvdbus/src/include/fifo.h | 724 ----- .../netease/libuvdbus/src/include/inet_api.h | 51 - .../libuvdbus/src/include/json_struct.h | 150 - .../libuvdbus/src/include/libuv_dbus.h | 232 -- package/netease/libuvdbus/src/include/log.h | 233 -- .../netease/libuvdbus/src/include/log_info.h | 13 - .../netease/libuvdbus/src/include/monitor.h | 21 - package/netease/libuvdbus/src/include/ota.h | 156 -- .../libuvdbus/src/include/server_addr.h | 49 - package/netease/libuvdbus/src/include/skins.h | 58 - .../netease/libuvdbus/src/include/skins_res.h | 296 -- .../libuvdbus/src/include/smart_sound.h | 523 ---- package/netease/libuvdbus/src/log/hexdump.c | 326 --- package/netease/libuvdbus/src/log/log.c | 1332 --------- package/netease/ota/Makefile | 52 - package/netease/ota/src/Makefile | 24 - package/netease/ota/src/ota_r311.c | 1067 -------- package/netease/system_resources/Makefile | 34 - .../resource/image/IconChaozuo001.jpg | Bin 1280 -> 0 bytes .../resource/image/IconChaozuo005.jpg | Bin 10999 -> 0 bytes .../resource/image/IconLianjie001.jpg | Bin 11003 -> 0 bytes .../resource/image/IconLianjie002.jpg | Bin 9258 -> 0 bytes .../resource/image/IconLianjie003.jpg | Bin 9224 -> 0 bytes .../resource/image/IconNaozhong001.jpg | Bin 10988 -> 0 bytes .../resource/image/IconTixing001.jpg | Bin 10993 -> 0 bytes .../resource/image/IconZhuangtai003.gif | Bin 4818 -> 0 bytes .../resource/image/Iconlianwang001.gif | Bin 1366 -> 0 bytes .../resource/image/Iconlianwang005.gif | Bin 1350 -> 0 bytes .../resource/image/Iconstart002.gif | Bin 2552 -> 0 bytes .../resource/image/Iconyinliang000.jpg | Bin 1227 -> 0 bytes .../resource/image/Iconyinliang001.jpg | Bin 1247 -> 0 bytes .../resource/image/Iconyinliang002.jpg | Bin 1247 -> 0 bytes .../resource/image/Iconyinliang003.jpg | Bin 1247 -> 0 bytes .../resource/image/Iconyinliang004.jpg | Bin 1311 -> 0 bytes .../resource/image/Iconyinliang005.jpg | Bin 1311 -> 0 bytes .../resource/image/Iconyinliang006.jpg | Bin 1311 -> 0 bytes .../resource/image/Iconyinliang007.jpg | Bin 1316 -> 0 bytes .../resource/image/Iconyinliang008.jpg | Bin 1316 -> 0 bytes .../resource/image/Iconyinliang009.jpg | Bin 1316 -> 0 bytes .../resource/image/Iconyinliang010.jpg | Bin 1316 -> 0 bytes .../resource/image/Iconyinliang011.jpg | Bin 1304 -> 0 bytes .../resource/image/Iconyinliang012.jpg | Bin 1304 -> 0 bytes .../resource/image/Iconyinliang013.jpg | Bin 1316 -> 0 bytes .../resource/image/Iconyinliang014.jpg | Bin 1316 -> 0 bytes .../resource/image/Iconyinliang015.jpg | Bin 1319 -> 0 bytes .../resource/image/Iconyinliang016.jpg | Bin 1319 -> 0 bytes .../resource/image/Iconyinliang017.jpg | Bin 1314 -> 0 bytes .../resource/image/Iconyinliang018.jpg | Bin 1314 -> 0 bytes .../resource/image/Iconyinliang019.jpg | Bin 1257 -> 0 bytes .../resource/image/Iconyinliang020.jpg | Bin 1257 -> 0 bytes .../resource/voice/Alianwang002.mp3 | Bin 111380 -> 0 bytes .../resource/voice/Alianwang003.mp3 | Bin 77972 -> 0 bytes .../resource/voice/Alianwang004.mp3 | Bin 46868 -> 0 bytes .../resource/voice/Alianwang005.mp3 | Bin 61460 -> 0 bytes .../resource/voice/Alianwang006.mp3 | Bin 74132 -> 0 bytes .../resource/voice/Alianwang007.mp3 | Bin 54932 -> 0 bytes .../resource/voice/Alianwang008.mp3 | Bin 71444 -> 0 bytes .../resource/voice/Alianwang009.mp3 | Bin 58388 -> 0 bytes .../resource/voice/Alianwang010.mp3 | Bin 68756 -> 0 bytes .../resource/voice/Alianwang011.mp3 | Bin 35732 -> 0 bytes .../resource/voice/Alianwang012.mp3 | Bin 42260 -> 0 bytes .../resource/voice/Alianwang013.mp3 | Bin 42260 -> 0 bytes .../resource/voice/Alianwang014.mp3 | Bin 122900 -> 0 bytes .../resource/voice/Ashiyong002.mp3 | Bin 37190 -> 0 bytes .../resource/voice/Ashiyong003.mp3 | Bin 38342 -> 0 bytes .../resource/voice/Ashiyong004.mp3 | Bin 33734 -> 0 bytes .../resource/voice/Ashiyong005.mp3 | Bin 35654 -> 0 bytes .../resource/voice/Ashiyong006.mp3 | Bin 37190 -> 0 bytes .../system_resources/resource/voice/S001.mp3 | Bin 91292 -> 0 bytes .../system_resources/resource/voice/S002.mp3 | Bin 100566 -> 0 bytes .../system_resources/resource/voice/S003.mp3 | Bin 22618 -> 0 bytes .../resource/voice/S004-1.mp3 | Bin 209867 -> 0 bytes .../resource/voice/S004-2.mp3 | Bin 309341 -> 0 bytes .../resource/voice/S004-3.mp3 | Bin 474853 -> 0 bytes .../resource/voice/S004-4.mp3 | Bin 386246 -> 0 bytes .../resource/voice/S004-5.mp3 | Bin 545906 -> 0 bytes .../system_resources/resource/voice/S005.mp3 | Bin 25962 -> 0 bytes .../system_resources/resource/voice/S006.mp3 | Bin 21783 -> 0 bytes .../system_resources/resource/voice/S007.mp3 | Bin 29306 -> 0 bytes .../system_resources/resource/voice/S008.mp3 | Bin 20111 -> 0 bytes .../system_resources/resource/voice/S009.mp3 | Bin 6736 -> 0 bytes .../system_resources/resource/voice/S010.mp3 | Bin 5064 -> 0 bytes .../system_resources/resource/voice/S011.mp3 | Bin 58563 -> 0 bytes .../resource/voice/a-a-01.mp3 | Bin 40872 -> 0 bytes .../resource/voice/a-a-02.mp3 | Bin 55416 -> 0 bytes .../resource/voice/a-a-03.mp3 | Bin 56520 -> 0 bytes .../resource/voice/a-n-01.mp3 | Bin 40608 -> 0 bytes .../resource/voice/b-h-01.mp3 | Bin 80649 -> 0 bytes .../resource/voice/b-h-50.mp3 | Bin 93993 -> 0 bytes .../resource/voice/b-h-51.mp3 | Bin 120343 -> 0 bytes .../system_resources/resource/voice/b-m-1.mp3 | Bin 21192 -> 0 bytes .../system_resources/resource/voice/b-m-2.mp3 | Bin 21672 -> 0 bytes 124 files changed, 18369 deletions(-) delete mode 100644 package/netease/LogCtrlTools/Makefile delete mode 100644 package/netease/LogCtrlTools/src/Makefile delete mode 100644 package/netease/LogCtrlTools/src/log_ctrl.c delete mode 100644 package/netease/alarm/Makefile delete mode 100644 package/netease/alarm/src/Makefile delete mode 100644 package/netease/alarm/src/assistant.c delete mode 100644 package/netease/libuvdbus/Config.in delete mode 100644 package/netease/libuvdbus/Makefile delete mode 100644 package/netease/libuvdbus/src/Framework/Compress/zlib.c delete mode 100644 package/netease/libuvdbus/src/Framework/Configure/config_engine.c delete mode 100644 package/netease/libuvdbus/src/Framework/Configure/ini_prase.c delete mode 100644 package/netease/libuvdbus/src/Framework/Crypto/aes.c delete mode 100644 package/netease/libuvdbus/src/Framework/Crypto/base64.c delete mode 100644 package/netease/libuvdbus/src/Framework/Crypto/crypto.c delete mode 100644 package/netease/libuvdbus/src/Framework/Crypto/md5.c delete mode 100644 package/netease/libuvdbus/src/Framework/Fifo/fifo.c delete mode 100644 package/netease/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c delete mode 100644 package/netease/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c delete mode 100644 package/netease/libuvdbus/src/Framework/JsonUtils/json_struct.c delete mode 100644 package/netease/libuvdbus/src/Framework/Monitor/monitor.c delete mode 100644 package/netease/libuvdbus/src/Framework/Network/inet_api.c delete mode 100644 package/netease/libuvdbus/src/Framework/Skins/skin_res_vtbl.c delete mode 100644 package/netease/libuvdbus/src/Framework/Skins/skins.c delete mode 100644 package/netease/libuvdbus/src/Framework/SvrManager/svr_manager.c delete mode 100644 package/netease/libuvdbus/src/Framework/Timer/timer.c delete mode 100644 package/netease/libuvdbus/src/Framework/WireshartScript/log_pv1.lua delete mode 100644 package/netease/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c delete mode 100644 package/netease/libuvdbus/src/Makefile delete mode 100644 package/netease/libuvdbus/src/include/assistant.h delete mode 100644 package/netease/libuvdbus/src/include/boardlink_iot.h delete mode 100644 package/netease/libuvdbus/src/include/config_engine.h delete mode 100644 package/netease/libuvdbus/src/include/crypto.h delete mode 100644 package/netease/libuvdbus/src/include/fifo.h delete mode 100644 package/netease/libuvdbus/src/include/inet_api.h delete mode 100644 package/netease/libuvdbus/src/include/json_struct.h delete mode 100644 package/netease/libuvdbus/src/include/libuv_dbus.h delete mode 100644 package/netease/libuvdbus/src/include/log.h delete mode 100644 package/netease/libuvdbus/src/include/log_info.h delete mode 100644 package/netease/libuvdbus/src/include/monitor.h delete mode 100644 package/netease/libuvdbus/src/include/ota.h delete mode 100644 package/netease/libuvdbus/src/include/server_addr.h delete mode 100644 package/netease/libuvdbus/src/include/skins.h delete mode 100644 package/netease/libuvdbus/src/include/skins_res.h delete mode 100644 package/netease/libuvdbus/src/include/smart_sound.h delete mode 100644 package/netease/libuvdbus/src/log/hexdump.c delete mode 100644 package/netease/libuvdbus/src/log/log.c delete mode 100644 package/netease/ota/Makefile delete mode 100644 package/netease/ota/src/Makefile delete mode 100644 package/netease/ota/src/ota_r311.c delete mode 100644 package/netease/system_resources/Makefile delete mode 100644 package/netease/system_resources/resource/image/IconChaozuo001.jpg delete mode 100644 package/netease/system_resources/resource/image/IconChaozuo005.jpg delete mode 100644 package/netease/system_resources/resource/image/IconLianjie001.jpg delete mode 100644 package/netease/system_resources/resource/image/IconLianjie002.jpg delete mode 100644 package/netease/system_resources/resource/image/IconLianjie003.jpg delete mode 100644 package/netease/system_resources/resource/image/IconNaozhong001.jpg delete mode 100644 package/netease/system_resources/resource/image/IconTixing001.jpg delete mode 100644 package/netease/system_resources/resource/image/IconZhuangtai003.gif delete mode 100644 package/netease/system_resources/resource/image/Iconlianwang001.gif delete mode 100644 package/netease/system_resources/resource/image/Iconlianwang005.gif delete mode 100644 package/netease/system_resources/resource/image/Iconstart002.gif delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang000.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang001.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang002.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang003.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang004.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang005.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang006.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang007.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang008.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang009.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang010.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang011.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang012.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang013.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang014.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang015.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang016.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang017.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang018.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang019.jpg delete mode 100644 package/netease/system_resources/resource/image/Iconyinliang020.jpg delete mode 100644 package/netease/system_resources/resource/voice/Alianwang002.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang003.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang004.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang005.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang006.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang007.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang008.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang009.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang010.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang011.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang012.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang013.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Alianwang014.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Ashiyong002.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Ashiyong003.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Ashiyong004.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Ashiyong005.mp3 delete mode 100644 package/netease/system_resources/resource/voice/Ashiyong006.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S001.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S002.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S003.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S004-1.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S004-2.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S004-3.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S004-4.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S004-5.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S005.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S006.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S007.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S008.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S009.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S010.mp3 delete mode 100644 package/netease/system_resources/resource/voice/S011.mp3 delete mode 100644 package/netease/system_resources/resource/voice/a-a-01.mp3 delete mode 100644 package/netease/system_resources/resource/voice/a-a-02.mp3 delete mode 100644 package/netease/system_resources/resource/voice/a-a-03.mp3 delete mode 100644 package/netease/system_resources/resource/voice/a-n-01.mp3 delete mode 100644 package/netease/system_resources/resource/voice/b-h-01.mp3 delete mode 100644 package/netease/system_resources/resource/voice/b-h-50.mp3 delete mode 100644 package/netease/system_resources/resource/voice/b-h-51.mp3 delete mode 100644 package/netease/system_resources/resource/voice/b-m-1.mp3 delete mode 100644 package/netease/system_resources/resource/voice/b-m-2.mp3 diff --git a/package/netease/LogCtrlTools/Makefile b/package/netease/LogCtrlTools/Makefile deleted file mode 100644 index 7ce3ca182..000000000 --- a/package/netease/LogCtrlTools/Makefile +++ /dev/null @@ -1,47 +0,0 @@ -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/package/netease/LogCtrlTools/src/Makefile b/package/netease/LogCtrlTools/src/Makefile deleted file mode 100644 index d60ae72a6..000000000 --- a/package/netease/LogCtrlTools/src/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -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/package/netease/LogCtrlTools/src/log_ctrl.c b/package/netease/LogCtrlTools/src/log_ctrl.c deleted file mode 100644 index ce94a86b8..000000000 --- a/package/netease/LogCtrlTools/src/log_ctrl.c +++ /dev/null @@ -1,323 +0,0 @@ - #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/package/netease/alarm/Makefile b/package/netease/alarm/Makefile deleted file mode 100644 index 34037410b..000000000 --- a/package/netease/alarm/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -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/package/netease/alarm/src/Makefile b/package/netease/alarm/src/Makefile deleted file mode 100644 index 1d2783eef..000000000 --- a/package/netease/alarm/src/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -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/package/netease/alarm/src/assistant.c b/package/netease/alarm/src/assistant.c deleted file mode 100644 index ae471b99e..000000000 --- a/package/netease/alarm/src/assistant.c +++ /dev/null @@ -1,864 +0,0 @@ -#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; - struct tm* pTmNextYear; - - 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/package/netease/libuvdbus/Config.in b/package/netease/libuvdbus/Config.in deleted file mode 100644 index 2c6deb052..000000000 --- a/package/netease/libuvdbus/Config.in +++ /dev/null @@ -1,17 +0,0 @@ -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/package/netease/libuvdbus/Makefile b/package/netease/libuvdbus/Makefile deleted file mode 100644 index 890c76511..000000000 --- a/package/netease/libuvdbus/Makefile +++ /dev/null @@ -1,68 +0,0 @@ -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/package/netease/libuvdbus/src/Framework/Compress/zlib.c b/package/netease/libuvdbus/src/Framework/Compress/zlib.c deleted file mode 100644 index b78f8632c..000000000 --- a/package/netease/libuvdbus/src/Framework/Compress/zlib.c +++ /dev/null @@ -1,110 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Configure/config_engine.c b/package/netease/libuvdbus/src/Framework/Configure/config_engine.c deleted file mode 100644 index 4b5c276b5..000000000 --- a/package/netease/libuvdbus/src/Framework/Configure/config_engine.c +++ /dev/null @@ -1,1042 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Configure/ini_prase.c b/package/netease/libuvdbus/src/Framework/Configure/ini_prase.c deleted file mode 100644 index 3542f87fb..000000000 --- a/package/netease/libuvdbus/src/Framework/Configure/ini_prase.c +++ /dev/null @@ -1,289 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Crypto/aes.c b/package/netease/libuvdbus/src/Framework/Crypto/aes.c deleted file mode 100644 index afff0ac8c..000000000 --- a/package/netease/libuvdbus/src/Framework/Crypto/aes.c +++ /dev/null @@ -1,104 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Crypto/base64.c b/package/netease/libuvdbus/src/Framework/Crypto/base64.c deleted file mode 100644 index 694107392..000000000 --- a/package/netease/libuvdbus/src/Framework/Crypto/base64.c +++ /dev/null @@ -1,158 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Crypto/crypto.c b/package/netease/libuvdbus/src/Framework/Crypto/crypto.c deleted file mode 100644 index 226f1a32a..000000000 --- a/package/netease/libuvdbus/src/Framework/Crypto/crypto.c +++ /dev/null @@ -1,187 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Crypto/md5.c b/package/netease/libuvdbus/src/Framework/Crypto/md5.c deleted file mode 100644 index 655e7b077..000000000 --- a/package/netease/libuvdbus/src/Framework/Crypto/md5.c +++ /dev/null @@ -1,156 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Fifo/fifo.c b/package/netease/libuvdbus/src/Framework/Fifo/fifo.c deleted file mode 100644 index 5fd3753d5..000000000 --- a/package/netease/libuvdbus/src/Framework/Fifo/fifo.c +++ /dev/null @@ -1,554 +0,0 @@ -/* - * 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/package/netease/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c b/package/netease/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c deleted file mode 100644 index 80e190b27..000000000 --- a/package/netease/libuvdbus/src/Framework/HeartDaemon/heart_daemon.c +++ /dev/null @@ -1,197 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c b/package/netease/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c deleted file mode 100644 index 0abd09bf5..000000000 --- a/package/netease/libuvdbus/src/Framework/IoT/Boardlink/boardlink_iot.c +++ /dev/null @@ -1,181 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/JsonUtils/json_struct.c b/package/netease/libuvdbus/src/Framework/JsonUtils/json_struct.c deleted file mode 100644 index c9be8c344..000000000 --- a/package/netease/libuvdbus/src/Framework/JsonUtils/json_struct.c +++ /dev/null @@ -1,1218 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Monitor/monitor.c b/package/netease/libuvdbus/src/Framework/Monitor/monitor.c deleted file mode 100644 index 6e78f6b51..000000000 --- a/package/netease/libuvdbus/src/Framework/Monitor/monitor.c +++ /dev/null @@ -1,347 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Network/inet_api.c b/package/netease/libuvdbus/src/Framework/Network/inet_api.c deleted file mode 100644 index ee3a9db37..000000000 --- a/package/netease/libuvdbus/src/Framework/Network/inet_api.c +++ /dev/null @@ -1,1396 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Skins/skin_res_vtbl.c b/package/netease/libuvdbus/src/Framework/Skins/skin_res_vtbl.c deleted file mode 100644 index ae30711b3..000000000 --- a/package/netease/libuvdbus/src/Framework/Skins/skin_res_vtbl.c +++ /dev/null @@ -1,320 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Skins/skins.c b/package/netease/libuvdbus/src/Framework/Skins/skins.c deleted file mode 100644 index 2fc624b19..000000000 --- a/package/netease/libuvdbus/src/Framework/Skins/skins.c +++ /dev/null @@ -1,1442 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/SvrManager/svr_manager.c b/package/netease/libuvdbus/src/Framework/SvrManager/svr_manager.c deleted file mode 100644 index 2a15b1c0f..000000000 --- a/package/netease/libuvdbus/src/Framework/SvrManager/svr_manager.c +++ /dev/null @@ -1,235 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/Timer/timer.c b/package/netease/libuvdbus/src/Framework/Timer/timer.c deleted file mode 100644 index 0263dd883..000000000 --- a/package/netease/libuvdbus/src/Framework/Timer/timer.c +++ /dev/null @@ -1,773 +0,0 @@ -#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/package/netease/libuvdbus/src/Framework/WireshartScript/log_pv1.lua b/package/netease/libuvdbus/src/Framework/WireshartScript/log_pv1.lua deleted file mode 100644 index c5edfdd1b..000000000 --- a/package/netease/libuvdbus/src/Framework/WireshartScript/log_pv1.lua +++ /dev/null @@ -1,93 +0,0 @@ -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/package/netease/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c b/package/netease/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c deleted file mode 100644 index e73264bf8..000000000 --- a/package/netease/libuvdbus/src/Framework/libuvEngine/libuv_dbus.c +++ /dev/null @@ -1,2405 +0,0 @@ -#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/package/netease/libuvdbus/src/Makefile b/package/netease/libuvdbus/src/Makefile deleted file mode 100644 index 138edf1a9..000000000 --- a/package/netease/libuvdbus/src/Makefile +++ /dev/null @@ -1,50 +0,0 @@ -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/package/netease/libuvdbus/src/include/assistant.h b/package/netease/libuvdbus/src/include/assistant.h deleted file mode 100644 index 56b28f738..000000000 --- a/package/netease/libuvdbus/src/include/assistant.h +++ /dev/null @@ -1,168 +0,0 @@ -#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/package/netease/libuvdbus/src/include/boardlink_iot.h b/package/netease/libuvdbus/src/include/boardlink_iot.h deleted file mode 100644 index 65dd47a2a..000000000 --- a/package/netease/libuvdbus/src/include/boardlink_iot.h +++ /dev/null @@ -1,44 +0,0 @@ -#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/package/netease/libuvdbus/src/include/config_engine.h b/package/netease/libuvdbus/src/include/config_engine.h deleted file mode 100644 index 80dfc499d..000000000 --- a/package/netease/libuvdbus/src/include/config_engine.h +++ /dev/null @@ -1,58 +0,0 @@ -#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/package/netease/libuvdbus/src/include/crypto.h b/package/netease/libuvdbus/src/include/crypto.h deleted file mode 100644 index 57961f828..000000000 --- a/package/netease/libuvdbus/src/include/crypto.h +++ /dev/null @@ -1,81 +0,0 @@ -#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/package/netease/libuvdbus/src/include/fifo.h b/package/netease/libuvdbus/src/include/fifo.h deleted file mode 100644 index 4ea395bf0..000000000 --- a/package/netease/libuvdbus/src/include/fifo.h +++ /dev/null @@ -1,724 +0,0 @@ -/* - * 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/package/netease/libuvdbus/src/include/inet_api.h b/package/netease/libuvdbus/src/include/inet_api.h deleted file mode 100644 index c49936de3..000000000 --- a/package/netease/libuvdbus/src/include/inet_api.h +++ /dev/null @@ -1,51 +0,0 @@ -#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/package/netease/libuvdbus/src/include/json_struct.h b/package/netease/libuvdbus/src/include/json_struct.h deleted file mode 100644 index 56643161b..000000000 --- a/package/netease/libuvdbus/src/include/json_struct.h +++ /dev/null @@ -1,150 +0,0 @@ -#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/package/netease/libuvdbus/src/include/libuv_dbus.h b/package/netease/libuvdbus/src/include/libuv_dbus.h deleted file mode 100644 index e019b8eb6..000000000 --- a/package/netease/libuvdbus/src/include/libuv_dbus.h +++ /dev/null @@ -1,232 +0,0 @@ -#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/package/netease/libuvdbus/src/include/log.h b/package/netease/libuvdbus/src/include/log.h deleted file mode 100644 index 118d79c76..000000000 --- a/package/netease/libuvdbus/src/include/log.h +++ /dev/null @@ -1,233 +0,0 @@ -/** @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/package/netease/libuvdbus/src/include/log_info.h b/package/netease/libuvdbus/src/include/log_info.h deleted file mode 100644 index cd24c6197..000000000 --- a/package/netease/libuvdbus/src/include/log_info.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef LOG_INFO_H -#define LOG_INFO_H - -#ifdef __cplusplus -extern "C" { -#endif - - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/package/netease/libuvdbus/src/include/monitor.h b/package/netease/libuvdbus/src/include/monitor.h deleted file mode 100644 index e5f8513fb..000000000 --- a/package/netease/libuvdbus/src/include/monitor.h +++ /dev/null @@ -1,21 +0,0 @@ -#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/package/netease/libuvdbus/src/include/ota.h b/package/netease/libuvdbus/src/include/ota.h deleted file mode 100644 index 7d4be7558..000000000 --- a/package/netease/libuvdbus/src/include/ota.h +++ /dev/null @@ -1,156 +0,0 @@ -#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/package/netease/libuvdbus/src/include/server_addr.h b/package/netease/libuvdbus/src/include/server_addr.h deleted file mode 100644 index 9f5d473d1..000000000 --- a/package/netease/libuvdbus/src/include/server_addr.h +++ /dev/null @@ -1,49 +0,0 @@ -#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/package/netease/libuvdbus/src/include/skins.h b/package/netease/libuvdbus/src/include/skins.h deleted file mode 100644 index 140381307..000000000 --- a/package/netease/libuvdbus/src/include/skins.h +++ /dev/null @@ -1,58 +0,0 @@ -#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/package/netease/libuvdbus/src/include/skins_res.h b/package/netease/libuvdbus/src/include/skins_res.h deleted file mode 100644 index 58b08387d..000000000 --- a/package/netease/libuvdbus/src/include/skins_res.h +++ /dev/null @@ -1,296 +0,0 @@ -#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", "2ecc61d16a3ee0f02c4e580f00396d1f"}, -#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", "v401", DEF_SKINS_ROOT_PATH"voice/b-h-01.mp3", "68ecfbab58563071b6663a348a39a51b"}, - {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"}, - - /////////////////////////////////////////////////////////////////////////////////////////////////////////// - /// 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/package/netease/libuvdbus/src/include/smart_sound.h b/package/netease/libuvdbus/src/include/smart_sound.h deleted file mode 100644 index a6a948002..000000000 --- a/package/netease/libuvdbus/src/include/smart_sound.h +++ /dev/null @@ -1,523 +0,0 @@ -#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_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_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/package/netease/libuvdbus/src/log/hexdump.c b/package/netease/libuvdbus/src/log/hexdump.c deleted file mode 100644 index 0217b3473..000000000 --- a/package/netease/libuvdbus/src/log/hexdump.c +++ /dev/null @@ -1,326 +0,0 @@ -#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/package/netease/libuvdbus/src/log/log.c b/package/netease/libuvdbus/src/log/log.c deleted file mode 100644 index 08026341a..000000000 --- a/package/netease/libuvdbus/src/log/log.c +++ /dev/null @@ -1,1332 +0,0 @@ -/** @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/package/netease/ota/Makefile b/package/netease/ota/Makefile deleted file mode 100644 index a5e3c439c..000000000 --- a/package/netease/ota/Makefile +++ /dev/null @@ -1,52 +0,0 @@ -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/package/netease/ota/src/Makefile b/package/netease/ota/src/Makefile deleted file mode 100644 index c0b48f799..000000000 --- a/package/netease/ota/src/Makefile +++ /dev/null @@ -1,24 +0,0 @@ -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/package/netease/ota/src/ota_r311.c b/package/netease/ota/src/ota_r311.c deleted file mode 100644 index c19fceb22..000000000 --- a/package/netease/ota/src/ota_r311.c +++ /dev/null @@ -1,1067 +0,0 @@ -#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/package/netease/system_resources/Makefile b/package/netease/system_resources/Makefile deleted file mode 100644 index eec6c199b..000000000 --- a/package/netease/system_resources/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -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/package/netease/system_resources/resource/image/IconChaozuo001.jpg b/package/netease/system_resources/resource/image/IconChaozuo001.jpg deleted file mode 100644 index ebb781e24bf6999c83dfae28cd9bb6b74f6efd41..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1280 zcma)6-D}fO6u(*3Z6dPh)Xk@msi>IGCd~({V@+2qqdMk5ee)){TSJ!*lhk&576e~p zZ$9}q_~agZaDuNs`YniW3Zmd2V7zIYwn!N}kZ|rf=XbvDIXC%`d;>E}ZD$>TYV|Uh z00T;X0hp^ZNAo-SiT#w^G=QuB7q3xT9wS1Rr!+;Z5o&)m>?EqR06jLVJ zaJ(Y@`^8I|a_k~~ORn*?z(959+IEO;ZeL%swi}ja(+gLr`L^D60~f`RYP*|Wq_>N7 z$GMLARLs#-$0TkP>BTfEb-T7g8GeW;nJq9DUr;DTV+C1JB;^Vv@`B9qc`na0VqTYc zT@tAt(KuRYuj{MjN-q{Z73p44tyYU|(6I9}vLk--*BwB^OH&3MsV=An!t zD|CX`@jWW_2u;5k7ipYnw*)t+)%uP{cFT3sx;oZTyov^CjI@r{wgSYhqR4NC7Q*Ip z85s9&|3IlB&PKlxI`~rHX4$uzF7o1PxkzITYdf}X79c``$TKR$KS@*tM$1b!15F4E zrmZNVBxZg_;rWtKQc8l6&&#qPEUBeRMO_lhLcvfM4OLSzY}Jcm=vgR>?cmrwY-wMt zZiEQNez@lQo7ohs)cx3x>V7~OM(5V4i#2FDUMjqlUR1a4G76ph$gYIGOLaP}J0r3< zSO>azd#HomNyQReNsuL^<2H!0D5;EMYAPcLipiLgw9eSF43TLS@&e>(4yVYa!!tBY znFvp4%Jx?SANtFMJiJjMUY+C@INn(ZVDI4-C6dqJ0U!=eV*|?dsRth;2&~0lUvW?- z*#qPRm;{qKf&^nEkt2!ZHMo-|Hh5lAZu02=5&)(EksBKyGCTuLojy4}eeV2`3p2B4 z$stYGS@H=S%MmzEjsy$f&G)D8V*ReP`{(P_@`)$jm!0XqJFo2B=kG|ZJkN*HFu~3Bo diff --git a/package/netease/system_resources/resource/image/IconChaozuo005.jpg b/package/netease/system_resources/resource/image/IconChaozuo005.jpg deleted file mode 100644 index 7e882ad021a463d859132cc7fd63c5fee07c9b89..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10999 zcmeG?d3;mF)^qR8+NNvL(z4#BD}^*o+oWxvbV*leXlYAXL?OAkO+&Mhr7eiEh^W95 zL9A@D3jzuXQWlY=tO|l4JL+pe1QfA|fQr&LbJL_L@_78-_j`YROq;o9&N*}DoS8Fo zXU?6rb8Rieb9wcKDge}K5Dx(00WKB{2nb>D4`5vZn}Gq)V%NC1KrPTokdHNrPUUP#a?Z(k}4IMlqi!Y$jLah zhBBBDx;KERRHZCQnW!KUkg7~h2Y^_Hb?CSZ_q4-bMs&ciO_Vqo(ay{9wg-#pum?-< zwg<=DGB5@1k&Tm#Gyn?W6ZVYj*>)f8Ld(StnDW7XG%af8S%AU1k-?k$K&yN z0zO|5 z5&>;{KoAcO3{GHTfCphj5Z3k$G!kpuk7YtF*%*_c!YB~{!&z(&m&f<J_u2csr71M39zKq-I4k9UaKzUKvAE zGKjMeQLLCYe!X z;A8dBVTq}jV|19?br5Ks2BX7ZW`saGpW#-iM+|b=-w%nvB{1u-G1$w-605^tG20=% z3*uB+9cH)MKxNe0JcTm7UF|8TY-UwQ!R+WL6l;xk4`s04QR^w>nT)xf0_?dC(K%F& zzTI?JzksrW92L}tKq{5#NK$8UYO^fOsK}%OoB40J9OK{la%{Sap=L*ZWSJ3-rYGeX zb>yS)Wp<;3!I#z>vuu0Z{64ib<*?XtH4Y83fKjqkUut*z0fG@Pd?K|$Fn^H8%D zaP56mv*nc0g)g;HStF1HCIwP9i*;Bv4F?zcq`|Crcb`8ZltGgM4`vxE4_r32O%KH-ar8OGdYuGP6jT2^J9wW zZ8VbM4EL0KGE#3dWj>R`3}b4+Hx)`g?b8A}EW>+;!4?8(RTZQdVGiFbFk$VO2 zgHL1%9M_A2!5|xu70B;gb$JY?eMaM1P$>Mhk3dfZG4EB^h;&6o0=|6O`vDc*K4r^XCHzkU>oQ^g|4uZ=&EO`qtA>hZrxC4!$Xt%r;xy~*56yMTftp4x z1JDHVcp)r5ej2C4Qb3z&o5n%wAOcj3x4K^qJ}zd2L6job3*vum zKjE|)JH23-&hLy-+x4AaLL80JQK8Xy;_|0xqp^ancNEzRE7ZmAMUUr3cVgyOTWk}u zjRw8DrvhBY7rN1~1GqZ6O5&VKL3XIg+pBZFgr67<4{A)oW(O+8Q3+)L=22v zn8WZfvl{OY%V=^S*GE4zYvIJeNe~7%girUgPxrHr+0Qb56ahU301fOL1)MW%3_k%YphaPLZTG(&#bpt4y1xp#?cBAU*>JsXb6D&48tec)LO-zy|B}pKM#6I5a(9}!J_DHvcT-r|A z49s4cL=xdX(CNq!Lrq;Kn5-VLkL)WiMz#9!tR@rc07k6ckyi^_dE6k_(Yh!tqwN-_ zjiU2vX|p5JU0p|c>RREOfw5FaNogZ(f^2p;h%!%8R(Ei~Q>Bv~9x^lXr~#`|WurB4 zS6l&i#O{IWIDkDe#NbtrhMQ?RLyTe$5?PWYQBmQJIrK?PQzj<5Sk=%Sba2=GWXu+w zp=$h-u&UL{BD3A0F;jF=ZiW~dlVC9Dlyp_9JVilMk|cQwB}qx5QYD%cS(PM>re!IV zRwmObQW(8p{ag#>M7@aWyS!Itp`Z*;M=7-m8J(C$(Gr=aDn%lbrD`P_MOw0?N=xe$ zRkSWORqnD9N^@;0G)8Z!NGlzbn3SfFS0%}lB?>K6EhUvsl%&(isj$mZwX$SNCfB5< zi%A`&tg_fl8t5(tlSWTV$69H!*dr|l&4b2 z(iI9xQi2S*Khy(iSZJ`ru^!((p~~rT?U2zxGG40GQ0O3;A*PU5&^mED+VF^eelm+( zV(Z}X=do_$VzXPS9CaESovnvs@}%A<{dYFlHMNho;K@AYe{Vs1CsWlLvz~_Qu2hU{ zlA;yLHAK>fM~|U-t!8d^xI`k*vo;TKuc1$$PkZ2L4?OLGr# z(@=J+x;!6!_5g5mNupgQf;-aPGp-=wSCYa~lI*}g5fnsOZ7{fxl|t@h9XzK&cp8L_ zbq*`Sw?bH?twAu3A~Yf!R1m^p2-dq`6yp|YU2qnHbtW?m>ETFctIniD@O}utTI)oi zKB5@H(`yZM9fVIoILhcW86b?J%OVr4f#F9MiUCDAXsQ~*i4YdpD$3y30Tzr3@dSD= zSnCBlV9X8j0+q!&o{2({aa3;-9#7NALb}dKI~R`d(+`>J3R;rLt0@?SblONe zjCjzbpMKzQn{@_s#3BvmPG>YP3IAm^F9`^A z`85QDs~!N+=mZdWTm*=pjslj@7Z9VCKnms=w_<)J3`7Aitk+eS-$NMEnY>em&xS?Z zZqSnmttzV^DW|O#!R@hsHvIk*07Ni^)e}U5IQT^(38aF4APeMyfuICbfDzz1K*3O# z3D`g#m0l;!1H1(mf~8;;SPM3QO<*h73HE}6;0X8nX2zV@MC>JOCN>vah%Lv~Vjp4KvAx)5 z*a_@B)`DHfe!>3030#1S@E&*!F2&REYZ~bJ|AC!zmGTKd+{Uq zX}lT#5x)bkM)(q;Lz6!g{=2jjja8wuUIXtR@MWyAG&vc><0E~ z_7?U5_G$JN_FWE#6UvF@q;d*5BRFF@&vRyR-r;QI?BSf?T;|;2a=GE$KHLm$30K2) zaHn$@aNpplc=l8AOZ~j961pgv` zo&O~NMgEQcC;e{*@B^X)vICwAm=MqqusPs(z>PqDU`(JYP!srK;G)3ofoB8n1POy= zK_x+^pjkodf<6nn7R(Kf3C;`F1y2iJ8N4s}vXBr)3ROZ%_>ypy@PP1&h$D&>6^X`* zW{N%#9TT;N1c#)AREE@tEDHHFq&bubjR`FZHHOX(-4uEz^p7q*x@32uyS&zALzk0X z?uB&=%L=2zW`u1FJ012%I2oQ7UK2hid~5hOU0Ge@yAJ7E*L6wP16^-)6Lss?jp{a| z+oo<8y5rsByO(u;zWd7VN4wwY(X&TE4{MJFJ@)mu(KEDXR?o3L=k?sx^Lj5~uK~Rb zz2^1W-RlQ3gv=(5tBc&K=)c%%56NT0~G$g0SBkxh}U zQN5znQ4^!qM_q{KN2f(sN536?DEeMZY|OBjS7NrtT#F5hEsC8GyFT{oIKQ~exN&hS z;!gGE^iJzt)BBy?U&iC{^7!ibMe)b`;C&Q*41M0|bD}T1Z+c&I-xYn&N(7Q@Nv&kP zq$MFVp*Ue`!q$YF(kSUj=^W`H>4QXhqA_t*;ze1oY@lqaY=`WZr1&H%X;IRtWWVJ6 zf+S1X`-~!v{`9~)7j}c z>66lTrvI)~C>_d8%Afm5`qlJX*Y8^Y*#30?RsAn#h%+=9%QKn>kORgHST>+JGa^%y zxgzsYR%DhgYjxJu?B3a9v)|9YnUk1f%h{51Po-47pxTp5y(!(SMFWJK2yh7sFFaz|Ewq#^*jA9WYumdh;0em|TT*rU6yX1?mC@8&!w+cWmL_rx~9+2zp1}oomt&beZ!zKEHvC2TR3*<*n2f4HEU|x zjKho@O+3>W({^*PxyHQT($i9JIbrQ%oo;O&ryTdzxK`UB+iE*zf7ZUuA%dH!qs}~Q&K7Rabh)u@6|%WtaRY@A2Vn=$X#w?@D9Swl+0(zkuycD~&_zj*$(1yKv$Sn%h< z>V>BlBSxYu7?Xh&`(m$3NmYrK(u)J|a%!-DUoRzgJzh70k z>d?Ds@2*|lb@j~Ef2}dEX@0Nlz5Q!b*REaHeckN!_+g?x|H}_@KiIZGvSIng z(2X-c1Rpv-{NbZ9AD!7WXj9YXw9Oknj{bP@7U7l|jacLO#@4OXTbs9y*mh$3!0k;t z`t8{ANx~;LInzpNL_k`Vd_E`7a*sI@rxoLFM#eKu~o!UQS|FHvu z4jew1e{kQS>_fW`XB^)7newykpQnAk^@!p~<5Bt1EnmpL*m6v9tnqm2@oitGf4SpC z{}a1TW}e*pRqj^@PZgaya(eLT6K95=Id^u{+2(V)bJxxr&)>RGd*S}Y$zQX-p7BlK zHx1u*|8~Vcd;fD|v!eOamfV)3m&z|)yi8sG@jLr>e_omPz2El@S9@JudoAhO&g=Qt zzx?5uAFljp{qg>d=|2ViwD@M+&5wW1`uS+<@YXB0Y`5BenRPq-_L^T)er>u_dgt4_ zrn~p=&G;?+xA%Te`~A=#!~VE>zwS@&pY#9f{nw5MgC2a{W`g%EZh{ErTMy7>!3_bt zNEk@qgzJM8+9ANiT<~+DfxNrAQ|bit1g_yh)T#JMi`?S~)X z0KA*lDRKEe*h47v^%r9i-fUzby8RdK17*ScecTQbycI~Wc!4-3Jky20RvG-TDAIKw z4ujVKgJ7+33s#eHy&#T<;qW3M2w*^Xzt9b$>xE$QlEs@3J7YE5`i^$7;+#z2szr2w z7zVMkCvHuq1lht-EvK>zx5{I{(9)K&h(dDjZ5o=5ENwxQ#fl0j ztH`FTf`AVcWf2vjfVl8LkWCO@fyX9`MFdoozL}e)De`#y-uHWdecblWJ#)^PGv~~l z*-obYWcyjxGlfmYS^%_KkPHCe10EIzSP;VCAHcc+4g&+A$GZFAu~?Fa2Zuaz08@|v zUpuB?U@?RjzGMV!PuX|j_au;hz6*fFQ13U7vg&D~qR#5HI_j)8LZcxRGPyEENhE1? zq|t)Vy#YjJsO1W^Ohq6dQ=KLUfVCX!&~Z8Lt4FY$)d9mg(Zj`99$v1$Jy=4AJy?pr zJvio-fvIqxY@A@E0Z;T+c0Ir`@hn)iI`I)AGuasKKTKYV@f(SQE(_LhCe zF5IrEZJ4%T&DPJ4U%Zo1Jj~Ge(i>~H?LTqpt_a{b)RxWY#N%?5j0!RGFgDa+oFts1 zm@-FEGtsKTKtCwJ)(-aG@PsKXfVQ#64q5Y25sF(EeTf^}y;54^K;xfz13;EjylR=ujs0OBkA( zL7adoq9acOAkb!qmO+yyG^R%>k)?R447^c31Z8#UbFHl?%RI$)%U^K$roZy#+o|fI7H3gxr3v+>@5wh& z#KZ8F4wI9?S2US&?Yq4E0Sz?iwAu@FP93sRq_zcD~s_|SX7``3}y%5B#t!|0kP?iN3AWvJMESxJmFUOEv z$6L4%NC8~%eSLs9ypLyCGFfjaFOB*7Gk6Ie)lk;rGNG9enatH&T^7pmz<4K}sA}Xk z01XnKC&K&#o(%FkJf3l*$_|G{d9K4`Bxy&DsSFKCtW!N4h6d4L@Z~X?(gMG_cm})G zW$T3ETJ1)I(Kp)`Rw3!-3=YZ&(z%@0V%kF6bxxXs2v9xV=3O2F+{_4rD5dU2;(u*F z%VjrpT4b2U?~Ktp44oGuuFmAF))_i+1(USNR82QIOC2TE+A{CN$M>Q;F$?Of_6d0= zqrux!A#USKylB_}Jc_Q>xtNJq&_LUr4`HwIqC2w(>J1vJ$!hm&T#;LTezA{$+IXX|9@FZe*%#dQy|Gvh7^RRo0a#dF#i*geL?42)dZ zJw6c!!281l4G!e`=tZLz4h)ssAgB)G|0|x;#@Q(lrAcGUW5~RQvIVn?{d#&UFKCBG>x1S9Tt#dkU z>eN(=BSnYKktw9roZ6(brOH!esi1#OlTAm~(@sK9!+A1W^3%tkNeCmAEg7cN%Ct5O zU1uzrV5h4l46Y_8)RS41BxeB8ze(L>wwYN(hFk7hNSQ3Ehy9nQiASj(e2!GY$*)Joc6b=gU} zuz|KXW4*;G(pT07R|dvXicFCEFU?<9bRoT1&0$-6%cKFCl&!Y-#YK@)N!JTn6 z+!cE}s^bv$&@h8vIT~)L>1+v#J4odUsZ3SvjXU&_WvXQ|H>(!90|j^9kH>7KjJ4w* zhgGXpms%W7orR=J3$i89m=vRtQmgbbg;J@aq%uVYDNQGpX;NLLl9uX}%GxYFtspb> zDn>6@zQ9VlP%EPHZttb6B$VN6C^e;2$W*mdrc|!0O_$2$8G5Nsm6;~3)zg%!mZmZ? zlx{1bH20=LXY!Ydw4$Iy3RSO9mrG@2mR_2!mn)@ul}sVcQphP;7L`Tmb$SUwk?LBj z-K>M|Vl?Xvbm~|eZIBQh>M(1i)=I%fPxHr@YBcctSZg#vf&-qth|)rhN}i=sNfjw_ zK zxY-=mT4$rqPUjh5pFFNNrv5t{9J+=_Tkv?E^1rvh)5v6<&SIe9yqhXPHl?B&%H2h& z5B45I^PA1Q>~M-ipl@y-;GILCe4n(ylNNZ=0#91tNeet_f&WJ>&~dt>EpThm2+wZq z=Y+%IesOd~WqDC)Ss`;M6_%74Emj=HHOw%sk2a9QM~ozR2VulR03(htw5KB-Hf>cA z`so9}%_V_$nF#K9?i_bV9>0~AR1ic5{;?ntX|uxsKUM*`(U>)miJf+@2FhV*cxvyC!S2;K|fmm6Ft)W<4=@U#Xa z-3Z~M5RNms%ti>K2(#Es>tOhijbcD?PMWNPunfXNdvzuJg@6sCLVTgY57zs^P8f58 zyg*~Mjc1}zL=xGXfXCBJqJ(ZV(N3qd0v@?_b_yPd%{HB7JOFN+Q7I7immNHVb|;S{ z`tdyqM1AX~-x|X785Vh<1J_Zq17}?cyDgLv9kB?brPCSBPr`p$%ufOW-F^*$@YVN$ zcytN~JtPLK>jwZkJP@!(y#*8u5;m8^}d9jyJVZ&|IZYpmbcTy{8{U`yHk z*d^?tY?3{W{XBandolYR_Ez>@_P6Y_>^Am&P7tRDrw>QXDdi037&wibX`BU|HJmM+ zeVk*Q3!FP#E;o{!$j#uEa7S>*a-ZeS#NEX`%stP&&ExU9^7`p_Zja9?*i{vejq=ZuizK)NAfNFsr&`}_57XuBm7JJdxB6wyg)4|7f^!nf?0yq zf*pcGf(wFs0iuA!fb4+kfUyBn0u}~r4A>X&eZZ~2z(7f0R^X68W8mb#g@Nw{ei3*! z@Hb(YFj=S(juN_ruL;)*cL~1}-Uq2*VrOU=HN4ngN z>K>IFMMq7K+7xvx>i4ch*TSy#UFUS&*7Zy`cDLkiL%KC~d#l^NZr8etyZ7r(cAwsT zbN5p{@E*xMDtkQJV^xm>J#P2x)w8&#t>>bidwO2$71=Ad*Vtb3d+qFXB|1EMK(sM> ze)MP2KN1l{9$_LD5_^fZm>w}DF|L>uF$ZJrNfISPB~vAvBxhm+Vl!iFW9P@V#J0sn z$7$mx#%+i@6)%X-jIWD-BYuDU-Gs!1VF@oKY)iPD7?oI>I3aOE;`d2GNjXX5l2#@i z?al3-*}J~?o4vnD#*>xFb;(PT5B0(OsQMWDyxHe)UryhwzLvf#`<{>rrFqf@=?3Z9 zl*p8_l&LA(Qf{QirH)LUle$0kzDy}I$yUow%fsXYT2b1h zwC!m()BB{;>2IZZD!Xc<>Pkjj#+Zzy87DHunH8BcGr!2ObRBu-Q)KA*4zTf(Om-{F7r~9w&e?D81t;=4K-8z66FlNB=0j)VPIl7#c zIp=a?bE(`lxtH>K=Z(#KH}6KiEZ?5LCI7BQt$9wftAJHdTrj=hU}0F{(89%qKNLxd z3`HA?+KQFM&lc}0;gk$2nNxD2v}Y+yF zP&-fi{owe)mciS~L3wHUyz(;@i5252J|4myQZZ!7kc*Y_%88ZxtHP^BSFNwQQ=MNu ztNQfNq@k{%Ej1xEqiWXG+#OahZ0@ku;in}mjafhD4_&!#rS7)ARKHZ;Mrz16 z$g5N?HJ`ddXVY`(OSRdxb89afvJLYLSL$-=7SvrcYK)7GH^-KYT{iY^eR=)b`gYSW z(P19Lp>*zOd=&C~%`lIum+ z*@giPOB#M{tZDq9Nz`O%Ixs$Y{43)xO(>f1_Ot9~$!A+8#!Q?t@$7SX&#ibKdtU#1 z%cR&z&66%nE}s0(lz=JqQ~o|xHg)dQUtSpY!j9&i&6AtYzgYa@hH1gm?9)!X)bFKb zFSB1ZzI^bNv{x3ra(_BC{i_+W84G6oF_WD6)vNMX7rxs5TJ38GXQ^hrHJdxzGW+

MVA&f1Z@AuQU0Ako`=Yo-vlsobxNh;W zCHYG>E$y-Nm8Eyzq~1L8R_>jC9~Eq_=3eak`B!L5ff4sHJ?>zf^i z`ybwUBnOq6>y#_sN6%HahMUt3ULx;@lh%?Pl!& zF$`i)y|0uiaPKazQb4Zj(`hadh*{#8DT0y7|`Idvl^sUu?ncb42pE%~36T e-ltwY^F{4Miy-{K#O?R*Uw!J5dDAcL-~9{pr+ef8 diff --git a/package/netease/system_resources/resource/image/IconLianjie002.jpg b/package/netease/system_resources/resource/image/IconLianjie002.jpg deleted file mode 100644 index c64910cc96c2139b1130f08ba2fa1876b52c34b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9258 zcmeG?dz=&1)pwH3X0w}pWFG}YX*PgR+H5k(W|NI9%O<-l`>|QpY(Uuh$v2sqWaB0? zAv4(r2!euWUx>w8tsey`Xz^G1D#iBeS3v=_+Rvik3m+{|pS3(hv9)N^bMNG}xFWx{ z{?)y^bLZT1&OP^>bI-YV=1x*CrH-jjwGBl=2>E6_p382wVWP zO;lkT56o0$9$b@#fs48XX^0$zwo?-~+XaqI79Il5b8-c3Y?>Kw-DK8B4582uFlD3{wx zyJ?$|rrov%x7ChN!L0~sL4JYNW}`Q!?M$T*+N{cst=p{5!N7}4A*D|1Uzl$rHITEB zTA6R7ipt2KZc=4ss~ANbnhSSqC%LCyN}WJ@V$~9_4^gR;sEo7_w+i#6UO{V+zNn~3 zSESeJ^oEk+5<^Y7USD1_zN)IGs%pGJPfGfxG|sQ7(vp(WveJsOvWn`mva)Jil~pTU z3>PCH^$0Q)L3rrYlnJQ}l-fY0UIQbk)B&m)wA4_ffWo+_5v3~76l#lf#U<4FL<*_Y z8Da&Z3MjRzK&8x0R#?4Z%TGO%r_}f#4chAyH$3ar zPQ9(?^s)C?$?>Io9=!4L*6#+mwtZXWhH-}$9OuvMTC@Lf@(=INnYQsqYkzk8f#+WT zVB7A;o`2))!qC7?-`oDs<1f7Vp|ky}@Zh>T?)~`_FTV9>15&9#+XAAKwov0BD%8@I z1)#xFQhLE$J3iTR_SD~wUH_-;%_(%y5hbk_UJV6 zfd_VK_IDAQo6uf_x&kg7#t4WfA`l@!*AZ^7Z}B|E{wuHul^Lp>jg@&e&X3Cx zQILQ>4s&|rvXD_5d85HZw&4#;zHGyr5WKmDAmq;k+7rU3aGvO=`8)|Out1RKO!i0dY-Wom z${9z)`=zK%@ZCev+5Rkh@c_@tVxpCi8EgSjvOC-@W#RzCm>KR^ZPdw!6fx%w8-PWA zv|)SLsDkfKu(KCq38Yl82{C?E9}klYF&PoU8TXZ8f**A9h_WokqM{H^chP4kScN=% zX$J3)g!}RdB^d(fmgUFUp+2GLkY3_dnLEiGyyYQOMru+uuTt_&eTFoP5lWGg&cafH z#d+FG`cKHVCy}w( zD_Z1g_1kHU2pcRDq*no6E?_go717U%A*7-dDjoxmg6CaJ=tTsR&M4JvV1+B)cM^v3 zWL<)r>MNmA^u$fb)AUt_IuMIQBp@&9LkvL6P!eh@{5gRqoe;Q7w&de7a_VBh%;4g%@rYO3?_*OADi& zI6-xmRvX*Ehobgn-V*K0;8XTbI_z;sM%c5?8PspRNFU+7vvX=zI zUNI^r@|rQ6 z=V(z83uDqb0bI+uu4TJr=Z@OlhMA2M6m0?R8=z41F6LEmoVwW-|kaSsE5(X2>i^ zlQR-pd5KL#$n&oeON3{;q}*fzO%)Sj@vPWUeU-=P^Ie!V7Q+r8VkNn407kjcBuIE= zwfK2SOeR>qZGac#$(io)%xS^sBC=#Mo0(1=o8^wfhD6-Mu@*kc$3V6Oyfo1-?)D~l z2A*^S@RXaGsN4(JsOJ-SjC4O99+3Ga6HK1dOxw&>SAec}I~v?}`m0tr!mui=J_rX6 zo}{zPF0+*e{y^q*V+6CvMMA?D!|L<7I|NB)1eWh;Z8CvUb&&|?wg>I3GvuJnjm{uz zuD7~uW>;g#Wwu$lMki}?*%`)0^n(7aBAdhx!Tpu!3 zv@>XifOVRKt`Jinbl4a^q*w{kl*bY#nlBY=#eqbYW*RsSw6eP(JnQQl?B<}&#+qq| zJ;<=u275i$?c~D@JKWJ7@U}+6yae%My>OxPdy`GsCvq@1Bk&zwFT6H}B2gf; zin6hti3mp8G1X+`Sa(QF#26ST5@W)=<=QwO#(4tNrD-S{F_Q3h zGc10qY%;MpoOsTZMn^`Opo?>bB6bkog)SIh3Y#Q`NGbp4wspugLH$F4!Rob&Ws1XNDI)C4l@DJ~ zPM;5(v8+78#efdJcDd+#ep4j@1Un`hdut}rV^lP3k z^b|g*oua+7sG{f=okn+KvAX!Cl9G}Q`b+fNO6{fl%6iJ)EMHzxS#iH%j^TLa>Z;nR z{ng=`(wg00x@Mei-0tz*gsKUTT{1M$Jn{8Q@4jroB*Ubqzx*v@XKiWiGp3D`d#9MD zygPOG<*TQ4O}}jViLdOLvEi%y*RC*En*UgL!16=ub#$+-(LTX`uKst9{SEgy*Sm%q z8F%Luu9;Jts%I6{nWz@jUK*xOI2i&N)AB-!}K2jxGPOdES=Jt-kGDJLd1~ z-hJi6{>OU`23}t9=E4sasTLc0O<%WPJ?B4ruMw84`L7=^yMj-%Z}FwDW~Z@=~4V?VaHqcpa>uWV9uDt$;*n{O z-m>rA16_~pdScwKS3LRpZ|42~&whK^!FA7^Idsk8r=EAcu>GZ)BWqti`)c^LBfsxF z`p9v|AMSsn_RTxrHoWtVch!GddE%o}$t?n|6{*q&x9Y(@vpJ-PmS+vmId#plL*_WpAB#$V`enYwFWt?#ea zZR;k-4?lb0e~wQOR4d=MZJ2i`aBNn|p{r+XY`#09T3#st diff --git a/package/netease/system_resources/resource/image/IconLianjie003.jpg b/package/netease/system_resources/resource/image/IconLianjie003.jpg deleted file mode 100644 index b4dc834b4c1debacf9328820123e3b61a5661973..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9224 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 diff --git a/package/netease/system_resources/resource/image/IconNaozhong001.jpg b/package/netease/system_resources/resource/image/IconNaozhong001.jpg deleted file mode 100644 index fe96da0f0f43f0f969cc59255204db91d078017d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10988 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 diff --git a/package/netease/system_resources/resource/image/IconZhuangtai003.gif b/package/netease/system_resources/resource/image/IconZhuangtai003.gif deleted file mode 100644 index 5d85a05c324258b766194683e1144fb0029fe151..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4818 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 YQDj6|i;(Av*cN?G@6__7Y)%Gi0C2FZ-~a#s diff --git a/package/netease/system_resources/resource/image/Iconstart002.gif b/package/netease/system_resources/resource/image/Iconstart002.gif deleted file mode 100644 index ca8bd3d12306cc10d6e83a7c81fd7bf3b6ddb2b2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2552 zcmbtUdt6g>6u)BwHpXjCaw9v2! zweTPwbR2;wiW(jsE-ES#3WXUN89W|ue0;pTyc|W*zP`T3#>S40j+B&?iHV8+{{H0T zWXto6Q~>87V9* z=H}*sfr0MsZmCr2a=9P~0)*iA|6k$>{xZFJrA}L-S4!n<7GMNRYfL3DZgE?{fBq5= zWwEX&+;AmPWp`>MC-?1_z;>HPvO32kH&HsG+HP#1iIok@%+`kWR@5e0aw(keQF|Pe zgK%45kE7PO>nx#;w!JRFKr!NVJM%&h@OL4<=Ebyg~RJ+}jS|+Qnub0-Vq$FJh zd{I;;SIU&iEP%*zZFIUVo-C&;HNb!qE-P)P+;-9lGmMr>vd*oM0HsqYIH(y~r%O7S zj?_vzWF8A8Q%L1ZN&%qB^xsg2V+QSVml9|61|@cxH&TSGlyH%Cw3PtxR3;Rq*3pE; zP10tPtPNDLq?&Y-u4$FrDHC zkC_1=oS^Gz(B7e)0ME*k>m`{p911 zKK$VQ_uhTy?YEBmj~#vUjnN~oj|>kTKJ?nF2VXhx@=JsJUwq;Dea}7n%+pUj`NTkf z-`>X`d-Rcq_dL|Q`@vlg+~0Gb@7|r=U7a2G+Z)~w&01->`l^cZvMaAxyJq#}tIR7) zSClMYW-7j{sL;67pvQFuT5QRsn*7CTbWvVzPPR&^kjtc5nHlK|kxLd_oR%sP!xyC_ zCtWx{@q+W`i4x8e3gY8pW1{&{JZ@w}IENhu4hivTPBV zj7UzWHW$#?`m#96TJ9(IEiC;S;b4R#N=}ZGTE9 zCqM$XggFGDI&Xa(7e(sndXj4-W0eBGkLr8$~cW#LF6(%PI9m8Dsym8=(Sl_*luCgdH93_(~L6VzSRVa-d&%lb`)&9*I6Vk zg&g~wPGgo7L%*wt6D^EFFR%$?5E*KRh?j*rP<2f!R7pUH9fXd9EY#qvi+6h#!q`Vv zuVX+s=ycqHyNi1R%kJ5}>6%UKFv$y&P}by*MD9f_yf)VBXN(j)JK+4dnS#ABFL*xY zsod|+Z(V*gA~Z^BT)&2$8xz?A~q@$t5f|3_vQ-$!ZWd=QuPyj0MgB6V3Qh`vjv0=FjApAJLE@w4FG!Ky>P=!imJ=@pDO8t=S5VtcsVqs-u zV_-sJphI_79#bb41VUm&GUp^tTNG9NlC9tWec%7O|9Ac=KLIy7nYRl-uXhJj!Kvim zL9IP@MhAccmzdcFAU~-*AEs$!$#RfL#0_mKIiW9SB$A<|$Y7(HMZ_7=l(*@g7c_*Q z?>`8<=Qe~Lqp$R%79DyI4rBWG@Zq*|IC8KnH1F{nnU(pGPgBBY{(g{HSwomQx0qg- zWr3eU(osXWUqt1f^tbp{7*pPmOwmzH#3L+010fyVYAdHbU;tjSc*=z4s&Uepra5kyT!YYZ%ge=W4R72J4BC>H^gb>-Ht?SI2VGwFN zrUr>3$Sg&<7@jl3RGQd?7V2U(*vDeIXuviqW~-C`0N1Ar0o)_DqFnwJJOkYS%gU)# z7BZ)=a2z{j&*I>JmHY_Qs$dnYR=65isd1GWmmh;ck=W_)g=tlA^&bl}u5p07d=9pH srJB9Nwewtt$iIMV6^;d{)Ibw_{IhoR_qUfjFJAq6{pRg40L}dKUoQSd;s5{u diff --git a/package/netease/system_resources/resource/image/Iconyinliang002.jpg b/package/netease/system_resources/resource/image/Iconyinliang002.jpg deleted file mode 100644 index 6816ea678e4e596ed53dcc22e4a3536d8cd5bf99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1247 zcma)6J8aWH7(O>3Qh`vjv0=FjApAJLE@w4FG!Ky>P=!imJ=@pDO8t=S5VtcsVqs-u zV_-sJphI_79#bb41VUm&GUp^tTNG9NlC9tWec%7O|9Ac=KLIy7nYRl-uXhJj!Kvim zL9IP@MhAccmzdcFAU~-*AEs$!$#RfL#0_mKIiW9SB$A<|$Y7(HMZ_7=l(*@g7c_*Q z?>`8<=Qe~Lqp$R%79DyI4rBWG@Zq*|IC8KnH1F{nnU(pGPgBBY{(g{HSwomQx0qg- zWr3eU(osXWUqt1f^tbp{7*pPmOwmzH#3L+010fyVYAdHbU;tjSc*=z4s&Uepra5kyT!YYZ%ge=W4R72J4BC>H^gb>-Ht?SI2VGwFN zrUr>3$Sg&<7@jl3RGQd?7V2U(*vDeIXuviqW~-C`0N1Ar0o)_DqFnwJJOkYS%gU)# z7BZ)=a2z{j&*I>JmHY_Qs$dnYR=65isd1GWmmh;ck=W_)g=tlA^&bl}u5p07d=9pH srJB9Nwewtt$iIMV6^;d{)Ibw_{IhoR_qUfjFJAq6{pRg40L}dKUoQSd;s5{u diff --git a/package/netease/system_resources/resource/image/Iconyinliang003.jpg b/package/netease/system_resources/resource/image/Iconyinliang003.jpg deleted file mode 100644 index 6816ea678e4e596ed53dcc22e4a3536d8cd5bf99..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1247 zcma)6J8aWH7(O>3Qh`vjv0=FjApAJLE@w4FG!Ky>P=!imJ=@pDO8t=S5VtcsVqs-u zV_-sJphI_79#bb41VUm&GUp^tTNG9NlC9tWec%7O|9Ac=KLIy7nYRl-uXhJj!Kvim zL9IP@MhAccmzdcFAU~-*AEs$!$#RfL#0_mKIiW9SB$A<|$Y7(HMZ_7=l(*@g7c_*Q z?>`8<=Qe~Lqp$R%79DyI4rBWG@Zq*|IC8KnH1F{nnU(pGPgBBY{(g{HSwomQx0qg- zWr3eU(osXWUqt1f^tbp{7*pPmOwmzH#3L+010fyVYAdHbU;tjSc*=z4s&Uepra5kyT!YYZ%ge=W4R72J4BC>H^gb>-Ht?SI2VGwFN zrUr>3$Sg&<7@jl3RGQd?7V2U(*vDeIXuviqW~-C`0N1Ar0o)_DqFnwJJOkYS%gU)# z7BZ)=a2z{j&*I>JmHY_Qs$dnYR=65isd1GWmmh;ck=W_)g=tlA^&bl}u5p07d=9pH srJB9Nwewtt$iIMV6^;d{)Ibw_{IhoR_qUfjFJAq6{pRg40L}dKUoQSd;s5{u diff --git a/package/netease/system_resources/resource/image/Iconyinliang004.jpg b/package/netease/system_resources/resource/image/Iconyinliang004.jpg deleted file mode 100644 index a5a51994ba84ceb6e85738425206036b6dd2c213..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1311 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 diff --git a/package/netease/system_resources/resource/image/Iconyinliang008.jpg b/package/netease/system_resources/resource/image/Iconyinliang008.jpg deleted file mode 100644 index ec7406d50fda524e0f95dcf3857a457dd5b6c096..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 zcma)6OK8+k6n&YgwiQuFw2FenxKU|7FW*UUEOus!U5uYPP{q|t^2P~mJ|wA4yYYj2 zm#zd??%Z0%g%w@6b5ZcSv51SJD1st_5MQSADN;%=B;0rJJ@@zSed*hD8SJknP6L4P z@#A0s^eFub3Y8gaY7S7KkBDsm(&hZ^W*i3w&wCMvY~RG3<-2@>0v>V#4^E6E0kWoW zOq=+Mo0xk30$%rkV$B%UfUr?RN@#o9T#?1z|EIF+>oRiibXgNmlf+Au8&P~ioMmjqUn z3|TN_k!}-1qJ?(Dn5c}kW06ydX%{s+JIl>VoF87{p|0z^Ao8Nf5(_q(^J0{+UUa16 zp@JhTbb{FNJv#GpEVyTdtec)v}J_3EWF#UF)bm7hrw@NB&G` zVPbxy117!OI8bItvN6tv4!IOGUGc3M7klw|rNj^oXFIlGst98!3TzRPpDY$3t4p%Y zA`>Civ^7nX#g3o#@N!Wqm&;XM9@WMmtQL!URUcDEtFk((RwP~OV8^{EMxKQ`u^ke- zjV*47HOe7Iu^-lbf4VaT=bC=(M@>JV%jMRs(?@H_a=c76xrjCeAXvTI|gB-fcg*~!SAz7XD8`#lW z2w*Rg6{XS-;1-}ZPq`lDyVQo~D2iyw*HvtmNf$w301Se`JXHX>0+laN=?icm?(EtDd diff --git a/package/netease/system_resources/resource/image/Iconyinliang009.jpg b/package/netease/system_resources/resource/image/Iconyinliang009.jpg deleted file mode 100644 index e35602a1a036c26c5288780819da8e7273fe335f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 zcma)6O=#3m5Ps>l+Da+r=D|aVD77@3y!>uL*W&JW?Fy@IVowT+-aP0bzHIkLrHBIwlX>6FH#2W0>6>%|?3zlP zc>rp)F)#>vl70bnWyxx+01EUIvkgGHk-NGO$AQ7~UX(|+Z{ob=yL^HI9_9reOiU&L zvKlyMOnlbyitM*1&sfH>i|h%dF4TiEUT~&YLws!Y$egv>uymW9JitsOM&br8juDf% zi(X_TMYa{(AbMuzS*8Vv8%6eD#>$+m&oE^_#Eg)dd==StQOnEA`DH2Zhi7@H>pCxpyeM)6!9^=xj1ta^ z_H-gtaAbu}5IerdWD$|+FU3WcWV%^`8`SIFz*~09b+fu!=qR4Wy)?E&M{_Fy=4Wx_ zFNGE+@I4)8(z|~XWk8aRaWr(urJ%)%Z!Njli))o4OHT5(V;iQ5FovSQ6%cvJVgYix zB-Z-XtCM~O zBdvu1c9X0qmA(g;0QLXU*OOdV+U|W6MNY}nJ@{WGZ321_41u8>MT0(?%F$H%9Gu7! z>-}DcHn@GqUlwBA38;R;*#q|H2DWVngMCBEBc1*;00E`%z;KQtEIArXg0-LA{;~77 z??1gvuN}C#@7|-)AG4*`wIdUItA`(aIl+Da+r=D|aVD77@3y!>uL*W&JW?Fy@IVowT+-aP0bzHIkLrHBIwlX>6FH#2W0>6>%|?3zlP zc>rp)F)#>vl70bnWyxx+01EUIvkgGHk-NGO$AQ7~UX(|+Z{ob=yL^HI9_9reOiU&L zvKlyMOnlbyitM*1&sfH>i|h%dF4TiEUT~&YLws!Y$egv>uymW9JitsOM&br8juDf% zi(X_TMYa{(AbMuzS*8Vv8%6eD#>$+m&oE^_#Eg)dd==StQOnEA`DH2Zhi7@H>pCxpyeM)6!9^=xj1ta^ z_H-gtaAbu}5IerdWD$|+FU3WcWV%^`8`SIFz*~09b+fu!=qR4Wy)?E&M{_Fy=4Wx_ zFNGE+@I4)8(z|~XWk8aRaWr(urJ%)%Z!Njli))o4OHT5(V;iQ5FovSQ6%cvJVgYix zB-AUf=FO_k|LiC&u_!jF_8())b47KkM43|k8D&(Rww-m zMp_F2>?T=JDt!+w0qXyyuP3>#wB7qCikyZE*XJzbwSK6Hxtxvj^_py00K(if#DoQSaLL&1ZzLJ{bT2E z-+y|UUORAe-@QkpKW0m>Yey#bRu4b;bY^Y+&iZik?yH9f>F=+vG|tyw9$(*my*55F g${ZS)o|(D&Ve<2>8>g>*Ou?xOkH5dT2%72JU%%00egFUf diff --git a/package/netease/system_resources/resource/image/Iconyinliang011.jpg b/package/netease/system_resources/resource/image/Iconyinliang011.jpg deleted file mode 100644 index 8780f8cebb4d7e127a2b1a2a3e099632b7c1e861..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1304 zcma)6No&L>##GX8x`}CoAD*|S$spWi)TwMSP+z(;RCh(>G_6Bs2xVkBi6&EL^k$Pe@THz@jLC;gK{%_8d-F z3tw^lGWYYvD~@%YGIv33h>fs{XWg^Q5k9|sZpvPsvkiwEIn55IX6l6=P7s@V^L}im zWv=PmBzkTZIJOB%=E~feJSscgm|&|xgjuzy@wTYxtZo#cs_Tk=ij_pD3Zg8?A}`6N zBASZCwuB?mB4@^&tc|u}k*_k>Dr#|YvA8G~gXoF?4Z{#bNsuI-AozI6Pf*JH@le}C z4aaumhKU>aZ0-?R!9r5zNTypQcwwW_alB)t0C(y|w{bhROJcXU z#y`1cHNq$fqNyO5Z%@I*Y>));Y!I^5YV+3F;|*lHer`OGU({CJH5|EDu`?P49^34+ z>F$sPv>}AZz`U*M2CwKU%V1sM%ooyZ5np9#Tm4xktOj%VWRZ>d4 zZW$#WLfzsmMIqi)6=BQPWQasgASnv@@N65Vwuww=u69;~d~}uz`(&dcvO3uhu&=og zz*!|LN@btGbwK^U^mK*pNQ>S>QRI|7orC{XvQ@woKtJfGDF*Z~6wOfC8*njCtowT* zT4DE|zbwQ!06-s2_jQ4T2M_HofCIg|j`Y)q)29aWrxOCqK7ze8MIzA*7y++0?pbdc z^ySvKmHUrYn8!Ej`!7%U$DZFcHzyzJU+)ZUyc{U(y-lw@fY&ar75eDSXTPvCoPp2d O?=DS00fR@g55EB#5L=}H diff --git a/package/netease/system_resources/resource/image/Iconyinliang012.jpg b/package/netease/system_resources/resource/image/Iconyinliang012.jpg deleted file mode 100644 index a2a5ab73abe86067dd8235d1e43d1d6591f15ae5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1304 zcma)6OKa3n6uxO%JC!0vt9EBhH!5b5o985SEOus!U5qWYpioe5lG`@4d61+w?M`s# z!lLL(H$K3h-~&|9om;`zs^~&QbSJnd@n$-YDy8&5!pXVccV73LWFNA1Fj!07Spdez zPl5vINcICT)g^mj1yG=ym>mGJb^6A9l7yxp_;C?AfrX29;0Y-T1y~dXFg%im$X>t+ zYvDQ9FLS@1zvNigDRURpx>ye@c-}p`8sYP+=cet|1>11Ak<;vOYNlT3;RLa%x9G=a zTIL$gO`_*!fnytxWTDKR$)mCt>yvCHh%l=bHQp9Aoz;yZRCQg^PqC5+RY8;mS>z?z zR76ve*rsqKTI9@{Q`NC%Eb>+6nnf)yFBg~PVi3&<&@c=^lmtoQ34)JT`~;=E9}l%W zRB>!aZkV`%&*mPH6)YuXj%2!7f*027ZO7Yo%k%QO8t6Eg!ksj>MaR=CAr_`^94tjP zCh(yane=YwKsk_PV@^aaxfHZm4eTWk`^k8<%#o9#<2t6LA&j9U@+CxGid2HUAuA4# zEQB=6(RE3YT7I_UYnnC+H3*eaeGI}{sbtiQF?F=2Xro$HHsls}+>aCF+qf0mC9#`a zaYwFMi7-lnXgUZMTT?JOA0$CMAB1eB(ztc@cpcfUpBqo)7qwY;6-VwB?2JW$$2K}` zy4z#{Z3rPUFmJ26!7I87c_eAGyklcsQ=zOG*x;IcXG;e+CzV)8C1EQeQ&v?;m6Q^% zTSke8P`7wXQHVEHMcA@686uGrNQy!}JX?mTWg-)rtL@bwAMNGBKG~>}xCp za9)uWrLxc98lZMBT^*s@(xi7$6geeN`(U?9_6jfs&ThEYHAs({s2O`5esi95^@- z`^cQc5pCcJ+buFbp1)vd+bS|=GS4r-dl@d76ZEJ3j0j2oet zb;I7KhcXV$!1g2CbLrG0GQ8=i$dF7|OK|*3rR8|tZaGd`R~;Qjqqv>My6A9h#>dVvH3|S;7MNww~+|62gq38+qx$+nRl+0HFp-5?V`?a^{=bHh`z1hx@yCYQ~D0dW1>o&CEn zz4^T|$G$pzd+EW4Kf7+t%QsHejxO9h_jh6W@xt8IxBX8Jtdy@j`7A%$w|Kv6yU@Gm j@~QW|&+gvq+gsT2_v_Dh)=UC^9shXY;d#)NO+Nht1kq+J diff --git a/package/netease/system_resources/resource/image/Iconyinliang014.jpg b/package/netease/system_resources/resource/image/Iconyinliang014.jpg deleted file mode 100644 index ddfbea119d41da58055379726e67f2ee214987f5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1316 zcma)6OK8+k6n&X#Z7ZUVptuYvNG)cPm+vGvRy)&T7o$?^2NdKbdF_NYAClBb3nHQ$ zsZa!$x^iRHjffz+P((p+Be<}(3vs0jsh|tdO?;Wor${NikZ^O~IrsPOO|qDL0egpH zdmMm~k$%t(+LC++x$?9*IRhxrLCh8a$(QVWHHv(lThEYHAs({s2O`5esi95^@- z`^cQc5pCcJ+buFbp1)vd+bS|=GS4r-dl@d76ZEJ3j0j2oet zb;I7KhcXV$!1g2CbLrG0GQ8=i$dF7|OK|*3rR8|tZaGd`R~;Qjqqv>My6A9h#>dVvH3|S;7MNww~+|62gq38+qx$+nRl+0HFp-5?V`?a^{=bHh`z1hx@yCYQ~D0dW1>o&CEn zz4^T|$G$pzd+EW4Kf7+t%QsHejxO9h_jh6W@xt8IxBX8Jtdy@j`7A%$w|Kv6yU@Gm j@~QW|&+gvq+gsT2_v_Dh)=UC^9shXY;d#)NO+Nht1kq+J diff --git a/package/netease/system_resources/resource/image/Iconyinliang015.jpg b/package/netease/system_resources/resource/image/Iconyinliang015.jpg deleted file mode 100644 index 19f3c6f4234d47fe5e8cc6d46f268f045cc35d69..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1319 zcma)6Nodqi7=G!rIu%i;xPcyGyr`H-Ue-x47H7jjMr$o7;=z~X)rM&nlGLU}P}G~C zcv1ACc=zA}Djw{?n;;%Us-Ak$izs;V7GI{bh?LSF68`ru-@m;7f9Ybn1a{UEXA*!$ z;{eEmKBYfEp*mx=<^Tl-iP#1pUCP~>isL}%I4>$9+c$C1@?9=L0SAjb2M&!U0kT>+ zrcHdo@eJnI>o*MT*amZ2Zt~5bf~TCL^C3Ppe|*B4Z&{knj2@;BC3@lpE{+kMxYJ&w zCkE37*9o7AIfibV#4Uq4l0~J@G{@+QA7WZADy+pTDy?coD66WZ9;5{x${a6pBF_q< zF7dh~&>dn(w9uZ^$E)>DEOIiKPEoV7v&C7l=!X|LsA(F<3!EUZ#Db0Hyci{{7wzpL zRB>d5P7pi3M`wu0^k-s&A(<|h;0DcR4|v6Hxo%ch+d7KJaX*a}t)q##0CVFw@@GN| z6Z5@YXVSaX17(IJ8~sG+kV`?+Ro|L%u@^V0217JO+p%?1K^Q}UXG@6uB%uUZO_XdF znFuMSt*U|~ba7Vl*J|~0l~)9*tkxl{l}cJotIOq@q?DDasEJ+Qh8M-ivv4=ILt-n6 zQicjFt?H{+LX2WRobdhW?i7qo`LQ2O`2k(2v~Qi>*F=`%Wy1a0MJ?A|#i4T%+x5_Q z>2{}eXN4@F1tCNlW-VFOSV@&3iv(qowJoeFG87dJYfQ)A{-=Y>lS(9{lAxQAF3PeX z3sQ+yO|8U2sG6)PNd!%n5jHJFgotN2k|LK4&p*S|6_E+e*xqW8LvOjTM>Z-XtCRi& zo7xKj>;>Lq7eFBohQV--Du96kl`Bx`TX2>n z)_+|xF2CV_2>@FF7#gI8`j)xDp>^xQw*2tcfsyUWORdmXb~i|~FFLbgkpKVy diff --git a/package/netease/system_resources/resource/image/Iconyinliang016.jpg b/package/netease/system_resources/resource/image/Iconyinliang016.jpg deleted file mode 100644 index fbe9353156a141be424745dee1c827abca8623d5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1319 zcma)6OK8+k6n*KmIu%i;_yb+UxKS~aynH9YSezdYGFodv5f{EBuQp8cAxUjo1V!Bm ziW@~YihCD+K*fb!xD&*MNYzz0x)B9e?&8aIJ|d;`Lc)Fb-gAHN-j^<>OJHX$aV7z1 zG!B3~=u`Rw6sj{;YYtFgkce#n(xu$3sW=XFj`N}-vV9X5E#Ku56mYP}bKuZu5+JLE zW7@cj%_ffG%;;hIP@*Sp;Nlq3i978@ zdSWnb=Q`mtF~`ttlelFtN3y8&ndTT>@k30@MTNC^MWt1(2xV23)PuCZLz&}6PUKlZ z)Fob*1iC{Ei5A+E`gpb8iA7EZ(VYytl8t^MbjYQk>8fwdxY&yuRf8d#qV3qasUVD@z_TSpev(jvtR_k} zi%f(R(^geM61sj?!fUm9xymbwR95Q{)=DLc;oAP5nn(_m>Qfc2hy|0NZ$IFEKvx{1;yNW~SBDU+H@6zo~ z>&^;UKnp^MG|XDEs`YUkS@xyAPZ87 zRZXqLLa3UoDM`eeEF)}MiU<+Ua3n=88=ilLsVgEAnz6mrAcx*^VUKK7NLDBP2{yGC z0@w>=MXB^FxDKeb(?FkcJ?g**D2iyw*Hf&ONf$sN4~D^Tjw*nG0+lOJ>05A?B-Vdj zGA_U2e+d9v02msihWeJd!J&2Q!M6PH)`5}j$xE%!S9QFlU%4kH5?tk3!YGnHI-9N_m=jUF?R~~O{T-~vF>}jq13_RR*DFwGn^tUHBPd>V~dw=W4 hfqi@KsUObgw{HIP{r5Y;NWrHE?_Zk_!Pw>W^IyhxV#WXf diff --git a/package/netease/system_resources/resource/image/Iconyinliang017.jpg b/package/netease/system_resources/resource/image/Iconyinliang017.jpg deleted file mode 100644 index 949048b74045054cc63c8367dcfa3b9b0541f2df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1314 zcma)6J#5rS6duRn*dPSA0tBUH8bEmM@$Zh6B}(=OR=VXU1nwj#7~7M?+W1GdmpJK= zuDJqHLIDL76civK!QBbzE)rBUC*A4ztw7Kq1RYQSX1v+mAQYiI$<~`U@4fH+PWC8! z26og_cN&0Za}Owh70Osn`J^d&ZudO_If%p$JQo z2u8=!5Zi5%a2ADw%Z;EJoz$;=w6N z-zI%*mtyy9(RXdlYD91nL{mX9*PnvJvq2KXvq8vJtKF`1yIR!Kj0+#h@!Lf;X{EQ485h_;9{*zwgid=FakzcrU-_L3|nNf zd*C?;gC@2fqf#&cJ?7E>5u)dJ~fr{TapfA!Bu#sgb2wMbW;OvWS z+EMNISMRSpIDh~2$#!a2O=)p-cZNoMXlB`X86TEm3 zk9yF99z1wZ5PTtMK~G);#rH|ki-_LTgBmB>-K|Iwe@OV}pa1{A|2f&q>@8S7l)7U8 z)a#o;0nAhO2^4EByEzRQu!xEs0J692nTaF`O;PmY5_STMl=p&DB_S%R7!C(sJ95Ls4SX*5h^?TNRCpTcTnb*;X!IN}SS`=X^J;6y$q1PbV?phBbUGyB2#JGM zWD}~sp=(TQ_ivzFkw#a)1NArp@0xx8y6a*q>dI0`(j zU1`%@APQ(h2r(jptr61WQ$^H%-IDvULSwi5F>zVm>^73{zJ`Cp2e!t3eOF54Mh8*maZ|4)7M#P+CT-p4TXmVUj9|7EgSP%MCc(9beO&{t&GB9lD?2WepQ zuS?Dqmi;XOU=^UCEMR+@i}?2cBNM*$m&^*!5uJt0T{@-8^z}-`cS?tB=9=Pfl$4 fK7P*ru)a`U`RmS)>tA;~{^|Z~y;%pC+3eMCQdnr$ diff --git a/package/netease/system_resources/resource/image/Iconyinliang019.jpg b/package/netease/system_resources/resource/image/Iconyinliang019.jpg deleted file mode 100644 index 9b0ecab9a7ce5248378c10418231dc159295382e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1257 zcma)6OK;Oa5MDPRQiKq>aa_3;ymrR<=llpckCgT6aQU%t$1nx+H?-Ru&OwNKN}D{(^tc2+>i1`k&+L}(7j;e0NxDJjX`G2pHuoYbZqOtg#SUfgrIO5gcYdG( z$g(llVvk)4*|kDvDY(filwi@hXwp=t|8x^zF$$x{ZlZ628AzM){{|24`?*CG0i zs@a=GTsv)K?EEXZQsJ2YN)5EY!S|mp*7zqsUX4CN09qejKU#jCgO{UETTfYAzWfEv C6G@@~ diff --git a/package/netease/system_resources/resource/image/Iconyinliang020.jpg b/package/netease/system_resources/resource/image/Iconyinliang020.jpg deleted file mode 100644 index 6208e158b2aaab89406accaf9f07d51cdb27bbf8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1257 zcma)6J8#oa6uxdiqzEChFXB?6pZk61bfH zEU<74Ne2yfrHBf*dh4(i#ssRo#yO&h1yL4ck&|Ro5luyc6Jcqz z*xfcatj;7B{c5n2qDG?;Ka%+{-Vu;t7=kDXlEhI2m+S{A&bT01Dm_>vabhn@y)b}< zM{I|~w87F$PfGBkUT^AnZnu2DsB4T)(hV|8V=g+`+>eN`L6UG7JA}fQN;2);`GE=` z&Bk1dJ$fm4*9x7XPlB{-HCTGWyPj*>8YTouB3H-srAT$e8M5MX*v441U0s(Hsq{0C zztU1=OI$(9s@_4UU9TH$qoc026>U|sWJ4~w-5^PE;E*!5M`KU8;<;S26%(9>@n#tA zmQ%3a57RK|hY@VG#P=NK zu^mlDSY!p7qEHOasbMNjbV3Vtx*GIjx?Cin8x_;l$^U@s$rG zYW8-~sGT)ZcK!`qt1#4mr3RYd@W-#0YwXjXuZN!?0L_nYo-Dt}!K>ltt!K0?U;hD? Cr%8+e diff --git a/package/netease/system_resources/resource/voice/Alianwang002.mp3 b/package/netease/system_resources/resource/voice/Alianwang002.mp3 deleted file mode 100644 index b63bc134d9f0169eb8b568a933fe43f42bb34eb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 111380 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 diff --git a/package/netease/system_resources/resource/voice/Alianwang003.mp3 b/package/netease/system_resources/resource/voice/Alianwang003.mp3 deleted file mode 100644 index ff5a6e3d4087df1d027d2cfcdb529d35d26ae63e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77972 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

^VlFFla>tTr=&U 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

  • KuYqBB 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 OIb59-;^;o0UIPFxd4wYX diff --git a/package/netease/system_resources/resource/voice/Alianwang004.mp3 b/package/netease/system_resources/resource/voice/Alianwang004.mp3 deleted file mode 100644 index ed4f40f1293917ae1f36324dbb6ccab476be364d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 46868 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%0D;KxIww5kQPCoHiDAp|3>6LcKNsr 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�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 diff --git a/package/netease/system_resources/resource/voice/Alianwang007.mp3 b/package/netease/system_resources/resource/voice/Alianwang007.mp3 deleted file mode 100644 index cc02636abe54d13388820d615dea1673711780c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54932 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əM7jX1MdRES9qL3AFxR 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 z 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%0ADM zWn@|&nMb1}!(+awmIIPbFJhGpVqtDwN_3epjo+d5ykR-R_7j3(yzxumn)?A#d8SE2 zOM{C?THiO#6dk;m7b!C*TIAi>ga_BJ5yi{$&b#i-w3?krN=jQ3M%`1lv07)3nIw*P zJw*UL!BKe;50EwakgKKH6rcLIi;WT*JBp--iezshcE4 zxw5m>7Q3w8yfGB^XHLjbFw5PWp9W`tf@S2k3qCQYEjc@U;nyW9*)k?XUhAPc)y8N&nJJ*74SGMUnQcBbx(n@AZeDxHNNIH=M?ara zZ)d8L+>|hSj8#_tmYg_FbSAfSiZ&OZ65I9ea6(g=aneo(2 zVm(3wn^%frIvS*R#`{#$eCY)f%^jG*lPOtDdxt$J_NmU34t1>vx!IcE_d|<&E^cfy zoh8ss?qiJcc`|mSBb68s!3l`vUDEKepjDMk|A3V~fExE)Z3{*630#l1$PdzS5}NW-+?MQyW@ds5_&_G9vnLAS19Po` zoTC9pys;uglpLFz5+R~)yq@Y1rwP&L7}d4{R$jf-u}ZiwHq1u;<}$Skifg;!atj)% z?bxW4Ud+kO;pP6$726!?{?8>i{AX4j_m}kW<{}Oh9kI%;Iqw5e$ zL5@}gfGkp3Up6iX?6(dcQVxUj5+3uM$amh(B^5|RZe~1`$Y;$&YS0gUupjAD;RE2o z;LAY8Cj>V7xAC)@WF4wd(t^9Tm8Cg#X71-*>8eHlawqkR?^w# zTG|zI!+&(-i|$sl+BndJ%Yj<>9W%XI;`NmZ)bkD8t*3j<5%jjzc6C1nW7a$~Gg9-H z%@OzMN!4(}f{~T7s1b>Kg zy!VEE!GIw(KYkTb&oTSC`(@iNiE>|*n3B)>;f}uiHVqp=t|E9krg~qHBpG-*O1`{R z0D)flL8FP-zPQ#ZIu1Fi~YxR4FNLB%^>5q=HQ= z(&<4Tpgsp)?m5nYOIk*-XUf_7U;GCGFoA9|2Os>aZn|=x`_8&95(_-z#4aN;&1 zqh_ti007V*2geDQY^5pO-o<}f)mNLGAeortJZu(<%9%&V-B%EfsNC+z$B9?Tn4Vo+ zn)TFX9sA_UtUlRpmXVRYEt3VsM+#0h>L2G4;zTo+Ew=q&j2GqHBzb$aG}o!-!-hty zDz28Sjo#uM6`3Hu4bb~$^DD);J|9a3+01PY*dB;+3}>$H;bhE7nS2)7Tg@52Q_9T%5b%A z2l(m9XEM|rO=+>H&ep&7EQzc-w%CoS>IkKThANyz`qJCx z&RVF$uOr&vY!?~{)YmhjlN}DFgShnC+W;qzVhQr3Qd$UE2aoD+-xX&9k#gN75=}V$ zcK54wG|JB=m$P}aJ$ac>6_XXGVM0ydA!t>ya)?KV2nphewC5J;ny*&+If z2|0?H?e-0RzXgO7!Aw?e?B+r$r!KD~uDD87q#(ojKt4eWuc=0O*YGkfEV_?F)uefM ze4d%OuaWH|-|-HG;U*En;-OL5HA*-oE?A2!e`6#JgMfLxCgU)|K-ZwZGvjp9P&eM5 zSu}yKbIEkBn0clkkzPoxCyJ=hZ4k{T?+>Zp(rSVRFy^Pu508ymn0+7eT3$%klF=<` z0nwUeE;YK_V*U=gAYX#wqoVD8ElOSi%=_vb)e2LE-R0s_Lm3Txkq7;}C2G{C2sMYD zOVcZArsIl33DYVO8iRd6n1?$Iw8m~5j-Vvl1@$qCZ#k)^2X`#nVu`WrVD{rqiEIuD zFZ^Bq69MRtB7ghuDm*F6-NNgdDD@T~vUoE(p4?_!1*tZQG|zp@bH7#EEX~3W7$=Cw z*|obui;>iQxODv*pk|(4;>C53MWNMx5?vtCX5SXQ9sliYJ-1jiy?ySS_<8XQr@~`F zZDV$#_^utU=*AvAh zUu*~Rl}5i(LzfhuxnkGLCh2m+Tzrn-bvA7(jznWx1?yOYw2Vn8=Y+1$zHp1rp>T^; zh{JqDSXxI&#dzxn>j42xxN@K!J5ZxG7>yn)-ms6_*fA}}sinx!A1wCEN2$om8Mp1D zKx)mWmZReBRcUK(QKVS0nL}c?2zc9QmvSmXGl>$40ZqCt7GD_4AESn(Ho?eWIW$B5 zc#F?~=zgbPgwz=Y3p3Aymxz%3_>2E07zQG{Ow33Bbx}!qQ#LV4L{~_BqI{Dw+S?QOC>6ys^iIV>Z2t72hdOvnba-m7RW&(4$&v9sX*CBfU~T zBj%?9x4HIjBQ>e~xtO~yR2%Eiex4G{EFDce9R_{F()^M*F{w9bIj6PUQ- zr~xE8+T}(-ycFcLhK$C5F0|kP2EH=aie(B@D|ytO(L5jeCI!it^j_WX1PuZ4p~E6l zuRjfy@^SSAD)aL5p6gq-tPA=kcNVREb{-j~+Y78yxc4T$SXw zzKl|W+!f;iTCi}ML9CKXeA!fxY6x2P)4uYGj;8rvY{8&W$X12^;(ro=VI;;|T1Q_o zSX#{f!GD04%mw>oTC@y{A`~P=oZRh_iVB(KyxHI9mAixwlW9Ga6*fj3=J?d@c3778 zVosjq_&Qqia`O#8obDi;#zZPd2JZ~7Ih2xhp5pYKlQ!+>v@N@~k8utfru!m$sv2E3 zAYyoBxwFhEb?YkqTjJPvh02vLq6q_%@3W0!>8%G~VhIA+LjDu!q8%uu7zxC9J){nJ zTruvA+E9?P!C(?T^Rk0Pp~Q3&%CsJBgD#TBm|*ewp^AmzC@EtMR}&h-0Mbt;Rs9~J z9Y|M1G2o4*@)Q{rQmRZH3#Ap`%@UT9L%#Y&=6FOivQ!pqvNjGV z>5`Zyl0O_{w<@2405WQkbd9@Kb~k2^;TxqIj&mqjE$bT5W2_OA^1PSaEi~>?E^wCB zpuL`&Id1(RTEX)H8wJhMqJ^W?_VwkVs~3Btm^1C-F%T=zuW#>XxUeuWIJmja5(Hj& zo93+^%|H4B*8zB165LfLh?V<{e;!`88kI7ExR~kYcG)wkVJ3z|tJt-AnfCdFVk7vg z)kZ$O(sHVo&irEt7)%B<^A*A6moI*l(*wn_*i*3uFXNA)!oB&Uat#Bvc%&>bA2kpcAL(X@@$VeA##{i!^Pb2OSIiJd8#wRO#PDzyp=8W<#P8-vc~ zbJVAjS|CE@g^+5W+d*i@-KSdmYYz6eNj(=6Ep&I9UgY?UNIW@^ax7dkQ<8pd$OeqF z%;&mqtIoyd93I$`IV8Kpk}3;Y`P;R|Bi}exo z-T9NtlZJ1Tl>Ywg3KQS%fzy&H!F(C`glKsdE?QpgLM*IVAI3gD6E|;!L#0h`ZtcHZ zJDC|D0^4SvJFReS3YOF5Ynu|U<3UIwat%L&!CQ$oP(s?VFBjo{rBqam_Id;NAr)?Y zUNx{CEbPr}%`}>rxOg*q(V}_BcX*0g8tAaGqlEK4n8CnEghky{845l#3Wzyui9X+X?w!qzAnftd0HG17we`>;ZHyTl`lV5*m#sok@nI}GtJnilv zO0jPov5xgQPWrvCcTc^0JcQPCzYo1@3{0kkK0vjR+7Q#&X_aot$wsr+LrsC4Xu+<*ztbB|6*nr}gD(Fd0K_9F%SJ?^ZSgQBa6U72a+9QcFST z^)DmRVtDSFJtBLHD}-BiSlDOfW>|av_?<4)8D~fExvjqK!=6xr|KuO~12Df@X`F1G z7KGK(dc5$1O#P}D(=y?+6y8;N<%yL`r0^*d25LQ-WJvK)FH2Tn_c%LzeP7St-@g6L z0l7CAL{)tw6;wv-0f0}mh6+}ZLX0R1jg`5J=;b+VYIP3spX+*j|5Ik0wtj6) z{FIgFrmeFb1>X1XmkoH%2EWbxm@Rc&^|%c?44Ji-tukq@np~NKUmR!(@^2*D)W!P| z&bPDHzCBI)et+|y|5n;hrG#H>q)L;E?DV^Stb|;}3CFeG zTFrUu``(S2xjbI|#R_Wzy4FT-MqxUj$h-r4IMeVW3!MPV-4@MGndtJ8aG0w{!Tk&DCGeURRE|Ds85 zVI@w3lEd}MO0Ah34jDJ#6{hE>D?E2hxjhdOYrV0!^mx-JyMd;ZFe@7@t%>{hxchs6 z((C2{fkzc1@p{WVHBp)Psi>)C{qRYH$at#lEEj530+F6%q**23l8AKa-s+cr zm~jR+a~)w*69w@xGKY2>jhb^ejBPXADw)#!9xw4ZavrdaZ>mgG4>ODm^fKcUR3;*1 zK00oLMi#0ibvZAK{)CvR^l!~l1|m+nU8*_IPN)?96E>nuUGWKlLdM8R!(K!P#*+Gs zXiQz*@9)>vLM7$iVkYK}p_FOJDJQPL74xVKc;?IKa}-vB<#2JZfr2di729e#6s6r_ zY*$u2oULJu_Haza6OOLU3}G)OB_a~8HDENBFa5^ydg|NT#Se#%AK{QX)<_Ndri)I0 z>X2Wl$3>HxbZgx~ecoO1F8xvXD)u8Q`A7eMp-pm1VzTF_Hd?)$<2_wY>2D3Tmi zovqqq9;l0<01qQIcGO#1v_MTBVw{6q=BkBZI{aECi-fDp#rHFXWN!s%TPoZ6D4&ZL1C&flRA5mlR~ zP{hxR4j5D_nqxK?7)vU1THoP%f3{w$jyFdzz?B6B97D-2xcPETK$oA$v%-b zr!MZNHtnkOJr-!{2Pzah8YgI|L&4uswRqL|EqTls3_q(>8wuJu`tq`M+3wTA>`IY$ zpTEzZ>v^C?P$JnnY^15}M#TnQz8cMnkt^otj3St{WH+|dm!1h39G}~<61c+xClF#; zcAq$#7mR4tXm+IF^rFjW7j1lBKDr;@U%bY!G@FNh9qL!OMzJR!hChX2A-gN^*LYcH}(9% z$hrK8-8XAttb&4anW)_i}QcYJN|zU~Bvd9Cd|lR_e=DJfM}!YBbu82U9#tK_aXeIw<{ zxPy4lIPh~*MEP=+6VG`e>g$kdJs+r?)H7z@$rMMb;$18Y)2&~^H+8z zmYc1PT^_)gSwz>b;Z>s?*7>q2k8?c8SjK9%iwZi%xInjIZDE>vk7# z3p<@(8IW)P;(q{!4*c*RtUE23ptoZG@Lwy>q$YoWc7_pJI3_fb9ztrXaSj5pcV&En zN-HKr``Q%CYU_>#)ofu9+a6~|q^o_YN#AN# zFF7m5kU)%2q{QJ7BAWmXANi)lvCpf-I#s96REhN|g*x5{ezhml1c0GzZJQ$HIEW#q zRP9!3?o#Oo8B>4%K#M%rLFUn##6q9|lMri3K$DplDG?Lnw1S+1%h%e92RAS}&obrn z>VH|&{RYf9J_kIRJ3wD%8-e&D(_&VFb}XXIN_LFE_SXyAGBb6eQ7o;d|73_t=h&3w zo%jWaw(O;@*v4`Scfj67snRPQ8&$Y3WLyNqJ|$|Lnze99MEdd4!;+^RS%EGwCa@J| zgMV0qm_B#r@?WIw)v5eMxjVV+-CZ8RT?*QDp4fKe9hl=mytdjpaTYbn=$70$N%{juBcRCX_r)ssXfIW+JSF(y6nP4%FPEKDRUF;3ZvRS6S} z@#E*lVB6Y3ty=sCbOqsA1_T6pY8!ryTb#{rCF2 zQlB3KG;)l#wL`-g=&Cc=V76GXr}jJwbmJZ=)TK=T%Se!1u^RSAFb>d^DkzpfKNRDk zmGN|!X8OFRgI8Frt_C%>hM7K_$Zx?A{4;Cr+=mlgQedxK*{94TytMZo>NJDVKLo#0(D|O$CJWnJWbMMg)-Js%i7&qQ(vc^%Gm* z^QuJ)h*vgH&L5SP2S=(NX6*b?HbIYCJv^bJA6wflZuhziZQrh;M^Qt}L*5ihIEKHE z-GZ7t{l5OAPzVK;ghbhjk~p$VYQ#Bt$pQONc~byD+`$_Mi$@jRMqlwXa^-7OE1Bsi z2on)C&H%3)Lw}#D+`EO6AwN&ndzV(8-47i8ZW6=(+W%p#6p^C_)Gzf&anvPE{-Ush z!{@{zCbC0pE&7lC(m5CwhTPx&$AW|MGM^Xz#-Fv`ENH2voSss&3ndD~92UGXj<;k6 zBQyxHC6u{EqEgF7EmZV<#3e4GtKXDYo^e zieKVW-(`dtOOaM+s_bSj_XVj;5Cw&K@l=0U&QgNnq`X#?n8Aqm+aB-y`k4JrJ|{EF ziO6C>3K6z~?dsyard~r^h691_(EZEX`K|uO5XoY3hFO^A`oi%+$Jv{I7-99hw4)4~7(r+HDH6e10~&eT+Tspl1DzUOrh^%}EMqJ`eyLY& zYd~bG@~jQE4R$ftC@274%r`LBcE@QOsmkU-oOCj!cNU=n#C>xTn8Vjc)<@DBpgq7d zMi<_1H_Jp+D~=WCPErH{4ZKe>Yv1kJWf#`XN`}$$wHG?74G?>huUa))qfpCbMsdU( zqN}t&xB02rBj$c6UnJCrhKs4Q)NGB2?%qNy2x}@=8&!U-C#WbCXK|u=1>#pZ#T;Hf z!+bf2YQn5veP;0;^YzyD_;PHiF}l@rjL(|Wabz!5%e{PTZ;Sizu2~A|-dJnMIhY7r z6PQqoa+^i;wcDr+^=lwV3|zzRax*fGiYoy?yY+fTF4^|^ zQmLMnFrsX+^q2LxNOXm$;OWyB9#BFNU~G6HeDE;}upTV|`spMy%9f+4u@yZsTP4yK6E3p`@KOCb`gVIXisDbi0PxRmYyTp~UP%cgdSu z_IXDmG_J7uqJ7Y#VtC891bZGQcq@^aaa#w&hN2H$^1e7pybp~zBH@na?m-fzH?Pq} z(25ncmV`R$(d8ZTfUo^eW47jMZNWcH9u^fS&{`#MCLVriOkr^Kz=#mk6zNQNWjOCL zKwr8t;0jrPtO;jqg}GNpIRd=wN|lWbZip4GO!voeU}YL-d6C3HCCQ@K>n~PT?vE1n zti~U{=Uwl#LFiClT55_e-EU4VO_LcluPh*5X+s&6SKWHHk}oMTlGZqKHUbC05G{`oeMeeCW(PC(hwQ&+I$$!p1gY!)a6(Ei%u% zcfX>&>InMTCTJ{=3-uL&n zy0(GfnC0JgvAez7j+jAnyZuF6OL3Ts5h11%9HpHN-yhvPl*(~4Zl0%##${ai8!z&E z`|B8^?bFAtXc-F6nZXZ;rV_Q)-`dl2cjI}P>u!rF(!^+3uV`_55FZ7{R$6R5nS<24&Kj_I4Ba55A{2> zEpyxQt$Uif8IZ0pYB3uI-a6)pOaj*c4q;gLEUou@^gHE?+uRYdM4i-A(Bdmy$>l_z z{`!P|Q-!c=kolqE3*UsaRlWp;4*tMT6?0&loEO&uD2#xqL zQcuMq(=6k*a31wbt9W#zk}XWW!nr@*aPU(%jqk6nrLP`dn*9W@x|r8cgGR^z+v4lk z@*}B(l8nrs0B*+RXTo@zqE1h-;yOuOj;B`kieG2(P+N$iyxi!JGu#Y7ev9YT`M>zj z2cV_sXi;|BwE-)wZe#eHCjI>1zrDU3>p!N^Rj;Q*{82`dgz?5lb^tw+((SkrDUA2p z8i@9@YeQZEAdOCreH<&{BY(TmqJi-Q=P>Bb>`jE>-J<-Mv&HM}bKd+-4?L;RQkwcb zYs2`JrBlS1A*RIqmvmAM2d9vu_m^eevz7H%_Nonk-obK9OeN|`r68;PLv$j~#FUVw zU#6p;;+Kwu`U6=Bt609gN z$wXDqnBDT4l@~ek2#e`#N%a)IV$rTuAj>5|rG?ez1o1+mL=lyA>J)Te#pr`{2X)GE z(M1Ldgq*N*E!x5Of)GQ!KW7VPKC*GOZb2>n-td|5CKs>=SmWPmqq)$vv)we{5@D-= zVK=d}OI`*Z$xX&{q7z&A7ykn=3}y|vkMn0ib;aQa|EjT7BgKpRI%%cpX`&cyaEL?V z68AmHHLOj&;a9zQM=WSvtVm;H*{cP!Q679sTM#z!;9m})(YFzc9Af_Q>i5w$@}x(e*mS@Ki^ zvebgA^7(z?1Tg3F2`VIZ|4)ckG7bcwb(;<03#&He=ZdB(39;2SXv3yx&+TtA3Cjk< zWMQMNxe(2xZgTbtn9)y8z}8;87K808-O~iJj?*07>hqf!H|I7nSDpn1F)r%He}s7{ zi$>)?@9i7RrgPspiBeIa5qsh~@+#a(j5Y>_Bxl{ZeUZi;U1z~yg?OZn_HgK#Z62o$>W)YL1N#5&>l?Zi*J?$kBwKrdkbx9rSLUTz zh!O>>E=~3(#iN;KP>I#DjpB<2u2zX3kUU2VYB}1>eeyAut)mh^|Fa=pvuckWpGP@4 zoCY?~jJZrbLq>0G<54Rnj2khMH@U3HH%49XqOKHXunur*J$>o_-#z{RhVee|e-9vB zV`i-~1GLr>k~+nt{EzwX{5Rar|7{4c{|7&R*Z+F}y&*W}$K;5>z{r1ohkM-66r9;BLX)-Ge*9NpN=w!2%@oZSrR3 z%*>fNcjnytzhCZKzy8pB*Q#1o&sw$i>e|&naW+^OXkkTEQUR*Nz@S0DYsxFZ@C&)y z8<|*vok@(r<`%XBfU~wP0EvaE06>F7o>|^r4E)AI+S3uN>Zzb+;%Q~VV+s%wMC5np zb+@s%0XrL!xZ7CUI`O&-0E|rSjKRFn?~k{c03^ReoUH@^B99d$P-P@yc8*{Y4n{Tx z6J{0`5>8G=7IqF!P8NC+R%RAfCT8e|lYxbumxGg+m5bze0SF?J@H?8C@v4YR{#FLP z5&*n$cDCnbVsdkHV{~IsWj;N)TJY~;>h>qPe0#UFi$gPlwq zE$p2w>}*LM`!q7Pb8!{`0HF0GzdJVuyF>5%?%mdj@z=B%P3&x#jNQzb9&4Fc7@3*= zwh0u4xconF1FiZcF79D#WMg3>4>q-cviTczP=SBZ(&&$t{~#>?uN3_jx3T%V?wy<^ zT>r&%+<&)lQuD9}GpT@`>|7j8z!I)tTW7MrRqEud0{$=Fe@En>cL5duyADiE{yIZ@ z7f0(~wlXzg0$YP^pt_u(d|3V%^CMhdJ4Xws9~wE^ISK%j9PLQd?Ch+aevRiJs-bGY zj$m68umHeCLKUbXBF@8QZ3Hb+R{vcbYH)EQXQ(LD)3_O!*%?^a{;80fg$+~)>Vqt7 zysWJMCE^Ud|2GObnYq|_I9UFx-WBZV1l1t`VE%OvYE@o&=rS-hayI%0y*z4;gn!z{$oN=VQ6!4I}?{j{(ot1`kysd{KHJv|Fj$Se`6G;CcI{L zjy6V6?=*5TwXkEdu?L&~TB#)b&=HEu^Qt*Q1C!I^+WozHMUBk=xcXx;TU-39dR(}V z;?9ra3Pz9i6LSG8*;&{+lgJx6T0t%I%O<~8_+JGdo&J~L-`ANrLOW3ToPAJ_!dT@IKhIakeW%f_q{jb7Kc4p3Q zMvh<+bEqf&rY(&5rO|m_)qWp6W4!4;6D=n)4Tp(!-e=?`y60fXxiuo-Nks^4*9eE zN#IWce-ikUz@G&EB=G+;0+9QJk1#MVgCt%Kz}xr*=4@4;C)#^}P1Q)TD74^xKRyZc z`@Aj4WIYQZ--uzuApfSYD&b>#V3PL^0*Oz<-Xq5OG4m5)d==1g-)<)-b|;yy3`%XdFY5OBQh;^+ZjD!JdL*WRYpn$;-+$zX%vK zw3%AKEuLH*tCf&CS#A4)>CNYrdU-sdHdPO0tO*nc+;7O4L7&GQ(PBm@?fGIT8Brv- zy|wgZ-bk{D?*v7eSEH=}@d|9+{AJN-o0egt5*K zsxNW8$9U+cga?BvQ|{4t7L|ma*mKXCYU9mY!L~Yiy=JM()MsFOkmNSU4r_YbO)7QnS|L zSKFw$*u8;{AHYEmTN2djY;|6gljL!$wTAq>2qx_b^0|4UByZULHIG_0@28ZXd|X8c3UB`s#jTRV zQk9;=U51j zjdR`jnMIiiGoi8gKxbW8zAlZL>4BQ!Xm^i=pc4lrX4q4IFVVWCC7;6cKSzrbQo-2nu9!$rRo+O-In}g($COfNAh+`Q z(0q_D)1`vqk$)5nng9)`Lcpfhy_)vCsG)HN7_TC$qoW5ooJ?Eb3d}uOyN6t#6>{dx zC&Fgr?!v3?EQBnR9Zcp)O^rAU%v1q1)-=CIoN3XOdCxBz3aTS4;%3wMz2^z49%7B< zp!Wc7CA!MuL~rHCNIvm9fjt#^2N@f0Ncestv6Azgo)Wu0AkL_V`vh)d+HV=s$1y>U z9+F2|8$O1N6!qyfwKA)xHBTKV$&vfsGA&yN@>qV}vBSuu9Wl1bR?w47az%hVgbXez zVJoBPkd%5!Hrd;ZmfoRR5*WGwh$bdn-E??wy69QwZ-EI~1#G*S$O4YW4_vNh<9^+R z9|_<>l}O3Z*+T_iz>qL^*HIKe``_xKX<5^{rD3h10i~eD!odu|y{dd3S$e7J49U>2 zCZxh8q7oM7q2&4i zSq}!6iHzQ~UzE+veP$(qWecY774jqhN?-KxcRJ-AHo3`6rB@jg^`jB`UWN1Bu}RLIae$OkA5l~-Fy^GWRA*+lvC}1E1r^wM$6`r3OCdrT&i)< ztA2MocM>EYSNY6iQ+i&i;zJot;&JInDan+=5hDv3BMQhWdj6sc3S^6;p{Z0jj537~ z^z0xA?p)nhGy(=`Yo0X%u|Q>esdT}0%uEdcI+^!8iEXI+)$Bzirj5PH{aI$h~)XPPWLddHP4L=^%w5+n|_xDZR zg!g@^XS{z`So>-Bd~=PjpDR;^9xfekH}Z)uPsFBkU~pU-KItR>eqW3!4vli7liZqW zy6T&bM(9Eqp)1Z4E3Hs{&R~`C4hk0X&{&|)HI}!-n{ZIQGBoUft$G0)K>y9Xg?Cqn&fmUZ0PjIYN~ zv}nkeA$J|rX{V;NEHJeA5qDqD&2ggjJ;Ts=+4jukfgHLyXS^M3SLZmKqfR>jcN3ak zHATf9xj0#$q4A2H)1%F?>xOxgqsQU>FqT}hH+^^`t|PZ3jB*2Cc` z%3HG_AZaZRa}!rieNDcIN*K1fIpCb5U?PXj&C~44iqJ4oR&H!;Ys9fNrG^?7fCZwaW-ua8^!Nr`Ra~(o7gq#X<5%;Nt>JIHBv91%Yj2sUO z9l_Q7)b9I4{xSNL5?4B_YwcM^S^*~8terarwE~YtmnwsYvQ_T}6DunkO3vlQCDS-P zzyTWWjA#6WXH>CkVz`VS?F-`CRK*Ub1ng|>3ofvR9?gTydFbMxQw*HZnhl6`7LS>^ z_=%V%X}rVt&Vsksl(ErW0pW^S<`PMb*HGev{Y{0(8n|`)8a77iW;#5c-9ZQ=NE|#) z^2wL{iMV59QEHi%APWsl-5&RV><}`?Y5YRRPByLptS}4&wZ8s0nuS){Ec!|HP4hSI zN)-qt69o7z7mYU!4S9W%(vXVv2AtF}#4IVteRFJF>LX7GLg z3UK$V_?c@=TsY<_UUpykTF>E;|F$m{hmS_NKve4-H2y>iG`;?WjYT|k;ytGFBCtBJ z;5AFmNu1WoBJhqRnLUYfrdofw&oHUFle9M?^s81=v08_loW#vQS3uObjg;O;_wFZ` z-sYThF7SA2Pi&gVY&qjxr@vOAiZ;vu=9)@AYu^ySbry#Tmu@`d_YL;VD`(EGCkXkI z`4UrvPNih@$q4b1b)zpB>JD>~j^yyXr>2rYcOsP^WaGuJt<=zSywhk6ysL82Y>k^Q z*CHP4$7?u#UZU{cav#`TkaTZ=u-&K1=Z$Y7?e7Mh9|WRWH+8Q`LNv zmnx{SruFFU=hdUAzCO>@OAqV`*8#z|n;Sq9W_la~gA#j@lK~j#FhE zFg#=&DgXtl>#5;+vIF(?%~WNk^v#c&$UDJfjgrpR0Zfk1hVkAH?HO z^ziu1b0rm~BlRq~51*pw&L}G{SyJ-C1nD#`u0U?=j7(mYGOnJ=1Hw4pRPdW6xjtP= z%4H>ue5v%lyi+Q(XPY#P((MeZG*Pvgz)gz)}7*l&|SkYf21f%AzO%_ z*|gT%?2-SeFII!kFa8-!wDmUyO@fIk{1R`59vox=4%7Y)i&kMEe)Zgn43F(~e{C8D z^pOQUX(Ql)Dr;GZ@~F%E73;WOy7mndr37Dcut~V&8VzrARJoMgElXs~)Qj7Z5SVLx z(M^dQTF39Wn?q{RsxJ-KUf|YY*5p-F-{5IrrOsqTgANCtjE_7Lm>Tqt!;ht09(V1HH4Vr)6wv*lP(dfp zCBT#E=3O2+MVw?ETi1IVHLBr`cA*T9cmP7>>g2)m7#q&ZJqtscqf)t_Sudl` zyCSB)_W2IAFf5&Q&YuyP!lb;+WzWbn$oHeRtV;o@u>%k&&^J}5i&dMzSq-{+?gF$3 zRLK|$!=>@gpz>>lD(&gd9iOi}%^?|s?UxgmU!GPB?~lNjs%E;m!W{->@gOROe!Wu+ zzr>Q|dve?+5EF*$gUGsf-H&;M|x)j4ISxu%6w%dS=~O(S_2olB7I3q(70*A zBUf+eZ|%Ytn(V)r-`&Q4MGOFx%vLfFt=v>tw#*yOyvksM`{DZz`R2s(`()h@#mKd@ z%+H-5(WXp6WbQ|jDNEMcr?fPMZXpK6p0Y6tc#o@*A`)eV&=s zkz4jXH?%Z{@kJWfyK2*7N&z{-z~{I=y@<{v>sFL2{ywS1X3Awjt9$FnWlDWp=M}!$eFTOL1 zykjE`xod=i7lu;gi+ha(_T#gyFWp)$chdtzt}9Nz{X5cewb7|Lzoy zaBwLlbx1(tBcTu_)23dOvXo$BBX@JVHh;C<+BjuIX6Oq8v~`(Yt}wzzP?zetLASQ= zic5BYOCN?BV&v5 z{;_E0wLhJ5_{jNR6^h0L$V%6eyM<$pfb9&jt4b$wNxE;AwN^UCl(6aqBhgaS#yiFa zL~OVBJ8uYTB#k>z$&H>oXGx4(ET$^T0wr_}aL^IrOgcnEzH;#ks4((t)>iX0@Pj^z z6k#4UvgUop z(xkz}7pOh4yImCpww4))b7dkE;l1Oh+k*E@XeJ~rZd7=|BUigCC*Rj5~g>LzM(&rG?ly7SNon2jd3E0$Wklo9Q z#*=}&0OU)zV;)iBrZnKp@YVouX#-SSE>6n3hC<+N;r2wkgip5gyi2INzPP50S>btQCV{L%j*zBpHIph#%`SzcLs1&#lM4ptdc*X#4v8k+q= z-dl)lQ<4q;o&UoyMdJ?SszsLdB_gryhh4KC%?6E*ol2d(JJ@8iPX(8G)uxsFLNXtB z$z0nMN!x^iq;4Dz23Nu;oah~h%~vY>O^*wlH z`3d;K=Rbfe>e9^?if#wz8_q9UkMz5KsMDvQ)Y|#xH!jC!sSaoFRxJD^bv8>q|%9 zYqbv5j(iSN^Y`{u*ew%m?bGBhj=s;I{pPRdq7m6~()y91j0KwiR~bb9*kfjU&Cwg^ zuE^nI&V2q;H^+ph1EBKt1mnLO;@6#rxM@cqMAj|++u|B6g8j#_u(Mg@&y=d}!})AB zu5<{>(Tr~zkjgEW-hTlh{b=>h5B9=sWKT6o&2cRBSxXuxKWmt|V9VzFa$!-y*s(^N zgB6gNpSM|p-A~5bs%mXXkpshh|M87Fzn|fAe3kIQZ!PjFj4Huxq{DY#y0-TeqXFpW zjv+#{KWcCe2@A<9bzIX6g%~BW*`zg=(!Qsd~~wEs^w;5Q~}Fj><+vC5Kg)?}b@XN+J)v6Cn-?8v3coiLW8 z-*{u!6-JmWz4Ox9Eir(@nBy?UieG*I5B_*~emc0;RC=i%)@Q`J?* z0@qsXK#kSEfc}rS`$j94Y;0?-A#^bWMzkh;+Ol{_TO7~?GgYqRg3h3;LQJI= zT!))0UvvWd981GNFXY+2n}t#8Rk)OVW~I2{)T9znSCeVZO6WR)wLA?okqd29oj5v& zzKZ5O;}b(=RnvS-O<8r)7(YL?zKtEL)7Z0`9qaA!hu8WYr+z+$a=CC5z^mffS6#7k z_VT+IYhMCw}`*YRemrzs!a5k1hQPwK{&D6C%Q7yQ{zAi=S?_zVq?pCNBe4SB2-$PeGAFX zXRp@xK^krvBh%mSsEVa_HnyL~ao_T!ye7yKdh_w;neS=n@?A?2Qjs6p=4%@ZY8$p6 zeL&L6o!7R%`R71?f3cjDx>j0T1+z3H@5I$OqnJ5lo)IekBjW%0`hjR9QCLTO$hb!! z?!3HmZC0A+=UHf~&yl$Hr}ulOi*2c9d-0?p#~brn{w9$8YFEHhS~=6Y2JlIdl^|PvHnNU06Zm-;rQq{(B9ortvKO_p4zsI#F$Ra| z$iqFtao(CT?vZKo;m>s%+3N=sQ73RrU9GE~6VdTnzDX`>?M1}#>X+>)REd$J3I_zV z2OenL1QaW3H^PlpODk_L7b!2{HdR5bI zkne0DnVwSmiSFoR>VF0fNw{TlT7CSghu7*osp~9|`X-uUpwas7z zWwB2|(%F5p_G1=Z*htQrUS1xI*_?NPE6bT9z2U~+-g|{rv(%9cbr<>I11#Kqt zbgb?&e&~r{G@@}FIra7&CSWRQj#pfRBd=@6Q8$qRso~kD->1pYb1@Wkvxa&` zAdF(pdW`X@dd-pUHb$UhwNuROO(}ln8bx$|_~Iay4hOTOWm_%BBMdVA9w@~13LqfU zf>4W~ews# z>rG^smX{UW=3&6rtEHJ*Yxe%V30FytAdz81+7J&Yb7 z9Aq0hH4EtyLe=A=yj_fo@*yVi*-kEe>!Ta>*YLgh5g1>O=#i9Pi(8upA#zYA+jH=Z z*u6uahr3i~%hgIPT>ZQ`Jz3H2MV(M8S$4gH(I*zM=VVz!cp<;1#I?B&=G=~ZH@h+w zjLHFdwubM(Ak;GQ7UtB!=t$X#fN#FzsC?Q>`ISK51JY2_;Y|BrV78%N@oN!{q*t%e zo6N#BOWd(^Vx1fls38NAPvCZn0QeF1PR=Rp4U zQF?UJeqCp8pt*8kqF%`-k|-{m-9Gpm@A(b&H}no_b#(m5XIu7ZtE^vmLt3;^>@K1< z`HH7B*kv~45`uO08t^HnHb(}L6`GBuvr6WjQqLbw#;335*ZBiHfu_Pl$i2^U}g1;^&%zScS@PFawA$O&Vw|F+2`=CEuZMua@=th;jUf9{q4&ksi0A%7k-3Y@dU6SB z=zYu)sr$P(){N;^4OVpY^{yRHPDlpBUg4f3JBA0(=~n*1A2$sAEB{HWp#2Kn|F_rB zUo;5A7N}q}6aTfdMy`G@krt;3U3n?%%jif1BG zTQ+H!wMEJT!>q7t(uZg+eJuJ=~u$A$;iH+=n9%p8*6Q;M}Pp7ZaKj+M%0P_edR zf{Z=Fy#^dZu#Ny28dC)eb9Cg^UoLMO@^risPs*&^Im)%GR~fVV3EWHF*Ah&d7~+8V z;t9Sga{$8`Si#L?3WZVfid+$E;0;!;kiygD-eT*<2A7i%sa!481nha=q`=TRm~F*F z!Dl5T-`D();Sv#ROh>{Q*op}!g>^NzXyAj_D8JU^ze$Pfe^s9+vGlCf<`p(Bl>^%6 zRJHRLWHB>Teo1PAfgiD1!B6l`>+Ei5w&&Q0%0?s2@slG2&+hMk$Da-(=>GFbYh5`_ z{Y^)ckjEj2wmeA()9tjoAN?Pg|GfqN&8r^(AbI>l0(byE1k;!_mbRHhDzaRD3 z2#lhc@$olsH*&Ucl0b@e;&TK7-YNhJ@Myf-b6Wu6ZZS%PIm6B5s z7qCVgB%aEXTGo>zhxjFED!s;r>x%*8*6A+C16Z|ys?;$a+eP|yni`eC)(RexQdI1A z#dLk3(ONKuXB{ZMz*xKukB2IqBr0BQ`9O=CGgiM(cU#a%KW&(2acD2*UvJhp1es z9BocIxB|J)yxk?<)5mJzxrEF$=x~@Ho7L}1S>{&(ZJ*Yk7&|i{+`jO@MC-^lML*@kaE4m)wy z9U=;?Hb<}?1*i+c_$|$|<_%mAkR%Ue7B(w5zl`L2CR~SFnv6pyXx9HleXhAR&xv8n z`#nrH<`aBukTJZba5)DYeGzK+U7rQQzIJ@>DZ`fd19X>)pquFR6K#oj$FHi*d?)zWu}DTw`rfIBq^Uv{yP5v@x|`PcwH_)=RZS5@%4v5b#Rz1BlY$j zX^^nq(3ACY2llBm)IrwI2||<_W3F`hw(4D~tUWeKZk39x%S&6;#feCEcvoJ1`TVN- zLK3*hEWb7N)7x#x+r^P7eB*2qM$Df!chYv|)o=fE%jJrKE9|2$ zX1oJrdYN@OzD7frgxRrg$S(jhlUt1l*chS?YcNg4lKF}pj*L{6y-nM>tX^Xo5h2vk z^MW?8#(#rFlH^S3J`C8>6pZ~NI~qT`C)#ZHdQ8molwf$bKISuV2}yQb>L2lkz{N&@ ze&eLpl49J&#HlYJnZThhq?Bk(BP|~%xD?`+_0)!^ zmu>M%gH%2QP-#?ObqZYGcC;v>OE$=P4ay!|BEBBf+7IdSypXTXIn(mNf+& zE%u!k6TfHXP=b*Ge!A01sLuUB4uUuJJ>YHNUNVeZ8a~g`=WJ#DvP6&(lShMWO>Wv?rI93u-`=YDJUrn#5GsjOxVzqD+q^hv57ieBQ zWSucnZf#s5VO-cy*%skHu-dRksfW19hAS)K^<9i7Bw@*L?#^o};-G+p4xWfS+grIh zP`o%lKM(EtX-O3S$bZ)t_rwMi1>JvZp|Ly<>1ZmCu0qFfiUbwVV(aK?MTIgY9?l^r z#D2+YDSRO!4UPkgRH11FA03_P&-LNFur3cQPA}En>J`)buAJE$p}mGm*)@>epS*x$ z>jP`>T7Qy;_stWM{1p(xl5W)Sdks7S3b(Oo>SvM&+KI9Hn|JCL`&S~7C+$m@a)?A2 zJ9^3JNh418R(V9I5weUMQpz+L86W5NL&PQD>tbWFB_DCN?7`)gEFPGGtt`>K^4UbQ$oC$ z2*-4DGc}oG2b7xHeFzplUc;7_SX65^Vb3Kg8)P5(Z@^%&_-I7doV1QGl|tXYH_=P0 zu58(q?xEo>)j1riuEfg?EP0}P5C#+v3n-AFRhB3=)kM3$pqFX7{+t?w&+qf@O`?6k zjgOux-DqD?{YkayKvR2d`!apwMiNH_-0BI07BCTw)^4ay@u z%h77N85<>&GIMRyM5IlP!smt}U0?HzpFccYWoLNn-2F5VWVq7RZgN zYMo-{2zyKcDB+|3THyVTY@M7!>2-~22>pfVd|Bq5xf?XS+|%hD&o$M~g5A69$$I3! z?~B9Wr}eo1)5=u(n18Zm(5y2`KS9Fb$iG6Uvx$oY!n)F0H)l2*vWHpXU-ck)&-9kv ziC<4}JTN`E{`xK3>-#4NK}F~4^q0aEJ1|B9{8HY&{j4wfO42BK7Z8dLaon za3WYIZ1F`{2nM#2Pwu%~`B}woz!|Sg@lSz*#T60sQ8HrLLJ?gX14S~)i7Bd=*ae4Q zQmi6X=I{E`vqhuY?K&g-Ic6%muEyx+PCJ2UoW3Y#S8|quHZBX61i0i0J4(rObrjkK z3K`|m*_LiCp6{drmpaD@_`E>G(0!X=qW(werb}fcS)F7K-Lca@6Lv)fwdsE15%*4&y)4H*B4U&n)?-Ph% z?tS*g4qN9f>3*QAd`mbjj|PL{>4U($$8zt*8Bf{gqt|OkUVAqXEh8&_hpx!V^4@!r ztTqw7#C|Q44?9$_PEwEj525eBd_YCe{m*FV``>GUrYFY$9;Fw|$RZp#PFF@Wo_Kg(9f z6JKGE&z3t5npjPtJnnVWvRp;ZQ{Ou-9gZOD?+t}5CzY) zvz>vDiOL^4s}={oW@5kw&Y!p`jEJoNU`WHqj_kiRtro5BBs_1YGl~L`k;KZyFhv&6 z&?hKpO^KCt6wi<8VFnnQ7A_|ZlUWo2G((o+m2;CC6oIdc(L@Zm{oFs?YGH&gNc*ol z^MkUy{Fc#?$_70VqJ+`Uy{(;DfT zdeJ`aTN4wFPhM-T-;3s0N!uWJxpJ2)o#~ zGFPSNvZH#ko4z(@*xjjPG~nTCzT~t*Wge}6?g1{4RMgrk`;u2*L}E6z-RnH({{o>L zwZnH-QpggNZ=&vpfyNH9B6O6ThKo_qr8K92Bh~yFr66FIRw-ThY@KzG704nY#SP!^ z997am1P%qpoZV5*j@cZk4(<3UHGDk``)K7-vTYo0q~r-7(nh5uAKlxXM8l>BCiVyB zemGUPx96@_>rzjj;5WmdbjlF)_(hwrkR0yJT>YXVTL!UVeaYyH%GD>CGku+-WUxX4G;&U zB11v13_kc6^ky#ba$i76nE`$)cYTs?8q<`0c+$L0qaw3Nhr@($c%Y|ma!A-hve;V| zLryp&g*QB*R!cn0hAnPyMt4k)<5gKLH@+pmU%PKzShcH>U{+ixe6RBMCgZeI#r&88STG$wqOR>EZ+6mmU-ZiiSdC-F)|~jn+s0%f8qpJ`#H!C#5S) zCHyxv4O=S3@#A^M)+w1La|z_koLo;V=UdfhD26{7@#?p?lV_sEyf9XwS2!_yZpK6x ztHB_uM>y)CH{3P$X?K2-&&_i&EoS9*A@_7OH6t}Ov+(9>@4~Crx}P;=oTelU4J|(- zY7}2H$1TT4_R~+S{h-Fu(FD2Xu-jojhCrX3%6OomYfBh45Zych+$c#|Rum!zA59o4 z3L`xC!b((m8*EZX432LebnnJ8kR0dgF6Y41WGQ(LYy6=NUjmRrSt=*Qh$1s+zs0CU zP*sS{S!!O1y#FHaCDL)s2ex({Av`0|=&p>-=DY6@1NVh_rzj1@3jFA!V!JEoQP;I` z7s0MEFSErC2Fv!i8Rlv7kFl&Q003*e4Hao(y&C>ui23@kb1;YWVgz1U>8vHmilIV& zP9w%V+L8QwL!>aj{b?5=_YMj4(6)Fn4i#O|9}QxR&F&w6s`CwgrFX|C#Cs}IP`#mi zVUk~`{_Fh1k}u|*pX^>oRPHC{U%$UNq~d6hLJLK+i2~yr8b8O8H3Bq~>6y8WoyR(LH_DVPQ{M!0 z@kBSk_ln94%x)s9hphOoXE89&0!p}dY@;m`ZCA5?>>S11uikpDT(Hg99@K$O6x_)v znL>|%Oj-OH{Xi(D$KNz_&#Q2)UexOt0O~HO*t8)Aq`EWe=OikYe6jmdG zXqfo@7&L$!LO;PU)JIrjG@|*l4Quyx#$h7x3s!d{hU(zKLbS5njM0xN^NE}Ft!}MC zK?vmNr%zAFlc-orI(A8yln{On5wnm-|KIY(?DmpB7O=_9fF7ewuBnGF@lqgv<#Kd- z-_;3$2<>^q5hh1h%&+mSc0u&-ufq=!$7nm8D8IRS)5Q=gUnJY5sK2K#8aAGfQ0OS1L2C zeqo87>?PgvAJds++y>BHw5^9mlcbdr+4~ai){@^wLy8`(@AkOPHEd3$ym1a^3a1i* zm#U7K22p|Jsk!F5{goVYTY|SY=OrDdQmLORS+b!cI@?n(5G*@Fob2+;lr?Eizzk4E zXBXE3cNy$3DC3M)U^J&Ue8nVsHxuc}ak5vkG%;$@bP`u&a#Eo#sZf;uJdY=x?p`NGhK{DmgH9?c$JC4p0)(6teEguGw;6Nmu2qX|AcsSm~;jD zx$o*=jR)iF^Gq=mpMSspWs1$p8bFv>D@1Rt>wp5g!lLDiQ=}tgC@`atQ-iVtIEw+o|ZV>Nxf)X z99dC@!O$+Dnhd_tPQ0(unBZttOq!lyNa%}MirQ0X*Wmyu2M+3OGPSS4`ZV0UOUQ7b zpPE%i&Blu(12}6>G_cm$&nzS+q13>#sx~n1p;}>U&%H%iP$Jntd^=FAJ#7SU2P8aQ zLk)z5kB=kAd|#N@gIP&C6!y&PqVt@%BOS?O;@4@7!P`nMc}pY@^Q@WRz^&LO@&KhL z>>$qVG@VTuS2a|a8suUdxzVvnhET>XYks>X+a`Qk&_&yV@l^>ho-|lX++Q;@=EqVm z(b9a11_K)q*%f!ToD<&q>qLYqe%P(GXd(){Fe7VoCnLcJo_geTGZj_iRuFrw58exI zQ`zK5N#=H2mKn!4tt!$|6S4?A?r&j+BaKWenGwm|yUCG<>r@@AI3E2U;)@G30v&Ih zD)B`jGB}64%rY?VsGNMV3Ab)*?YEC~*e$r!Ex<1o zJbZ9#^kDa>Aqj#}v7lpZXKhSOum{3V0T6Z~T+$CzT%QJ7=DzZ`UE;`Jt^VvVI z*qn^e00)ymSx`Yp{H3_mAgI<|C|nV>aPv?HtLS`WXo8+vXNRupO*Z7>fve5@AZ#bS zu*;%BLA{;YXd0oXMUI4s2ML4xC$99CTx0&aD18G)<)rkDaZx>I3a?p@@-+ceC&gfSO114Wfhb`M>U-T^wn>NVo=VRf%s5!VXE z9toPJc)!$d-Yqqy3Wc$POr@8~FIZH_wg(NF`p_H;ba>%;?5Hfk`J@a8oL?lrR~d9q zWa+p@ZNtG}>6*P)qpTbDV*{{@OOdzgWbfji!%p1DzSR9TXDc=^3o~!G-=!_F)P?+{ zQbr|KHSAzD{IDU=2z#K`lp?dzzrEXxOe)W7b5IMpse1V3-tc@f-1&3~kF4eFg#CF{ zRrHlm2)5mGYjy2uLiZ{yF1%L-v7d72QtNlStrBGdzl!)SP>j-;)|A#Z>j6eb)Tzh# zFuP*}6DY>EfAg<#QH+GXe`%zm@qy<5vT`H4v)|(9weB^l4m|?4jsO7kzap@n* zD3Heay=+FK%2ZnMRss8FP{P3$C06qV%Dmc@uUi3=B(F;k24KBc6xUZDCP#`eE$daH zqJ|Yk;8(^0Ap2YWgo>RV@f(?)5wLKJUXFZ3%BNYbm3Q+Hh?al<3*Kz(@e~l^Qn!`; z(tvqfXUG$+XXle8GI8evnXmi@@XcuGDPA7Ibv%>8Sl$`2PN~FnBs~z_d1a1{V046p zu+`y*c-?P@a7@c{3~0oqnNg}?Ba<|l-jYZ>!RW?g7yIaYHt%!F^Y;eN1;9GDKw=DZ!e;Mt%APir+{ogZU3-;}p9TaWgOEMv(G%OG@rHDf z+9+i4GPKc8KR0Tpc-^RjG7Sg8PlwX8B!-*7QH0KEKnYmV6*pMClK1de&n+>*2y{o? zedkr=NpmNeTvIN@t({c7*bvVqik)%FH6VN3(0Ud5nZUESQM`y6=6!Nq!YR_UDok^k zp8Y1WO7}Dd+r%5e4<%oepN<*yQ}-~9OL}6zedRlWMz)+UYEZh#lqKU3oIoA6zDK;L z_X-|GYvrtb4{{UbIT|fvcNlBcNWq#Y#viHJc>VCSL+%}wY?;OGgeJ_$7`em)AU_p< zzsA9mCV`?~8;mdKXZ4%^xr7vye`zHR6?Ff!6!sV6?v>{Pb>`QS8JT`d?NcBa*$Vq(iwmR~F zz`l3@A5#$3NSlG>Q2Ts6`h?cYQra38e(>R25_g0L|J-dXK|gF#2O{wl74hbuIJhxc zB5|Ed6KoNOUA&+Cx*!Ei$i=(u+;R?1*jG-0Z*#(LN;eM$Smg3I5}Yzw&^)5tPr2L+ zLCqz}%wh1CjeTZbI<}uLS3A$!B`3=EIM)Iyuo;hBr%mIQtmGTYjM-5T=88KCWpwyp_Fi0_rNemq_4nvSnoo)<{DtvrA&6l9DJEd!3g~Q5{U84$1b>tfE zm@@#I;!0*0yTVHD-o-Y`a$IDue_;AIe^N0H=>9|Q5Op5(|3@`>Vv6jXcQ_VTiKfwz zs(T^G1N6VH|Bp+OXx@9tMIeO_2;{H;yY>PlupqiyiFpT2#wkqavq>_p6$_{WgDvsJ z5AwJrwkmTD0l4g>U8p_hn+lY`h#wu#{095 z3k4r1tv-2dZLZ-L>Ow~1U9H2&nWz>OKgZl4?-1SA75&dXJ2c_bK;LVl!@+E4Wg_OK z;$}TbfJMcUwTO80%6#AmG2W8*6wBl!G#;RwknG1&^gcAOyP%RKqac#KPI8JFU@JB* z-|CE%go=fLA>W5jW&uRQ-Jm@a>yogb>?SIgGswPun!bHDVB|T<_{G~rKJA*=98e_PZ1(lB!Tk4#ov$)Yd zaVO-BEGRYkl~3@Z%hfUH&Thu)a*2Bxjl1hvEUtv{QdcceEIGq9zGC+)s(r27cA9rd zw$_w*Qh?a&YzCUF+Of#4XkD}PN{99>&xR9Sb4ZzXV6D9myh!t5VYrImpFP)E#He!AB5=~>DrjyrN$2DNCQmxN#7UEe`)T!AU zVN~^h9gu(Khr8>s@`_KqL)xk+7Mih+WLIi;F67gtXcjWaQeQF!RA3BJN=;HME?sEfYM$rRKjX62b)|)~Zm$HE67Ek$j6oR&= zxTxfoOiG4Ezf$esyfcbELQ6sohwB;@kYFN)U217a$Ru}r1>m#>cT8y1NXKBp&ua3~ zlX9y{7tha1{9F_xId@O=|7Q;U?>2wgKgs$iby&#RXicpN?n`Q{#uyBPIn0RSp4RB+4Ei#<-N_tG8VyJ+_@?GGd^A96 z7v&U^P#Sa_Igl4tc2yu0@+*2KB)Vf+30t6N<+gg71?}(HNoY5v^^WeZ+R4>r8cSsg z!7S*XM%=gx$csOwa(ukcu(qT6p~`D(X?<*}t)df8W)Z}PX=(dCdNBWr^?D2J(*+i6 zZe5>Z458V|h8}`|-Piz)NP(H4Tlw$r@vsi0s}Mooc6PGSL<)gsB#(`2mJcP`lTS56N9~B}v{WL3 z4(>abwhn=wZ?y@|mmG9;InYTFgGDNH$c{mDo;i;Z9}2C&Gt{kTTm z2k5Y@$0wa8*jB=Ip+=4>LW)bQE69ktsalZ9A_6ANNRARX**IFP&MrzKkgnXie?~{D zl5)@2GiP0v2hvn7PN0%0ufze1i4ct&wYO2I|KZFd%0cYmG3YsvGa)cDH< zV&%t162V2V;ML_LSx^E{u;+#IpP})${mVJvz))I&=i!t8x`ng+XZrn*w0VxZEpGK#qJ33eM(W`Hq++ImZNzP9Ku51S-DwgjR zh_)wTtwpA$Hj16C5|wUa)z4i3C$zhk;2?i`Z+`Lcy9QLMTs#YqDX)&bCXCagyLFYpYLueBb~drb4P-EapfeybDusS z(AXrno}deyb2uo?WhgOF8qTHJWG8ceE3K;T4;&^i{wkJ1c}G4~p*wL~m0&Dosg;$za&(DFfFDq1hRkOk9=^-m9_RSz*<% z3X-(xc{}>2#^Z1Mw*=sY)ee2nK_K4>EBy6Ob^Nb2dZ3VROkyh^&a4$dA|p3W2jJSC zK?Nnmn^2Ap(p4W>9KT4U27IZ#34$de{U9{5hYhzvGWoLqeQ4A@ny+^R0M)luxDpQ* z3`T|xclMI0=hfY?D<_@1aw@Z z|HXhI@_|~+*o($2O*GD>FM7YVL1)kXxG;sdkF<*R``}&ZqDv87wu#h>+MQExd`oC# z6fz7Ujp?O`4fMRT(zjUe9c@%6maFgXl(l=ZcuY$1Zh7;A0OB$#a&U`W@KA@hL<@iO zFs+4)v-!QA|2L?=_!D0)<3+RBe46-Lz#5iD`v30nU-|W-rnpQAE{uw%w?G^-({`2y zUCj}?P*|dMBgwtohOtV^K7q4(z>yzji}eoW)brVnYS}DRNn1PdDZi~#M!RwMjQ?Xw z^=>DrDtP=aFtrHvG=a#O+8YhC7?r`yP)4|g!I(B%0JMHomFOB*bGu!v9eEd)AjkUi z=NSK^)$W=iRP;~9n5v<_utY5-m8^RGV-0aJhFCd_0#2`kb0kXAaTugZ86tXb(b45( zks2}&!c#PatIzKXypPWLNQbC< z(5ax-T0dC^RT;mmtYK*q`e^H3W$k>YO}|<4qS1yZbwVXC{OV);_s=rWiR#?VRwXX%y;Ffj}$VsU-Nf>u=eUNyGu z5hY3ZMW^0{G74x6z+4L}@0)drGxjVMQwIc*U<<@Fl?*Y(Q7K zFDLvp^LNzYqH)U>@L}Mjy+Q*xPGra)7@RaqSQ-l*OskUj8Y(|rv?B?Cqb2&Px-rdG z(yLt+MPQ_XGdLS@;o^DFbi|W!^`w?7K_5BkwT{i92G2^$P)2;%W>b#qp!=*K$Chy? z^b1#Sh^?k~1$xLF*Mg{Ik!8~myZzzbZ0?@ytBzu~)*4>DRF{Y-l(uW=5>W7eBDYP- zYM1SZrt{RPB$6*K5n|IDJG51`-)mQ3$f=ZQ8Z0CTx62E@m&yL?ApFH2zw#Rnb=Q$7 z5Z`z&TJXQ+{`j-G<1flN)h_O(a8!eJ*pU-ecw9*1sn zu5xN}uBy!EOuRbz_HDnq^atM96+t9X{ur24j}>mznJV(HZn3j2ck}aUIhQ}xR{T6f z$td~F%AcTS4f~)F~E)>?C@kw;qh8GRi5I~7Z&ui9VBam>UlRQI)+k4C0U)`t!<@Na^ z-%s;+_S#ufso2><$*|eLF`^oDAo%fKif32ty+CuiQH>&TSSj;);M+*jyn0N5oBeUn zPGoYabZtK7QBVUDadxu5`{t&x{~zZ6xctqZG7T?U7*13Q-Gno`>%V^e|HmD?jeLut zx-PFm-ebih>gx4}gV8kZy_0I8aYd4%` za=<1gmlyc;J4!qa0c7R4gj5iDuX9kIinS4V4WFetBLg@p!iOMH^xb$KePl&}M?=z2 zCD4k)I80U!aI<};{aCR~PMmz%inVVs75Z844v-AT3Kd&EG=lZvFjzdYDx>9f%3VIP zK;?MypseE=Gye)fs#?_0X2wV7!Xw@$Q!R)-44~lB5X;)MQc*!0cAm21(J(`v?kGnR z&vzr(8N>D|_(V~9L0%NqY8$SX z=Xm=}yy4k=OK7pHO&;CmOp(^RD97Mf@!4Vaxja1ysDj*A;8w1buzpZX=Y^4~4N0%~ z@SPu@A^A|+m(ptOcEr5Lr~QOR+)J61$EqNPEAjC62K${ms6_GB|6dR6pLzd_KdEI1PP7s2r|hWhUl0Ei z{^y-qefdvs6mVG~xVkN@7TO2?wic~^(n~s!y5M~RTYOtb)dpzk^GnWzhWP>6=8l5< z-DbzD|E3>k^Y_&9IXhWNCx@62!>90vlrHTINv`QN7#UpH5+WZ-R#S5+|Yj!&fU zMmtlQYbTV4^2D(n%Tr=vDTLF|VzuR>sv5^aQ=pBcCRP@6Y;x_On{IAlbU zRo;(o4Q~6N36zq%n~!jngzyo+;bK5SeV=GO`VqKd3aMsZctz?$2Ah}4js|BARbNN> z=t~0C5c*5|rhHQ~v~BUIYjU+aWy+NS8S;Ca)0Uwp7&2Udh>KV{9+ChWlO+bfBVh=* zN%(W=p-f2o&BEl8kL&si$sOo9t^!zYRmQebf!#0A!=yT4?TMVaN;++VlOpn-a;J}o zWKESiQ!HZcE!kkc8X9bFBN8Hw3YGljQ1hFNb*=0qD-P;RZmu{vHY5xbF0WX?VT{P+ zKFf%6o+Yjde856K9kQbmIcagw2{7_WM6FD6;R}Pw$-F8H7N0yPloY3LdO1{H<&)8h z367nn4V$^mr%l7yf2sc>Z1TgQjGhd_!rtCZth3~F%q(S6hU{Tx?*|t;C%Am;Gn-AL zxIpBI_o!E7ta49SdqWzpi{52BN=w~U7_gsw;bxRynm?XhE8m%#Kl8)`lj6T zj*C~YtcX4s-0+Y$bT4OuN{+X@^aWk$Ra7_;wWW60%P>wGe=T464LPW<(m#yq2QX^) zrDqp?P8Z{^C>9cQnI75XGmRenGKLvvf{f>?cdN-{S!FptdaQGe?6+PNF?RQ({)8X@ z1v?ST>LFmYjh=Q`$W51daJ^2oV#C^gi|sS<@@PYN4DlVc6;%$B%qHB=(jS2`ysR`l zGR0Gr+=@$@1~b~ylvqwIN5W{AY2Z|E)^tE86?N-x|A(mP6CU*e(wFx7lFvB-VCSxJ z` zTAzkpwfl%ek+Fqqz6-uK}LnPqkz!G0yFmY2dyv7LY zHj`+v7s;J8LuoGrV``i;iJ_`Y%>)F;kTVvAdKA({Mb^w9=L606F(Dg7Pok(z z)v$+gsY%C8doXCQIY#M8#10GjX=iY-uE$#}3`z9i_-y^g^;73p$=0vC%OjcwOuv93 zqQMDdoKm@&Xf?4WMM*~!I*DU81Z59+*-hz8$jrs@PB7^X!l=b~`eFk#Zbqx_RI6l( z8NTy41C=YC>I;N)xwW0a6E{9hEiY#a%#%JR*|2Iu%zHu~^^_4u5+mgYXU6PlMz0Td zjjdgrDi9e@>R+j~_V(hkmou$8KzIbymMR?t%4!_P(89^s@`xA->XR6mF`g(kFH7>g_Y9I8R1);Y-@QH$tE;dRN#h9nLe*kG3sAj(F! zebCaNWu*CE`af|27)Mq*!%1i9In3q0w_SD6ZBrFfj0?VR7OE=(>PI)}l9w*2Tvha% zs*8(W6CGXjHpZBYMImlt9AxA&fHssL$5;cT-6U{$z|(WihE;n`5ASCcFSm%LLZ`1w zz$3E__cQZYp)ed5X(tkU+!YapY zG`}z|%i001(Qc_DFy3_a)h{usGkf2Goy9N7$W-b zuX`4|?`o18;1{cn!_AazQ9`Y4>D9Oe=$Cf|Z^x@*HYjNqcC3h}1(4K{+?G_U!c}FG zt;@H^nVhzNbVX#fbGYMtqeJ;X6WMBRO+>SpE7mN^-? zgs9Ag?ve(FUAx2kqp9$&k%6Z=>3G0J6d2htLF)m&{s8e|p0iVR@jH$mbGN5Eq~dmq`Vd>@RVBbB_7g<~ZMWcP=EBN)b$ zj_RNMljKUeKlxWCc+P&DQTGisUTs%}WGYeS)V%*re~y@tw(G=t>$j^8w! zE$!EDUg_BtvFa%&b#A+x&~}Yh_LCJvT##GI%tA^5}1_faz+;^I97&fPI!*# z=~?`6g2$9SZ&{P7^#DDCR-4~eos3tm;5#JhBBkeufPIn`G=ihWQ%H2eO1(PaGZ4@0g17((}2uWr5;UkoO89# z;OG;(I|I$PXAC4AZgd7|<(tYK;RB9Bj`TSSPEw^SGwE~YW61Ui;t+DV?#1Iy4NC(Wn?OwTz0+~i;z;aAg2fZ@b!f!25?zz_hQd{M%e zca9mm^ou&TghcTV|Dga(JH@~19|Ne%8*jUsvGj;SRM7#MNf!%i1On8 zZ{_JyHO*T<_?=eS8AfLsQlv}ZEleA$w(---;y>S$g900@CRrsmwm{hbDQlGAUa9 z96(z&aNcyzMIE0?9k%0B=4>$tX!-Ouus)U^|x+AxMlYX2<^sPV{!NX zgl03D80KCQb&kGtSpHs5-4}NcJrBPhav~ZkK_96VO>irTz$nKZKo?EToZo1pof+tTQ3+b2`yj(BNgqsl9t9mwnT=fcXoN6pI3)v!Xf=qid?h^q zd;X&Pw(skG@^Z4s(opFz31ILJb#};q`rIq`Lu+f(t}0otG(mkb6wWgy*+^N#&^5G} z)VJv2j1FwRkU`_#o6{OUTKYvE;7pOJuV;dAIZq$-+*sxpqa8CJ`T}dghb$F`JAX5f z*5VPoQq%sKf6^Q=p|x=v;;k&xd;8fXM4Ht|f8{PP6c-+A%SyUrWVY?ceW8$RKTQ18 zd#vvlil|U71B8si_h1}|0V<4I|AF+Orkb2|^Xw;E^G>-|;~9FPGpTX?GO(CrLv(R- zk1#(_Gr)<6Rjgw_*nuw-EvmVgb0)huk*2^m zxjuz8l0`1=l}jS2^*|r;iVpe`8{(wIF@>gA10t&u!l)-6@OauB1f9549R7#@ZU8nd z0Qjyy-#$ujE%>g#w~_duI&-^bJRwCVW7FP&UQ}U1;C8*9<&d^I|4ROI`M~>J3z&J} zv#wWM^i4s;8E!#Oy`zAkLU!tc$pz_i+v}oN*Uxo82EqAtB{59oxbOh*FTd}JNtQB! zYZky46i%NgOBFxkPja=KBKN%LC)?$7J#C3kh>B&&rSIX@wdP^vvu>9IaxggYXa0TS zcX!tfy0JMG%B}@#48>_P(;=1XR~7n>L<}pza~6f!i2Ky6QvU15T~kS*rv-q|R2jZWy$)P~M@rf?$5+YD#$fYn$0 z5{2eNaJ)n#NM8g;2nZhGgmLG#*CO=Ep}m{5)n^%*x;B6IX?R(}X`0oChn|kNmWt&E zNG%hKk|I*^q6dE&GX<->a~U@sz6Qm~>wTRm$hS4}C0%0Xyd$YYpF4^{DC`stEd=Eb z4$>axLwNEbKHNY255aJnWaUqVk?J04OI>g9TI}(l*LH|QzxZYqO@Bue!-Au<259ex z(oMo}t{m}AVhd&NM|g_`Y*N|bGtjo6U$Fg#sjIMld{`IcY(FN-+rf(<9u#d!B`%bj zxk3a;MUY2OmIv0eB=(=`rH#4-wIk@L_yroo6$*%H9c2s35HEcuG64_54X{8BR<>@D z`>aA&f2CfgZGLM%^)Uj#E|}L+u_!CE^EUbVQOkH+D%`|{n8?RqvVv~*3c?`gK4!;|!F4GWPP;tzjN03onJSZeF6uZfY?@m{b|Y0uf* zD%=B~#ypcm{Hx5cpPl)n#N)AvVkz*4YWcztvs8_F+GJH1K%k|fax`nZF|1ujg-~Ug z`zH^2VFK4~Oc9kVgsjKgI_CzO6tc=$yIK>~l(B|(Giy#%kCQots$4(5z)a_pb(#3g z3u4?!vdsbZx-tEgbgXTaTQ|4$K$K74dcOMa+fJUJ>Ef(0gEIP&Soofu-_UDi!$|#_ z5&HIJzLmm8g6%O)MjY7DEY^~2Wkb#A