#include "precompile.h" #include "app.h" #include "log.h" #include "svc.h" #include "def.h" #include "bus.h" #include "memutil.h" #include "fileutil.h" #include "strutil.h" #include "sockutil.h" #include "sp_svc.h" #include "sp_var.h" #include "sp_mod.h" #include "sp_def.h" #include "sp_env.h" #include "sp_pst.h" #include "sp_shm.h" #include "sp_rpc.h" #include "sp_bcm.h" #include "sp_cfg.h" #include "SimpleString.h" #include "SpBase.h" #include "sp_dbg_export.h" #include "sp_gui.h" #include "SpDefine.h" #ifdef realloc #undef realloc //(p, s) #endif #ifdef RVC_OS_WIN #include "SpShellConsole.h" #else #include #endif //RVC_OS_WIN #include #include #include struct app_t g_app; #if defined(RVC_OS_LINUX) static void shutdown_app(void* arg) { app_stop(EXIT_FROM_GUARDIAN); } static void sig_handle(int signo) { switch (signo) { case SIGSEGV: { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("%s: =========>>> capture signal SIGSEGV <<<=========", __FUNCTION__); break; } case SIGHUP: { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("%s: =========>>> capture signal SIGHUP <<<=========", __FUNCTION__); break; } case SIGTERM: DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("%s: =========>>> capture signal SIGTERM <<<=========", __FUNCTION__); toolkit_thread_t tid; toolkit_thread_create(&tid, shutdown_app, NULL); //sp_iom_stop(g_app.iom); break; default: DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("%s: =========>>> capture signal %d <<<=========", __FUNCTION__, signo); break; } return; } #endif //RVC_OS_LINUX static int get_child_range() { char tmp[32]; return _spawnl(_P_WAIT, #ifdef RVC_OS_WIN ".\\bin\\sphost.exe", "sphost.exe", #else "./bin/sphost", "sphost", #endif _itoa(sp_shm_get_range(0xffffffff), tmp, 10), NULL); } static void on_info(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt, void *user_data) { BEGIN_INFO_MAP() HANDLE_INFO(SHELL_CMD_INFO_BLUESCREEN_DISPLAY, on_bluesceen_display) HANDLE_INFO(SHELL_CMD_INFO_FATAL_ERROR_DISPLAY, on_fatal_error_display) HANDLE_INFO(SHELL_CMD_INFO_STARTUP_INFO_DISPLAY, on_startup_info_display) HANDLE_INFO(SHELL_CMD_INFO_BLUESCREEN_UNDISPLAY, on_bluesceen_undisplay) HANDLE_INFO(SHELL_CMD_INFO_MACHINE_REBOOT, on_machine_reboot) HANDLE_INFO(SHELL_CMD_INFO_ENTITY_QUIT, on_entity_quit) HANDLE_INFO(SHELL_CMD_INFO_OUTPUT_CONSOLE_ON, on_output_console_on) HANDLE_INFO(SHELL_CMD_INFO_OUTPUT_CONSOLE_OFF, on_output_console_off) HANDLE_INFO(SHELL_CMD_INFO_TERMINALSTAGE_CHANGE, on_terminal_stage_change) HANDLE_INFO(SHELL_CMD_INFO_START_UPLOAD_LOG, on_start_upload_log) HANDLE_INFO(SHELL_CMD_INFO_UPDATE_TOKEN, on_start_update_token) HANDLE_INFO(SHELL_CMD_INFO_REFRESH_ENV, on_fresh_env) END_INFO_MAP() } static void on_req(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt, void *user_data) { BEGIG_REQ_MAP() HANDLE_REQ(SHELL_CMD_REQ_ENTITY_START, on_entity_start) HANDLE_REQ(SHELL_CMD_REQ_ENTITY_STOP, on_entity_stop) // close HANDLE_REQ(SHELL_CMD_REQ_ENTITY_PAUSE, on_entity_pause) HANDLE_REQ(SHELL_CMD_REQ_ENTITY_CONTINUE, on_entity_continue) HANDLE_REQ(SHELL_CMD_REQ_ENTITY_TEST, on_entity_test) HANDLE_REQ(SHELL_CMD_REQ_ENTITY_TERMINATE, on_entity_termination) //kill HANDLE_REQ(SHELL_CMD_REQ_GET_BCAST_RECEIVER, on_get_bcast_receiver) HANDLE_REQ(SHELL_CMD_REQ_TRY_UPDATE_CFG, on_try_update_cfg) HANDLE_REQ(SHELL_CMD_REQ_WRITE_TERMINALNO, on_write_terminalNo) HANDLE_REQ(SHELL_CMD_REQ_MODIFY_MEM_CFG, on_modify_mem_cfg) HANDLE_REQ(SHELL_CMD_REQ_TRY_UPDATE_VTMERRMSG, on_try_update_VTMERRMSG) HANDLE_REQ(SHELL_CMD_REQ_GET_UPLOAD_LOGS_INFO, on_try_upload_logs_info) END_REQ_MAP() } static unsigned int __stdcall __startlist_proc(void *param) { sp_env_t *env = sp_get_env(); sp_cfg_t *cfg = env->cfg; int i; bool bAllSuc = true; for (i = 0; i < cfg->shell_ini->arr_startlist->nelts; ++i) { sp_cfg_shell_entity_t *cfg_ent = ARRAY_IDX(cfg->shell_ini->arr_startlist, i, sp_cfg_shell_entity_t*); int rc = sp_mod_mgr_start_entity(env->mod_mgr, cfg_ent->idx, cfg_ent->cmdline, SP_SHELL_SVC_ID); if (rc != 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("start entity %s failed!", cfg_ent->name); bAllSuc = false; } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("start entity %s ok!", cfg_ent->name); Sleep(100); } } if (!bAllSuc) { //特指需要框架启动的两个实体,healthManager和guiconsole DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("======================================================"); DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("!!!!!! 部分实体启动失败,请检查dbg\\spshell日志排除故障 !!!!!!"); DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("======================================================"); //app_update_terminal_state(FrameworkState_Breakdown); // 启动失败 app_upload_last_log(); Sleep(10000); app_t *app = get_app_instance(); sp_iom_post_quit(app->iom); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("all boot up entities has been started succ."); } return 0; } /*! launch limited startup module processes */ static int kickoff_startlist() { HANDLE hTempThread; hTempThread = (HANDLE)_beginthreadex(NULL, 0, &__startlist_proc, NULL, 0, NULL); //run sp_mod_mgr_start_entity 开启实体 if (hTempThread) { CloseHandle(hTempThread); return 0; } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create startlist_proc thread failed!"); } return Error_Resource; } #include "shm_mem.h" #include "sp_runTask.h" #include int RenameLightPacks(const char *pszAdPath) { int nRet = 0; if (pszAdPath == NULL || strlen(pszAdPath) == 0) return -1; auto pLogList = fileutil_get_sub_files2_a(pszAdPath, 50); for (int i = 0; i < pLogList->nelts; ++i) { CSimpleStringA strFilePath = ARRAY_IDX(pLogList, i, char*); if (strFilePath.IsEndWith(".new")) { auto strNewFile = strFilePath.SubString(0, strFilePath.GetLength() -4); if (!MoveFileExA(strFilePath, strNewFile, MOVEFILE_REPLACE_EXISTING )) { nRet = Error_Unexpect; DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("rename [%s] to [%s] fail: 0x%X", (const char*)strFilePath, (const char*)strNewFile, GetLastError()); } } } toolkit_array_free2(pLogList); return nRet; } static CSimpleStringA GetInstallStateStr(InstallStateEnum eState) { const struct { const char *str; InstallStateEnum val; } tbl[] = { { "Active", Install_Active }, { "Pending", Install_Pending }, { "SetToStart", Install_SetToStart }, { "FailRun", Install_FailRun }, { "RollBack", Install_RollBack }, { "Upgraded", Install_Upgraded }, { "Cancelled", Install_Cancelled }, { "WaitConfirm", Install_WaitConfirm }, { "Installed", Install_Installed }, }; for (int i = 0; i < sizeof(tbl) / sizeof(tbl[0]); ++i) { if (tbl[i].val == eState) return tbl[i].str; } return CSimpleStringA::Format("invalid state: %d", (int)eState); } #if defined(_MSC_VER) std::pair app_init(const sp_cfg_start_args_t* args) #else int app_init(const sp_cfg_start_args_t* args, std::function const& popup) #endif //_MSC_VER { const char *urls[1]; sp_env_t *env; void *hint_addr; int range; int rc; int flag; sp_rpc_server_callback callback; auto getClockDual = []() -> int { static clock_t t_begin = clock(); int dual = clock() - t_begin; t_begin = clock(); return dual; }; #if defined(_MSC_VER) auto popup = [&](const char* msg, bool ctritial)->void {}; #endif //_MSC_VER getClockDual(); memset(&g_app, 0, sizeof(g_app)); if (winsock_init() != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("winsock init failed!"); #if defined(_MSC_VER) return std::make_pair(-1, "winsock init failed!"); #else popup("winsock init failed!", true); return -1; #endif //_MSC_VER } #if defined(RVC_OS_LINUX) if (signal(SIGTERM, sig_handle) == SIG_ERR) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("register for SIGTERM failed: %s(%d)", strerror(errno), errno); } else { sp_dbg_debug("register for SIGTERM succ."); } if (signal(SIGHUP, sig_handle) == SIG_ERR) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("register for SIGHUP failed: %s(%d)", strerror(errno), errno); } else { sp_dbg_debug("register for SIGHUP succ."); } #endif //RVC_OS_LINUX popup("初始化 SHM 模块... ...", false); range= get_child_range(); hint_addr = sp_shm_init(range, TRUE); if (!hint_addr) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("init shm failed! range:%d", range); #if defined(_MSC_VER) return std::make_pair(-1, "init shm failed!"); #else popup("初始化 SHM 模块失败", true); return Error_Resource; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("init shm ok, addr = %p, cost:%d", hint_addr, getClockDual()); popup("初始化 ENV 模块... ...", false); flag = 0; rc = sp_env_create(hint_addr, range, args, &env, &flag); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("create env failed! %d, %d", rc, flag); #if defined(_MSC_VER) return std::make_pair(rc, "create env failed!"); #else popup("初始化 ENV 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create env ok!, cost:%d", getClockDual()); if(args->gui) { sp_gui_setShow(false); #if defined(_MSC_VER) rc = sp_gui_create(&g_app.bsc_gui); //创建窗口和消息循环机制 if (rc != 0) return std::make_pair(rc, "app shell gui init failed!"); sp_gui_undisplay(g_app.bsc_gui); sp_dbg_set_output_gui(g_app.bsc_gui); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("app shell gui init ok!, cost:%d", getClockDual()); #else rc = sp_gui_create_format(&g_app.bsc_gui); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("app shell gui init failed!"); popup("initialize gui module failed", true); return rc; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("machine_type is %s, display the logGui", env->cfg->root_ini->machine_type); g_app.bsc_gui->display(g_app.bsc_gui->gui_inst); #endif //_MSC_VER } else { g_app.bsc_gui = nullptr; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("do not create and init app shell gui!"); } env->gui = g_app.bsc_gui; // log current version info sp_cfg_install_ini_t *install_ini = env->cfg->install_ini; CVersion curVersion = CVersion(install_ini->install_version.major, install_ini->install_version.minor , install_ini->install_version.revision, install_ini->install_version.build); auto version_info = sp_cfg_find_previous_version_info(env->cfg, &install_ini->install_version); CVersion preVersion; if (version_info) { preVersion = CVersion(version_info->version.major, version_info->version.minor , version_info->version.revision, version_info->version.build); } version_info = sp_cfg_find_version_info(env->cfg, &install_ini->install_version); if (version_info) { CSmallDateTime tmSwithOverDate = version_info->switch_time; CSimpleStringA strInstallPack = version_info->install_pack; CSimpleStringA strInstallState = GetInstallStateStr((InstallStateEnum)version_info->install_state); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("current version:[%s], previous version:[%s], pack:[%s], state:[%s], swith time:[%s], cost:%d", (const char*)curVersion.ToString(), (const char*)preVersion.ToString(), (const char*)strInstallPack, (const char*)strInstallState, (const char*)tmSwithOverDate.ToTimeString(), getClockDual()); } else DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get version info fail, current version: [%s]", (const char*)curVersion.ToString()); sp_cfg_root_ini_t *root_ini = env->cfg->root_ini; if (root_ini->arr_path != NULL) { int i; sp_cfg_path_t* pos; ARRAY_FOR_EACH_ENTRY(pos, i, root_ini->arr_path, sp_cfg_path_t*) { if (!ExistsDirA(pos->path)) { BOOL bRet = CreateDirRecursiveA(pos->path); if (bRet) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("create %s ok!", pos->path); } else { #if defined(_MSC_VER) return std::make_pair(Error_Resource, CSimpleStringA::Format("create %s failed!", pos->path)); #else char message_info[1024] = { '\0' }; sprintf_s(message_info, 1023, "create %s failed!", pos->path); DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)(message_info); popup(message_info, true); return Error_Resource; #endif //_MSC_VER } } } } sp_pst_recover(env->dir->obj_path); #ifdef RVC_OS_WIN CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&sp_runtask_killprocess, NULL, 0, NULL)); #else sp_runtask_killprocess(); #endif //RVC_OS_WIN popup("初始化 BUS DEAMON 模块... ...", false); urls[0] = env->url; rc = bus_daemon_create(array_size(urls), urls, 2, &g_app.bus_daemon); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("create bus deamon failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "create bus deamon failed!"); #else popup("初始化 BUS DEAMON 模块失败", true); return rc; #endif //_MSC_VER } popup("启动 BUS DEAMON ... ...", false); rc = bus_daemon_start(g_app.bus_daemon); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("start bus daemon failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "start bus daemon failed!"); #else popup("启动 BUS DEAMON 失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start bus daemon ok!"); popup("初始化 IO MGR 模块... ...", false); /** and create bus endpt inner*/ rc = sp_iom_create(env->url, SP_SHELL_MOD_ID, &g_app.iom); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setResultCode(RTAERR_SPHOST_IOM_FAILED)("create iom failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "create iom failed!"); #else popup("初始化 IO MGR 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create iom ok!, cost:%d", getClockDual()); popup("初始化 SVC 模块... ...", false); rc = sp_svc_create(g_app.iom, 1/*multi-thread-switch*/, SP_SHELL_SVC_ID, 0, &g_app.svc); //threadpool if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("create svc failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "create svc failed!"); #else popup("初始化 SVC 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("create svc ok!"); popup("启动 SVC ... ....", false); rc = sp_svc_start(g_app.svc); //threadpool if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("start svc failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "start svc failed!"); #else popup("启动 SVC 失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start svc ok!"); sp_mod_mgr_bind_shell_svc(env->mod_mgr, g_app.svc); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("bind svc ok!"); popup("初始化 MOD MGR 模块... ...", false); rc = sp_mod_mgr_init(env->mod_mgr); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("init mod mgr failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "init mod mgr failed!"); #else popup("初始化 MOD MGR 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("init mod mgr ok!, cost:%d", getClockDual()); popup("初始化 LOG 模块... ...", false); rc = log_create(g_app.svc, &g_app.log); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("log daemon create failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "log daemon create failed!"); #else popup("初始化 LOG 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("log daemon create ok!"); RenameLightPacks(env->cfg->root_ini->ref_addata_path); /** for update terminal state event*/ popup("初始化 VAR CLIENT 模块... ...", false); rc = sp_var_client_create(g_app.svc, &g_app.var_client); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("var client create failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "var client create failed!"); #else popup("初始化 VAR CLIENT 模块失败", true); return rc; #endif //_MSC_VER } popup("初始化 VAR DEAMON 模块... ...", false); rc = sp_var_daemon_create(g_app.svc, &g_app.var_daemon); // add workitem daemon_on_pkt and daemon_on_sys if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("var daemon create failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "var daemon create failed!"); #else popup("初始化 VAR DEAMON 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("var daemon create ok!"); popup("初始化 BCM DEAMON 模块... ...", false); rc = sp_bcm_daemon_create(g_app.svc, &g_app.bcm_daemon); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("bcm daemon create failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "bcm daemon create failed!"); #else popup("初始化 BCM DEAMON 模块失败", true); return rc; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("bcm daemon create ok!"); sp_mod_mgr_bind_bcm_daemon(env->mod_mgr, g_app.bcm_daemon); popup("初始化 RPC SERVER 模块... ...", false); callback.on_info = &on_info; callback.on_req = &on_req; callback.on_destroy = NULL; callback.user_data = NULL; rc = sp_rpc_server_create(g_app.svc, &callback, &g_app.rpc_server); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("app shell rpc server init failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "app shell rpc server init failed!"); #else popup("初始化 RPC SERVER 模块失败", true); return rc; #endif //_MSC_VER } popup("启动 RPC SERVER... ...", false); rc = sp_rpc_server_start(g_app.rpc_server); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("app shell rpc server start failed!"); #if defined(_MSC_VER) return std::make_pair(rc, "app shell rpc server start failed!"); #else popup("启动 RPC SERVER 失败", true); return rc; #endif //_MSC_VER } #ifdef RVC_OS_WIN rc = sp_sps_create(&g_app.sps); if (rc != 0) { /*slv内容,不作为关键依赖项*/ DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("create silverlight policy server failed!"); //return rc; } rc = sp_sps_start(g_app.sps); if (rc != 0) { /*slv启动对应端口,不作为关键依赖项*/ DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("start silverlight policy server failed!"); //return rc; } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create silverlight policy server ok!,cost:%d", getClockDual()); #endif //RVC_OS_WIN #if defined(RVC_OS_WIN) && defined(WITH_DEBUG) // start console service const int nConsolePort = env->cfg->shell_ini->nConsolePort; if (nConsolePort > 0) { g_app.pConsole = new CSpShellConsole(); if (!g_app.pConsole->StartListen(nConsolePort)) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("start spshell console service at port %d fail, %s", nConsolePort, g_app.pConsole->GetLastErrorMsg()); #if defined(_MSC_VER) return std::make_pair(rc, CSimpleStringA::Format("start spshell console service at port %d fail, %s", nConsolePort, g_app.pConsole->GetLastErrorMsg())); #else return Error_Unexpect; #endif //_MSC_VER } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("start spshell console service at port %d ok!", nConsolePort); } #endif // RVC_OS_WIN && WITH_DEBUG //app_update_terminal_state(flag != 0 ? FrameworkState_NotConfig : FrameworkState_Booting); auto shellEnv = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, 0); #if defined(_MSC_VER) shellEnv->cfg->m_EntityInitEndTime.longPart = sp_cfg_getShellFirstStartTime().longPart + clock() * 10000; #else //GetLocalTime(&shellEnv->cfg->m_EntityInitEndTime); ZeroMemory(&shellEnv->cfg->m_EntityInitEndTime, sizeof(SYSTEMTIME)); const ULONGLONG curTickCount = GetTickCount64(); memcpy(&shellEnv->cfg->m_EntityInitEndTime, &curTickCount, sizeof(ULONGLONG)); #endif //_MSC_VER rc = kickoff_startlist(); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("kickoff startlist thread proc failed!"); } DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("kickoff startlist thread proc ok!,cost:%d", getClockDual()); #ifdef RVC_OS_WIN sp_runtask_startprocess(); #endif //RVC_OS_WIN popup("", false); sp_dbg_set_output_gui(g_app.bsc_gui); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("app shell gui init ok!"); //框架启动结束 #if defined(_MSC_VER) shellEnv->cfg->m_EntityStartEndTime.longPart = sp_cfg_getShellFirstStartTime().longPart + clock() * 10000; #else GetLocalTime(&shellEnv->cfg->m_EntityStartEndTime); #endif //_MSC_VER #if defined(_MSC_VER) return std::make_pair(0, ""); #else return 0; #endif //_MSC_VER } int app_term() { int rc; #if defined(RVC_OS_WIN) && defined(WITH_DEBUG) if (g_app.pConsole != NULL) { g_app.pConsole->StopListen(); g_app.pConsole = NULL; } #endif //defined(RVC_OS_WIN) && defined(WITH_DEBUG) /*kill all children process ?*/ rc = sp_mod_mgr_terminate_all_entity(sp_get_env()->mod_mgr, 0/*SP_SHELL_SVC_ID*/); if (0 != rc) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("terminate all entity failed: %s", sp_strerror(rc)); #if defined(_MSC_VER) sp_shm_term(); winsock_term(); return 0; #endif //_MSC_VER } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("terminate all entity ok!"); } #ifdef RVC_OS_WIN if (g_app.sps) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop silverlight policy server."); sp_sps_stop(g_app.sps); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy silverlight policy server."); sp_sps_destroy(g_app.sps); g_app.sps = NULL; } #endif //RVC_OS_WIN DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop rpc server."); if (g_app.rpc_server) { rc = sp_rpc_server_stop(g_app.rpc_server); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("stop rpc server failed! %d", rc); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop rpc server ok!"); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy rpc server."); sp_rpc_server_destroy(g_app.rpc_server); g_app.rpc_server = NULL; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy bcm daemon."); if (g_app.bcm_daemon) { sp_bcm_daemon_destroy(g_app.bcm_daemon); g_app.bcm_daemon = NULL; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy var daemon."); if (g_app.var_daemon) { sp_var_daemon_destroy(g_app.var_daemon); g_app.var_daemon = NULL; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy var client"); if (g_app.var_client) { sp_var_client_destroy(g_app.var_client); g_app.var_client = NULL; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy log daemon."); if (g_app.log) { log_destroy(g_app.log); } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("term mod mgr."); if(sp_get_env()->mod_mgr) sp_mod_mgr_term(sp_get_env()->mod_mgr); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop svc."); if (g_app.svc) { rc = sp_svc_stop(g_app.svc); if (rc != 0) DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("stop svc failed!"); else DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop svc ok!"); sp_svc_destroy(g_app.svc); /*destroy iom and bus endpt*/ g_app.svc = NULL; g_app.iom = NULL; } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop bus daemon."); if (g_app.bus_daemon) { rc = bus_daemon_stop(g_app.bus_daemon); /*destroy ioqueue*/ if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("stop bus daemon failed!"); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("stop bus daemon ok!"); } } DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy bus daemon."); if (g_app.bus_daemon) { rc = bus_daemon_destroy(g_app.bus_daemon); if (rc != 0) { DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("destroy bus daemon failed!"); } else { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy bus daemon ok!"); } g_app.bus_daemon = NULL; } #ifdef RVC_OS_WIN if (g_app.bsc_gui != NULL) { DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy gui."); sp_gui_destroy(g_app.bsc_gui); g_app.bsc_gui = NULL; } #endif DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy env."); sp_env_destroy(sp_get_env()); DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("destroy share memory."); sp_shm_term(); winsock_term(); return 0; } int app_run() { int rc; rc = sp_iom_run(g_app.iom); return rc; } void app_stop(int from_id) { if (from_id != 0) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("app stop from: %d", from_id); } stop_all_stated_entity(NULL); sp_iom_stop(g_app.iom); } int app_update_terminal_state(int state) { int rc; char n[12] = {'\0'}; sp_env_t* env = sp_get_env(); sp_cfg_t* cfg = env->cfg; const int old_state = cfg->shell_ini->shell_state; cfg->shell_ini->shell_state = state; _itoa(state, n, 10); rc = sp_var_client_set(g_app.var_client, VAR_RSERVERD_KEY_TERM_STATE, n, 0); if (rc == 0) { if (g_app.bsc_gui != NULL && state != old_state) { #if defined(_MSC_VER) ///*TODO(80374374@3/24/2023): */ #else g_app.bsc_gui->post_message(g_app.bsc_gui->gui_inst, GUI_DISPLAY_ELEM_LOG_OTHER, state); #endif //_MSC_VER } } return rc; } app_t *get_app_instance() { return &g_app; } void app_clear() { } void app_upload_last_log() { CSimpleString t_terminalNo = "unknown terminalNo"; sp_env_t* env = sp_get_env(); if (env && env->cfg && env->cfg->root_ini && env->cfg->root_ini->terminal_no) t_terminalNo = env->cfg->root_ini->terminal_no; char dstVer[SP_MAX_VER_LEN] = ""; auto ret = sp_cfg_getVer(dstVer); if (ret != Error_Succeed) sprintf_s(dstVer, SP_MAX_VER_LEN, "Unknown"); create_log_producer_send(SpDefine::endpoint, SpDefine::topicSys, SpDefine::topicUser, SpDefine::topicBeidou, SpDefine::topicBussSys, SpDefine::topicBussUser, SpDefine::topicVTMWeb, t_terminalNo, dstVer, "", 100); }