svc.cpp 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877
  1. #include "precompile.h"
  2. #include "sp_mod.h"
  3. #include "svc.h"
  4. #include "app.h"
  5. #include "SpBase.h"
  6. #include "SpHelper.h"
  7. #include "sp_btr.h"
  8. #include "sp_gui.h"
  9. #include "sp_dbg_export.h"
  10. #include "sp_iom.h"
  11. #include "sp_svc.h"
  12. #include "sp_def.h"
  13. #include "sp_cfg.h"
  14. #include "sp_rpc.h"
  15. #include "sp_env.h"
  16. #include <memory>
  17. #include <shm_mem.h>
  18. #include "osutil.h"
  19. #include "fileutil.h"
  20. #include "toolkit.h"
  21. #include <winpr/library.h>
  22. #include <winpr/sysinfo.h>
  23. #include <iniutil.h>
  24. static void shutdown_app(void* arg)
  25. {
  26. app_stop(EXIT_FROM_REBOOT_CMD);
  27. }
  28. void on_bluesceen_display(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  29. {
  30. app_t *app = get_app_instance();
  31. char *msg = NULL;
  32. //int iBlueScreen=0;
  33. //iobuffer_format_read(*info_pkt, "s4", &msg, &iBlueScreen);
  34. iobuffer_format_read(*info_pkt, "s", &msg);
  35. #if defined(_MSC_VER)
  36. sp_gui_show_running_info(app->bsc_gui, msg, GUI_DISPLAY_ELEM_BLUESCREEN);
  37. #else
  38. if (app->bsc_gui != NULL)
  39. app->bsc_gui->show_running_info(app->bsc_gui->gui_inst, msg, GUI_DISPLAY_ELEM_BLUESCREEN);
  40. #endif //_MSC_VER
  41. FREE(msg);
  42. }
  43. ///*TODO(80374374@3/23/2023): 抛送内容格式的处理,看与操作系统是否有关 */
  44. void on_fatal_error_display(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  45. {
  46. app_t *app = get_app_instance();
  47. char *msg = NULL;
  48. int level = 0;
  49. #if defined(_MSC_VER)
  50. iobuffer_format_read(*info_pkt, "s", &msg);
  51. sp_gui_show_running_info(app->bsc_gui, msg, GUI_DISPLAY_ELEM_FATAL_ERROR);
  52. #else
  53. iobuffer_format_read(*info_pkt, "4s", &level, &msg);
  54. if (app->bsc_gui != NULL) {
  55. app->bsc_gui->show_running_info(app->bsc_gui->gui_inst, msg, GUI_DISPLAY_ELEM_FATAL_ERROR);
  56. }
  57. #endif //_MSC_VER
  58. FREE(msg);
  59. }
  60. void on_startup_info_display(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  61. {
  62. app_t *app = get_app_instance();
  63. char *msg = NULL;
  64. iobuffer_format_read(*info_pkt, "s", &msg);
  65. #if defined(_MSC_VER)
  66. sp_gui_show_running_info(app->bsc_gui, msg, GUI_DISPLAY_ELEM_STARTUP_INFO);
  67. #else
  68. if (app->bsc_gui != NULL)
  69. app->bsc_gui->show_running_info(app->bsc_gui->gui_inst, msg, GUI_DISPLAY_ELEM_STARTUP_INFO);
  70. #endif //_MSC_VER
  71. FREE(msg);
  72. }
  73. void on_bluesceen_undisplay(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  74. {
  75. app_t *app = get_app_instance();
  76. #if defined(_MSC_VER)
  77. sp_gui_undisplay(app->bsc_gui);
  78. #else
  79. if (app->bsc_gui != NULL)
  80. app->bsc_gui->hide(app->bsc_gui->gui_inst);
  81. #endif //_MSC_VER
  82. }
  83. #if defined(_MSC_VER)
  84. ///*TODO(80374374@3/23/2023): 移动到 libtoolkit */
  85. static BOOL RestartWindows(BOOL fShutdownOnly = FALSE)
  86. {
  87. HANDLE hToken; // handle to process token
  88. TOKEN_PRIVILEGES tkp; // pointer to token structure
  89. BOOL fResult; // system shutdown flag
  90. if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
  91. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get proc token fail GLE=%u", GetLastError());
  92. return FALSE;
  93. }
  94. LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
  95. tkp.PrivilegeCount = 1; // one privilege to set
  96. tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  97. if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0)) {
  98. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("adjust proc token privilege fail GLE=%u", GetLastError());
  99. return FALSE;
  100. }
  101. fResult = InitiateSystemShutdown(
  102. NULL, // shut down local computer
  103. NULL, // message for user
  104. 0, // time-out period, in seconds
  105. FALSE, // ask user to close apps
  106. !fShutdownOnly); // reboot after shutdown
  107. if (!fResult) {
  108. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("request windows reboot fail GLE=%u", GetLastError());
  109. return FALSE;
  110. }
  111. tkp.Privileges[0].Attributes = 0;
  112. AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES)NULL, 0);
  113. return TRUE;
  114. }
  115. #endif //_MSC_VER
  116. DWORD getExePath(char *exePath)
  117. {
  118. char pathbuf[MAX_PATH] = "";
  119. int pathlen = ::GetModuleFileName(NULL, pathbuf, MAX_PATH);
  120. while (pathlen > 0)
  121. {
  122. if (pathbuf[pathlen--] == SPLIT_SLASH)
  123. break;
  124. }
  125. pathbuf[++pathlen] = '\0';
  126. sprintf(exePath, "%s", pathbuf);
  127. return strlen(exePath);
  128. }
  129. #define RESTART_FRAMEWORK 1
  130. #define SHUTDOWN_FRAMEWORK 2
  131. #define RESTART_PC 3
  132. #define SHUTDOWN_PC 4
  133. static int KickoffSpRestartInner(int options)
  134. {
  135. #ifdef _WIN32
  136. if (options == RESTART_PC || options == SHUTDOWN_PC) {
  137. return RestartWindows(options == SHUTDOWN_PC) ? 0 : -1;
  138. }
  139. else {
  140. STARTUPINFO si;
  141. PROCESS_INFORMATION pi;
  142. ZeroMemory(&si, sizeof(si));
  143. si.cb = sizeof(si);
  144. ZeroMemory(&pi, sizeof(pi));
  145. // Start the child process.
  146. char exepath[MAX_PATH] = "";
  147. getExePath(exepath);
  148. CSimpleStringA csRestart, csVerPath, csAll, csSep("\""), csBlank(" "), csScript("wscript.exe"), csReFlag("r");
  149. csRestart = CSimpleStringA(exepath) + "\\sprestart.exe";
  150. sp_env_t* env = sp_get_env();
  151. csVerPath = env->dir->root_ver_path;
  152. csVerPath += "\\VTM.exe";
  153. if (options == SHUTDOWN_FRAMEWORK)
  154. csReFlag = "n";
  155. csAll = csRestart + csBlank + csVerPath + csBlank + csReFlag;
  156. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("allpath[%s]", (LPCTSTR)csAll);
  157. LPTSTR szCmdline = _strdup(csAll);
  158. if (!CreateProcess(NULL, szCmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
  159. {
  160. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CreateProcess failed (%d).\n", GetLastError());
  161. return -1;
  162. }
  163. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("CreateProcess Success PID:%d.\n", pi.dwProcessId);
  164. DWORD dwErr = GetLastError();
  165. // Close process and thread handles.
  166. CloseHandle(pi.hProcess);
  167. CloseHandle(pi.hThread);
  168. return 0;
  169. }
  170. #else
  171. sp_env_t* env = sp_get_env();
  172. if (env && env->dir) {
  173. tk_process_t* process = NULL;
  174. tk_process_option_t option;
  175. char app[MAX_PATH] = { '\0' };
  176. char shell_scripts[MAX_PATH] = { '\0' };
  177. sprintf(shell_scripts, "%s/%s", env->dir->root_ver_path, "spexplorer.sh");
  178. if (options == RESTART_FRAMEWORK) {
  179. if (env && env->cfg && env->cfg->args && env->cfg->args->arguments) {
  180. sprintf(app, "%s %s -Rwait", shell_scripts, env->cfg->args->arguments);
  181. }
  182. else {
  183. sprintf(app, "%s -Rwait", shell_scripts);
  184. }
  185. }
  186. else if (options == SHUTDOWN_FRAMEWORK) {
  187. sprintf(app, "%s --shutdown", shell_scripts);
  188. }
  189. else if (options == RESTART_PC) {
  190. sprintf(app, "%s --reboot", shell_scripts);
  191. }
  192. else if (options == SHUTDOWN_PC) {
  193. sprintf(app, "%s --systemoff", shell_scripts);
  194. }
  195. else {
  196. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("invalid restart pararm: %d", options);
  197. return -1;
  198. }
  199. option.exit_cb = NULL;
  200. option.file = NULL;
  201. option.flags = 0;
  202. option.params = app;
  203. char szldPath[1024] = { '\0' };
  204. size_t szldLen = 1023;
  205. const int ldRet = toolkit_getenv("LD_LIBRARY_PATH", szldPath, &szldLen);
  206. if (ldRet == 0) {
  207. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("get library path: %s", szldPath);
  208. toolkit_unsetenv("LD_LIBRARY_PATH");
  209. }
  210. else {
  211. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("GetEnv of LD_LIBRARY_PATH failed: %s", toolkit_strerror(ldRet));
  212. }
  213. if (0 == process_spawn(&option, &process)) {
  214. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("create new process succ pid=%u! %s", process->pid, app);
  215. FREE(process);
  216. return 0;
  217. }
  218. else {
  219. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("create new process failed! %s", app);
  220. if (ldRet == 0) {
  221. toolkit_setenv("LD_LIBRARY_PATH", szldPath);
  222. }
  223. }
  224. }
  225. else {
  226. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Env has no any dir information!");
  227. }
  228. return -1;
  229. #endif //_WIN32
  230. }
  231. int KickoffSpRestart(bool bRestart)
  232. {
  233. return KickoffSpRestartInner(bRestart ? RESTART_FRAMEWORK : SHUTDOWN_FRAMEWORK);
  234. }
  235. int KickoffSpRestartPC(bool bRestart)
  236. {
  237. return KickoffSpRestartInner(bRestart ? RESTART_PC : SHUTDOWN_PC);
  238. }
  239. #if 1
  240. static const int max_entity_total_about_num = 100;
  241. static const int each_thread_close_entity_num = 10;
  242. int total_active_module_num = 0;
  243. int entity_close_thread_num = 0;
  244. toolkit_barrier_t blocker;
  245. void hare(void* arg)
  246. {
  247. const int startpos = (int)(intptr_t)((int*)arg);
  248. sp_env_t* env = sp_get_env();
  249. bool bAllSuc = true;
  250. sp_mod_mgr_t* mod_mgr = env->mod_mgr;
  251. sp_mod_t* pos;
  252. int skipnum = 0, dealnum = 0;
  253. sp_dbg_debug("threshold: %d", startpos);
  254. list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry)
  255. {
  256. if (pos->closing) {
  257. if (++skipnum < startpos)
  258. continue;
  259. if (++dealnum > each_thread_close_entity_num)
  260. break;
  261. sp_entity_t* ent;
  262. list_for_each_entry(ent, &pos->entity_list, sp_entity_t, entry)
  263. {
  264. const int state = ent->state;
  265. if (state != EntityState_NoStart && state != EntityState_Close && state != EntityState_Killed) {
  266. sp_dbg_debug("to stop entity %s ...", ent->cfg->name);
  267. int result = sp_mod_mgr_stop_entity(env->mod_mgr, ent->cfg->idx, SP_SHELL_SVC_ID, CloseCause_ShellQuit);
  268. if (result == 0) {
  269. sp_dbg_info("to stop entity %s succ, pre state: %s, curr state: %s",
  270. ent->cfg->name, SpStrEntityState((EntityStateEnum)state), SpStrEntityState((EntityStateEnum)ent->state));
  271. } else {
  272. sp_dbg_error("to stop entity %s failed !! %s, pre state: %s, curr state: %s",
  273. ent->cfg->name, SpStrError((ErrorCodeEnum)result), SpStrEntityState((EntityStateEnum)state), SpStrEntityState((EntityStateEnum)ent->state));
  274. bAllSuc = false;
  275. }
  276. } else {
  277. sp_dbg_info("ignore to stop %s, curr state: %d", ent->cfg->name, state);
  278. }
  279. }
  280. }
  281. }
  282. if (!bAllSuc) {
  283. sp_dbg_error("some booted up entities has been closed failed!");
  284. } else {
  285. sp_dbg_info("all booted up entities has been closed succ.");
  286. }
  287. toolkit_barrier_wait(&blocker);
  288. }
  289. int stop_all_stated_entity_sync()
  290. {
  291. sp_env_t* env = sp_get_env();
  292. bool bAllSuc = true;
  293. sp_mod_mgr_t* mod_mgr = env->mod_mgr;
  294. sp_mod_t* pos;
  295. list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry)
  296. {
  297. if (pos->loaded) {
  298. sp_entity_t* ent;
  299. list_for_each_entry(ent, &pos->entity_list, sp_entity_t, entry)
  300. {
  301. const int state = ent->state;
  302. if (state != EntityState_NoStart && state != EntityState_Close && state != EntityState_Killed) {
  303. int result = sp_mod_mgr_stop_entity(env->mod_mgr, ent->cfg->idx, SP_SHELL_SVC_ID, CloseCause_ShellQuit);
  304. if (result == 0) {
  305. sp_dbg_debug("to stop entity succ: %s, pre state: %s, curr state: %s",
  306. ent->cfg->name, result, SpStrEntityState((EntityStateEnum)state), SpStrEntityState((EntityStateEnum)ent->state));
  307. } else {
  308. sp_dbg_error("to stop entity failed: %s !! %d, pre state: %s, curr state: %s",
  309. ent->cfg->name, SpStrError((ErrorCodeEnum)result), SpStrEntityState((EntityStateEnum)state), SpStrEntityState((EntityStateEnum)ent->state));
  310. bAllSuc = false;
  311. }
  312. } else {
  313. sp_dbg_info("ignore to stop %s, curr state: %d", ent->cfg->name, state);
  314. }
  315. }
  316. }
  317. }
  318. if (!bAllSuc) {
  319. sp_dbg_warn("======================================================");
  320. sp_dbg_warn("!!!!!! 部分实体退出失败 !!!!!!");
  321. sp_dbg_warn("======================================================");
  322. return -1;
  323. } else {
  324. sp_dbg_info("all booted up entities has been closed succ.");
  325. return 0;
  326. }
  327. }
  328. int stop_all_stated_entity(void* param)
  329. {
  330. sp_env_t* env = sp_get_env();
  331. sp_mod_mgr_t* mod_mgr = env->mod_mgr;
  332. sp_mod_t* pos;
  333. total_active_module_num = 0;
  334. sp_dbg_info(">>>>>> start to stop all started entities <<<<<<");
  335. list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry) {
  336. if (pos->loaded) {
  337. ++total_active_module_num;
  338. pos->closing = 1;
  339. }
  340. }
  341. entity_close_thread_num = total_active_module_num / each_thread_close_entity_num;
  342. if (total_active_module_num % each_thread_close_entity_num) entity_close_thread_num++;
  343. sp_dbg_info("total moudule: %d, thread num: %d, each thread close module num: %d", total_active_module_num,
  344. entity_close_thread_num, each_thread_close_entity_num);
  345. if (total_active_module_num > max_entity_total_about_num) {
  346. return stop_all_stated_entity_sync();
  347. }
  348. toolkit_barrier_init(&blocker, entity_close_thread_num + 1);
  349. toolkit_thread_t threads[max_entity_total_about_num];
  350. for (int i = 0; i < entity_close_thread_num; ++i) {
  351. int nums = each_thread_close_entity_num * i;
  352. toolkit_thread_create(&threads[i], hare, (void*)(uintptr_t)nums);
  353. }
  354. const DWORD begin = GetTickCount();
  355. sp_dbg_info("wait working thread done...");
  356. toolkit_barrier_wait(&blocker);
  357. toolkit_barrier_destroy(&blocker);
  358. const DWORD end = GetTickCount();
  359. sp_dbg_info(">>>>>> working thread done !! consumed: %u ms <<<<<<", end - begin);
  360. return 0;
  361. }
  362. #else
  363. int stop_all_stated_entity(void* param)
  364. {
  365. sp_dbg_warn("%s: do nothing!!", __FUNCTION__);
  366. return 0;
  367. }
  368. #endif
  369. void on_machine_reboot(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  370. {
  371. static int retry = 0;
  372. int result = 0;
  373. int reason(0), way(0);
  374. sp_env_t *env = sp_get_env();
  375. sp_cfg_t *cfg = env->cfg;
  376. //stop from duplicating
  377. if(retry != 0) {
  378. return;
  379. }
  380. retry = 1;
  381. iobuffer_read(*info_pkt, IOBUF_T_I4, &reason, 0);
  382. iobuffer_read(*info_pkt, IOBUF_T_I4, &way, 0);
  383. const RebootWayEnum eRebootWay = (RebootWayEnum)way;
  384. const RebootTriggerEnum eRebootTrigger = (RebootTriggerEnum)reason;
  385. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("now reboot: reason = %s, way = %s", SpStrRebootTrigger(eRebootTrigger), SpStrRebootWay(eRebootWay));
  386. CSimpleStringA strPath = env->dir->root_runinfo_path;
  387. strPath += SPLIT_SLASH_STR "BootLog";
  388. sp_btr_write_on_shutdown(strPath, env->btr_ctx, reason, way);
  389. if (eRebootWay == RebootWay_Framework)
  390. {
  391. if (eRebootTrigger == RebootTrigger_DeadForever) {
  392. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("shutdown framework now");
  393. result = KickoffSpRestart(false);
  394. } else {
  395. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("reboot framework now");
  396. result = KickoffSpRestart(true);
  397. }
  398. }
  399. else if (eRebootWay == RebootWay_OS || eRebootWay == RebootWay_Power) /** UPS 下线后,Power类型也兼容到框架 [Gifur@2024511]*/
  400. {
  401. if (eRebootTrigger != RebootTrigger_DeadForever) {
  402. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("reboot operation system now");
  403. result = KickoffSpRestartPC(true);
  404. //result = osutil_restart_system();
  405. } else {
  406. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("shutdown operation system now");
  407. result = KickoffSpRestartPC(false);
  408. //result = osutil_shutdown_system();
  409. }
  410. }
  411. if (result == 0) {
  412. stop_all_stated_entity(NULL);
  413. app_t* app = get_app_instance();
  414. sp_iom_post_quit(app->iom);
  415. } else {
  416. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Stop from quit the framework, bcz preceed task failed!");
  417. }
  418. }
  419. void on_entity_quit(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  420. {
  421. int entity_id;
  422. sp_env_t *env = sp_get_env();
  423. iobuffer_read(*info_pkt, IOBUF_T_I4, &entity_id, NULL);
  424. sp_mod_mgr_stop_entity(env->mod_mgr, entity_id, svc_id, CloseCause_Self);
  425. }
  426. void on_output_console_on(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  427. {
  428. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("set output console on");
  429. auto app = get_app_instance();
  430. #if defined(_MSC_VER)
  431. sp_gui_display(app->bsc_gui);
  432. #else
  433. if (app->bsc_gui != NULL)
  434. app->bsc_gui->display(app->bsc_gui->gui_inst);
  435. #endif //_MSC_VER
  436. }
  437. void on_output_console_off(sp_rpc_server_t *server, int epid, int svc_id, int call_type, iobuffer_t **info_pkt)
  438. {
  439. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("set output console off");
  440. auto app = get_app_instance();
  441. #if defined(_MSC_VER)
  442. sp_gui_undisplay(app->bsc_gui);
  443. #else
  444. if (app->bsc_gui != NULL)
  445. app->bsc_gui->hide(app->bsc_gui->gui_inst);
  446. #endif //_MSC_VER
  447. }
  448. void on_start_upload_log(sp_rpc_server_t* server, int epid, int svc_id, int call_type, iobuffer_t** info_pkt)
  449. {
  450. static bool isStarted = false;
  451. if (isStarted)
  452. return;
  453. sp_env_t* env = sp_get_env();
  454. char* endpoint = NULL, * topicSys = NULL, * topicUser = NULL, * topicBeidou = NULL, * bussSys = NULL, * bussUser = NULL , *vtmWeb = NULL;
  455. iobuffer_format_read(*info_pkt, "sssssss", &endpoint, &topicSys, &topicUser, &topicBeidou, &bussSys, &bussUser, &vtmWeb);
  456. char dstVer[SP_MAX_VER_LEN] = "";
  457. auto ret = sp_cfg_getVer(dstVer);
  458. if (ret != Error_Succeed)
  459. sprintf_s(dstVer, SP_MAX_VER_LEN, "Unknown");
  460. auto logSender = create_log_producer_send(endpoint, topicSys, topicUser, topicBeidou, bussSys, bussUser, vtmWeb, env->cfg->root_ini->terminal_no, dstVer, "", 20000);
  461. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("create log produce sender %s-%s-%s-%s-%s-%s-%s %s",
  462. endpoint, topicSys, topicUser, topicBeidou, bussSys, bussUser, vtmWeb, logSender == NULL ? "failed" : "success");
  463. toolkit_free(endpoint);
  464. toolkit_free(topicSys);
  465. toolkit_free(topicUser);
  466. toolkit_free(topicBeidou);
  467. toolkit_free(bussSys);
  468. toolkit_free(bussUser);
  469. toolkit_free(vtmWeb);
  470. }
  471. void on_terminal_stage_change(sp_rpc_server_t* server, int epid, int svc_id, int call_type, iobuffer_t** info_pkt)
  472. {
  473. int result = 0;
  474. int newStage(0), oldStage(0);
  475. sp_env_t* env = sp_get_env();
  476. sp_cfg_t* cfg = env->cfg;
  477. iobuffer_read(*info_pkt, IOBUF_T_I4, &newStage, 0);
  478. iobuffer_read(*info_pkt, IOBUF_T_I4, &oldStage, 0);
  479. const FrameworkStateEnum eNewStage = (FrameworkStateEnum)newStage;
  480. const FrameworkStateEnum eOldStage = (FrameworkStateEnum)oldStage;
  481. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("change teriminal state from %s to %s", SpStrFrameworkState(eOldStage), SpStrFrameworkState(eNewStage));
  482. auto app = get_app_instance();
  483. #if defined(RVC_OS_LINUX)
  484. if (app->bsc_gui != NULL) {
  485. app->bsc_gui->post_message(app->bsc_gui->gui_inst, GUI_DISPLAY_ELEM_LOG_OTHER, newStage);
  486. }
  487. #else
  488. ///*TODO(80374374@3/24/2023): */
  489. #endif //RVC_OS_LINUX
  490. }
  491. void on_start_update_token(sp_rpc_server_t* server, int epid, int svc_id, int call_type, iobuffer_t** info_pkt)
  492. {
  493. sp_env_t* env = sp_get_env();
  494. char* channelId = NULL, * token = NULL;
  495. iobuffer_format_read(*info_pkt, "ss", &channelId, &token);
  496. auto t_cfg = sp_get_env()->cfg->shell_ini;
  497. if (t_cfg->channelId != NULL)
  498. {
  499. shm_free(t_cfg->channelId);
  500. t_cfg->channelId = NULL;
  501. }
  502. if (t_cfg->token != NULL)
  503. {
  504. shm_free(t_cfg->token);
  505. t_cfg->token = NULL;
  506. }
  507. t_cfg->channelId = shm_strdup(channelId);
  508. t_cfg->token = shm_strdup(token);
  509. toolkit_free(channelId);
  510. toolkit_free(token);
  511. }
  512. typedef struct
  513. {
  514. sp_rpc_server_t* server;
  515. int epid;
  516. int rpc_id;
  517. int svc_id;
  518. int Entity_id;
  519. char cmdline[1024];
  520. }EntityStartParam;
  521. static unsigned int __stdcall on_entity_startThread(void* param)
  522. {
  523. EntityStartParam *dst = (EntityStartParam*)param;
  524. auto ans_pkt = on_entity_start(dst->svc_id, dst->Entity_id, dst->cmdline);
  525. if (ans_pkt) {
  526. int rc = sp_rpc_server_send_answer(dst->server, dst->epid, dst->svc_id, dst->rpc_id, &ans_pkt);
  527. if (rc != 0)
  528. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("send answer failed!");
  529. if (ans_pkt)
  530. iobuffer_dec_ref(ans_pkt);
  531. }
  532. return 0;
  533. }
  534. iobuffer_t* on_entity_startEx(sp_rpc_server_t* server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t** req_pkt)
  535. {
  536. int entity_id;
  537. char* cmdline = NULL;
  538. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  539. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("handle start entityEx req: %d", entity_id);
  540. iobuffer_format_read(*req_pkt, "s", &cmdline);
  541. EntityStartParam *param = new EntityStartParam();
  542. param->server = server;
  543. param->epid = epid;
  544. param->rpc_id = rpc_id;
  545. param->svc_id = svc_id;
  546. param->Entity_id = entity_id;
  547. sprintf(param->cmdline, "%s", cmdline);
  548. FREE(cmdline);
  549. CloseHandle(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&on_entity_startThread, param, 0, NULL));
  550. return NULL;
  551. }
  552. iobuffer_t *on_entity_start(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  553. {
  554. sp_env_t *env = sp_get_env();
  555. int entity_id;
  556. int result;
  557. char *cmdline = NULL;
  558. iobuffer_t *ans_pkt = NULL;
  559. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  560. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("handle start entity req: %d", entity_id);
  561. iobuffer_format_read(*req_pkt, "s", &cmdline);
  562. result = sp_mod_mgr_start_entity(env->mod_mgr, entity_id, cmdline, svc_id);
  563. FREE(cmdline);
  564. ans_pkt = iobuffer_create(-1, -1);
  565. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  566. return ans_pkt;
  567. }
  568. iobuffer_t* on_entity_start(int svc_id, int entity_id, const char* cmdline)
  569. {
  570. sp_env_t* env = sp_get_env();
  571. int result;
  572. iobuffer_t* ans_pkt = NULL;
  573. result = sp_mod_mgr_start_entity(env->mod_mgr, entity_id, cmdline, svc_id);
  574. ans_pkt = iobuffer_create(-1, -1);
  575. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  576. return ans_pkt;
  577. }
  578. iobuffer_t *on_entity_stop(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  579. {
  580. sp_env_t *env = sp_get_env();
  581. int entity_id;
  582. int result;
  583. int cause_code;
  584. iobuffer_t *ans_pkt = NULL;
  585. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  586. if (svc_id == SP_SHELL_SVC_ID) {
  587. cause_code = CloseCause_ShellQuit;
  588. } else if (svc_id == SP_INVALID_SVC_ID) {
  589. cause_code = CloseCause_Lost;
  590. } else if (svc_id == entity_id) {
  591. cause_code = CloseCause_Self;
  592. } else {
  593. cause_code = CloseCause_Other;
  594. }
  595. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("handle stop entity req: %d", entity_id);
  596. result = sp_mod_mgr_stop_entity(env->mod_mgr, entity_id, svc_id, cause_code);
  597. ans_pkt = iobuffer_create(-1, -1);
  598. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  599. return ans_pkt;
  600. }
  601. iobuffer_t *on_entity_continue(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  602. {
  603. sp_env_t *env = sp_get_env();
  604. int entity_id;
  605. int result;
  606. iobuffer_t *ans_pkt = NULL;
  607. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  608. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("handle continue entity req: %d", entity_id);
  609. result = sp_mod_mgr_continue_entity(env->mod_mgr, entity_id, svc_id);
  610. ans_pkt = iobuffer_create(-1, -1);
  611. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  612. return ans_pkt;
  613. }
  614. iobuffer_t *on_entity_pause(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  615. {
  616. sp_env_t *env = sp_get_env();
  617. int entity_id;
  618. int result;
  619. iobuffer_t *ans_pkt = NULL;
  620. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  621. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("handle pause entity req: %d", entity_id);
  622. result = sp_mod_mgr_pause_entity(env->mod_mgr, entity_id, svc_id);
  623. ans_pkt = iobuffer_create(-1, -1);
  624. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  625. return ans_pkt;
  626. }
  627. iobuffer_t *on_entity_test(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  628. {
  629. sp_env_t *env = sp_get_env();
  630. int entity_id;
  631. int test_type;
  632. int result;
  633. int statistic;
  634. iobuffer_t *ans_pkt = NULL;
  635. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  636. iobuffer_read(*req_pkt, IOBUF_T_I4, &test_type, NULL);
  637. statistic = 0;
  638. //sp_dbg_debug("handle test entity req: %d", entity_id);
  639. result = sp_mod_mgr_test_entity(env->mod_mgr, entity_id, svc_id, test_type, &statistic);
  640. ans_pkt = iobuffer_create(-1, -1);
  641. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  642. iobuffer_write(ans_pkt, IOBUF_T_I4, &statistic, 0);
  643. return ans_pkt;
  644. }
  645. iobuffer_t *on_entity_termination(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  646. {
  647. sp_env_t *env = sp_get_env();
  648. int entity_id;
  649. int result;
  650. iobuffer_t *ans_pkt = NULL;
  651. iobuffer_read(*req_pkt, IOBUF_T_I4, &entity_id, NULL);
  652. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("handle terminate entity req: %d", entity_id);
  653. result = sp_mod_mgr_terminate_entity(env->mod_mgr, entity_id, svc_id);
  654. ans_pkt = iobuffer_create(-1, -1);
  655. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  656. return ans_pkt;
  657. }
  658. iobuffer_t *on_get_bcast_receiver(sp_rpc_server_t *server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt)
  659. {
  660. sp_env_t *env = sp_get_env();
  661. iobuffer_t *ans_pkt = NULL;
  662. int result = 0;
  663. int i;
  664. array_header_t *arr = sp_bcm_daemon_get_receiver(get_app_instance()->bcm_daemon, svc_id);
  665. ans_pkt = iobuffer_create(-1, -1);
  666. iobuffer_write(ans_pkt, IOBUF_T_I4, &result, 0);
  667. iobuffer_write(ans_pkt, IOBUF_T_I4, &arr->nelts, 0);
  668. for (i = 0; i < arr->nelts; ++i) {
  669. sp_bcm_receiver_t *recver = ARRAY_IDX(arr, i, sp_bcm_receiver_t*);
  670. iobuffer_write(ans_pkt, IOBUF_T_I8, &recver->id, 0);
  671. iobuffer_write(ans_pkt, IOBUF_T_I4, &recver->receiver_id, 0);
  672. iobuffer_write(ans_pkt, IOBUF_T_STR, &recver->param, -1);
  673. }
  674. sp_bcm_daemon_free_receiver_array(arr);
  675. return ans_pkt;
  676. }
  677. iobuffer_t* on_try_update_VTMERRMSG(sp_rpc_server_t* server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t** req_pkt)
  678. {
  679. iobuffer_t* ans_pkt = iobuffer_create(-1, -1);
  680. auto ret = sp_TryUpdate_vtm_err_msg();
  681. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret, 0);//需要sysError和UserError
  682. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret, 0);
  683. return ans_pkt;
  684. }
  685. iobuffer_t* on_try_update_cfg(sp_rpc_server_t* server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t** req_pkt)
  686. {
  687. iobuffer_t* ans_pkt = iobuffer_create(-1, -1);
  688. auto ret = sp_TryUpdateCfg();
  689. int rc = Error_Succeed;
  690. sp_mod_mgr_init(sp_get_env()->mod_mgr);
  691. //add workitem daemon_on_pkt and daemon_on_sys
  692. if (0 != (rc = sp_var_daemon_create(get_app_instance()->svc, &get_app_instance()->var_daemon)))
  693. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("var daemon create failed!");
  694. else
  695. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("var daemon create ok!");
  696. if (0 != (rc = sp_bcm_daemon_create(get_app_instance()->svc, &get_app_instance()->bcm_daemon)))
  697. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("bcm daemon create failed!");
  698. else
  699. DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("bcm daemon create ok!");
  700. sp_mod_mgr_bind_bcm_daemon(sp_get_env()->mod_mgr, get_app_instance()->bcm_daemon);
  701. auto env = sp_get_env();
  702. if (!env)
  703. {
  704. rc = Error_Unexpect;
  705. DbgWithLink(LOG_LEVEL_ERROR, LOG_TYPE_SYSTEM)("on_try_update_cfg env error");
  706. }
  707. else
  708. set_ld_library_path(env);
  709. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret, 0);//需要sysError和UserError
  710. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret, 0);
  711. return ans_pkt;
  712. }
  713. iobuffer_t* on_write_terminalNo(sp_rpc_server_t* server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t** req_pkt)
  714. {
  715. iobuffer_t* ans_pkt = iobuffer_create(-1, -1);
  716. char* terminalNo = NULL;
  717. iobuffer_format_read(*req_pkt, "s", &terminalNo);
  718. std::string t_terminalNo = terminalNo;
  719. FREE(terminalNo);
  720. auto env = sp_get_env();
  721. auto cfg = env->cfg;
  722. CSimpleStringA strRootPath = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "%s", env->dir->root_hardwarecfg_path, "root.ini");
  723. int nRet = inifile_format_write((const char*)strRootPath, "Terminal", "TerminalNo", t_terminalNo.c_str());
  724. iobuffer_write(ans_pkt, IOBUF_T_I4, &nRet, 0);//需要sysError和UserError
  725. iobuffer_write(ans_pkt, IOBUF_T_I4, &nRet, 0);
  726. return ans_pkt;
  727. }
  728. iobuffer_t* on_modify_mem_cfg(sp_rpc_server_t* server, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t** req_pkt)
  729. {
  730. iobuffer_t* ans_pkt = iobuffer_create(-1, -1);
  731. char *configType = NULL, * module = NULL, *name = NULL, *value = NULL;
  732. std::shared_ptr<void> delHandleFun((void*)0, [&](void*) {
  733. if (configType)
  734. FREE(configType);
  735. if (module)
  736. FREE(module);
  737. if (name)
  738. FREE(name);
  739. if (value)
  740. FREE(value);
  741. });
  742. iobuffer_format_read(*req_pkt, "s", &configType);
  743. iobuffer_format_read(*req_pkt, "s", &module);
  744. iobuffer_format_read(*req_pkt, "s", &name);
  745. iobuffer_format_read(*req_pkt, "s", &value);
  746. auto nRet = sp_ModifyMemCfg(configType, module, name, value);
  747. iobuffer_write(ans_pkt, IOBUF_T_I4, &nRet, 0);//需要sysError和UserError
  748. iobuffer_write(ans_pkt, IOBUF_T_I4, &nRet, 0);
  749. return ans_pkt;
  750. }