SpEntity.cpp 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026
  1. #include "stdafx.h"
  2. #include "SpBase.h"
  3. #include "SpTimer.h"
  4. #include "SpMisc.h"
  5. #include "SpBinaryPersistStream.h"
  6. #include "SpEntity.h"
  7. #include "SpModule.h"
  8. #include "SpAsyncWait.h"
  9. #include "SpClientSessionFunction.h"
  10. #include "SpServerSessionFunction.h"
  11. #include "sp_iom.h"
  12. #include "sp_svc.h"
  13. #include "sp_dbg_export.h"
  14. #include "sp_log.h"
  15. #include "sp_var.h"
  16. #include "sp_def.h"
  17. #include "sp_cfg.h"
  18. #include "sp_env.h"
  19. #include "sp_btr.h"
  20. #include "memutil.h"
  21. #include "strutil.h"
  22. #include "fileutil.h"
  23. #include "shm_array.h"
  24. #include "def.h"
  25. #ifdef _WIN32
  26. #include "CodeSignVerify.h"
  27. #include "sp_checkEntity.h"
  28. #endif //_WIN32
  29. static void var_callback(sp_var_listener_t *listener,
  30. const char *key,
  31. const char *oldstr,
  32. const char *newstr,
  33. int client_id,
  34. void *user_data)
  35. {
  36. ISysVarListener *pListener = (ISysVarListener *)user_data;
  37. SpEntity *pEntity = (SpEntity*)sp_var_listener_get_tag(listener);
  38. #ifdef _WIN32
  39. SetthreadGroup(GetCurrentThreadId(), pEntity->get_cfg_ent()->name);
  40. getEntityResource()->m_Entity = pEntity;
  41. #else
  42. GetSpModule()->SetThreadEntity(pEntity);
  43. #endif //_WIN32
  44. sp_env_t *env = sp_get_env();
  45. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, client_id);
  46. if (ent) {
  47. if(strcmp(VAR_RSERVERD_KEY_TERM_STATE, key) != 0)
  48. pListener->OnSysVarEvent(key, newstr, oldstr, ent->cfg->name);
  49. else {
  50. FrameworkStateEnum oldState = static_cast<FrameworkStateEnum>(atoi(oldstr));
  51. FrameworkStateEnum newState = static_cast<FrameworkStateEnum>(atoi(newstr));
  52. (static_cast<ITerminalStateChangedListener*>(user_data))->OnStateChanged(oldState, newState, ent->cfg->name);
  53. }
  54. }
  55. else {
  56. sp_dbg_warn("cannot found the entity by id: %d", client_id);
  57. }
  58. }
  59. static void bcm_callback(sp_bcm_listener_t *listener,
  60. int from_client_id,
  61. int message_id,
  62. int message_sig,
  63. const void *buf,
  64. int len,
  65. void *user_data)
  66. {
  67. IBroadcastListener *pListener = (IBroadcastListener *)user_data;
  68. SpEntity *pEntity = (SpEntity*)sp_bcm_listener_get_tag(listener);
  69. sp_uid_t uid;
  70. #ifdef _WIN32
  71. SetthreadGroup(GetCurrentThreadId(), pEntity->get_cfg_ent()->name);
  72. getEntityResource()->m_Entity = pEntity;
  73. #else
  74. GetSpModule()->SetThreadEntity(pEntity);
  75. #endif //_WIN32
  76. sp_bcm_listener_get_uid(listener, &uid);
  77. sp_env_t *env = sp_get_env();
  78. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, from_client_id);
  79. if (ent) {
  80. CAutoBuffer Buf;
  81. Buf.Init(len);
  82. if (len > 0) {
  83. memcpy(&Buf[0], buf, len);
  84. }
  85. pListener->OnBroadcastEvent(CUUID(uid), ent->cfg->name, (DWORD)message_id, (DWORD)message_sig, Buf);
  86. }
  87. }
  88. static void on_log(void *inst,
  89. int nsub,
  90. u__int64_t *sub,
  91. int client_id,
  92. int log_epid,
  93. int client_instance_id,
  94. u__int64_t log_id,
  95. u__int64_t prev_rsn,
  96. u__int64_t curr_rsn,
  97. int original_rsn_type,
  98. int rsn_depth,
  99. unsigned int log_time,
  100. int log_type,
  101. int log_severity,
  102. int log_sys_error,
  103. int log_usr_error,
  104. int param_cnt,
  105. int *params,
  106. const char *msg,
  107. void *user_data)
  108. {
  109. try
  110. {
  111. ILogListener *pListener = (ILogListener *)user_data;
  112. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, client_id);
  113. if (ent) {
  114. int i;
  115. CAutoArray<DWORD> arr;
  116. arr.Init(param_cnt);
  117. for (i = 0; i < param_cnt; ++i) {
  118. arr[i] = (DWORD)params[i];
  119. }
  120. CAutoArray<CUUID> subIDs;
  121. subIDs.Init(nsub);
  122. CUUID *pSub = (CUUID*)sub;
  123. for (i = 0; i < nsub; i++)
  124. subIDs[i] = pSub[i];
  125. pListener->OnLog(subIDs,
  126. CUUID(log_id), (LogTypeEnum)log_type, (SeverityLevelEnum)log_severity, log_sys_error, log_usr_error,
  127. ent->instance_id, ent->cfg->devel_id,
  128. arr, ent->cfg->name, ent->mod->cfg->name, msg);
  129. }
  130. }
  131. catch (const std::exception&)
  132. {
  133. }
  134. }
  135. static void task_callback(threadpool_t *threadpool, void *arg, param_size_t param1, param_size_t param2)
  136. {
  137. ITaskSp *pTask = (ITaskSp*)arg;
  138. SpEntity *pEntity = (SpEntity*)param1;
  139. //Dbg("task_callback pTask = %08x", pTask);
  140. #ifdef _WIN32
  141. SetthreadGroup(GetCurrentThreadId(), pEntity->GetEntityBase()->GetEntityName());
  142. try {
  143. getEntityResource()->m_Entity = pEntity;
  144. pTask->Process();
  145. pTask->DecRef();
  146. }
  147. catch (...) {
  148. }
  149. #else
  150. GetSpModule()->SetThreadEntity(pEntity);
  151. #endif //_WIN32
  152. }
  153. static void tpool_log(threadpool_t *threadpool, const char* str)
  154. {
  155. sp_dbg_debug(str);
  156. }
  157. static ErrorCodeEnum GetEntityStaticInfo(CEntityStaticInfo &Info, sp_entity_t *ent)
  158. {
  159. sp_env_t *env = sp_get_env();
  160. if (ent) {
  161. bool bStartedByShell = false;
  162. for (int i = 0; i < env->cfg->shell_ini->arr_startlist->nelts; ++i) {
  163. sp_cfg_shell_entity_t * tmp_ent = ARRAY_IDX(env->cfg->shell_ini->arr_startlist, i, sp_cfg_shell_entity_t*);
  164. if (tmp_ent->idx == ent->cfg->idx) {
  165. bStartedByShell = true;
  166. break;
  167. }
  168. }
  169. Info.wEntityDevelopID = ent->cfg->devel_id;
  170. Info.strSpFileName = ent->mod->cfg->name;
  171. Info.bStartedByShell = bStartedByShell;
  172. Info.bIndispensable = true;
  173. Info.bHasPrivilege = !!ent->cfg->privilege;
  174. } else {
  175. return Error_NotExist;
  176. }
  177. return Error_Succeed;
  178. }
  179. SpEntity::SpEntity(SpModule *pModule, sp_entity_t *ent, sp_cfg_shell_entity_t *cfg_ent, CEntityBase *pEntityBase)
  180. : m_pModule(pModule), m_pEntityBase(pEntityBase), m_pTimerList(NULL), m_svc(NULL), m_var_client(NULL), m_log_client(NULL),
  181. m_ent(ent), m_cfg_ent(cfg_ent), m_tbs(NULL), m_bcm_client(NULL), m_arr_any_var(NULL), m_arr_bcm_listener(NULL), m_log_mgr(NULL)
  182. {
  183. m_ent->service_flag = m_pEntityBase->IsService() ? 1 : 0;
  184. memset(&m_arr_var[0], 0, sizeof(m_arr_var));
  185. }
  186. SpEntity::~SpEntity()
  187. {
  188. Dbg("run ~SpEntity()");
  189. #ifdef _WIN32
  190. getEntityResource()->m_Entity = NULL;
  191. #endif //_WIN32
  192. }
  193. ErrorCodeEnum SpEntity::Init()
  194. {
  195. sp_mod_entity_stub_cb cb;
  196. int rc;
  197. threadpool_t *threadpool;
  198. rc = sp_svc_create(m_pModule->get_iom(), 0, m_ent->cfg->idx,m_ent->cfg->devel_id, &m_svc); //threadpool
  199. if (rc != 0) {
  200. sp_dbg_warn("create svc failed!");
  201. return SpTranslateError(rc);
  202. }
  203. sp_dbg_info("create svc ok!");
  204. threadpool = sp_svc_get_threadpool(m_svc);
  205. threadpool_set_thread_decorator(threadpool, &SpEntity::__on_thread_init, &SpEntity::__on_thread_term, this); //Entity thread
  206. threadpool_create(&m_tpool);
  207. threadpool_set_log(m_tpool, &tpool_log);
  208. threadpool_set_thread_decorator(m_tpool, &SpEntity::__on_thread_init, &SpEntity::__on_thread_term, this);
  209. threadpool_start(m_tpool, 0, 64, 5*60*1000, 0);
  210. #ifdef _WIN32
  211. setModuleAliasName(GetEntityBase()->GetEntityName());
  212. #endif //_WIN32
  213. rc = sp_svc_start(m_svc);
  214. if (rc != 0) {
  215. sp_dbg_warn("start svc failed!");
  216. return SpTranslateError(rc);
  217. }
  218. sp_dbg_info("start svc ok!");
  219. m_pTimerList = SpTimerListCreate(this);
  220. if (!m_pTimerList) {
  221. sp_dbg_warn("create timer list failed!");
  222. return Error_Unexpect;
  223. }
  224. cb.on_entity_prestart = &SpEntity::__on_entity_prestart;
  225. cb.on_entity_stop = &SpEntity::__on_entity_stop;
  226. cb.on_entity_prepause = &SpEntity::__on_entity_prepause;
  227. cb.on_entity_test = &SpEntity::__on_entity_test;
  228. cb.on_entity_precontinue = &SpEntity::__on_entity_precontinue;
  229. cb.on_entity_redirect_subscribe = &SpEntity::__on_entity_redirect_subscribe;
  230. cb.user_data = this;
  231. rc = sp_mod_entity_stub_create(&cb, m_svc, &m_stub); //add a workItem mod_entity_on_pkt
  232. if (rc != 0) {
  233. sp_dbg_warn("create entity stub failed!");
  234. return SpTranslateError(rc);
  235. }
  236. sp_dbg_info("start entity stub ok!");
  237. sp_rpc_client_mgr_callback mgr_cb = {SpEntity::__on_rpc_request, NULL, this};
  238. rc = sp_rpc_client_mgr_create(m_svc, &mgr_cb, &m_rpc_mgr); //Init variable m_rpc_mgr, callback handle
  239. if (rc != 0) {
  240. sp_dbg_warn("create rpc client mgr failed!");
  241. return SpTranslateError(rc);
  242. }
  243. rc = sp_rpc_client_mgr_start(m_rpc_mgr); //add workItem mgr_on_pkt and mgr_on_sys
  244. if (rc != 0) {
  245. sp_dbg_warn("start rpc client mgr failed!");
  246. return SpTranslateError(rc);
  247. }
  248. sp_dbg_info("start rpc client ok!");
  249. sp_ses_mgr_callback_t ses_mgr_cb = {0};
  250. ses_mgr_cb.on_accept = &__on_accept;
  251. ses_mgr_cb.on_destroy = NULL;
  252. ses_mgr_cb.user_data = this;
  253. rc = sp_ses_mgr_create(m_svc, &ses_mgr_cb, &m_ses_mgr); //Init variable m_ses_mgr
  254. if (rc != 0) {
  255. sp_dbg_warn("create ses mgr failed!");
  256. return SpTranslateError(rc);
  257. }
  258. rc = sp_ses_mgr_start(m_ses_mgr); //add workItem mgr_on_pkt and mgr_on_sys
  259. if (rc != 0) {
  260. sp_dbg_warn("start ses mgr failed!");
  261. return SpTranslateError(rc);
  262. }
  263. sp_dbg_info("start ses mgr ok!");
  264. rc = sp_log_client_create(m_svc, m_pModule->get_iom(), &m_log_client);
  265. if (rc != 0) {
  266. sp_dbg_warn("create log client failed!");
  267. return SpTranslateError(rc);
  268. }
  269. sp_dbg_info("start entity log client ok!");
  270. rc = sp_var_client_create(m_svc, &m_var_client);
  271. if (rc != 0) {
  272. sp_dbg_warn("create var client failed!");
  273. return SpTranslateError(rc);
  274. }
  275. sp_dbg_info("create var client ok!");
  276. rc = sp_bcm_client_create(m_svc, &m_bcm_client);
  277. if (rc != 0) {
  278. sp_dbg_warn("create bcm client failed!");
  279. return SpTranslateError(rc);
  280. }
  281. sp_dbg_warn("create bcm client ok!");
  282. rc = sp_log_listener_mgr_create(m_svc, on_log, &m_log_mgr);
  283. if (rc == 0) {
  284. rc = sp_log_listener_mgr_start(m_log_mgr);
  285. if (rc != 0) {
  286. sp_dbg_warn("create log mgr failed!");
  287. return SpTranslateError(rc);
  288. }
  289. }
  290. sp_dbg_warn("create log mgr ok!");
  291. m_arr_bcm_listener = array_make(0, sizeof(sp_bcm_listener_t*));
  292. return SpTranslateError(rc);
  293. }
  294. void SpEntity::Term()
  295. {
  296. SpTimerListStopAll(m_pTimerList);
  297. }
  298. void SpEntity::on_entity_prestart(int trigger_entity_id, int argc, char *argv[])
  299. {
  300. CAutoArray<CSimpleStringA> Args;
  301. Args.Init(argc);
  302. CSmartPointer<ITransactionContext> pTransactionContext;
  303. pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_START));
  304. for (int i = 0; i < argc; ++i)
  305. Args[i] = argv[i];
  306. m_pEntityBase->OnPreStart(Args, pTransactionContext);
  307. }
  308. void SpEntity::on_entity_stop(int trigger_entity_id, int cause_code)
  309. {
  310. CSmartPointer<ITransactionContext> pTransactionContext;
  311. pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_CLOSE));
  312. m_pEntityBase->OnPreClose((EntityCloseCauseEnum)cause_code, pTransactionContext);
  313. }
  314. void SpEntity::on_entity_prepause(int trigger_entity_id)
  315. {
  316. CSmartPointer<ITransactionContext> pTransactionContext;
  317. pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_PAUSE));
  318. m_pEntityBase->OnPrePause(pTransactionContext);
  319. }
  320. void SpEntity::on_entity_precontinue(int trigger_entity_id)
  321. {
  322. CSmartPointer<ITransactionContext> pTransactionContext;
  323. pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_CONTINUE));
  324. m_pEntityBase->OnPreContinue(pTransactionContext);
  325. }
  326. void SpEntity::on_entity_test(int trigger_entity_id, int test_type)
  327. {
  328. CSmartPointer<ITransactionContext> pTransactionContext;
  329. pTransactionContext.Attach(new SpMUITransactionContext(this, SpMUITransactionContext::OP_SELFTEST));
  330. m_pEntityBase->OnSelfTest((EntityTestEnum)test_type, pTransactionContext);
  331. }
  332. void SpEntity::on_entity_redirect_subscribe(sp_uid_t *uid, int from_entity_id, const char *param)
  333. {
  334. CUUID id(*uid);
  335. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(sp_get_env()->mod_mgr, from_entity_id);
  336. if (ent) {
  337. m_pEntityBase->OnBroadcastSubscribe(id, ent->cfg->name, param);
  338. }
  339. }
  340. void SpEntity::__on_entity_prestart(sp_mod_entity_stub_t *, int trigger_entity_id, int argc, char *argv[], void *user_data)
  341. {
  342. sp_dbg_debug("==> %s", __FUNCTION__);
  343. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  344. pThis->on_entity_prestart(trigger_entity_id, argc, argv);
  345. sp_dbg_debug("<== %s", __FUNCTION__);
  346. }
  347. void SpEntity::__on_entity_stop(sp_mod_entity_stub_t *, int trigger_entity_id, int cause_code, void *user_data)
  348. {
  349. Dbg("stop Entity");
  350. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  351. pThis->on_entity_stop(trigger_entity_id, cause_code);
  352. }
  353. void SpEntity::__on_entity_prepause(sp_mod_entity_stub_t *, int trigger_entity_id, void *user_data)
  354. {
  355. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  356. pThis->on_entity_prepause(trigger_entity_id);
  357. }
  358. void SpEntity::__on_entity_precontinue(sp_mod_entity_stub_t *, int trigger_entity_id, void *user_data)
  359. {
  360. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  361. pThis->on_entity_precontinue(trigger_entity_id);
  362. }
  363. void SpEntity::__on_entity_test(sp_mod_entity_stub_t *, int trigger_entity_id, int test_type, void *user_data)
  364. {
  365. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  366. pThis->on_entity_test(trigger_entity_id, test_type);
  367. }
  368. void SpEntity::__on_entity_redirect_subscribe(sp_mod_entity_stub_t *, sp_uid_t *uid, int from_entity_id, const char *param, void *user_data)
  369. {
  370. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  371. pThis->on_entity_redirect_subscribe(uid, from_entity_id, param);
  372. }
  373. int SpEntity::__on_accept(sp_ses_mgr_t *mgr, int epid, int svc_id, int conn_id, iobuffer_t **conn_pkt, int *redirect_entity_id, void *user_data)
  374. {
  375. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  376. return pThis->on_accept(epid, svc_id, conn_id, conn_pkt, redirect_entity_id);
  377. }
  378. int SpEntity::on_accept(int epid, int svc_id, int conn_id, iobuffer_t **conn_pkt, int *redirect_entity_id)
  379. {
  380. sp_env_t *env = sp_get_env();
  381. ErrorCodeEnum Error = Error_Succeed;
  382. if (!m_pEntityBase->IsService()) {
  383. sp_dbg_warn("current entity is no registed as service type, please confirm it at code scope.");
  384. return Error_Bug;
  385. }
  386. sp_entity_t *remote_ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, svc_id);
  387. if (!remote_ent) {
  388. sp_dbg_error("cannot recognize the customer entity: %d!", svc_id);
  389. return Error_Bug;
  390. }
  391. char *pszParam = NULL;
  392. CServerSessionBase *pServerSessionBase = NULL;
  393. iobuffer_format_read(*conn_pkt, "s", &pszParam);
  394. try {
  395. m_redirect_entity_cache = NULL; // user can set entity_cache value in OnNewSession by invoking RedirectSession method
  396. pServerSessionBase = m_pEntityBase->OnNewSession(remote_ent->cfg->name, pszParam);
  397. } catch (...) {
  398. Error = Error_Exception;
  399. }
  400. toolkit_free(pszParam);
  401. if (pServerSessionBase)
  402. {
  403. SpServerSessionFunction *pServerSessionFunction = new SpServerSessionFunction(this, pServerSessionBase, epid, svc_id, conn_id);
  404. pServerSessionBase->m_pSessionFunction = pServerSessionFunction;
  405. Error = pServerSessionFunction->Begin();
  406. if (Error != Error_Succeed)
  407. {
  408. delete pServerSessionBase; // this will also delete pServerSessionFunction
  409. }
  410. }
  411. else
  412. {
  413. if (m_redirect_entity_cache)
  414. {
  415. *redirect_entity_id = m_redirect_entity_cache->cfg->idx;
  416. Error = Error_Redirect;
  417. }
  418. else
  419. {
  420. Error = Error_NotImpl;
  421. }
  422. }
  423. return Error;
  424. }
  425. void SpEntity::on_thread_init()
  426. {
  427. #ifdef _WIN32
  428. SetthreadGroup(GetCurrentThreadId(), this->get_cfg_ent()->name);
  429. getEntityResource()->m_Entity = this;
  430. #else
  431. m_pModule->SetThreadEntity(this);
  432. #endif //_WIN32
  433. }
  434. void SpEntity::on_thread_term()
  435. {
  436. #ifdef _WIN32
  437. SetthreadGroup(GetCurrentThreadId(), this->get_cfg_ent()->name);
  438. getEntityResource()->m_Entity = NULL;
  439. #else
  440. m_pModule->SetThreadEntity(NULL);
  441. #endif //_WIN32
  442. }
  443. void SpEntity::__on_thread_init(threadpool_t *, void *arg)
  444. {
  445. SpEntity *pThis = static_cast<SpEntity*>(arg);
  446. pThis->on_thread_init();
  447. sp_dbg_debug("thread init, thread id:%d", GetCurrentThreadId());
  448. }
  449. void SpEntity::__on_thread_term(threadpool_t *, void *arg)
  450. {
  451. SpEntity *pThis = static_cast<SpEntity*>(arg);
  452. pThis->on_thread_term();
  453. sp_dbg_debug("thread term, thread id:%d", GetCurrentThreadId());
  454. }
  455. ErrorCodeEnum SpEntity::SetTimer(DWORD nTimerID, ITimerListener *pListener, DWORD dwInterval)
  456. {
  457. ErrorCodeEnum Error = Error_Succeed;
  458. if (!pListener)
  459. return Error_Param;
  460. SpTimerListLock(m_pTimerList);
  461. if (SpTimerListFind(m_pTimerList, nTimerID)) {
  462. sp_dbg_warn("timer id %d already in use!", nTimerID);
  463. Error = Error_AlreadyExist;
  464. } else {
  465. SpTimer *pTimer = SpTimerCreate(m_pTimerList, nTimerID, dwInterval, pListener);
  466. if (pTimer) {
  467. SpTimerListAdd(m_pTimerList, pTimer);
  468. Error = SpTimerStart(pTimer);
  469. if (Error) {
  470. SpTimerListRemove(m_pTimerList, pTimer);
  471. SpTimerDestroy(pTimer);
  472. sp_dbg_warn("start timer %d failed: %d!", nTimerID, Error);
  473. } else {
  474. sp_dbg_info("timer %d added! interval = %d", nTimerID, dwInterval);
  475. }
  476. } else {
  477. Error = Error_Unexpect;
  478. }
  479. }
  480. SpTimerListUnlock(m_pTimerList);
  481. return Error;
  482. }
  483. ErrorCodeEnum SpEntity::SetTimerData(DWORD dwTimerID, IReleasable *pData)
  484. {
  485. ErrorCodeEnum Error = Error_Succeed;
  486. SpTimerListLock(m_pTimerList);
  487. SpTimer *pTimer = SpTimerListFind(m_pTimerList, dwTimerID);
  488. if (pTimer) {
  489. SpTimerSetUserData(pTimer, pData);
  490. } else {
  491. sp_dbg_warn("timer %d not found!", dwTimerID);
  492. Error = Error_NotExist;
  493. }
  494. SpTimerListUnlock(m_pTimerList);
  495. return Error;
  496. }
  497. ErrorCodeEnum SpEntity::GetTimerData(DWORD dwTimerID, CSmartPointer<IReleasable> &pData)
  498. {
  499. ErrorCodeEnum Error = Error_Succeed;
  500. SpTimerListLock(m_pTimerList);
  501. SpTimer *pTimer = SpTimerListFind(m_pTimerList, dwTimerID);
  502. if (pTimer) {
  503. SpTimerGetUserData(pTimer, pData);
  504. } else {
  505. sp_dbg_warn("timer %d not found!", dwTimerID);
  506. Error = Error_NotExist;
  507. }
  508. SpTimerListUnlock(m_pTimerList);
  509. return Error;
  510. }
  511. ErrorCodeEnum SpEntity::KillTimer(DWORD nTimerID)
  512. {
  513. ErrorCodeEnum Error = Error_Succeed;
  514. SpTimerListLock(m_pTimerList);
  515. SpTimer *pTimer = SpTimerListFind(m_pTimerList, nTimerID);
  516. if (pTimer) {
  517. sp_dbg_info("timer %d killed!", nTimerID);
  518. SpTimerListRemove(m_pTimerList, pTimer);
  519. SpTimerStop(pTimer);
  520. SpTimerDestroy(pTimer);
  521. } else {
  522. sp_dbg_warn("timer %d has not set!", nTimerID);
  523. Error = Error_NotExist;
  524. }
  525. SpTimerListUnlock(m_pTimerList);
  526. return Error;
  527. }
  528. ErrorCodeEnum SpEntity::ResetTimer(DWORD nTimerID, DWORD dwInterval)
  529. {
  530. ErrorCodeEnum Error = Error_Succeed;
  531. SpTimerListLock(m_pTimerList);
  532. SpTimer *pTimer = SpTimerListFind(m_pTimerList, nTimerID);
  533. if (pTimer) {
  534. SpTimerSetInterval(pTimer, dwInterval);
  535. } else {
  536. sp_dbg_warn("timer %d has not set!", nTimerID);
  537. Error = Error_NotExist;
  538. }
  539. SpTimerListUnlock(m_pTimerList);
  540. return Error;
  541. }
  542. ErrorCodeEnum SpEntity::GetTimerInterval(DWORD nTimerID, DWORD &dwInterval)
  543. {
  544. ErrorCodeEnum Error = Error_Succeed;
  545. SpTimerListLock(m_pTimerList);
  546. SpTimer *pTimer = SpTimerListFind(m_pTimerList, nTimerID);
  547. if (pTimer) {
  548. dwInterval = SpTimerGetInterval(pTimer);
  549. } else {
  550. sp_dbg_warn("timer %d has not set!", nTimerID);
  551. Error = Error_NotExist;
  552. }
  553. SpTimerListUnlock(m_pTimerList);
  554. return Error;
  555. }
  556. ErrorCodeEnum SpEntity::ReadPersistObject(const char *pszClass, const char *pszKey, IEntityPersistObject *pInstance)
  557. {
  558. sp_env_t *env = sp_get_env();
  559. sp_pst_tree_t *tree;
  560. int rc;
  561. if (!pszClass || !pszKey || !pInstance)
  562. return Error_Param;
  563. rc = sp_pst_tree_load(env->dir->obj_path, m_ent->cfg->name, pszClass, pszKey, &tree);
  564. if (rc == 0) {
  565. sp_pst_elem_t *root = sp_pst_tree_get_root(tree);
  566. CSmartPointer<IEntityPersistStreamRead> pStream;
  567. pStream.Attach(new SpBinaryPersistStream(SpBinaryPersistStream::Read, root));
  568. rc = (int)pInstance->OnRead(pStream);
  569. sp_pst_tree_destroy(tree);
  570. }
  571. return SpTranslateError(rc);
  572. }
  573. ErrorCodeEnum SpEntity::WritePersistObject(const char *pszClass, const char *pszKey, const IEntityPersistObject *pInstance)
  574. {
  575. sp_env_t *env = sp_get_env();
  576. sp_pst_elem_t *root;
  577. int rc;
  578. if (!pszClass || !pszKey || !pInstance)
  579. return Error_Param;
  580. root = sp_pst_elem_create(NULL, pszKey);
  581. CSmartPointer<IEntityPersistStreamWrite> pStream;
  582. pStream.Attach(new SpBinaryPersistStream(SpBinaryPersistStream::Write, root));
  583. rc = (int)pInstance->OnWrite(pStream);
  584. if (rc == 0) {
  585. sp_pst_tree_t *tree;
  586. sp_pst_tree_create(&tree);
  587. sp_pst_tree_set_root(tree, root);
  588. rc = sp_pst_tree_save(env->dir->obj_path, m_ent->cfg->name, pszClass, pszKey, tree);
  589. sp_pst_tree_destroy(tree);
  590. } else {
  591. sp_pst_elem_destroy(root);
  592. }
  593. return SpTranslateError(rc);
  594. }
  595. ErrorCodeEnum SpEntity::ReadNumOfPersistObject(const char *pszClassName,DWORD &nNum)
  596. {
  597. if (!pszClassName)
  598. return Error_Param;
  599. sp_env_t *env = sp_get_env();
  600. int cnt;
  601. int rc = sp_pst_get_object_count(env->dir->obj_path, m_ent->cfg->name, pszClassName, &cnt);
  602. if (rc == 0)
  603. //nNum = (DWORD)rc; // {bug}
  604. nNum = (DWORD)cnt;
  605. return SpTranslateError(rc);
  606. }
  607. ErrorCodeEnum SpEntity::GetPersistClassObjectKeys(const char *pszClassName, CAutoArray<CSimpleStringA> &strKeys)
  608. {
  609. if (!pszClassName)
  610. return Error_Param;
  611. sp_env_t *env = sp_get_env();
  612. array_header_t *arr = sp_pst_get_object_keys(env->dir->obj_path, m_ent->cfg->name, pszClassName);
  613. if (arr) {
  614. strKeys.Init(arr->nelts);
  615. for (int i = 0; i < arr->nelts; ++i)
  616. strKeys[i] = ARRAY_IDX(arr, i, char*);
  617. array_free2(arr);
  618. } else {
  619. strKeys.Init(0);
  620. }
  621. return Error_Succeed;
  622. }
  623. ErrorCodeEnum SpEntity::DeleteKeyOfPersistObject(const char *pszClassName,const char *pszKey)
  624. {
  625. if (!pszClassName || !pszKey)
  626. return Error_Param;
  627. sp_env_t *env = sp_get_env();
  628. int rc = sp_pst_delete_object(env->dir->obj_path, m_ent->cfg->name, pszClassName, pszKey);
  629. return SpTranslateError(rc);
  630. }
  631. ErrorCodeEnum SpEntity::EnumKeyOfPersistObject(const char *pszClass,CSimpleStringA &strKey,DWORD &handle)
  632. {
  633. if (!pszClass)
  634. return Error_Param;
  635. int rc = 0;
  636. sp_env_t *env = sp_get_env();
  637. struct HelperIterator {
  638. array_header_t *arr;
  639. int Current;
  640. } * pIterator = NULL;
  641. if (handle == 0) {
  642. pIterator = new HelperIterator();
  643. pIterator->arr = sp_pst_get_object_keys(env->dir->obj_path, m_ent->cfg->name, pszClass);
  644. if (!pIterator->arr) {
  645. delete pIterator;
  646. return Error_NotExist;
  647. }
  648. pIterator->Current = 0;
  649. //TODO: x64 environment, depend on how to use the out-param
  650. handle = (uintptr_t)(static_cast<void*>(pIterator));
  651. //Handle = (DWORD)pIterator;
  652. } else {
  653. pIterator = (HelperIterator *)handle;
  654. }
  655. if (pIterator->Current < pIterator->arr->nelts) {
  656. strKey = ARRAY_IDX(pIterator->arr, pIterator->Current, char*);
  657. pIterator->Current++;
  658. } else {
  659. if (pIterator->arr)
  660. array_free2(pIterator->arr);
  661. delete pIterator;
  662. handle = 0; // zero handle
  663. rc = Error_NotExist;// the end
  664. }
  665. return SpTranslateError(rc);
  666. }
  667. ErrorCodeEnum SpEntity::CleanAllOfPersistObject(const char *pszClass)
  668. {
  669. if (!pszClass)
  670. return Error_Param;
  671. sp_env_t *env = sp_get_env();
  672. int rc = sp_pst_delete_class_objects(env->dir->obj_path, m_ent->cfg->name, pszClass);
  673. return SpTranslateError(rc);
  674. }
  675. ErrorCodeEnum SpEntity::SubscribeLog(CUUID &SubscribeID, ILogListener *pListener,LogTypeEnum eLogType,SeverityLevelEnum eLevel,
  676. ErrorCodeEnum eSysError,DWORD dwUserCode,const char *pszEntityName,bool bIgnoreMessage)
  677. {
  678. _ASSERT(pListener);
  679. sp_entity_t *ent = NULL;
  680. if (pszEntityName) {
  681. ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszEntityName);
  682. if (!ent) {
  683. sp_dbg_error("SubscribeLog failed! Entity %s not exist!", pszEntityName);
  684. return Error_NotExist;
  685. }
  686. }
  687. unsigned int listen_id = 0;
  688. int rc = sp_log_listener_mgr_subscribe(m_log_mgr, &listen_id, pListener, !!bIgnoreMessage,
  689. eLogType, ent ? ent->cfg->idx : -1, eLevel, eSysError, dwUserCode);
  690. if (rc == 0) {
  691. SubscribeID = listen_id;
  692. }
  693. return SpTranslateError(rc);
  694. }
  695. ErrorCodeEnum SpEntity::UnsubscribeLog(CUUID SubscribeID)
  696. {
  697. unsigned int listen_id = (unsigned int)SubscribeID;
  698. int rc = sp_log_listener_mgr_unsubscribe(m_log_mgr, listen_id);
  699. return SpTranslateError(rc);
  700. }
  701. ErrorCodeEnum SpEntity::FlushLogFile()
  702. {
  703. return LogFlush();
  704. }
  705. ErrorCodeEnum SpEntity::SetSysVar(const char *pszKey,const char *pszValue, bool bPersist)
  706. {
  707. int rc;
  708. _ASSERT(pszValue); // pszValue can be null, use for delete
  709. rc = sp_var_client_set((sp_var_client_t*)m_var_client, pszKey, pszValue, bPersist ? 1 : 0);
  710. return SpTranslateError(rc);
  711. }
  712. ErrorCodeEnum SpEntity::GetSysVar(const char *pszKey,CSimpleStringA &strValue)
  713. {
  714. sp_var_client_t* client = (sp_var_client_t*)m_var_client;
  715. int slen = 0;
  716. int rc;
  717. _ASSERT(pszKey);
  718. rc = sp_var_client_lock(client);
  719. if (rc == 0) {
  720. rc = sp_var_client_get(client, pszKey, NULL, &slen);
  721. if (rc == Error_TooSmallBuffer) {
  722. CSimpleStringA strTmp('\0', slen);
  723. rc = sp_var_client_get((sp_var_client_t*)m_var_client, pszKey, &strTmp[0], &slen);
  724. if (rc == 0)
  725. strValue = strTmp;
  726. }
  727. sp_var_client_unlock(client);
  728. }
  729. return SpTranslateError(rc);
  730. }
  731. ErrorCodeEnum SpEntity::RegistSysVarEvent(const char *pszKey,ISysVarListener *pListener)
  732. {
  733. int rc = 0;
  734. if (!pszKey || strlen(pszKey) == 0 || !pListener)
  735. return Error_Param;
  736. sp_env_t *env = sp_get_env();
  737. sp_var_listener_t **pp_var;
  738. //if (strcmp(pszKey, VAR_RSERVERD_KEY_TERM_STATE) == 0)
  739. // return Error_NoPrivilege;
  740. if (strcmp(pszKey, "*") != 0) {
  741. sp_cfg_shell_sysevent_t *sysevent = sp_cfg_get_sysevent(env->cfg, pszKey);
  742. if (!sysevent)
  743. return Error_NotExist;
  744. if (m_arr_var[sysevent->idx])
  745. return Error_Duplication;
  746. pp_var = &m_arr_var[sysevent->idx];
  747. } else {
  748. if (m_arr_any_var)
  749. return Error_Duplication;
  750. pp_var = &m_arr_any_var;
  751. }
  752. sp_var_listener_t *listener;
  753. sp_var_listener_create(m_svc, pszKey, &var_callback, pListener, &listener);
  754. sp_var_listener_set_tag(listener, this);
  755. rc = sp_var_listener_subscribe(listener);
  756. if (rc == 0) {
  757. *pp_var = listener;
  758. } else {
  759. sp_var_listener_destroy(listener);
  760. }
  761. return SpTranslateError(rc);
  762. }
  763. ErrorCodeEnum SpEntity::UnregistSysVarEvent(const char *pszKey)
  764. {
  765. if (!pszKey || strlen(pszKey) == 0)
  766. return Error_Param;
  767. int rc = 0;
  768. //if (strcmp(pszKey, VAR_RSERVERD_KEY_TERM_STATE) == 0)
  769. // return Error_NoPrivilege;
  770. if (strcmp(pszKey, "*") != 0) {
  771. sp_env_t *env = sp_get_env();
  772. sp_cfg_shell_sysevent_t *sysevent = sp_cfg_get_sysevent(env->cfg, pszKey);
  773. if (!sysevent)
  774. return Error_NotExist;
  775. sp_var_listener_t *listener = m_arr_var[sysevent->idx];
  776. if (listener) {
  777. int rc;
  778. rc = sp_var_listener_unsubscribe(listener);
  779. if (rc == 0) {
  780. sp_var_listener_destroy(listener);
  781. m_arr_var[sysevent->idx] = NULL;
  782. }
  783. } else {
  784. rc = Error_NotInit;
  785. }
  786. } else {
  787. if (m_arr_any_var != NULL)
  788. {
  789. rc = sp_var_listener_unsubscribe(m_arr_any_var);
  790. if (rc == 0)
  791. {
  792. sp_var_listener_destroy(m_arr_any_var);
  793. m_arr_any_var = NULL;
  794. }
  795. }
  796. }
  797. return SpTranslateError(rc);
  798. }
  799. ErrorCodeEnum SpEntity::RegistTerminalStateChangeEvent(ITerminalStateChangedListener* pListener)
  800. {
  801. return RegistSysVarEvent(VAR_RSERVERD_KEY_TERM_STATE, (ISysVarListener*)(void*)((uintptr_t)pListener));
  802. }
  803. ErrorCodeEnum SpEntity::UnregistTerminalStateChangeEvent()
  804. {
  805. return UnregistSysVarEvent(VAR_RSERVERD_KEY_TERM_STATE);
  806. }
  807. ErrorCodeEnum SpEntity::SendBroadcast(DWORD dwMessageId, DWORD dwMessageSignature,CAutoBuffer Buffer)
  808. {
  809. int rc;
  810. iobuffer_t *pkt = iobuffer_create(-1, Buffer.GetCount());
  811. iobuffer_write(pkt, IOBUF_T_BUF, &Buffer[0], Buffer.GetCount());
  812. rc = sp_bcm_client_bcast(m_bcm_client, dwMessageId, dwMessageSignature, &pkt);
  813. if (pkt)
  814. iobuffer_dec_ref(pkt);
  815. return SpTranslateError(rc);
  816. }
  817. ErrorCodeEnum SpEntity::GetBroadcastReceivers(CAutoArray<BroadcastSubscribeInfo> &Subscribers)
  818. {
  819. ErrorCodeEnum Error;
  820. iobuffer_t *req_pkt = iobuffer_create(-1, -1);
  821. iobuffer_t *ans_pkt = NULL;
  822. Error = AskShell(SHELL_CMD_REQ_GET_BCAST_RECEIVER, &req_pkt, &ans_pkt);
  823. if (Error == Error_Succeed) {
  824. sp_env_t *env = sp_get_env();
  825. int size;
  826. iobuffer_read(ans_pkt, IOBUF_T_I4, &size, NULL);
  827. Subscribers.Init(size);
  828. for (int i = 0; i < size; ++i) {
  829. int ent_id;
  830. sp_uid_t uid;
  831. char *param = NULL;
  832. iobuffer_format_read(ans_pkt, "84s", &uid, &ent_id, &param);
  833. Subscribers[i].SubID = CUUID(uid);
  834. sp_entity_t *ent = sp_mod_mgr_find_entity_by_idx(env->mod_mgr, ent_id);
  835. Subscribers[i].strListener = ent->cfg->name;
  836. Subscribers[i].strParam = param;
  837. toolkit_free(param);
  838. }
  839. }
  840. if (req_pkt)
  841. iobuffer_dec_ref(req_pkt);
  842. if (ans_pkt)
  843. iobuffer_dec_ref(ans_pkt);
  844. return Error;
  845. }
  846. ErrorCodeEnum SpEntity::SubscribeBroadcast(const char *pszRemoteEntity, const char *pszParam, IBroadcastListener *pListener, CUUID &SubscribeID)
  847. {
  848. if (pszParam == NULL)
  849. pszParam = "";
  850. if (pListener == NULL)
  851. return Error_Param;
  852. sp_entity_t *remote_ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszRemoteEntity);
  853. if (remote_ent) {
  854. int rc;
  855. sp_uid_t uid;
  856. sp_bcm_listener_t *listener;
  857. sp_bcm_listener_cb cb = {0};
  858. cb.on_destroy = NULL;
  859. cb.on_message = &bcm_callback;
  860. cb.on_message_raw = NULL;
  861. cb.user_data = pListener;
  862. rc = sp_bcm_listener_create(m_svc, remote_ent->cfg->idx, pszParam, &cb, &listener);
  863. if (rc == 0) {
  864. rc = sp_bcm_listener_subscribe(listener, &uid);
  865. }
  866. if (rc != 0) {
  867. return SpTranslateError(rc);
  868. }
  869. SubscribeID = CUUID(uid);
  870. sp_bcm_listener_set_tag(listener, this);
  871. ARRAY_PUSH(m_arr_bcm_listener, sp_bcm_listener_t*) = listener;
  872. } else {
  873. return Error_NotExist;
  874. }
  875. return Error_Succeed;
  876. }
  877. ErrorCodeEnum SpEntity::UnsubscribeBroadcast(CUUID SubscribeID)
  878. {
  879. sp_bcm_listener_t *listener = NULL;
  880. int i;
  881. for (i = 0; i < m_arr_bcm_listener->nelts; ++i) {
  882. listener = ARRAY_IDX(m_arr_bcm_listener, i, sp_bcm_listener_t*);
  883. sp_uid_t uid;
  884. sp_bcm_listener_get_uid(listener, &uid);
  885. if (uid == SubscribeID.m_nUUID64) {
  886. ARRAY_DEL(m_arr_bcm_listener, i, sp_bcm_listener_t*);
  887. break;
  888. }
  889. }
  890. if (listener) {
  891. sp_bcm_listener_unsubscribe(listener);
  892. sp_bcm_listener_destroy(listener);
  893. return Error_Succeed;
  894. } else {
  895. return Error_NotExist;
  896. }
  897. }
  898. ErrorCodeEnum SpEntity::UnsubscribeBroadcast(const char *pszRemoteEntity)
  899. {
  900. if (pszRemoteEntity == NULL)
  901. return Error_Param;
  902. sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszRemoteEntity);
  903. if (!ent)
  904. return Error_NotExist;
  905. sp_bcm_listener_t *listener = NULL;
  906. int i;
  907. for (i = m_arr_bcm_listener->nelts-1; i >= 0; --i) {
  908. listener = ARRAY_IDX(m_arr_bcm_listener, i, sp_bcm_listener_t*);
  909. if (ent->cfg->idx == sp_bcm_listener_get_target_entity_id(listener)) {
  910. ARRAY_DEL(m_arr_bcm_listener, i, sp_bcm_listener_t*);
  911. sp_bcm_listener_unsubscribe(listener);
  912. sp_bcm_listener_destroy(listener);
  913. }
  914. }
  915. return Error_Succeed;
  916. }
  917. ErrorCodeEnum SpEntity::LogMessage( const LogTypeEnum LogType, const SeverityLevelEnum Level, DWORD dwSysErrorCode, DWORD dwUserErrorCode, const char *pMessage )
  918. {
  919. // xkm@20160726: 校验 dwUserErrorCode 是否合法
  920. int nDevID = m_ent->cfg->devel_id;
  921. if (dwUserErrorCode!=0 && ((dwUserErrorCode >> 20) & nDevID) != nDevID)
  922. {
  923. sp_dbg_warn("[InvalidUserCode] devID: 0x%x, userCode: 0x%x", nDevID, dwUserErrorCode);
  924. }
  925. auto rc = sp_log_client_log(m_log_client, LogType, Level, (int)dwSysErrorCode, (int)dwUserErrorCode, 0, 0, pMessage);
  926. if (rc != 0) {
  927. sp_dbg_warn("log message failed! raw msg: %s", pMessage);
  928. }
  929. else if(dwUserErrorCode != 0) {
  930. sp_dbg_info("userCode: 0x%x send", dwUserErrorCode);
  931. }
  932. return SpTranslateError(rc);
  933. }
  934. ErrorCodeEnum SpEntity::LogMessage(const LogTypeEnum LogType, const SeverityLevelEnum Level, DWORD iSysErrorCode, DWORD iUserErrorCode, CAutoArray<DWORD> Param, const char *pMessage)
  935. {
  936. // xkm@20160726: 校验 iUserErrorCode 是否合法
  937. int nDevID = m_ent->cfg->devel_id;
  938. if (iUserErrorCode != 0 && ((iUserErrorCode >> 20) & nDevID) != nDevID)
  939. {
  940. sp_dbg_warn("[InvalidUserCode] devID: 0x%x, userCode: 0x%x", nDevID, iUserErrorCode);
  941. }
  942. int rc;
  943. sp_log_client_t *client = (sp_log_client_t*)m_log_client;
  944. rc = sp_log_client_log(client, LogType, Level, (int)iSysErrorCode, (int)iUserErrorCode, (int)Param.GetCount(), (int*)&Param[0], pMessage);
  945. if (rc != 0) {
  946. sp_dbg_warn("log message failed! raw msg: %s", pMessage);
  947. }
  948. return SpTranslateError(rc);
  949. }
  950. ErrorCodeEnum SpEntity::LogFlush()
  951. {
  952. int rc;
  953. sp_log_client_t *client = (sp_log_client_t*)m_log_client;
  954. rc = sp_log_client_flush(client);
  955. if (rc != 0) {
  956. sp_dbg_warn("flush log message failed!");
  957. }
  958. return SpTranslateError(rc);
  959. }
  960. ErrorCodeEnum SpEntity::OpenConfig(ConfigTypeEnum eConfigType,CSmartPointer<IConfigInfo> &spConfigInfo)
  961. {
  962. IConfigInfo *pConfigInfo = new SpIniConfig(this, eConfigType);
  963. spConfigInfo.Attach(pConfigInfo);
  964. return Error_Succeed;
  965. }
  966. ErrorCodeEnum SpEntity::SetUserDefineState(DWORD dwState)
  967. {
  968. sp_env_t *env = sp_get_env();
  969. sp_mod_mgr_t *mod_mgr = env->mod_mgr;
  970. //sp_mod_mgr_lock(mod_mgr);
  971. DWORD dwOldState = m_ent->user_state;
  972. m_ent->user_state = dwState;
  973. //sp_mod_mgr_unlock(mod_mgr);
  974. // send state chage event to shell
  975. if (dwOldState != dwState)
  976. sp_mod_entity_stub_report_user_state_change(m_stub, dwOldState, dwState);
  977. return Error_Succeed;
  978. }
  979. ErrorCodeEnum SpEntity::GetSystemStaticInfo(CSystemStaticInfo &Info)
  980. {
  981. sp_env_t *env = sp_get_env();
  982. sp_cfg_t *cfg = env->cfg;
  983. sp_cfg_root_ini_t *root_ini = cfg->root_ini;
  984. sp_cfg_install_ini_t *install_ini = cfg->install_ini;
  985. //char tmp[MAX_PATH];
  986. //char *pdir;
  987. //int major, minor;
  988. int i;
  989. sp_cfg_version_info_t *version_info;
  990. memset(&Info, 0, sizeof(Info));
  991. Info.strTerminalID = CSimpleStringA(root_ini->terminal_no);
  992. Info.strMachineType = CSimpleStringA(root_ini->machine_type);
  993. //Info.strMachineModel = CSimpleStringA(root_ini->machine_model);
  994. Info.MachineVersion = CVersion(root_ini->machine_version.major, root_ini->machine_version.minor, root_ini->machine_version.revision, root_ini->machine_version.build);
  995. Info.LatterInstallVersion = CVersion(install_ini->latter_install_version.major, install_ini->latter_install_version.minor, install_ini->latter_install_version.revision, install_ini->latter_install_version.build);
  996. if (install_ini->arr_light_pack->nelts > 0) {
  997. Info.LightPackInfos.Init(install_ini->arr_light_pack->nelts);
  998. }
  999. for (i = 0; i < install_ini->arr_light_pack->nelts; ++i) {
  1000. sp_cfg_pack_info_t *pack = ARRAY_IDX(install_ini->arr_light_pack, i, sp_cfg_pack_info_t*);
  1001. Info.LightPackInfos[i].strPackName = pack->name;
  1002. Info.LightPackInfos[i].State = (InstallStateEnum)pack->state;
  1003. Info.LightPackInfos[i].tmInstalledDate = CSmallDateTime(pack->install_time);
  1004. }
  1005. Info.nTotalRunCount = install_ini->total_run_count;
  1006. Info.nTodayRunCount = install_ini->today_run_count;
  1007. Info.tmCreateDate = install_ini->install_time;
  1008. Info.tmCurrentTime = install_ini->current_startup_time;
  1009. Info.strSite = root_ini->site;
  1010. Info.eScreen = (ScreenEnum)root_ini->screen;
  1011. Info.strEnrolAddr = root_ini->enroll_address;
  1012. Info.EnrolGPS = CSphereVector(root_ini->enroll_gps_x, root_ini->enroll_gps_y);
  1013. version_info = sp_cfg_find_previous_version_info(cfg, &install_ini->install_version);
  1014. if (version_info) {
  1015. Info.PreviousInstallVersion = CVersion(version_info->version.major, version_info->version.minor, version_info->version.revision, version_info->version.build);
  1016. } else {
  1017. Info.PreviousInstallVersion = CVersion(0, 0, 0, 0);
  1018. }
  1019. version_info = sp_cfg_find_version_info(cfg, &install_ini->install_version);
  1020. if (version_info)
  1021. {
  1022. Info.InstallVersion = CVersion(install_ini->install_version.major, install_ini->install_version.minor, install_ini->install_version.revision, install_ini->install_version.build);
  1023. Info.tmSwithOverDate = version_info->switch_time;
  1024. Info.InstallPack = version_info->install_pack;
  1025. Info.InstallState = (InstallStateEnum)version_info->install_state;
  1026. }
  1027. return Error_Succeed;
  1028. }
  1029. ErrorCodeEnum SpEntity::GetInstallInfo(CVersion Version,CInstallInfo &Info)
  1030. {
  1031. sp_env_t *env = sp_get_env();
  1032. sp_cfg_t *cfg = env->cfg;
  1033. /*sp_cfg_root_ini_t *root_ini = cfg->root_ini;
  1034. sp_cfg_install_ini_t *install_ini = cfg->install_ini;*/
  1035. sp_cfg_version_info_t *version_info;
  1036. sp_version_t ver = {Version.GetMajor(), Version.GetMinor(), Version.GetRevision(), Version.GetBuild()};
  1037. version_info = sp_cfg_find_version_info(cfg, &ver);
  1038. if (version_info) {
  1039. Info.InstallPack = version_info->install_pack;
  1040. Info.InstallState = (InstallStateEnum)version_info->install_state;
  1041. Info.InstallVersion = Version;
  1042. Info.PreviousInstallVersion = CVersion(version_info->previous_version.major,
  1043. version_info->previous_version.minor,
  1044. version_info->previous_version.revision,
  1045. version_info->previous_version.build);
  1046. Info.tmSwithOverDate = version_info->switch_time;
  1047. } else {
  1048. return Error_NotExist;
  1049. }
  1050. return Error_Succeed;
  1051. }
  1052. bool SpEntity::IsPackInstalled(const char *pPackName)
  1053. {
  1054. if (pPackName && strlen(pPackName) > 0)
  1055. {
  1056. sp_env_t *env = sp_get_env();
  1057. sp_cfg_t *cfg = env->cfg;
  1058. sp_cfg_root_ini_t *root_ini = cfg->root_ini;
  1059. sp_cfg_install_ini_t *install_ini = cfg->install_ini;
  1060. // 先查询当前版本的轻量安装历史
  1061. if (strstr(install_ini->light_packs, pPackName) != NULL)
  1062. {
  1063. for(int i=0; i<install_ini->arr_light_pack->nelts; i++)
  1064. {
  1065. sp_cfg_pack_info_t *pack = ARRAY_IDX(install_ini->arr_light_pack, i, sp_cfg_pack_info_t*);
  1066. if (pack && pack->name && _stricmp(pack->name, pPackName) == 0)
  1067. return true;
  1068. }
  1069. }
  1070. // 查询历史版本安装包
  1071. for(int i=0; i<install_ini->arr_version->nelts; i++)
  1072. {
  1073. sp_cfg_version_info_t *ver_info = ARRAY_IDX(cfg->install_ini->arr_version, i, sp_cfg_version_info_t*);
  1074. if (strstr(ver_info->install_pack, pPackName) != NULL)
  1075. return true;
  1076. }
  1077. }
  1078. return false;
  1079. }
  1080. const char *SpEntity::GetCenterSettingNameBySite()
  1081. {
  1082. CSystemStaticInfo info;
  1083. GetSystemStaticInfo(info);
  1084. if ((stricmp(info.strSite, "CMB.LIB") == 0)
  1085. || (stricmp(info.strSite, "CMB.SSB") == 0))
  1086. {
  1087. return "CenterSetting.LAN.ini";
  1088. }
  1089. else if ((stricmp(info.strSite, "CMB.LSS") == 0)
  1090. || (stricmp(info.strSite, "CMB.FLB") == 0)
  1091. || (stricmp(info.strSite, "CMB.OSB") == 0)
  1092. || (stricmp(info.strSite, "CMB.SMM") == 0))
  1093. {
  1094. return "CenterSetting.DMZ.ini";
  1095. }
  1096. else
  1097. {
  1098. return "CenterSetting.DMZ.ini";
  1099. }
  1100. }
  1101. ErrorCodeEnum SpEntity::GetPath(const char *pszKey,CSimpleStringA &strPath)
  1102. {
  1103. sp_env_t *env = sp_get_env();
  1104. ErrorCodeEnum Error = Error_Succeed;
  1105. if (!pszKey)
  1106. return Error_Null;
  1107. if (_stricmp(pszKey, "Root") == 0) {
  1108. strPath = env->dir->root_path;
  1109. } else if (_stricmp(pszKey, "RootVer") == 0) {
  1110. strPath = env->dir->root_ver_path;
  1111. } else if (_stricmp(pszKey, "Data") == 0) {
  1112. strPath = CSimpleStringA(env->dir->obj_path);
  1113. } else if (_stricmp(pszKey, "Bin") == 0) {
  1114. strPath = CSimpleStringA(env->dir->bin_path);
  1115. } else if (_stricmp(pszKey, "Cfg") == 0 || _stricmp(pszKey, "Etc") == 0) {
  1116. strPath = CSimpleStringA(env->dir->cfg_path);
  1117. } else if (_stricmp(pszKey, "Rec") == 0) {
  1118. strPath = CSimpleStringA(env->cfg->root_ini->ref_localvideo_path);
  1119. } else if (_stricmp(pszKey, "Temp") == 0 || _stricmp(pszKey, "Tmp") == 0) {
  1120. strPath = CSimpleStringA(env->cfg->root_ini->ref_tmp_path);
  1121. } else if (_stricmp(pszKey, "SysLog") == 0) {
  1122. strPath = CSimpleStringA(env->cfg->root_ini->ref_syslog_path);
  1123. } else if (_stricmp(pszKey, "InterLog") == 0) {
  1124. strPath = CSimpleStringA(env->cfg->root_ini->ref_intlog_path);
  1125. } else if (_stricmp(pszKey, "Base") == 0 || _stricmp(pszKey, "BaseDir") == 0) {
  1126. strPath = CSimpleStringA(env->dir->base_path);
  1127. } else if (_stricmp(pszKey, "SysRoot") == 0) {
  1128. strPath = CSimpleStringA(env->cfg->root_ini->ref_sysroot_path);
  1129. } else if (_stricmp(pszKey, "Photo") == 0 || _stricmp(pszKey, "UploadPhoto") == 0) {
  1130. strPath = CSimpleStringA(env->cfg->root_ini->ref_uploadphoto_path);
  1131. } else if (_stricmp(pszKey, "Download") == 0 || _stricmp(pszKey, "Downloads") == 0) {
  1132. strPath = CSimpleStringA(env->cfg->root_ini->ref_downloads_path);
  1133. } else if (_stricmp(pszKey, "Upgraded") == 0){
  1134. strPath = CSimpleStringA(env->cfg->root_ini->ref_upgraded_path);
  1135. } else if (_stricmp(pszKey, "Ad") == 0) {
  1136. strPath = CSimpleStringA(env->cfg->root_ini->ref_addata_path);
  1137. } else if (_stricmp(pszKey, "UploadPhoto") == 0) {
  1138. strPath = CSimpleStringA(env->cfg->root_ini->ref_uploadphoto_path);
  1139. } else if (_stricmp(pszKey, "UploadVideo") == 0) {
  1140. strPath = CSimpleStringA(env->cfg->root_ini->ref_uploadvideo_path);
  1141. } else if (_stricmp(pszKey, "Dbg") == 0) {
  1142. strPath = CSimpleStringA(env->dir->dbg_path);
  1143. } else if (_stricmp(pszKey, "Slv") == 0) {
  1144. strPath = CSimpleStringA(env->dir->slv_path);
  1145. } else if (_stricmp(pszKey, "Dep") == 0) {
  1146. strPath = CSimpleStringA(env->dir->dep_path);
  1147. } else if (_stricmp(pszKey, "Ad0") == 0) {
  1148. strPath = CSimpleStringA(env->dir->ad0_path);
  1149. //} else if (_stricmp(pszKey, "CenterSetting") == 0) {
  1150. // strPath = CSimpleStringA(env->cfg->root_ini->ref_centersetting_path);
  1151. } else if (_stricmp(pszKey, "Dmp") == 0 || _stricmp(pszKey, "Dump") == 0) {
  1152. strPath = CSimpleStringA(env->dir->dmp_path);
  1153. } else if (_stricmp(pszKey, "RunInfo") == 0){
  1154. strPath = CSimpleStringA(env->dir->root_runinfo_path);
  1155. } else if (_stricmp(pszKey, "HardwareCfg") ==0){
  1156. strPath = CSimpleStringA(env->dir->root_hardwarecfg_path);
  1157. } else if (_stricmp(pszKey, "CenterSetting") == 0) {
  1158. // return centersetting name by current site
  1159. strPath = CSimpleStringA(env->dir->cfg_path);
  1160. strPath += SPLIT_SLASH_STR;
  1161. strPath += GetCenterSettingNameBySite();
  1162. }
  1163. else {
  1164. char *path = sp_cfg_get_path(env->cfg, pszKey);
  1165. if (path) {
  1166. strPath = path;
  1167. } else {
  1168. Error = Error_Param;
  1169. }
  1170. }
  1171. return Error;
  1172. }
  1173. ErrorCodeEnum SpEntity::GetSystemRunInfo(CSystemRunInfo &Info)
  1174. {
  1175. sp_env_t *env = sp_get_env();
  1176. sp_cfg_t *cfg = env->cfg;
  1177. Info.eDebugLevel = (DebugLevelEnum)cfg->shell_ini->shell_debug_level;
  1178. Info.tmStart = cfg->run_info->startup_time;
  1179. sp_mod_mgr_t *mod_mgr = env->mod_mgr;
  1180. sp_mod_t *pos;
  1181. array_header_t *arr = array_make(16, sizeof(char*));
  1182. list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry) {
  1183. if (pos->state) {
  1184. sp_entity_t *ent;
  1185. list_for_each_entry(ent, &pos->entity_list, sp_entity_t, entry) {
  1186. int state = ent->state;
  1187. if (state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause) {
  1188. ARRAY_PUSH(arr, char*) = ent->cfg->name;
  1189. }
  1190. }
  1191. }
  1192. }
  1193. Info.strRunningEntityNames.Init(arr->nelts);
  1194. for (int i = 0; i < arr->nelts; ++i) {
  1195. Info.strRunningEntityNames[i] = CSimpleStringA(ARRAY_IDX(arr, i, char*));
  1196. }
  1197. array_free(arr);
  1198. return Error_Succeed;
  1199. }
  1200. ErrorCodeEnum SpEntity::GetEntityBusyRate(WORD &nBusyEntity,WORD &nAllEntity)
  1201. {
  1202. sp_env_t *env = sp_get_env();
  1203. sp_mod_mgr_t *mod_mgr = env->mod_mgr;
  1204. int nAll(0), nBusy(0);
  1205. sp_mod_t *mod;
  1206. list_for_each_entry(mod, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry)
  1207. {
  1208. if (mod->state)
  1209. {
  1210. sp_entity_t *ent;
  1211. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry)
  1212. {
  1213. int state = ent->state;
  1214. if (state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause)
  1215. nAll++;
  1216. if (state == EntityState_Busy)
  1217. nBusy++;
  1218. }
  1219. }
  1220. nBusyEntity = nBusy;
  1221. nAllEntity = nAll;
  1222. }
  1223. return Error_Succeed;
  1224. }
  1225. ErrorCodeEnum SpEntity::GetRebootInfo(CSmallDateTime BeforeThisTime, CBootInfo &Info)
  1226. {
  1227. CSimpleStringA strPath;
  1228. auto rc = GetPath("RunInfo", strPath);
  1229. if (rc != Error_Succeed)
  1230. return rc;
  1231. strPath += SPLIT_SLASH_STR "BootLog";
  1232. sp_env_t *env = sp_get_env();
  1233. auto pRec = sp_btr_get_rec_before(strPath, env->btr_ctx, BeforeThisTime);
  1234. if (pRec == NULL)
  1235. return Error_NotExist;
  1236. Info.tmStart = pRec->tm_start;
  1237. Info.tmReboot = pRec->tm_shutdown;
  1238. Info.InstallVersion = CVersion(pRec->version.major, pRec->version.minor, pRec->version.revision, pRec->version.build);
  1239. Info.eTriggerReason = (RebootTriggerEnum)pRec->shutdown_reason;
  1240. Info.eWay = (RebootWayEnum)pRec->shutdown_way;
  1241. Info.wSameReasonTime = pRec->shutdown_reason_cnt;
  1242. Info.wSameWayTime = pRec->shutdown_way_cnt;
  1243. delete pRec;
  1244. return Error_Succeed;
  1245. }
  1246. ErrorCodeEnum SpEntity::GetAllRegistSpFile(CAutoArray<CSimpleStringA> &Names)
  1247. {
  1248. sp_env_t *env = sp_get_env();
  1249. sp_cfg_t *cfg = env->cfg;
  1250. array_header_t *arr_module = cfg->shell_ini->arr_module;
  1251. Names.Init(arr_module->nelts);
  1252. for (int i = 0; i < arr_module->nelts; ++i) {
  1253. sp_cfg_shell_module_t* mod = ARRAY_IDX(arr_module, i, sp_cfg_shell_module_t*);
  1254. Names[i] = mod->name;
  1255. }
  1256. return Error_Succeed;
  1257. }
  1258. ErrorCodeEnum SpEntity::GetSpFileInfo(const char *pszSpName,CSpInfo &Info)
  1259. {
  1260. if (!pszSpName)
  1261. return Error_Null;
  1262. sp_env_t *env = sp_get_env();
  1263. sp_cfg_t *cfg = env->cfg;
  1264. sp_cfg_shell_module_t *cfg_mod = sp_cfg_get_module_by_name(cfg, pszSpName);
  1265. if (!cfg_mod)
  1266. return Error_NotExist;
  1267. Info.strAuthor = cfg_mod->author;
  1268. Info.strCompany = cfg_mod->company;
  1269. Info.SoftwareVersion = CVersion((WORD)cfg_mod->version.major,
  1270. (WORD)cfg_mod->version.minor,
  1271. (WORD)cfg_mod->version.revision,
  1272. (WORD)cfg_mod->version.build);
  1273. sp_mod_mgr_t *mod_mgr = env->mod_mgr;
  1274. sp_mod_t *mod = sp_mod_mgr_find_module_by_name(mod_mgr, pszSpName);
  1275. if (!mod)
  1276. return Error_NotExist;
  1277. sp_entity_t *ent;
  1278. int cnt = 0;
  1279. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
  1280. cnt++;
  1281. }
  1282. Info.strEntitys.Init(cnt);
  1283. int i = 0;
  1284. list_for_each_entry(ent, &mod->entity_list, sp_entity_t, entry) {
  1285. Info.strEntitys[i++] = ent->cfg->name;
  1286. }
  1287. return Error_Succeed;
  1288. }
  1289. ErrorCodeEnum SpEntity::GetAllRegistedEntity(CAutoArray<CSimpleStringA> &strEntityNames, CAutoArray<WORD> &wEntityDevelopIDs)
  1290. {
  1291. sp_env_t *env = sp_get_env();
  1292. sp_cfg_t *cfg = env->cfg;
  1293. array_header_t *arr_entity = cfg->shell_ini->arr_entity;
  1294. strEntityNames.Init(arr_entity->nelts-1);
  1295. wEntityDevelopIDs.Init(arr_entity->nelts-1);
  1296. for (int i = 1; i < arr_entity->nelts; ++i) { // from index 1, because zero for special entity, ie. spshell entity
  1297. sp_cfg_shell_entity_t *ent = ARRAY_IDX(arr_entity, i, sp_cfg_shell_entity_t*);
  1298. strEntityNames[i-1] = ent->name;
  1299. wEntityDevelopIDs[i-1] = ent->devel_id;
  1300. }
  1301. return Error_Succeed;
  1302. }
  1303. ErrorCodeEnum SpEntity::GetAllStartedEntity(CAutoArray<CSimpleStringA> &strEntityNames, CAutoArray<DWORD> &dwEntityInstanceIDs)
  1304. {
  1305. sp_env_t *env = sp_get_env();
  1306. sp_mod_mgr_t *mod_mgr = env->mod_mgr;
  1307. sp_mod_t *pos;
  1308. int i;
  1309. array_header_t *arr = array_make(16, sizeof(sp_entity_t*));
  1310. list_for_each_entry(pos, sp_mod_mgr_get_module_list_head(mod_mgr), sp_mod_t, entry) {
  1311. if (pos->state) {
  1312. sp_entity_t *ent;
  1313. list_for_each_entry(ent, &pos->entity_list, sp_entity_t, entry) {
  1314. int state = ent->state;
  1315. if (state == EntityState_Idle || state == EntityState_Busy || state == EntityState_Pause) {
  1316. ARRAY_PUSH(arr, sp_entity_t*) = ent;
  1317. }
  1318. }
  1319. }
  1320. }
  1321. strEntityNames.Init(arr->nelts);
  1322. dwEntityInstanceIDs.Init(arr->nelts);
  1323. for (i = 0; i < arr->nelts; ++i) {
  1324. sp_entity_t *ent = ARRAY_IDX(arr, i, sp_entity_t*);
  1325. strEntityNames[i] = ent->cfg->name;
  1326. dwEntityInstanceIDs[i] = ent->instance_id;
  1327. }
  1328. // {bug} forget array_free(arr)
  1329. array_free(arr);
  1330. return Error_Succeed;
  1331. }
  1332. ErrorCodeEnum SpEntity::GetSelfEntityRunInfo(CEntityRunInfo &Info)
  1333. {
  1334. return GetEntityRunInfo(m_ent->cfg->name, Info);
  1335. }
  1336. ErrorCodeEnum SpEntity::GetEntityStaticInfo(const char *pszEntityName,CEntityStaticInfo &Info)
  1337. {
  1338. if (!pszEntityName)
  1339. return Error_Null;
  1340. sp_env_t *env = sp_get_env();
  1341. sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszEntityName);
  1342. return ::GetEntityStaticInfo(Info, ent);
  1343. }
  1344. ErrorCodeEnum SpEntity::GetEntityStaticInfo(WORD wEntitySerialNO,CEntityStaticInfo &Info)
  1345. {
  1346. sp_env_t *env = sp_get_env();
  1347. sp_entity_t *ent = sp_mod_mgr_find_entity_by_devel_id(env->mod_mgr, wEntitySerialNO);
  1348. return ::GetEntityStaticInfo(Info, ent);
  1349. }
  1350. ErrorCodeEnum SpEntity::GetEntityRunInfo(const char *pszEntityName, CEntityRunInfo &Info)
  1351. {
  1352. sp_env_t *env = sp_get_env();
  1353. if (!pszEntityName)
  1354. return Error_Null;
  1355. sp_mod_mgr_t *mod_mgr = env->mod_mgr;
  1356. sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(mod_mgr, pszEntityName);
  1357. if (!ent)
  1358. return Error_NotExist;
  1359. Info.dwEntityInstanceID = (DWORD)ent->instance_id;
  1360. Info.tmFirstStart = ent->first_start_time;
  1361. Info.tmLastStart = ent->last_start_time;
  1362. Info.bService = !!ent->service_flag;
  1363. Info.eState = (EntityStateEnum)ent->state;
  1364. Info.tmBeginCurrentState = ent->state_start_time;
  1365. Info.dwProcessID = (DWORD)ent->mod->process.pid;
  1366. Info.eDebugLevel = (DebugLevelEnum)ent->cfg->debug_level;
  1367. Info.dwUserState = (DWORD)ent->user_state;
  1368. return Error_Succeed;
  1369. }
  1370. ErrorCodeEnum SpEntity::GetEntityName(WORD wEntityDevelopID, CSimpleStringA &strName)
  1371. {
  1372. sp_env_t *env = sp_get_env();
  1373. sp_entity_t *ent = sp_mod_mgr_find_entity_by_devel_id(env->mod_mgr, wEntityDevelopID);
  1374. if (ent) {
  1375. strName = ent->cfg->name;
  1376. } else {
  1377. return Error_NotExist;
  1378. }
  1379. return Error_Succeed;
  1380. }
  1381. ErrorCodeEnum SpEntity::GetEntityName(DWORD dwEntityInstanceID, CSimpleStringA &strName)
  1382. {
  1383. assert(dwEntityInstanceID != 0);
  1384. sp_env_t *env = sp_get_env();
  1385. sp_entity_t *ent = sp_mod_mgr_find_entity_by_inst_id(env->mod_mgr, dwEntityInstanceID);
  1386. if (ent) {
  1387. strName = ent->cfg->name;
  1388. } else {
  1389. return Error_NotExist;
  1390. }
  1391. return Error_Succeed;
  1392. }
  1393. ErrorCodeEnum SpEntity::GetModuleName(DWORD nModuleID, CSimpleStringA &strName)
  1394. {
  1395. if (nModuleID != SP_INVALID_MOD_ID) {
  1396. sp_env_t *env = sp_get_env();
  1397. sp_mod_t *mod = sp_mod_mgr_find_module_by_idx(env->mod_mgr, nModuleID);
  1398. if (mod) {
  1399. strName = mod->cfg->name;
  1400. return Error_Succeed;
  1401. } else {
  1402. return Error_NotExist;
  1403. }
  1404. }
  1405. return Error_Param;
  1406. }
  1407. ErrorCodeEnum SpEntity::GetEntitySessionInfo(const char *pszEntityName, CAutoArray<CEntitySessionInfo> &Infos)
  1408. {
  1409. iobuffer_t *req_pkt = iobuffer_create(-1, -1);
  1410. iobuffer_t *ans_pkt = NULL;
  1411. auto rc = AskEntityByRPC(pszEntityName, ENTITY_CMD_REQ_QUERY_ENTITY_SESSIONS, &req_pkt, &ans_pkt);
  1412. if (rc == Error_Succeed)
  1413. {
  1414. int nCount(0);
  1415. iobuffer_read(ans_pkt, IOBUF_T_I4, &nCount, NULL);
  1416. auto pCfg = sp_get_env()->cfg;
  1417. Infos.Init(nCount);
  1418. for (int i = 0; i < nCount; ++i)
  1419. {
  1420. int nFromSvcID, nToSvcID, nBeginTime, nState, nStateBeginTime;
  1421. iobuffer_format_read(ans_pkt, "44444", &nFromSvcID, &nToSvcID, &nBeginTime, &nState, &nStateBeginTime);
  1422. Infos[i].strCallerEntity = sp_cfg_get_entity_by_idx(pCfg, nFromSvcID)->name;
  1423. Infos[i].strServiceEntity = sp_cfg_get_entity_by_idx(pCfg, nToSvcID)->name;
  1424. Infos[i].tmStart = CSmallDateTime(nBeginTime);
  1425. Infos[i].eState = (SessionStateEnum)nState;
  1426. Infos[i].tmBeginState = CSmallDateTime(nStateBeginTime);
  1427. }
  1428. }
  1429. if (req_pkt)
  1430. iobuffer_dec_ref(req_pkt);
  1431. if (ans_pkt)
  1432. iobuffer_dec_ref(ans_pkt);
  1433. return rc;
  1434. }
  1435. bool SpEntity::HasPrivilege()
  1436. {
  1437. return !!m_cfg_ent->privilege;
  1438. }
  1439. CSmartPointer<IEntityFunctionPrivilege> SpEntity::GetPrivilegeFunction()
  1440. {
  1441. return NULL;
  1442. }
  1443. ErrorCodeEnum SpEntity::PostQuit()
  1444. {
  1445. ErrorCodeEnum Error;
  1446. iobuffer_t *pkt = iobuffer_create(-1, -1);
  1447. int v = m_ent->cfg->idx;
  1448. iobuffer_write(pkt, IOBUF_T_I4, &v, 0);
  1449. Dbg("Pre PostQuit...");
  1450. Error = PostInfoShell(SHELL_CMD_INFO_ENTITY_QUIT, &pkt);
  1451. if (pkt)
  1452. iobuffer_dec_ref(pkt);
  1453. return Error;
  1454. }
  1455. ErrorCodeEnum SpEntity::PostReload()
  1456. {
  1457. ErrorCodeEnum Error;
  1458. iobuffer_t *pkt = iobuffer_create(-1, -1);
  1459. int v = m_ent->cfg->idx;
  1460. iobuffer_write(pkt, IOBUF_T_I4, &v, 0);
  1461. Dbg("Pre PostReload...");
  1462. Error = PostInfoShell(SHELL_CMD_INFO_ENTITY_RELOAD, &pkt);
  1463. if (pkt)
  1464. iobuffer_dec_ref(pkt);
  1465. return Error;
  1466. }
  1467. ErrorCodeEnum SpEntity::PostEntityTaskFIFO(ITaskSp *pTask)
  1468. {
  1469. threadpool_t *threadpool = sp_svc_get_threadpool(m_svc);
  1470. int rc;
  1471. rc = threadpool_post_workitem_fifo2(threadpool, NULL, &task_callback, pTask, (param_size_t)((intptr_t)this), 0);
  1472. return rc == 0 ? Error_Succeed : Error_Unexpect;
  1473. }
  1474. ErrorCodeEnum SpEntity::PostEntityTaskLIFO(ITaskSp *pTask)
  1475. {
  1476. threadpool_t *threadpool = sp_svc_get_threadpool(m_svc);
  1477. int rc;
  1478. rc = threadpool_post_workitem_lifo2(threadpool, NULL, &task_callback, pTask, (param_size_t)((intptr_t)this), 0);
  1479. return rc == 0 ? Error_Succeed : Error_Unexpect;
  1480. }
  1481. ErrorCodeEnum SpEntity::PostThreadPoolTask(ITaskSp *pTask)
  1482. {
  1483. int rc = threadpool_post_workitem_fifo2(m_tpool, NULL, &task_callback, pTask, (param_size_t)((intptr_t)this), 0);
  1484. return rc == 0 ? Error_Succeed : Error_Unexpect;
  1485. }
  1486. ErrorCodeEnum SpEntity::StartTcpBridgeServer(unsigned short port)
  1487. {
  1488. if (port >4506 || port < 4502)
  1489. return Error_Duplication;
  1490. #ifdef _DEBUG
  1491. const char *ip = "0.0.0.0";
  1492. #else
  1493. const char *ip = "127.0.0.1";
  1494. #endif
  1495. if (m_tbs)
  1496. return Error_Duplication;
  1497. int rc = sp_tbs_create(m_ses_mgr, ip, port, &m_tbs);
  1498. if (rc == 0) {
  1499. rc = sp_tbs_start(m_tbs);
  1500. if (rc != 0) {
  1501. sp_tbs_destroy(m_tbs);
  1502. m_tbs = NULL;
  1503. }
  1504. }
  1505. return SpTranslateError(rc);
  1506. }
  1507. ErrorCodeEnum SpEntity::StopTcpBridgeServer()
  1508. {
  1509. if (m_tbs) {
  1510. sp_tbs_stop(m_tbs);
  1511. sp_tbs_destroy(m_tbs);
  1512. m_tbs = NULL;
  1513. return Error_Succeed;
  1514. } else {
  1515. return Error_NotInit;
  1516. }
  1517. }
  1518. ErrorCodeEnum SpEntity::RequestCloseDelay(WORD nSecond)
  1519. {
  1520. return Error_NotImpl;
  1521. }
  1522. void SpEntity::SendLog(const LogTypeEnum eLogType,const SeverityLevelEnum eLevel,DWORD dwUserEventCode,CAutoArray<DWORD> Param,const char *pszMessage)
  1523. {
  1524. LogMessage(eLogType, eLevel, 0, dwUserEventCode, Param, pszMessage);
  1525. }
  1526. ErrorCodeEnum SpEntity::VerifySignature(const char *pszSignedFile, CSimpleStringA &strErrInfo)
  1527. {
  1528. #ifdef _WIN32
  1529. CCodeSignVerify verify;
  1530. CSignInfo signInfo;
  1531. if (!verify.VerifySignature(pszSignedFile, signInfo)) {
  1532. strErrInfo = verify.GetErrorMsg();
  1533. return Error_FailVerify;
  1534. }
  1535. // xkm@20140905: check cer file's hash is consistent with spbase's hash
  1536. sp_env_t* env = sp_get_env();
  1537. assert(env != NULL);
  1538. auto pShellCfg = env->cfg->shell_ini;
  1539. if (pShellCfg->spbase_sign_cert_hash != NULL
  1540. && stricmp(pShellCfg->spbase_sign_cert_hash, signInfo.strSignCertHash) != 0) {
  1541. strErrInfo = "signing certificate is not authorized certificate.";
  1542. return Error_FailVerify;
  1543. }
  1544. strErrInfo = signInfo.strSignCertHash;
  1545. #else
  1546. strErrInfo = "TODO: not implement VerifySignature current times.";
  1547. #endif //_WIN32
  1548. return Error_Succeed;
  1549. }
  1550. ErrorCodeEnum SpEntity::ShowFatalError(const char *pszMsg)
  1551. {
  1552. LogError(Severity_High, Error_Unrecover, 0, pszMsg);
  1553. ErrorCodeEnum Error;
  1554. iobuffer_t *pkt = iobuffer_create(-1, -1);
  1555. iobuffer_write(pkt, IOBUF_T_STR, pszMsg, -1);
  1556. //int nBlueScreen = 1;
  1557. //iobuffer_write(pkt, IOBUF_T_I4, &nBlueScreen, 0);
  1558. Error = PostInfoShell(SHELL_CMD_INFO_FATAL_ERROR_DISPLAY, &pkt);
  1559. if (pkt)
  1560. iobuffer_dec_ref(pkt);
  1561. return Error;
  1562. }
  1563. ErrorCodeEnum SpEntity::ShowStartupInfo(const char *pszMsg)
  1564. {
  1565. LogEvent(Severity_High, 0, pszMsg);
  1566. ErrorCodeEnum Error;
  1567. iobuffer_t *pkt = iobuffer_create(-1, -1);
  1568. iobuffer_write(pkt, IOBUF_T_STR, pszMsg, -1);
  1569. Error = PostInfoShell(SHELL_CMD_INFO_STARTUP_INFO_DISPLAY, &pkt);
  1570. if (pkt)
  1571. iobuffer_dec_ref(pkt);
  1572. return Error;
  1573. }
  1574. ErrorCodeEnum SpEntity::InitLogCurrentThread()
  1575. {
  1576. #ifdef _WIN32
  1577. SetthreadGroup(GetCurrentThreadId(), get_cfg_ent()->name);
  1578. getEntityResource()->m_Entity = this;
  1579. #else
  1580. GetSpModule()->SetThreadEntity(this);
  1581. #endif //_WIN32
  1582. return Error_Succeed;
  1583. }
  1584. ErrorCodeEnum SpEntity::ConnectRemoteEntity(CClientSessionBase *pClientSession,
  1585. const char *pszRemoteEntity,
  1586. const char *pszParam,
  1587. CSmartPointer<IAsynWaitSp> &pAsynWaitSp)
  1588. {
  1589. ErrorCodeEnum Error;
  1590. if (!pClientSession || !pszRemoteEntity)
  1591. return Error_Param;
  1592. if (pClientSession->m_pSessionFunction)
  1593. return Error_Param;
  1594. SpClientSessionFunction *pFunction = new SpClientSessionFunction(this, pClientSession, pszRemoteEntity);
  1595. Error = pFunction->Begin(pszParam);
  1596. if (Error == Error_Succeed) {
  1597. pClientSession->m_pSessionFunction = pFunction;
  1598. pAsynWaitSp.Attach(pFunction, pFunction->GetRefCountPtr());
  1599. } else {
  1600. pFunction->DecrementRef();
  1601. }
  1602. Dbg("connect to %s %s", pszRemoteEntity, Error_Succeed == Error ? "success" : "fail");
  1603. return Error;
  1604. }
  1605. ErrorCodeEnum SpEntity::RedirectSession(CClientSessionBase *pClientSession)
  1606. {
  1607. return Error_NotImpl;
  1608. }
  1609. ErrorCodeEnum SpEntity::RedirectSession(const char *pszSuggestEntity)
  1610. {
  1611. if (pszSuggestEntity) {
  1612. sp_env_t *env = sp_get_env();
  1613. sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(env->mod_mgr, pszSuggestEntity);
  1614. if (ent) {
  1615. m_redirect_entity_cache = ent;
  1616. return Error_Succeed;
  1617. } else {
  1618. sp_dbg_warn("RedirectSession failed, cannot find entity %s", pszSuggestEntity);
  1619. return Error_Param;
  1620. }
  1621. }
  1622. return Error_Param;
  1623. }
  1624. ErrorCodeEnum SpEntity::RedirectSubscribBroadcast(CUUID SubID, const char *pszSugguestEntity)
  1625. {
  1626. if (pszSugguestEntity) {
  1627. sp_entity_t *ent = sp_mod_mgr_find_entity_by_name(sp_get_env()->mod_mgr, pszSugguestEntity);
  1628. if (ent) {
  1629. sp_uid_t uid = SubID.m_nUUID64;
  1630. sp_mod_entity_stub_finish_redirect_subscribe(m_stub, &uid, ent->cfg->idx);
  1631. } else {
  1632. return Error_NotExist;
  1633. }
  1634. } else {
  1635. return Error_Param;
  1636. }
  1637. return Error_Succeed;
  1638. }
  1639. ErrorCodeEnum SpEntity::AskShell(int call_type, iobuffer_t **req_pkt, iobuffer_t **ans_pkt)
  1640. {
  1641. ErrorCodeEnum Error;
  1642. iobuffer_t *r_pkt = NULL;
  1643. if (!req_pkt || !*req_pkt || !ans_pkt)
  1644. return Error_Param;
  1645. if (*ans_pkt)
  1646. return Error_Param; // must be null so can return pkt
  1647. SpAsyncWaitRPC *pAsyncWait = new SpAsyncWaitRPC(this, req_pkt, call_type);
  1648. Error = pAsyncWait->Begin();
  1649. if (Error == Error_Succeed)
  1650. {
  1651. Error = pAsyncWait->WaitAnswer(INFINITE);
  1652. if (Error == Error_Succeed)
  1653. {
  1654. CAutoBuffer AnsBuf;
  1655. bool bEnd;
  1656. Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd);
  1657. if (Error == Error_Succeed)
  1658. {
  1659. iobuffer_t *pkt = iobuffer_create(-1, AnsBuf.GetCount());
  1660. iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount());
  1661. *ans_pkt = pkt;
  1662. }
  1663. }
  1664. }
  1665. pAsyncWait->DecrementRef(); // xkm@20150115
  1666. return Error;
  1667. }
  1668. ErrorCodeEnum SpEntity::AskEntityByRPC(const char *pszEntityName, int call_type, iobuffer_t **req_pkt, iobuffer_t **ans_pkt)
  1669. {
  1670. ErrorCodeEnum Error;
  1671. iobuffer_t *r_pkt = NULL;
  1672. if (!req_pkt || !*req_pkt || !ans_pkt)
  1673. return Error_Param;
  1674. if (*ans_pkt)
  1675. return Error_Param; // must be null so can return pkt
  1676. SpAsyncWaitRPC *pAsyncWait = new SpAsyncWaitRPC(this, req_pkt, call_type);
  1677. Error = pAsyncWait->Begin(pszEntityName);
  1678. if (Error == Error_Succeed)
  1679. {
  1680. Error = pAsyncWait->WaitAnswer(INFINITE);
  1681. if (Error == Error_Succeed)
  1682. {
  1683. CAutoBuffer AnsBuf;
  1684. bool bEnd;
  1685. Error = pAsyncWait->AsyncGetAnswer(AnsBuf, bEnd);
  1686. if (Error == Error_Succeed) {
  1687. iobuffer_t *pkt = iobuffer_create(-1, AnsBuf.GetCount());
  1688. iobuffer_write(pkt, IOBUF_T_BUF, &AnsBuf[0], AnsBuf.GetCount());
  1689. *ans_pkt = pkt;
  1690. }
  1691. }
  1692. }
  1693. pAsyncWait->DecrementRef(); // xkm@20150115
  1694. return Error;
  1695. }
  1696. void SpEntity::__on_rpc_request(sp_rpc_client_mgr_t *mgr, int epid, int svc_id, int rpc_id, int call_type, iobuffer_t **req_pkt, void *user_data)
  1697. {
  1698. SpEntity *pThis = static_cast<SpEntity*>(user_data);
  1699. Dbg("on_rpc_req(), calltype: %d", call_type);
  1700. if (call_type == ENTITY_CMD_REQ_QUERY_ENTITY_SESSIONS)
  1701. {
  1702. pThis->OnQueryEntitySessions(epid, svc_id, rpc_id);
  1703. }
  1704. }
  1705. void SpEntity::OnQueryEntitySessions(int epid, int svc_id, int rpc_id)
  1706. {
  1707. int rc;
  1708. int nCount(0);
  1709. int nResult(0);
  1710. sp_ses_info_t* ret = sp_ses_mgr_get_ses_info(m_ses_mgr, &nCount);
  1711. iobuffer_t *ans_pkt = iobuffer_create(-1, -1);
  1712. iobuffer_write(ans_pkt, IOBUF_T_I4, &nResult, 0);
  1713. iobuffer_write(ans_pkt, IOBUF_T_I4, &nCount, 0);
  1714. for(int i=0; i<nCount; i++)
  1715. {
  1716. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret[i].from_svc_id, 0);
  1717. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret[i].to_svc_id, 0);
  1718. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret[i].begin_time, 0);
  1719. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret[i].state, 0);
  1720. iobuffer_write(ans_pkt, IOBUF_T_I4, &ret[i].state_begin_time, 0);
  1721. }
  1722. if (ret != NULL)
  1723. free(ret);
  1724. rc = sp_rpc_client_mgr_send_answer(m_rpc_mgr, epid, svc_id, rpc_id, &ans_pkt);
  1725. if (rc != 0) {
  1726. sp_dbg_warn("send rpc answer failed!");
  1727. }
  1728. if (ans_pkt) {
  1729. iobuffer_dec_ref(ans_pkt);
  1730. }
  1731. }
  1732. ErrorCodeEnum SpEntity::PostInfoShell(int call_type, iobuffer_t **info_pkt)
  1733. {
  1734. int rc;
  1735. rc = sp_rpc_client_mgr_one_way_call(get_rpc_mgr(),
  1736. SP_SHELL_MOD_ID,
  1737. SP_SHELL_SVC_ID,
  1738. call_type,
  1739. info_pkt);
  1740. return SpTranslateError(rc);
  1741. }
  1742. void SpEntity::FinishStart(ErrorCodeEnum Error)
  1743. {
  1744. sp_mod_entity_stub_finish_start(m_stub, Error);
  1745. if (Error == Error_Succeed) {
  1746. m_pEntityBase->OnStarted();
  1747. }
  1748. }
  1749. void SpEntity::FinishClose(ErrorCodeEnum Error)
  1750. {
  1751. sp_mod_entity_stub_finish_stop(m_stub, Error);
  1752. if (Error == Error_Succeed) {
  1753. Term();
  1754. }
  1755. }
  1756. void SpEntity::FinishPause(ErrorCodeEnum Error)
  1757. {
  1758. sp_mod_entity_stub_finish_pause(m_stub, Error);
  1759. if (Error == Error_Succeed) {
  1760. m_pEntityBase->OnPaused();
  1761. }
  1762. }
  1763. void SpEntity::FinishContinue(ErrorCodeEnum Error)
  1764. {
  1765. sp_mod_entity_stub_finish_continue(m_stub, Error);
  1766. if (Error == Error_Succeed) {
  1767. m_pEntityBase->OnContinued();
  1768. }
  1769. }
  1770. void SpEntity::FinishSelfTest(ErrorCodeEnum Error)
  1771. {
  1772. sp_mod_entity_stub_finish_test(m_stub, Error);
  1773. }