evtengine.cpp 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096
  1. #include "stdafx.h"
  2. #include "evtengine.h"
  3. #include "list.h"
  4. #include "array.h"
  5. #include "spinlock.h"
  6. #include "hashset.h"
  7. #include "hash.h"
  8. #include "jhash.h"
  9. #include "strutil.h"
  10. #include "fileutil.h"
  11. #include "scew.h"
  12. #if 0
  13. <?xml version="1.0" encoding="utf-8"?>
  14. <Transfer xmlns="test">
  15. <SlotList>
  16. <Slot Code="A" Timeout="1:00" OnceTrigger="true">
  17. <Filter></Filter>
  18. <Reset Source="B"/>
  19. <Reset Source="C"/>
  20. </Slot>
  21. <Slot Code="B" Timeout="" OnceTrigger="false">
  22. </Slot>
  23. </SlotList>
  24. <TriggerList>
  25. <Trigger LogType="Log_Warning" UserCode="2001" SeverityLevel="Severity_High" SysError="Error_Close" Message="">
  26. <Slot Code="Test2.TestSlot1" Positive="true"/>
  27. <Slot Code="TestSlot2"/>
  28. <SysVar Code="RunState">
  29. <State>O</State>
  30. <State>M</State>
  31. </SysVar>
  32. <SysVar Code="NetState" Positive="false">
  33. <State>D</State>
  34. </SysVar>
  35. </Trigger>
  36. </TriggerList>
  37. </Transfer>
  38. #endif
  39. #define BIT_MASK(bit) (1 << (bit))
  40. typedef struct evt_filter_key_t evt_filter_key_t;
  41. typedef struct evt_filter_t evt_filter_t;
  42. typedef struct evt_expire_t evt_expire_t;
  43. typedef struct evt_slot_key_t evt_slot_key_t;
  44. typedef struct evt_slot_t evt_slot_t;
  45. typedef struct evt_sysvar_rule_t evt_sysvar_rule_t;
  46. typedef struct evt_sysvar_key_t evt_sysvar_key_t;
  47. typedef struct evt_sysvar_t evt_sysvar_t;
  48. typedef struct evt_slot_rule_t evt_slot_rule_t;
  49. typedef struct evt_trigger_t evt_trigger_t;
  50. typedef struct evt_slotvar_t evt_slotvar_t;
  51. static int nIslog = 0;
  52. struct evt_filter_key_t
  53. {
  54. unsigned long long listen_id; // id
  55. };
  56. struct evt_filter_t
  57. {
  58. evt_filter_key_t key;
  59. int log_type;
  60. int ent_id;
  61. int severity;
  62. int sys_code;
  63. int user_code;
  64. char *entity;
  65. evt_slotvar_t *content_to_var;
  66. evt_slot_t *owner;
  67. struct hlist_node hentry;
  68. };
  69. struct evt_expire_t
  70. {
  71. int timer_id;
  72. int timeout;
  73. evt_slot_t *parent;
  74. };
  75. struct evt_slot_key_t
  76. {
  77. char *code;
  78. unsigned int index_hash_code;
  79. };
  80. struct evt_slotvar_t
  81. {
  82. char *name;
  83. char *init_value;
  84. char *current_value;
  85. };
  86. struct evt_slot_t
  87. {
  88. struct hlist_node hentry;
  89. evt_slot_key_t key;
  90. evt_expire_t *timer;
  91. evt_engine_t *parent;
  92. int once;
  93. array_header_t *arr_filter;
  94. array_header_t *arr_rref_reset;
  95. array_header_t *arr_ref_reset;
  96. array_header_t *arr_reset;
  97. array_header_t *arr_ref_trigger;
  98. array_header_t *arr_slotvar;
  99. int signal_state;
  100. struct list_head use_entry;
  101. struct list_head *use_list_ptr;
  102. };
  103. struct evt_sysvar_rule_t
  104. {
  105. struct list_head entry;
  106. evt_trigger_t *parent;
  107. int positive;
  108. array_header_t *arr_state;
  109. evt_sysvar_t *ref_sysvar;
  110. };
  111. struct evt_sysvar_key_t
  112. {
  113. char *code;
  114. unsigned int index_hash_code;
  115. };
  116. struct evt_sysvar_t
  117. {
  118. struct hlist_node hentry;
  119. evt_sysvar_key_t key;
  120. array_header_t *arr_ref_rule;
  121. struct evt_engine_t *parent;
  122. };
  123. struct evt_slot_rule_t
  124. {
  125. struct list_head entry;
  126. evt_trigger_t *parent;
  127. int positive;
  128. char *code;
  129. char *message;
  130. evt_slot_t *ref_slot;
  131. };
  132. struct evt_trigger_t
  133. {
  134. struct list_head entry;
  135. evt_engine_t *parent;
  136. struct list_head sysvar_list;
  137. struct list_head slot_rule_list;
  138. int log_type;
  139. int severity_level;
  140. int sys_code;
  141. int user_code;
  142. int delay_ms;
  143. int delay_timer_id; // if delay_ms != 0
  144. char *msg;
  145. struct list_head use_entry;
  146. };
  147. struct evt_engine_t
  148. {
  149. evt_engine_callback_t cb;
  150. struct list_head trigger_list;
  151. htable_t *filter_ht;
  152. htable_t *sysvar_ht;
  153. htable_t *slot_ht;
  154. spinlock_t lock;
  155. };
  156. static __inline void env_engine_lock(evt_engine_t *engine)
  157. {
  158. spinlock_enter(&engine->lock, -1);
  159. }
  160. static __inline void env_engine_unlock(evt_engine_t *engine)
  161. {
  162. spinlock_leave(&engine->lock);
  163. }
  164. static __inline unsigned int filter_key_hasher(const evt_filter_key_t *key)
  165. {
  166. return (unsigned int)key->listen_id;
  167. }
  168. static __inline int filter_key_cmp(const evt_filter_key_t *key1, const evt_filter_key_t *key2)
  169. {
  170. return key1->listen_id - key2->listen_id;
  171. }
  172. IMPLEMENT_HTABLE_STATIC(filter, evt_filter_key_t, evt_filter_t, key, hentry, filter_key_hasher, filter_key_cmp)
  173. static __inline unsigned int sysevt_key_hasher(const evt_sysvar_key_t *key)
  174. {
  175. return key->index_hash_code;
  176. }
  177. static __inline int sysevt_key_cmp(const evt_sysvar_key_t *key1, const evt_sysvar_key_t *key2)
  178. {
  179. return strcmp(key1->code, key2->code);
  180. }
  181. IMPLEMENT_HTABLE_STATIC(sysvar, evt_sysvar_key_t, evt_sysvar_t, key, hentry, sysevt_key_hasher, sysevt_key_cmp)
  182. static __inline unsigned int slot_key_hasher(const evt_slot_key_t *key)
  183. {
  184. return key->index_hash_code;
  185. }
  186. static __inline int sysevt_key_cmp(const evt_slot_key_t *key1, const evt_slot_key_t *key2)
  187. {
  188. return strcmp(key1->code, key2->code);
  189. }
  190. IMPLEMENT_HTABLE_STATIC(slot, evt_slot_key_t, evt_slot_t, key, hentry, slot_key_hasher, sysevt_key_cmp)
  191. static int process_trigger_list(evt_engine_t *engine, struct list_head *trigger_list);
  192. static int postprocess_slot_list(evt_engine_t *engine, struct list_head *affect_list);
  193. static void clear_slot_list(struct list_head *affect_list);
  194. static void clear_trigger_list(struct list_head *matched_trigger_list);
  195. static int generate_trigger_log(evt_engine_t *engine, evt_trigger_t *trigger);
  196. static int detect_loop();
  197. static void filter_free(evt_filter_t *filter)
  198. {
  199. if (filter) {
  200. if (filter->entity)
  201. free(filter->entity);
  202. free(filter);
  203. }
  204. }
  205. static void slot_free(evt_slot_t *slot)
  206. {
  207. if (slot) {
  208. if (slot->key.code) {
  209. toolkit_free(slot->key.code);
  210. }
  211. if (slot->arr_filter) {
  212. int i;
  213. for (i = 0; i < slot->arr_filter->nelts; ++i) {
  214. evt_filter_t *filter = ARRAY_IDX(slot->arr_filter, i, evt_filter_t*);
  215. filter_free(filter);
  216. }
  217. array_free(slot->arr_filter);
  218. }
  219. if (slot->arr_reset) {
  220. int i;
  221. for (i = 0; i < slot->arr_reset->nelts; ++i) {
  222. toolkit_free(ARRAY_IDX(slot->arr_reset, i, char*));
  223. }
  224. array_free(slot->arr_reset);
  225. }
  226. if (slot->arr_ref_trigger) {
  227. array_free(slot->arr_ref_trigger);
  228. }
  229. if (slot->arr_rref_reset) {
  230. array_free(slot->arr_rref_reset);
  231. }
  232. if (slot->arr_ref_reset) {
  233. array_free(slot->arr_ref_reset);
  234. }
  235. if (slot->arr_slotvar) {
  236. int i;
  237. for (i = 0; i < slot->arr_slotvar->nelts; ++i) {
  238. evt_slotvar_t *slotvar = ARRAY_IDX(slot->arr_slotvar, i, evt_slotvar_t*);
  239. if (slotvar->name)
  240. free(slotvar->name);
  241. if (slotvar->init_value)
  242. free(slotvar->init_value);
  243. if (slotvar->current_value)
  244. free(slotvar->current_value);
  245. free(slotvar);
  246. }
  247. array_free(slot->arr_slotvar);
  248. }
  249. if (slot->timer) {
  250. if (slot->signal_state) {
  251. int rc;
  252. evt_engine_t *engine = slot->parent;
  253. rc = engine->cb.kill_timer(engine, slot->timer->timer_id, engine->cb.user_data);
  254. if (rc != 0)
  255. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("kill timer %d failed!", slot->timer->timer_id);}
  256. slot->timer->timer_id = -1;
  257. }
  258. free(slot->timer);
  259. }
  260. free(slot);
  261. }
  262. }
  263. static void sysvar_free(evt_sysvar_t *sysvar)
  264. {
  265. if (sysvar) {
  266. if (sysvar->arr_ref_rule)
  267. array_free(sysvar->arr_ref_rule);
  268. if (sysvar->key.code)
  269. free(sysvar->key.code);
  270. free(sysvar);
  271. }
  272. }
  273. static void trigger_free(evt_trigger_t *trigger)
  274. {
  275. if (trigger) {
  276. evt_slot_rule_t *slot_rule, *n1;
  277. evt_sysvar_rule_t *sysvar_rule, *n2;
  278. if (trigger->msg)
  279. free(trigger->msg);
  280. list_for_each_entry_safe(slot_rule, n1, &trigger->slot_rule_list, evt_slot_rule_t, entry) {
  281. list_del(&slot_rule->entry);
  282. //if (slot_rule->code)
  283. //free(slot_rule->code);
  284. free(slot_rule);
  285. }
  286. list_for_each_entry_safe(sysvar_rule, n2, &trigger->sysvar_list, evt_sysvar_rule_t, entry) {
  287. list_del(&sysvar_rule->entry);
  288. if (sysvar_rule->arr_state) {
  289. int i;
  290. for (i = 0; i < sysvar_rule->arr_state->nelts; ++i) {
  291. free(ARRAY_IDX(sysvar_rule->arr_state, i, char*));
  292. }
  293. array_free(sysvar_rule->arr_state);
  294. }
  295. free(sysvar_rule);
  296. }
  297. free(trigger);
  298. }
  299. }
  300. static void slot_rule_free(evt_slot_rule_t *rule)
  301. {
  302. if (rule) {
  303. if (rule->code)
  304. free(rule->code);
  305. if (rule->message)
  306. free(rule->message);
  307. free(rule);
  308. }
  309. }
  310. static void sysvar_rule_free(evt_sysvar_rule_t *rule)
  311. {
  312. if (rule) {
  313. if (rule->arr_state) {
  314. int i;
  315. for (i = 0; i < rule->arr_state->nelts; ++i) {
  316. free(ARRAY_IDX(rule->arr_state, i, char*));
  317. }
  318. array_free(rule->arr_state);
  319. }
  320. free(rule);
  321. }
  322. }
  323. static void output_char(char **po, int *poi, int *pon, char *s, int sn)
  324. {
  325. char *o = *po;
  326. int on = *pon;
  327. int oi = *poi;
  328. if (sn == -1)
  329. sn = strlen(s);
  330. while (on-oi <= sn) {
  331. on = on * 2;
  332. o = (char*)realloc(o, on);
  333. }
  334. memcpy(o+oi, s, sn);
  335. oi += sn;
  336. *po = o;
  337. *poi = oi;
  338. *pon = on;
  339. }
  340. static evt_slotvar_t *slot_find_var(evt_slot_t *slot, char *s)
  341. {
  342. int i;
  343. for (i = 0; i < slot->arr_slotvar->nelts; ++i) {
  344. evt_slotvar_t *slotvar = ARRAY_IDX(slot->arr_slotvar, i, evt_slotvar_t*);
  345. if (_stricmp(slotvar->name, s) == 0)
  346. return slotvar;
  347. }
  348. return NULL;
  349. }
  350. static char *expand_slot_rule_message(evt_slot_rule_t *slot_rule)
  351. {
  352. int oi = 0;
  353. int on = 32;
  354. char *o = (char*)malloc(on);
  355. int m = 0;
  356. char *s = NULL;
  357. char *p = slot_rule->message;
  358. while (*p) {
  359. if (m == 0) {
  360. if (p[0] == '$' && p[1] == '(') {
  361. m = 1;
  362. p++;
  363. } else {
  364. output_char(&o, &oi, &on, p, 1);
  365. }
  366. } else {
  367. if (p[0] == ')') {
  368. if (s) {
  369. char *t = (char*)malloc(p - s + 1);
  370. memcpy(t, s, p-s);
  371. t[p-s] = 0;
  372. evt_slotvar_t *slotvar = slot_find_var(slot_rule->ref_slot, t);
  373. free(t);
  374. if (slotvar) {
  375. output_char(&o, &oi, &on, slotvar->current_value, -1);
  376. }
  377. s = NULL;
  378. m = 0;
  379. }
  380. } else {
  381. if (!s) {
  382. s = p;
  383. }
  384. }
  385. }
  386. p++;
  387. }
  388. o[oi] = 0;
  389. return o;
  390. }
  391. static char *expand_trigger_message(evt_trigger_t *trigger)
  392. {
  393. int oi = 0;
  394. int on = 32;
  395. char *o = (char*)malloc(on);
  396. evt_slot_rule_t *tpos;
  397. list_for_each_entry(tpos, &trigger->slot_rule_list, evt_slot_rule_t, entry) {
  398. if (tpos->message) {
  399. char *t = expand_slot_rule_message(tpos);
  400. if (t) {
  401. output_char(&o, &oi, &on, t, -1);
  402. free(t);
  403. }
  404. }
  405. }
  406. if (trigger->msg) {
  407. output_char(&o, &oi, &on, trigger->msg, -1);
  408. }
  409. o[oi] = 0;
  410. return o;
  411. }
  412. static void get_matched_slot_list(evt_engine_t *engine, const CAutoArray<CUUID> &SubIDs, int log_type, int ent_id, int severity, int sys_code, int usr_code, const char *message, struct list_head *use_list)
  413. {
  414. #if 0
  415. evt_filter_key_t k;
  416. int i, j;
  417. for (j = 0; j < 3; ++j) {
  418. if (j == 0) {
  419. k.user_code = usr_code; // strict match
  420. } else if (j == 1) {
  421. k.user_code = -2; // accept any
  422. } else {
  423. if (usr_code) {
  424. k.user_code = -1; // reject ones that has no user code
  425. } else {
  426. continue;
  427. }
  428. }
  429. for (i = 0; i < engine->masks_cnt; ++i) {
  430. evt_filter_t *filter;
  431. int t = engine->masks[i];
  432. k.log_type = (t & BIT_MASK(LOG_FILTER_BIT_LOGTYPE)) ? Log_Ignore : log_type;
  433. k.ent_id = (t & BIT_MASK(LOG_FILTER_BIT_ENTITY)) ? -1 : ent_id;
  434. k.severity = (t & BIT_MASK(LOG_FILTER_BIT_SEVERITY)) ? Severity_None : severity;
  435. k.sys_code = (t & BIT_MASK(LOG_FILTER_BIT_SYSCODE)) ? Error_IgnoreAll : sys_code;
  436. k.index_hash_code = hash_filter(k.log_type, k.ent_id, k.severity, k.sys_code, k.user_code);
  437. filter = filter_find(engine->filter_ht, &k);
  438. while (filter) {
  439. int ii;
  440. for (ii = 0; ii < filter->arr_ref_slot->nelts; ++ii) {
  441. evt_slot_t *slot = ARRAY_IDX(filter->arr_ref_slot, ii, evt_slot_t*);
  442. if (!slot->use_entry.next) {
  443. list_add_tail(&slot->use_entry, use_list);
  444. slot->use_list_ptr = use_list;
  445. }
  446. }
  447. filter = filter_find_continue(engine->filter_ht, &filter->hentry, &k);
  448. }
  449. }
  450. }
  451. #endif
  452. int i;
  453. for (i = 0; i < SubIDs.GetCount(); ++i) {
  454. evt_filter_t *filter;
  455. evt_filter_key_t k;
  456. k.listen_id = (unsigned int)SubIDs[i];
  457. filter = filter_find(engine->filter_ht, &k);
  458. if (filter) {
  459. evt_slot_t *slot = filter->owner;
  460. if (nIslog)
  461. {
  462. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("filter found, usr_code:%d, listen_id:%d", usr_code, k.listen_id);
  463. }
  464. if (!slot->use_entry.next) {
  465. list_add_tail(&slot->use_entry, use_list);
  466. slot->use_list_ptr = use_list;
  467. }
  468. if (filter->content_to_var) {
  469. if (filter->content_to_var->current_value)
  470. free(filter->content_to_var->current_value);
  471. filter->content_to_var->current_value = _strdup(message);
  472. }
  473. } else {
  474. if (nIslog)
  475. {
  476. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cannot find filter, listen_id:%d", k.listen_id);
  477. }
  478. }
  479. }
  480. }
  481. static void get_reset_slot_list(evt_engine_t *engine, struct list_head *matched_list, struct list_head *reset_list)
  482. {
  483. evt_slot_t *pos;
  484. list_for_each_entry(pos, matched_list, evt_slot_t, use_entry) {
  485. if (pos->arr_ref_reset) {
  486. int i;
  487. for (i = 0; i < pos->arr_ref_reset->nelts; ++i) {
  488. evt_slot_t *t = ARRAY_IDX(pos->arr_ref_reset, i, evt_slot_t*);
  489. if (!t->use_entry.next) {
  490. list_add_tail(&t->use_entry, reset_list);
  491. t->use_list_ptr = reset_list;
  492. } else {
  493. if (t->use_list_ptr == matched_list) {
  494. if (nIslog)
  495. {
  496. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("warning: slot %s already set, cannot reset from slot %s ", t->key.code, pos->key.code);
  497. }
  498. } else if (t->use_list_ptr == reset_list) {
  499. // already triggers by others
  500. } else {
  501. if (nIslog)
  502. {
  503. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("bug detected! %s%d", __FUNCTION__, __LINE__);
  504. }
  505. }
  506. }
  507. }
  508. }
  509. }
  510. }
  511. static void get_matched_trigger_list(evt_engine_t *engine, struct list_head *use_slot_list, struct list_head *use_trigger_list)
  512. {
  513. evt_slot_t *pos;
  514. list_for_each_entry(pos, use_slot_list, evt_slot_t, use_entry) {
  515. int i;
  516. for (i = 0; i < pos->arr_ref_trigger->nelts; ++i) {
  517. evt_trigger_t *trigger = ARRAY_IDX(pos->arr_ref_trigger, i, evt_trigger_t*);
  518. if (!trigger->use_entry.next) {
  519. list_add_tail(&trigger->use_entry, use_trigger_list);
  520. }
  521. }
  522. }
  523. }
  524. static void timer_cb(int timer_id, void *user_data)
  525. {
  526. evt_slot_t *slot = (evt_slot_t*)user_data;
  527. evt_engine_t *engine = slot->parent;
  528. if (timer_id == slot->timer->timer_id) {
  529. int rc;
  530. struct list_head affect_list = LIST_HEAD_INIT(affect_list);
  531. struct list_head trigger_list = LIST_HEAD_INIT(trigger_list);
  532. list_add_tail(&slot->use_entry, &affect_list);
  533. slot->use_list_ptr = &affect_list;
  534. slot->signal_state = !slot->signal_state;
  535. if (!slot->signal_state && slot->arr_slotvar) {
  536. int i;
  537. for (i = 0; i < slot->arr_slotvar->nelts; ++i) {
  538. evt_slotvar_t *slotvar = ARRAY_IDX(slot->arr_slotvar, i, evt_slotvar_t *);
  539. free(slotvar->current_value);
  540. slotvar->current_value = _strdup(slotvar->init_value);
  541. }
  542. }
  543. engine->cb.kill_timer(engine, slot->timer->timer_id, engine->cb.user_data);
  544. slot->timer->timer_id = -1;
  545. get_matched_trigger_list(engine, &affect_list, &trigger_list);
  546. rc = process_trigger_list(engine, &trigger_list);
  547. if (rc != 0) {
  548. if (nIslog)
  549. {
  550. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process trigger list failed!");
  551. }
  552. return;
  553. }
  554. rc = postprocess_slot_list(engine, &affect_list);
  555. if (rc != 0) {
  556. if (nIslog)
  557. {
  558. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("postprocess slotlist failed!");
  559. }
  560. return;
  561. }
  562. clear_slot_list(&affect_list);
  563. clear_trigger_list(&trigger_list);
  564. }
  565. }
  566. static void trigger_timer_cb(int timer_id, void *user_data)
  567. {
  568. evt_trigger_t *trigger = (evt_trigger_t *)user_data;
  569. evt_engine_t *engine = trigger->parent;
  570. if (timer_id == trigger->delay_timer_id) {
  571. generate_trigger_log(engine, trigger);
  572. engine->cb.kill_timer(engine, trigger->delay_timer_id, engine->cb.user_data);
  573. trigger->delay_timer_id = -1;
  574. }
  575. }
  576. static int process_matched_slot(evt_engine_t *engine, evt_slot_t *slot, int *removed)
  577. {
  578. int rc = 0;
  579. if (slot->signal_state) {
  580. // reset timer
  581. if (slot->timer) {
  582. rc = engine->cb.kill_timer(engine, slot->timer->timer_id, engine->cb.user_data);
  583. if (rc != 0) {
  584. if (nIslog)
  585. {
  586. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("kill timer failed! slot: %s, timer_id: %d", slot->key.code, slot->timer->timer_id);
  587. }
  588. } else {
  589. int new_id = engine->cb.new_timer_id(engine, engine->cb.user_data);
  590. slot->timer->timer_id = new_id;
  591. rc = engine->cb.set_timer(engine, new_id, slot->timer->timeout, &timer_cb, slot, engine->cb.user_data);
  592. if (rc != 0) {
  593. if (nIslog)
  594. {
  595. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("set timer failed! slot: %s, timer_id: %d", slot->key.code, new_id);
  596. }
  597. }
  598. }
  599. }
  600. if (removed)
  601. *removed = TRUE;
  602. } else {
  603. slot->signal_state = !slot->signal_state;
  604. if (slot->timer) {
  605. int new_id = engine->cb.new_timer_id(engine, engine->cb.user_data);
  606. slot->timer->timer_id = new_id;
  607. rc = engine->cb.set_timer(engine, new_id, slot->timer->timeout, &timer_cb, slot, engine->cb.user_data);
  608. if (rc != 0) {
  609. if (nIslog)
  610. {
  611. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("set timer failed! slot: %s, timer_id: %d", slot->key.code, new_id);
  612. }
  613. }
  614. }
  615. if (removed)
  616. *removed = FALSE;
  617. }
  618. return rc;
  619. }
  620. static int process_matched_slot_list(evt_engine_t *engine, struct list_head *slot_list)
  621. {
  622. evt_slot_t *pos, *n;
  623. int rc = 0;
  624. list_for_each_entry_safe(pos, n, slot_list, evt_slot_t, use_entry) {
  625. int removed;
  626. rc = process_matched_slot(engine, pos, &removed);
  627. if (rc != 0) {
  628. if (nIslog)
  629. {
  630. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process matched slot %s failed!", pos->key.code);
  631. }
  632. break;
  633. }
  634. if (removed) {
  635. list_del(&pos->use_entry);
  636. pos->use_entry.next = pos->use_entry.prev = NULL;
  637. pos->use_list_ptr = NULL;
  638. }
  639. }
  640. return rc;
  641. }
  642. static int process_reset_slot(evt_engine_t *engine, evt_slot_t *slot, int *removed)
  643. {
  644. int rc = 0;
  645. if (nIslog)
  646. {
  647. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process reset slot: %s, current signal:%d", slot->key.code, slot->signal_state);
  648. }
  649. if (slot->signal_state) {
  650. slot->signal_state = !slot->signal_state;
  651. if (slot->timer) {
  652. rc = engine->cb.kill_timer(engine, slot->timer->timer_id, engine->cb.user_data);
  653. slot->timer->timer_id = -1;
  654. }
  655. if (removed)
  656. *removed = FALSE;
  657. if (slot->arr_slotvar) {
  658. int i;
  659. for (i = 0; i < slot->arr_slotvar->nelts; ++i) {
  660. evt_slotvar_t* slotvar = ARRAY_IDX(slot->arr_slotvar, i, evt_slotvar_t*);
  661. free(slotvar->current_value);
  662. slotvar->current_value = _strdup(slotvar->init_value);
  663. }
  664. }
  665. } else {
  666. if (removed)
  667. *removed = TRUE;
  668. }
  669. return rc;
  670. }
  671. static int process_reset_slot_list(evt_engine_t *engine, struct list_head *reset_list)
  672. {
  673. evt_slot_t *pos, *n;
  674. int rc = 0;
  675. list_for_each_entry_safe(pos, n, reset_list, evt_slot_t, use_entry) {
  676. int removed;
  677. rc = process_reset_slot(engine, pos, &removed);
  678. if (rc != 0) {
  679. if (nIslog)
  680. {
  681. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process reset slot %s failed!", pos->key.code);
  682. }
  683. break;
  684. }
  685. if (removed) {
  686. list_del(&pos->use_entry);
  687. pos->use_entry.next = pos->use_entry.prev = NULL;
  688. pos->use_list_ptr = NULL;
  689. }
  690. }
  691. return rc;
  692. }
  693. static int generate_trigger_log(evt_engine_t *engine, evt_trigger_t *trigger)
  694. {
  695. int rc = Error_Succeed;
  696. char *msg = expand_trigger_message(trigger);
  697. switch (trigger->log_type) {
  698. case Log_Warning:
  699. LogWarn((SeverityLevelEnum)trigger->severity_level,(ErrorCodeEnum)trigger->sys_code, (DWORD)trigger->user_code,msg);
  700. break;
  701. case Log_Debug:
  702. LogTrace(msg, __FILE__, __LINE__);
  703. break;
  704. case Log_Error:
  705. LogError((SeverityLevelEnum)trigger->severity_level, (ErrorCodeEnum)trigger->sys_code, trigger->user_code, msg);
  706. break;
  707. case Log_Event:
  708. LogEvent((SeverityLevelEnum)trigger->severity_level, (DWORD)trigger->user_code,msg);
  709. break;
  710. default:
  711. if (nIslog)
  712. {
  713. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("bug detected! %s %d", __FUNCTION__, __LINE__);
  714. }
  715. assert(0);
  716. rc = Error_Bug;
  717. }
  718. free(msg);
  719. return rc;
  720. }
  721. static int process_trigger(evt_engine_t *engine, evt_trigger_t *trigger)
  722. {
  723. int rc = 0;
  724. int ok = 0;
  725. if (nIslog)
  726. {
  727. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process_trigger %s begin!", trigger->msg);
  728. }
  729. {
  730. evt_slot_rule_t *pos;
  731. list_for_each_entry(pos, &trigger->slot_rule_list, evt_slot_rule_t, entry) {
  732. if (nIslog)
  733. {
  734. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("slot rule, code:%s positive:%d signal:%d", pos->code, pos->positive, pos->ref_slot->signal_state);
  735. }
  736. if (pos->positive ^ pos->ref_slot->signal_state)
  737. goto on_done;
  738. }
  739. }
  740. {
  741. evt_sysvar_rule_t *pos;
  742. list_for_each_entry(pos, &trigger->sysvar_list, evt_sysvar_rule_t, entry) {
  743. int i;
  744. CSimpleStringA strState;
  745. rc = engine->cb.get_sysevent(engine, pos->ref_sysvar->key.code, strState, engine->cb.user_data);
  746. if (rc != 0) {
  747. if (nIslog)
  748. {
  749. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get sysvar failed!");
  750. }
  751. goto on_done;
  752. }
  753. if (nIslog)
  754. {
  755. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sysvar key=%s, value=%s", pos->ref_sysvar->key.code, (LPCSTR)strState);
  756. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sysvar rule, %s, positive:%d", pos->ref_sysvar->key.code, pos->positive);
  757. }
  758. if (pos->positive) {
  759. for (i = 0; i < pos->arr_state->nelts; ++i) {
  760. char *state = ARRAY_IDX(pos->arr_state, i, char*);
  761. if (nIslog)
  762. {
  763. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sys var state:%s", state);
  764. }
  765. if (strcmp(strState, state) == 0) {
  766. break;
  767. }
  768. }
  769. if (i == pos->arr_state->nelts)
  770. goto on_done;
  771. } else {
  772. for (i = 0; i < pos->arr_state->nelts; ++i) {
  773. char *state = ARRAY_IDX(pos->arr_state, i, char*);
  774. if (nIslog)
  775. {
  776. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("sys var state:%s", state);
  777. }
  778. if (strcmp(strState, state) == 0) {
  779. goto on_done;
  780. }
  781. }
  782. }
  783. }
  784. }
  785. ok = 1;
  786. on_done:
  787. if (ok) {
  788. if (trigger->delay_ms != 0 && trigger->delay_timer_id == -1) {
  789. trigger->delay_timer_id = engine->cb.new_timer_id(engine, engine->cb.user_data);
  790. rc = engine->cb.set_timer(engine, trigger->delay_timer_id, trigger->delay_ms, &trigger_timer_cb, trigger, engine->cb.user_data);
  791. if (rc != 0) {
  792. if (nIslog)
  793. {
  794. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("set timer failed!");
  795. }
  796. }
  797. } else {
  798. rc = generate_trigger_log(engine, trigger);
  799. if (rc != 0) {
  800. if (nIslog)
  801. {
  802. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("generate trigger log failed!");
  803. }
  804. }
  805. }
  806. } else {
  807. if (trigger->delay_timer_id != -1) {
  808. engine->cb.kill_timer(engine, trigger->delay_timer_id, engine->cb.user_data);
  809. trigger->delay_timer_id = -1;
  810. }
  811. }
  812. if (nIslog)
  813. {
  814. DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("process_trigger end (ok=%d)!", ok);
  815. }
  816. return rc;
  817. }
  818. static int process_trigger_list(evt_engine_t *engine, struct list_head *trigger_list)
  819. {
  820. evt_trigger_t *pos;
  821. int rc = 0;
  822. list_for_each_entry(pos, trigger_list, evt_trigger_t, use_entry) {
  823. rc = process_trigger(engine, pos);
  824. if (rc != 0)
  825. break;
  826. }
  827. return rc;
  828. }
  829. static int postprocess_slot_list(evt_engine_t *engine, struct list_head *affect_list)
  830. {
  831. int rc = 0;
  832. evt_slot_t *pos;
  833. list_for_each_entry(pos, affect_list, evt_slot_t, use_entry) {
  834. if (pos->once && pos->signal_state) {
  835. pos->signal_state = !pos->signal_state;
  836. if (pos->timer) {
  837. rc = engine->cb.kill_timer(engine, pos->timer->timer_id, engine->cb.user_data);
  838. pos->timer->timer_id = -1;
  839. if (rc != 0) {
  840. if (nIslog)
  841. {
  842. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("postprocess slot %s failed!", pos->key.code);
  843. }
  844. return rc;
  845. }
  846. }
  847. }
  848. }
  849. return rc;
  850. }
  851. static void clear_slot_list(struct list_head *affect_list)
  852. {
  853. evt_slot_t *pos, *n;
  854. list_for_each_entry_safe(pos, n, affect_list, evt_slot_t, use_entry) {
  855. list_del(&pos->use_entry);
  856. pos->use_entry.next = pos->use_entry.prev = NULL;
  857. pos->use_list_ptr = NULL;
  858. }
  859. }
  860. static void clear_trigger_list(struct list_head *matched_trigger_list)
  861. {
  862. evt_trigger_t *pos, *n;
  863. list_for_each_entry_safe(pos, n, matched_trigger_list, evt_trigger_t, use_entry) {
  864. list_del(&pos->use_entry);
  865. pos->use_entry.next = pos->use_entry.prev = NULL;
  866. }
  867. };
  868. static int process_log(evt_engine_t *engine, const CAutoArray<CUUID> &SubIDs, int log_type, int ent_id, int severity, int sys_code, int usr_code, const char *message)
  869. {
  870. int rc;
  871. struct list_head matched_list = LIST_HEAD_INIT(matched_list);
  872. struct list_head reset_list = LIST_HEAD_INIT(reset_list);
  873. struct list_head affect_list = LIST_HEAD_INIT(affect_list);
  874. struct list_head matched_trigger_list = LIST_HEAD_INIT(matched_trigger_list);
  875. get_matched_slot_list(engine, SubIDs,log_type, ent_id, severity, sys_code, usr_code, message, &matched_list);
  876. if (list_empty(&matched_list)) {
  877. if (nIslog)
  878. {
  879. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("warning: no matched slot! sys_code = %d, usr_code = %d", sys_code, usr_code);
  880. }
  881. return 0;
  882. }
  883. get_reset_slot_list(engine, &matched_list, &reset_list);
  884. rc = process_matched_slot_list(engine, &matched_list);
  885. if (rc != 0) {
  886. if (nIslog)
  887. {
  888. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process matched slot list failed!");
  889. }
  890. return rc;
  891. }
  892. rc = process_reset_slot_list(engine, &reset_list);
  893. if (rc != 0) {
  894. if (nIslog)
  895. {
  896. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process reset slot list failed!");
  897. }
  898. return rc;
  899. }
  900. list_splice_tail(&matched_list, &affect_list);
  901. list_splice_tail(&reset_list, &affect_list);
  902. get_matched_trigger_list(engine, &affect_list, &matched_trigger_list);
  903. rc = process_trigger_list(engine, &matched_trigger_list);
  904. if (rc != 0) {
  905. if (nIslog)
  906. {
  907. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process trigger list failed!");
  908. }
  909. return rc;
  910. }
  911. rc = postprocess_slot_list(engine, &affect_list);
  912. if (rc != 0) {
  913. if (nIslog)
  914. {
  915. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("postprocess slot list failed!");
  916. }
  917. return rc;
  918. }
  919. clear_slot_list(&affect_list);
  920. clear_trigger_list(&matched_trigger_list);
  921. return rc;
  922. }
  923. static int process_sysvar(evt_engine_t *engine, evt_sysvar_t *sysvar, const char *old_value, const char *curr_value)
  924. {
  925. int i;
  926. int rc = 0;
  927. struct list_head trigger_list = LIST_HEAD_INIT(trigger_list);
  928. for (i = 0; i < sysvar->arr_ref_rule->nelts; ++i) {
  929. evt_sysvar_rule_t *rule = ARRAY_IDX(sysvar->arr_ref_rule, i, evt_sysvar_rule_t*);
  930. evt_trigger_t *trigger = rule->parent;
  931. if (!trigger->use_entry.next) {
  932. list_add_tail(&trigger->use_entry, &trigger_list);
  933. }
  934. }
  935. rc = process_trigger_list(engine, &trigger_list);
  936. if (rc != 0) {
  937. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process trigger list failed!");}
  938. }
  939. clear_trigger_list(&trigger_list);
  940. return rc;
  941. }
  942. static int build_ref(evt_engine_t *engine)
  943. {
  944. int i;
  945. evt_trigger_t *trigger;
  946. for (i = 0; i < engine->slot_ht->size; ++i) {
  947. evt_slot_t *tpos;
  948. struct hlist_node *pos;
  949. hlist_for_each_entry(tpos, pos, &engine->slot_ht->buckets[i], evt_slot_t, hentry) {
  950. int j;
  951. for (j = 0; j < tpos->arr_reset->nelts; ++j) {
  952. char *code = ARRAY_IDX(tpos->arr_reset, j, char*);
  953. evt_slot_key_t key;
  954. key.code = code;
  955. key.index_hash_code = hash32_str(code, HASH32_STR_INIT);
  956. evt_slot_t *ref_slot = slot_find(engine->slot_ht, &key);
  957. if (ref_slot) {
  958. ARRAY_PUSH(ref_slot->arr_rref_reset, evt_slot_t*) = tpos;
  959. ARRAY_PUSH(tpos->arr_ref_reset, evt_slot_t*) = ref_slot;
  960. } else {
  961. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cannot build reset ref for slot %s->%s", tpos->key.code, code);}
  962. return Error_Unexpect;
  963. }
  964. }
  965. }
  966. }
  967. list_for_each_entry(trigger, &engine->trigger_list, evt_trigger_t, entry) {
  968. evt_slot_rule_t *rule;
  969. list_for_each_entry(rule, &trigger->slot_rule_list, evt_slot_rule_t, entry) {
  970. evt_slot_key_t key;
  971. key.code = rule->code;
  972. key.index_hash_code = hash32_str(key.code, HASH32_STR_INIT);
  973. evt_slot_t *ref_slot = slot_find(engine->slot_ht, &key);
  974. if (ref_slot) {
  975. rule->ref_slot = ref_slot;
  976. ARRAY_PUSH(ref_slot->arr_ref_trigger, evt_trigger_t*) = rule->parent;
  977. } else {
  978. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger.slot %s cannot find code!", rule->code);}
  979. return Error_Unexpect;
  980. }
  981. }
  982. }
  983. return 0;
  984. }
  985. // HH:MM:SS.mmm or MM:SS.mmm or xxxms or xxx
  986. // 10:10:10 -> 10h 10m 10 second
  987. // 1:00 -> 1min = 1000ms
  988. // 1s -> 1 second = 1000ms
  989. // 1000 -> 1000millisecond
  990. // 1000ms -> 1000millisecond
  991. // 1min -> 1000millisecond
  992. // return millisecond
  993. static int parse_timeout_value(const char *s)
  994. {
  995. int t[8] = {0};
  996. int tc = 0;
  997. const char *p = s;
  998. #define PARSE_T_COLON 0x7fff0000
  999. #define PARSE_T_DOT 0x7fff0001
  1000. #define PARSE_T_MIN 0x7fff0002
  1001. #define PARSE_T_MS 0x7fff0003
  1002. #define PARSE_T_S 0x7fff0004
  1003. #define PARSE_T_H 0x7fff0005
  1004. while (*p && tc < 8) {
  1005. switch (*p) {
  1006. case ':':
  1007. t[tc++] = PARSE_T_COLON;
  1008. p++;
  1009. break;
  1010. case '.':
  1011. t[tc++] = PARSE_T_DOT;
  1012. p++;
  1013. break;
  1014. case 's':
  1015. t[tc++] = PARSE_T_S;
  1016. p++;
  1017. break;
  1018. case 'h':
  1019. t[tc++] = PARSE_T_H;
  1020. p++;
  1021. break;
  1022. case 'm':
  1023. if (p[1] == 'i' && p[2] == 'n') {
  1024. t[tc++] = PARSE_T_MIN;
  1025. p += 3;
  1026. } else if (p[1] == 's') {
  1027. t[tc++] = PARSE_T_MS;
  1028. p += 2;
  1029. }
  1030. break;
  1031. case '0':
  1032. case '1':
  1033. case '2':
  1034. case '3':
  1035. case '4':
  1036. case '5':
  1037. case '6':
  1038. case '7':
  1039. case '8':
  1040. case '9':
  1041. {
  1042. int x = *p - '0';
  1043. ++p;
  1044. while (*p >= '0' && *p <= '9') {
  1045. x = x * 10 + (*p - '0');
  1046. p++;
  1047. }
  1048. if (x >= 0x7fff0000)
  1049. return -1;
  1050. t[tc++] = x;
  1051. }
  1052. break;
  1053. default:
  1054. return -1;
  1055. }
  1056. }
  1057. switch (tc) {
  1058. case 0:
  1059. return 0;
  1060. case 1:
  1061. if (t[0] < 0x7fff0000)
  1062. return t[0];
  1063. break;
  1064. case 2:
  1065. if (t[0] < 0x7fff0000) {
  1066. if (t[1] == PARSE_T_S) {
  1067. return t[0] * 1000;
  1068. } else if (t[1] == PARSE_T_MS) {
  1069. return t[0];
  1070. } else if (t[1] == PARSE_T_H) {
  1071. return t[0] * 60 * 60 * 1000;
  1072. } else if (t[1] == PARSE_T_MIN) {
  1073. return t[0] * 60 * 1000;
  1074. } else {
  1075. return -1;
  1076. }
  1077. } else if (t[0] == PARSE_T_DOT && t[1] < 0x7fff0000) {
  1078. return t[1];
  1079. }
  1080. break;
  1081. case 3:
  1082. if (t[0] < 0x7fff0000 && t[2] < 0x7fff0000) {
  1083. if (t[1] == PARSE_T_DOT) {
  1084. return t[0] * 1000 + t[2];
  1085. } else if (t[1] == PARSE_T_COLON) {
  1086. return (t[0] * 60 + t[2]) * 1000;
  1087. }
  1088. }
  1089. break;
  1090. case 5:
  1091. if (t[0] < 0x7fff0000 && t[2] < 0x7fff0000 && t[4] < 0x7fff0000 && t[1] == PARSE_T_COLON && t[3] == PARSE_T_COLON)
  1092. return ((t[0] * 60 + t[2]) * 60 + t[4]) * 1000;
  1093. break;
  1094. case 7:
  1095. if (t[0] < 0x7fff0000 && t[2] < 0x7fff0000 && t[4] < 0x7fff0000 && t[1] == PARSE_T_COLON && t[3] == PARSE_T_COLON && t[5] == PARSE_T_DOT && t[6] < 0x7fff0000)
  1096. return ((t[0] * 60 + t[2]) * 60 + t[4]) * 1000 + t[6];
  1097. default:
  1098. break;
  1099. }
  1100. return -1;
  1101. }
  1102. static int parse_bool(const char *s)
  1103. {
  1104. if (_stricmp(s, "true") == 0 || _stricmp(s, "1") == 0) {
  1105. return 1;
  1106. } else if (_stricmp(s, "false") == 0 || _stricmp(s, "0") == 0) {
  1107. return 0;
  1108. } else {
  1109. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse bool failed! s : %s", s);}
  1110. return -1;
  1111. }
  1112. }
  1113. static int parse_log_type(const char *s)
  1114. {
  1115. static const char *keys[] = {"Log_Ignore", "Log_Event", "Log_Warning", "Log_Error", "Log_Debug"};
  1116. int i;
  1117. for (i = 0; i < array_size(keys); ++i) {
  1118. if (_stricmp(s, keys[i]) == 0)
  1119. return i;
  1120. }
  1121. return -1;
  1122. }
  1123. static int parse_ent_id(evt_engine_t *engine, const char *s)
  1124. {
  1125. // get entity devel id
  1126. return engine->cb.get_entity_id(engine, s, engine->cb.user_data);
  1127. }
  1128. static int parse_severity(const char *s)
  1129. {
  1130. static const struct {
  1131. char *key;
  1132. int level;
  1133. } ts[] = {
  1134. {"Severity_None", 0},
  1135. {"Severity_Low", 1},
  1136. {"Severity_Middle", 2},
  1137. {"Severity_High", 3},
  1138. {"0", 0},
  1139. {"1", 1},
  1140. {"2", 2},
  1141. {"3", 3},
  1142. };
  1143. for (int i = 0; i < array_size(ts); ++i) {
  1144. if (_stricmp(s, ts[i].key) == 0) {
  1145. return ts[i].level;
  1146. }
  1147. }
  1148. return -1;
  1149. }
  1150. #define DEF_CODE(x) {#x, x},
  1151. static int parse_sys_code(const char *s)
  1152. {
  1153. static const struct {
  1154. const char *code;
  1155. int code_value;
  1156. }keys[] = {
  1157. DEF_CODE(Error_Succeed)
  1158. DEF_CODE(Error_DataCheck)
  1159. DEF_CODE(Error_Null)
  1160. DEF_CODE(Error_Param)
  1161. DEF_CODE(Error_Overflow)
  1162. DEF_CODE(Error_TooSmallBuffer)
  1163. DEF_CODE(Error_NotIntegrated)
  1164. DEF_CODE(Error_TargetBeing)
  1165. DEF_CODE(Error_NoTarget)
  1166. DEF_CODE(Error_NoDefine)
  1167. DEF_CODE(Error_NotImpl)
  1168. DEF_CODE(Error_NotExist)
  1169. DEF_CODE(Error_Duplication)
  1170. DEF_CODE(Error_Unregisted)
  1171. DEF_CODE(Error_AlreadyExist)
  1172. DEF_CODE(Error_MethodNotFound)
  1173. DEF_CODE(Error_Redirect)
  1174. DEF_CODE(Error_InvalidState)
  1175. DEF_CODE(Error_NotInit)
  1176. DEF_CODE(Error_Paused)
  1177. DEF_CODE(Error_Stoped)
  1178. DEF_CODE(Error_Losted)
  1179. DEF_CODE(Error_Closed)
  1180. DEF_CODE(Error_TaskControl)
  1181. DEF_CODE(Error_Pending)
  1182. DEF_CODE(Error_Cancel)
  1183. DEF_CODE(Error_Break)
  1184. DEF_CODE(Error_NotMeetCondition)
  1185. DEF_CODE(Error_NoPrivilege)
  1186. DEF_CODE(Error_MethodSignatureFailed)
  1187. DEF_CODE(Error_PeerAction)
  1188. DEF_CODE(Error_PeerClose)
  1189. DEF_CODE(Error_PeerIgnore)
  1190. DEF_CODE(Error_PeerReject)
  1191. DEF_CODE(Error_PeerDelay)
  1192. DEF_CODE(Error_Process)
  1193. DEF_CODE(Error_NetBroken)
  1194. DEF_CODE(Error_UpdateFailed)
  1195. DEF_CODE(Error_RegistryFailed)
  1196. DEF_CODE(Error_IO)
  1197. DEF_CODE(Error_Readonly)
  1198. DEF_CODE(Error_TimeOut)
  1199. DEF_CODE(Error_BlockTimeOut)
  1200. DEF_CODE(Error_ThreadTimeOut)
  1201. DEF_CODE(Error_QueueTimeOut)
  1202. DEF_CODE(Error_ReplyTimeOut)
  1203. DEF_CODE(Error_Hardware)
  1204. DEF_CODE(Error_DevLoadFileFailed)
  1205. DEF_CODE(Error_DevNotAvailable)
  1206. DEF_CODE(Error_DevAlreadyConnected)
  1207. DEF_CODE(Error_DevConnFailed)
  1208. DEF_CODE(Error_DevCommFailed)
  1209. DEF_CODE(Error_DevMedia)
  1210. DEF_CODE(Error_Debug)
  1211. DEF_CODE(Error_Assert)
  1212. DEF_CODE(Error_Trace)
  1213. DEF_CODE(Error_Bug)
  1214. DEF_CODE(Error_Unrecover)
  1215. DEF_CODE(Error_Resource)
  1216. DEF_CODE(Error_NewProcess)
  1217. DEF_CODE(Error_FailVerify)
  1218. DEF_CODE(Error_Block)
  1219. DEF_CODE(Error_Exception)
  1220. DEF_CODE(Error_Unexpect)
  1221. };
  1222. if (s) {
  1223. if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
  1224. char *p;
  1225. return (int)strtol(&s[2], &p, 16);
  1226. } else if (s[0] <= '9' && s[0] >= '1') {
  1227. return atoi(s);
  1228. } else {
  1229. int i;
  1230. for (i = 0; i < array_size(keys); ++i) {
  1231. if (_stricmp(s, keys[i].code) == 0) {
  1232. return keys[i].code_value;
  1233. }
  1234. }
  1235. }
  1236. }
  1237. return -1;
  1238. }
  1239. static int parse_usr_code(const char *s)
  1240. {
  1241. if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) {
  1242. char *p;
  1243. return (int)strtol(&s[2], &p, 16);
  1244. } else if (s[0] <= '9' && s[0] >= '1') {
  1245. return atoi(s);
  1246. } else {
  1247. return -1;
  1248. }
  1249. }
  1250. static char *parse_code(const char *ns, const char *s)
  1251. {
  1252. if (strchr(s, '.')) {
  1253. return toolkit_strdup(s);
  1254. } else {
  1255. return strdup_printf("%s.%s", ns, s);
  1256. }
  1257. }
  1258. static int extract_filter(evt_engine_t *engine, scew_element *filter_elem, int *p_log_type, int *p_ent_id, const char **p_entity, int *p_severity, int *p_sys_code, int *p_usr_code, const char **p_slotvar)
  1259. {
  1260. int log_type, ent_id, severity, sys_code, usr_code;
  1261. const char *entity = NULL;
  1262. const char *slotvar = NULL;
  1263. scew_attribute *attr;
  1264. attr = scew_element_attribute_by_name(filter_elem, "LogType");
  1265. if (attr) {
  1266. log_type = parse_log_type(scew_attribute_value(attr));
  1267. if (log_type == -1) {
  1268. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse log type failed!");}
  1269. return Error_Unexpect;
  1270. }
  1271. } else {
  1272. log_type = Log_Ignore;
  1273. }
  1274. attr = scew_element_attribute_by_name(filter_elem, "Entity");
  1275. if (attr) {
  1276. ent_id = parse_ent_id(engine, scew_attribute_value(attr));
  1277. if (ent_id == -1) {
  1278. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse entity id failed!");}
  1279. return Error_Unexpect;
  1280. } else {
  1281. entity = scew_attribute_value(attr);
  1282. }
  1283. } else {
  1284. ent_id = -1;
  1285. }
  1286. attr = scew_element_attribute_by_name(filter_elem, "SeverityLevel");
  1287. if (attr) {
  1288. severity = parse_severity(scew_attribute_value(attr));
  1289. if (severity == -1) {
  1290. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse severity level failed!");}
  1291. return Error_Unexpect;
  1292. }
  1293. } else {
  1294. severity = Severity_None;
  1295. }
  1296. attr = scew_element_attribute_by_name(filter_elem, "SysError");
  1297. if (attr) {
  1298. sys_code = parse_sys_code(scew_attribute_value(attr));
  1299. if (sys_code == -1) {
  1300. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse sys code failed! sys_code: %s", scew_attribute_value(attr));}
  1301. return Error_Unexpect;
  1302. }
  1303. } else {
  1304. sys_code = Error_IgnoreAll;
  1305. }
  1306. attr = scew_element_attribute_by_name(filter_elem, "UserCode");
  1307. if (attr) {
  1308. usr_code = parse_usr_code(scew_attribute_value(attr));
  1309. } else {
  1310. usr_code = -2;
  1311. }
  1312. attr = scew_element_attribute_by_name(filter_elem, "ContentToVar");
  1313. if (attr) {
  1314. slotvar = scew_attribute_value(attr);
  1315. } else {
  1316. slotvar = NULL;
  1317. }
  1318. *p_log_type = log_type;
  1319. *p_ent_id = ent_id;
  1320. *p_severity = severity;
  1321. *p_sys_code = sys_code;
  1322. *p_usr_code = usr_code;
  1323. *p_entity = entity;
  1324. *p_slotvar = slotvar;
  1325. return 0;
  1326. }
  1327. static int load_filter(evt_engine_t *engine, evt_slot_t *slot, scew_element *filter_elem)
  1328. {
  1329. evt_filter_t *filter = ZALLOC_T(evt_filter_t);
  1330. const char *entity = NULL;
  1331. const char *slotvar = NULL;
  1332. int rc = extract_filter(engine, filter_elem, &filter->log_type, &filter->ent_id, (const char**)&entity, &filter->severity, &filter->sys_code, &filter->user_code, &slotvar);
  1333. if (rc != 0) {
  1334. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("extract filter failed!");}
  1335. return rc;
  1336. }
  1337. if (slotvar) {
  1338. int i;
  1339. for (i = 0; i < slot->arr_slotvar->nelts; ++i) {
  1340. evt_slotvar_t *var = ARRAY_IDX(slot->arr_slotvar, i, evt_slotvar_t *);
  1341. if (_stricmp(var->name, slotvar) == 0) {
  1342. filter->content_to_var = var;
  1343. break;
  1344. }
  1345. }
  1346. if (!filter->content_to_var) {
  1347. if (nIslog)
  1348. {
  1349. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("cannot find %s slotvar!", slotvar);
  1350. }
  1351. return -1;
  1352. }
  1353. }
  1354. filter->entity = entity ? _strdup(entity) : NULL;
  1355. filter->key.listen_id = 0;
  1356. filter->owner = slot;
  1357. ARRAY_PUSH(slot->arr_filter, evt_filter_t*) = filter;
  1358. return 0;
  1359. }
  1360. static int load_slotvar(evt_engine_t *engine, evt_slot_t *slot, scew_element *slotvar_elem)
  1361. {
  1362. evt_slotvar_t *slotvar = ZALLOC_T(evt_slotvar_t);
  1363. scew_attribute *attr;
  1364. attr = scew_element_attribute_by_name(slotvar_elem, "Name");
  1365. if (attr) {
  1366. slotvar->name = _strdup(scew_attribute_value(attr));
  1367. } else {
  1368. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("not found slot var Name property!");}
  1369. return -1;
  1370. }
  1371. attr = scew_element_attribute_by_name(slotvar_elem, "Value");
  1372. if (attr) {
  1373. slotvar->init_value = _strdup(scew_attribute_value(attr));
  1374. slotvar->current_value = _strdup(slotvar->init_value);
  1375. } else {
  1376. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("not found slot var Value property!");}
  1377. return -1;
  1378. }
  1379. ARRAY_PUSH(slot->arr_slotvar, evt_slotvar_t*) = slotvar;
  1380. return 0;
  1381. }
  1382. static int load_slot(evt_engine_t *engine, const char *ns, scew_element *slot_elem)
  1383. {
  1384. evt_slot_t *slot = ZALLOC_T(evt_slot_t);
  1385. if (!slot)
  1386. return Error_Resource;
  1387. INIT_HLIST_NODE(&slot->hentry);
  1388. slot->arr_filter = array_make(-1, sizeof(evt_filter_t*));
  1389. slot->arr_reset = array_make(-1, sizeof(char*));
  1390. slot->arr_rref_reset = array_make(-1, sizeof(evt_slot_t*));
  1391. slot->arr_ref_reset = array_make(-1, sizeof(evt_slot_t*));
  1392. slot->arr_ref_trigger = array_make(-1, sizeof(evt_trigger_t*));
  1393. slot->arr_slotvar = array_make(-1, sizeof(evt_slotvar_t*));
  1394. slot->parent = engine;
  1395. char* code = NULL;
  1396. scew_list* slotval_list = NULL;
  1397. scew_list* filter_list = NULL;
  1398. scew_list* reset_list = NULL;
  1399. scew_attribute *attr = scew_element_attribute_by_name(slot_elem, "Code");
  1400. if (!attr) {
  1401. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("slot miss attribute code!");}
  1402. goto on_error;
  1403. } else {
  1404. code = parse_code(ns, scew_attribute_value(attr));
  1405. if (!code) {
  1406. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse code failed!");}
  1407. goto on_error;
  1408. } else {
  1409. slot->key.code = code;
  1410. slot->key.index_hash_code = hash32_str(code, HASH32_STR_INIT);
  1411. }
  1412. }
  1413. attr = scew_element_attribute_by_name(slot_elem, "Timeout");
  1414. if (attr) {
  1415. evt_expire_t *expire = ZALLOC_T(evt_expire_t);
  1416. if (!expire)
  1417. goto on_error;
  1418. expire->timeout = parse_timeout_value(scew_attribute_value(attr));
  1419. if (expire->timeout < 0) {
  1420. free(expire);
  1421. goto on_error;
  1422. }
  1423. if (expire->timeout == 0) {
  1424. free(expire);
  1425. } else {
  1426. expire->parent = slot;
  1427. expire->timer_id = 0;
  1428. slot->timer = expire;
  1429. }
  1430. }
  1431. attr = scew_element_attribute_by_name(slot_elem, "OnceTrigger");
  1432. if (attr) {
  1433. slot->once = parse_bool(scew_attribute_value(attr));
  1434. } else {
  1435. slot->once = 0;
  1436. }
  1437. slotval_list = scew_element_list_by_name(slot_elem, "Var");
  1438. if (slotval_list) {
  1439. for (scew_list *it = scew_list_first(slotval_list); it; it = scew_list_next(it)) {
  1440. scew_element *elem = (scew_element *)scew_list_data(it);
  1441. int rc = load_slotvar(engine, slot, elem);
  1442. if (rc != 0) {
  1443. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load slot var failed!%s", slot->key.code);}
  1444. goto on_error;
  1445. }
  1446. }
  1447. scew_list_free(slotval_list);
  1448. }
  1449. filter_list = scew_element_list_by_name(slot_elem, "Filter");
  1450. if (filter_list) {
  1451. for (scew_list *it = scew_list_first(filter_list); it; it = scew_list_next(it)) {
  1452. scew_element *elem = (scew_element *)scew_list_data(it);
  1453. int rc = load_filter(engine, slot, elem);
  1454. if (rc != 0) {
  1455. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load filter failed!");}
  1456. goto on_error;
  1457. }
  1458. }
  1459. scew_list_free(filter_list);
  1460. }
  1461. reset_list = scew_element_list_by_name(slot_elem, "Reset");
  1462. if (reset_list) {
  1463. for (scew_list *it = scew_list_first(reset_list); it; it = scew_list_next(it)) {
  1464. scew_element *elem = (scew_element *)scew_list_data(it);
  1465. attr = scew_element_attribute_by_name(elem, "Source");
  1466. if (attr) {
  1467. char *source = parse_code(ns, scew_attribute_value(attr));
  1468. if (!source) {
  1469. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("parse code of Reset tag Source attribute failed!");}
  1470. goto on_error;
  1471. } else {
  1472. ARRAY_PUSH(slot->arr_reset, char*) = source;
  1473. }
  1474. } else {
  1475. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Reset tag miss source attribute!");}
  1476. goto on_error;
  1477. }
  1478. }
  1479. scew_list_free(reset_list);
  1480. }
  1481. if (!slot->timer)
  1482. slot->once = 1;
  1483. if (slot_find(engine->slot_ht, &slot->key)) {
  1484. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("duplicate slot %s", slot->key.code);}
  1485. goto on_error;
  1486. }
  1487. slot_add(engine->slot_ht, slot);
  1488. return 0;
  1489. on_error:
  1490. slot_free(slot);
  1491. return Error_Unexpect;
  1492. }
  1493. static int load_slot_rule(evt_trigger_t *trigger, const char *ns, scew_element *slot_elem)
  1494. {
  1495. evt_slot_rule_t *rule = ZALLOC_T(evt_slot_rule_t);
  1496. scew_attribute *attr = scew_element_attribute_by_name(slot_elem, "Code");
  1497. if (attr) {
  1498. rule->code = parse_code(ns, scew_attribute_value(attr));
  1499. } else {
  1500. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("slot rule parse code attribute failed!");}
  1501. goto on_error;
  1502. }
  1503. attr = scew_element_attribute_by_name(slot_elem, "Positive");
  1504. if (attr) {
  1505. rule->positive = parse_bool(scew_attribute_value(attr));
  1506. if (rule->positive == -1) {
  1507. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("slot rule parse positive attr failed!");}
  1508. goto on_error;
  1509. }
  1510. } else {
  1511. rule->positive = TRUE;
  1512. }
  1513. attr = scew_element_attribute_by_name(slot_elem, "Message");
  1514. if (attr) {
  1515. rule->message = _strdup(scew_attribute_value(attr));
  1516. }
  1517. rule->parent = trigger;
  1518. list_add_tail(&rule->entry, &trigger->slot_rule_list);
  1519. return 0;
  1520. on_error:
  1521. slot_rule_free(rule);
  1522. return Error_Unexpect;
  1523. }
  1524. static int load_sysvar_rule(evt_engine_t *engine, evt_trigger_t *trigger, scew_element *sysvar_elem)
  1525. {
  1526. evt_sysvar_rule_t *rule = ZALLOC_T(evt_sysvar_rule_t);
  1527. scew_list* state_list = NULL;
  1528. scew_attribute *attr = scew_element_attribute_by_name(sysvar_elem, "Code");
  1529. if (attr) {
  1530. char *code = (char*)scew_attribute_value(attr);
  1531. evt_sysvar_key_t key;
  1532. key.code = code;
  1533. key.index_hash_code = hash32_str(code, HASH32_STR_INIT);
  1534. evt_sysvar_t *sysvar = sysvar_find(engine->sysvar_ht, &key);
  1535. if (!sysvar) {
  1536. sysvar = ZALLOC_T(evt_sysvar_t);
  1537. INIT_HLIST_NODE(&sysvar->hentry);
  1538. sysvar->arr_ref_rule = array_make(-1, sizeof(evt_sysvar_rule_t*));
  1539. sysvar->parent = engine;
  1540. sysvar->key.code = _strdup(code);
  1541. sysvar->key.index_hash_code = key.index_hash_code;
  1542. sysvar_add(engine->sysvar_ht, sysvar);
  1543. }
  1544. ARRAY_PUSH(sysvar->arr_ref_rule, evt_sysvar_rule_t*) = rule;
  1545. rule->ref_sysvar = sysvar;
  1546. } else {
  1547. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load sysvar rule, undefine code attr!");}
  1548. goto on_error;
  1549. }
  1550. attr = scew_element_attribute_by_name(sysvar_elem, "Positive");
  1551. if (attr) {
  1552. rule->positive = parse_bool((char*)scew_attribute_value(attr));
  1553. } else {
  1554. rule->positive = 1;
  1555. }
  1556. rule->parent = trigger;
  1557. rule->arr_state = array_make(0, sizeof(char*));
  1558. state_list = scew_element_children(sysvar_elem);
  1559. if (state_list) {
  1560. for (scew_list *it = scew_list_first(state_list); it; it = scew_list_next(it)) {
  1561. scew_element *state_elem = (scew_element *)scew_list_data(it);
  1562. const char *state = scew_element_contents(state_elem);
  1563. if (state) {
  1564. ARRAY_PUSH(rule->arr_state, char*) = _strdup(state);
  1565. } else {
  1566. ARRAY_PUSH(rule->arr_state, char*) = NULL;
  1567. }
  1568. }
  1569. scew_list_first(state_list);
  1570. } else {
  1571. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger sysvar does not have state children!");}
  1572. goto on_error;
  1573. }
  1574. list_add_tail(&rule->entry, &trigger->sysvar_list);
  1575. return 0;
  1576. on_error:
  1577. sysvar_rule_free(rule);
  1578. return Error_Unexpect;
  1579. }
  1580. void SetLogType(int nIslog)
  1581. {
  1582. nIslog = nIslog;
  1583. }
  1584. static int load_trigger(evt_engine_t *engine, const char *ns, scew_element *trigger_elem)
  1585. {
  1586. evt_trigger_t *trigger = ZALLOC_T(evt_trigger_t);
  1587. scew_attribute *attr;
  1588. scew_list *slot_list, *sysvar_list;
  1589. scew_element *delayer;
  1590. INIT_LIST_HEAD(&trigger->slot_rule_list);
  1591. INIT_LIST_HEAD(&trigger->sysvar_list);
  1592. attr = scew_element_attribute_by_name(trigger_elem, "LogType");
  1593. if (attr) {
  1594. trigger->log_type = parse_log_type(scew_attribute_value(attr));
  1595. if (trigger->log_type == -1) {
  1596. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger log type parse failed!");}
  1597. goto on_error;
  1598. }
  1599. } else {
  1600. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger LogType undefined!");}
  1601. goto on_error;
  1602. }
  1603. attr = scew_element_attribute_by_name(trigger_elem, "SeverityLevel");
  1604. if (attr) {
  1605. trigger->severity_level = parse_severity(scew_attribute_value(attr));
  1606. if (trigger->severity_level == -1) {
  1607. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger parse severity level failed!");}
  1608. goto on_error;
  1609. }
  1610. } else {
  1611. if (trigger->log_type == Log_Event || trigger->log_type == Log_Error) {
  1612. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger LogType undefined!");}
  1613. goto on_error;
  1614. }
  1615. }
  1616. attr = scew_element_attribute_by_name(trigger_elem, "SysError");
  1617. if (attr) {
  1618. trigger->sys_code = parse_sys_code(scew_attribute_value(attr));
  1619. if (trigger->sys_code == -1) {
  1620. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger parse sys code failed! sys_code: %s", scew_attribute_value(attr));}
  1621. goto on_error;
  1622. }
  1623. } else {
  1624. if (trigger->log_type == Log_Error || trigger->log_type == Log_Warning) {
  1625. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger parse sys code undefined!");}
  1626. goto on_error;
  1627. }
  1628. }
  1629. attr = scew_element_attribute_by_name(trigger_elem, "UserCode");
  1630. if (attr) {
  1631. trigger->user_code = parse_usr_code(scew_attribute_value(attr));
  1632. } else {
  1633. if (trigger->log_type == Log_Event || trigger->log_type == Log_Error || trigger->log_type == Log_Warning) {
  1634. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("trigger parse user code undefined!");}
  1635. goto on_error;
  1636. }
  1637. }
  1638. attr = scew_element_attribute_by_name(trigger_elem, "Message");
  1639. if (attr) {
  1640. trigger->msg = _strdup(scew_attribute_value(attr));
  1641. }
  1642. slot_list = scew_element_list_by_name(trigger_elem, "Slot");
  1643. if (slot_list) {
  1644. for (scew_list *it = scew_list_first(slot_list); it; it = scew_list_next(it)) {
  1645. scew_element *slot_elem = (scew_element*)scew_list_data(it);
  1646. int rc = load_slot_rule(trigger, ns, slot_elem);
  1647. if (rc != 0) {
  1648. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load slot rule failed!");}
  1649. scew_list_free(slot_list);
  1650. goto on_error;
  1651. }
  1652. }
  1653. scew_list_free(slot_list);
  1654. }
  1655. sysvar_list = scew_element_list_by_name(trigger_elem, "SysVar");
  1656. if (sysvar_list) {
  1657. for (scew_list *it = scew_list_first(sysvar_list); it; it = scew_list_next(it)) {
  1658. scew_element *sysvar_elem = (scew_element*)scew_list_data(it);
  1659. int rc = load_sysvar_rule(engine, trigger, sysvar_elem);
  1660. if (rc != 0) {
  1661. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load sysvar rule failed!");}
  1662. scew_list_free(sysvar_list);
  1663. goto on_error;
  1664. }
  1665. }
  1666. scew_list_free(sysvar_list);
  1667. }
  1668. delayer = scew_element_by_name(trigger_elem, "Delayer");
  1669. if (delayer) {
  1670. trigger->delay_ms = parse_timeout_value(scew_element_contents(delayer));
  1671. trigger->delay_timer_id = -1;
  1672. } else {
  1673. trigger->delay_ms = 0;
  1674. trigger->delay_timer_id = -1;
  1675. }
  1676. trigger->parent = engine;
  1677. list_add_tail(&trigger->entry, &engine->trigger_list);
  1678. return 0;
  1679. on_error:
  1680. trigger_free(trigger);
  1681. return Error_Unexpect;
  1682. }
  1683. static int load_file(evt_engine_t *engine, const char *filename)
  1684. {
  1685. scew_reader *reader = NULL;
  1686. scew_parser *parser = NULL;
  1687. scew_tree *tree = NULL;
  1688. scew_element *root;
  1689. const char *ns;
  1690. char tmp_ns[MAX_PATH];
  1691. int rc = Error_Param;
  1692. scew_attribute* attr = NULL;
  1693. scew_element* elem = NULL;
  1694. reader = scew_reader_file_create(filename);
  1695. if (!reader) {
  1696. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("open file %s failed!", filename);}
  1697. goto on_error;
  1698. }
  1699. parser = scew_parser_create();
  1700. tree = scew_parser_load(parser, reader);
  1701. if (!tree) {
  1702. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("read file %s failed! parser xml failed", filename);}
  1703. goto on_error;
  1704. }
  1705. root = scew_tree_root(tree);
  1706. if (!root) {
  1707. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("%s file does not have root element!", filename);}
  1708. goto on_error;
  1709. }
  1710. attr = scew_element_attribute_by_name(root, "xmlns");
  1711. if (attr) {
  1712. ns = (const char*)scew_attribute_value(attr);
  1713. } else {
  1714. const char *s = strrchr(filename, SPLIT_SLASH)+1;
  1715. const char *e = strrchr(filename, '.');
  1716. memcpy(tmp_ns, s, e-s);
  1717. tmp_ns[e-s] = 0;
  1718. ns = tmp_ns;
  1719. }
  1720. elem = scew_element_by_name(root, "SlotList");
  1721. if (elem) {
  1722. scew_list *slot_list = scew_element_children(elem);
  1723. if (slot_list) {
  1724. for (scew_list *it = scew_list_first(slot_list); it; it = scew_list_next(it)) {
  1725. scew_element *slot_elem = (scew_element *)scew_list_data(it);
  1726. if (load_slot(engine, ns, slot_elem) != 0) {
  1727. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load slot failed!");}
  1728. goto on_error;
  1729. }
  1730. }
  1731. }
  1732. }
  1733. elem = scew_element_by_name(root, "TriggerList");
  1734. if (elem) {
  1735. scew_list *trigger_list = scew_element_children(elem);
  1736. if (trigger_list) {
  1737. for (scew_list *it = scew_list_first(trigger_list); it; it = scew_list_next(it)) {
  1738. scew_element *trigger_elem = (scew_element*)scew_list_data(it);
  1739. if (load_trigger(engine, ns, trigger_elem) != 0) {
  1740. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("load trigger failed!");}
  1741. goto on_error;
  1742. }
  1743. }
  1744. }
  1745. }
  1746. rc = 0;
  1747. on_error:
  1748. if (tree) {
  1749. scew_tree_free(tree);
  1750. }
  1751. if (parser) {
  1752. scew_parser_free(parser);
  1753. }
  1754. if (reader) {
  1755. scew_reader_close(reader);
  1756. }
  1757. return rc;
  1758. }
  1759. int evt_engine_create(const evt_engine_callback_t *callback, evt_engine_t **p_engine)
  1760. {
  1761. evt_engine_t *engine = MALLOC_T(evt_engine_t);
  1762. engine->filter_ht = htable_create(0);
  1763. engine->sysvar_ht = htable_create(0);
  1764. engine->slot_ht = htable_create(0);
  1765. INIT_LIST_HEAD(&engine->trigger_list);
  1766. spinlock_init(&engine->lock);
  1767. memcpy(&engine->cb, callback, sizeof(evt_engine_callback_t));
  1768. *p_engine = engine;
  1769. return 0;
  1770. }
  1771. void evt_engine_destroy(evt_engine_t *engine)
  1772. {
  1773. assert(engine->filter_ht->count == 0);
  1774. assert(engine->slot_ht->count == 0);
  1775. assert(engine->sysvar_ht->count == 0);
  1776. htable_destroy(engine->filter_ht);
  1777. htable_destroy(engine->slot_ht);
  1778. htable_destroy(engine->sysvar_ht);
  1779. free(engine);
  1780. }
  1781. int evt_engine_load(evt_engine_t *engine, int nfile, const char **files)
  1782. {
  1783. int i;
  1784. int rc = 0;
  1785. for (i = 0; i < nfile; ++i) {
  1786. const char *filename = files[i];
  1787. assert(filename);
  1788. rc = load_file(engine, filename);
  1789. if (rc != 0) {
  1790. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("Load file %s failed!", filename);}
  1791. return rc;
  1792. } else {
  1793. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("%s loaded!", filename);}
  1794. }
  1795. }
  1796. rc = build_ref(engine);
  1797. if (rc != 0) {
  1798. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("build ref failed!");}
  1799. return rc;
  1800. }
  1801. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("build ref ok!");}
  1802. return rc;
  1803. }
  1804. int evt_engine_unload(evt_engine_t *engine)
  1805. {
  1806. int i;
  1807. struct hlist_node *pos, *n;
  1808. evt_trigger_t *trigger, *tmp;
  1809. for (i = 0; i < engine->slot_ht->size; ++i) {
  1810. evt_slot_t *slot;
  1811. hlist_for_each_entry_safe(slot, pos, n, &engine->slot_ht->buckets[i], evt_slot_t, hentry) {
  1812. hlist_del(pos);
  1813. slot_free(slot);
  1814. engine->slot_ht->count--;
  1815. }
  1816. }
  1817. for (i = 0; i < engine->sysvar_ht->size; ++i) {
  1818. evt_sysvar_t *sysvar;
  1819. hlist_for_each_entry_safe(sysvar, pos, n, &engine->sysvar_ht->buckets[i], evt_sysvar_t, hentry) {
  1820. hlist_del(pos);
  1821. sysvar_free(sysvar);
  1822. engine->sysvar_ht->count--;
  1823. }
  1824. }
  1825. list_for_each_entry_safe(trigger, tmp, &engine->trigger_list, evt_trigger_t, entry) {
  1826. list_del(&trigger->entry);
  1827. trigger_free(trigger);
  1828. }
  1829. return 0;
  1830. }
  1831. int evt_engine_process_log(evt_engine_t *engine,
  1832. const CAutoArray<CUUID> &SubIDs,
  1833. unsigned long long nLogID,
  1834. LogTypeEnum eLogType,
  1835. SeverityLevelEnum eLevel,
  1836. DWORD dwSysError,
  1837. DWORD dwUserCode,
  1838. DWORD dwEntityId,
  1839. const char *pszEntityName,
  1840. const char *pszModuleName,
  1841. const char *pszMessage)
  1842. {
  1843. return process_log(engine, SubIDs, (int)eLogType, (int)dwEntityId, (int)eLevel, (int)dwSysError, (int)dwUserCode, pszMessage);
  1844. }
  1845. int evt_engine_process_sysvar(evt_engine_t *engine,
  1846. const char *pszKey,
  1847. const char *pszValue,
  1848. const char *pszOldValue,
  1849. const char *pszEntityName)
  1850. {
  1851. if (!pszKey)
  1852. return Error_Param;
  1853. evt_sysvar_key_t key;
  1854. key.code = const_cast<char*>(pszKey);
  1855. key.index_hash_code = hash32_str(pszKey, HASH32_STR_INIT);
  1856. evt_sysvar_t *sysvar = sysvar_find(engine->sysvar_ht, &key);
  1857. if (sysvar) {
  1858. return process_sysvar(engine, sysvar, pszOldValue, pszValue);
  1859. } else {
  1860. return Error_NotExist;
  1861. }
  1862. }
  1863. int evt_engine_start(evt_engine_t *engine)
  1864. {
  1865. int i;
  1866. int rc;
  1867. rc = engine->cb.subscribe_sysevent(engine, engine->cb.user_data);
  1868. if (rc != 0) {
  1869. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("subscribe sysevent failed!");}
  1870. return rc;
  1871. }
  1872. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("subscribe sysevent ok!");}
  1873. for (i = 0; i < engine->sysvar_ht->size; ++i) {
  1874. evt_sysvar_t *tpos;
  1875. struct hlist_node *pos;
  1876. hlist_for_each_entry(tpos, pos, &engine->sysvar_ht->buckets[i], evt_sysvar_t, hentry) {
  1877. CSimpleStringA strValue;
  1878. rc = engine->cb.get_sysevent(engine, tpos->key.code, strValue, engine->cb.user_data);
  1879. if (rc != 0) {
  1880. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("get sysvar %s failed! Error = %d", tpos->key.code, rc);}
  1881. return rc;
  1882. } else {
  1883. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("get sysvar %s ok! value=%s", tpos->key.code, (LPCSTR)strValue);}
  1884. rc = process_sysvar(engine, tpos, NULL, strValue);
  1885. if (rc != 0) {
  1886. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("process sysvar %s failed! value = %s", tpos->key.code, (LPCSTR)strValue);}
  1887. return rc;
  1888. } else {
  1889. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("process sysvar %s ok! key = %s, value = %s", tpos->key.code, tpos->key.code, (LPCSTR)strValue);}
  1890. }
  1891. }
  1892. }
  1893. }
  1894. for (i = 0; i < engine->slot_ht->size; ++i) {
  1895. evt_slot_t *slot;
  1896. struct hlist_node *pos;
  1897. hlist_for_each_entry(slot, pos, &engine->slot_ht->buckets[i], evt_slot_t, hentry) {
  1898. int kk;
  1899. for (kk = 0; kk < slot->arr_filter->nelts; ++kk) {
  1900. evt_filter_t *filter = ARRAY_IDX(slot->arr_filter, kk, evt_filter_t*);
  1901. rc = engine->cb.subscribe_log(engine, &filter->key.listen_id,
  1902. (LogTypeEnum)filter->log_type, filter->entity, (SeverityLevelEnum)filter->severity, (ErrorCodeEnum)filter->sys_code, filter->user_code, filter->content_to_var ? false : true, engine->cb.user_data);
  1903. if (rc != 0) {
  1904. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("subscribe log failed!");}
  1905. return rc;
  1906. } else {
  1907. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("subscribe log ok, id = %d", filter->key.listen_id);}
  1908. }
  1909. filter_add(engine->filter_ht, filter);
  1910. }
  1911. }
  1912. }
  1913. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("subscribe started!");}
  1914. return rc;
  1915. }
  1916. int evt_engine_stop(evt_engine_t *engine)
  1917. {
  1918. int rc;
  1919. int i;
  1920. for (i = 0; i < engine->slot_ht->size; ++i) {
  1921. evt_slot_t *slot;
  1922. struct hlist_node *pos;
  1923. hlist_for_each_entry(slot, pos, &engine->slot_ht->buckets[i], evt_slot_t, hentry) {
  1924. int kk;
  1925. for (kk = 0; kk < slot->arr_filter->nelts; ++kk) {
  1926. evt_filter_t *filter = ARRAY_IDX(slot->arr_filter, kk, evt_filter_t*);
  1927. rc = engine->cb.unsubscribe_log(engine, filter->key.listen_id, engine->cb.user_data);
  1928. if (rc != 0) {
  1929. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("unsubscribe log failed, slot = %s, log listen_id = %s", slot->key.code, filter->key.listen_id);}
  1930. return rc;
  1931. }
  1932. filter_remove(engine->filter_ht, filter);
  1933. }
  1934. }
  1935. }
  1936. rc = engine->cb.unsubscribe_sysevent(engine, engine->cb.user_data);
  1937. if (rc != 0) {
  1938. if (nIslog){DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("unsubscibe sysevent failed!");}
  1939. return rc;
  1940. }
  1941. if (nIslog){DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("unsubscibe sysevent ok!");}
  1942. return rc;
  1943. }