SpEntity.cpp 59 KB

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