evtengine.cpp 58 KB

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