AlarmFSM.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643
  1. #include "stdafx.h"
  2. #include "AlarmFSM.h"
  3. #include "Event.h"
  4. AlarmFSM::AlarmFSM() : m_pConnection(NULL),m_b_alarmstate(FALSE)
  5. {
  6. InitializeCriticalSection(&cs);
  7. INIT_LIST_HEAD(&m_uploading_alarm);
  8. INIT_LIST_HEAD(&m_uploaded_alarm);
  9. m_iEachSend=0;//每次连接发送的数量
  10. m_iRec=0;//累计收到的告警数目
  11. m_iSend=0;//累计队列发送总数
  12. m_iThrow=0;//累计队列丢弃总数
  13. m_iFail=0;//累计发送失败总次数
  14. m_iSucc=0;//累计发送成功总次数
  15. }
  16. AlarmFSM::~AlarmFSM()
  17. {
  18. DeleteCriticalSection(&cs);
  19. }
  20. void AlarmFSM::OnStateTrans( int iSrcState, int iDstState )
  21. {
  22. Dbg("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState));
  23. }
  24. void AlarmFSM::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName )
  25. {
  26. }
  27. ErrorCodeEnum AlarmFSM::OnInit()
  28. {
  29. AddStateHooker(this);
  30. //......
  31. CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
  32. CSmartPointer<IConfigInfo> spConfig;
  33. ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig);
  34. if (Error_Succeed == Error)
  35. {
  36. Error = spConfig->ReadConfigValueInt("Alarm", "DealWarningTime", m_nDealWarningTime);
  37. if (Error_Succeed == Error)
  38. {
  39. Dbg("get DealWarningTime=%d from CenterSetting.ini", m_nDealWarningTime);
  40. }
  41. else
  42. {
  43. Dbg("get DealWarningTime from CenterSetting.ini failed");
  44. }
  45. }
  46. if (m_nDealWarningTime == 0)
  47. {
  48. m_nDealWarningTime = 10;
  49. }
  50. return Error_Succeed;
  51. }
  52. ErrorCodeEnum AlarmFSM::OnExit()
  53. {
  54. return Error_Succeed;
  55. }
  56. void AlarmFSM::s0_on_entry()
  57. {
  58. //if (m_b_alarmstate)
  59. //{
  60. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMSTATEUP));
  61. //}
  62. //else if (!is_alarm_empty())
  63. //{
  64. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMUP));
  65. //}
  66. //else
  67. //{
  68. // ScheduleTimer(1, 5000);
  69. //}
  70. //connect
  71. if (!m_pConnection)
  72. {
  73. m_pConnection = new AlarmConnection(m_pEntity, this);
  74. if (m_pConnection->ConnectFromCentralSetting()&& m_pConnection->IsConnectionOK())
  75. {
  76. //创建成功
  77. }else{
  78. //创建失败
  79. Dbg("connect server fail,config or Servers Error!");
  80. closeClientConn();//断开连接
  81. }
  82. }
  83. if (!m_pConnection)
  84. {
  85. ScheduleTimer(1, 10000); // try 10 seconds later
  86. }
  87. else
  88. {
  89. PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMUP));//跳转S1状态
  90. }
  91. }
  92. void AlarmFSM::s0_on_exit()
  93. {
  94. CancelTimer(1);
  95. }
  96. unsigned int AlarmFSM::s0_on_event( FSMEvent* event )
  97. {
  98. //if (event->iEvt == EVT_TIMER)
  99. //{
  100. // if (m_b_alarmstate)
  101. // {
  102. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMSTATEUP));
  103. // }
  104. // else if (!is_alarm_empty())
  105. // {
  106. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMUP));
  107. // }
  108. // else
  109. // {
  110. // ScheduleTimer(1, 5000);
  111. // }
  112. //}
  113. if (event->iEvt == EVT_TIMER)
  114. {
  115. if (!m_pConnection)
  116. {
  117. m_pConnection = new AlarmConnection(m_pEntity, this);
  118. if (m_pConnection->ConnectFromCentralSetting()&& m_pConnection->IsConnectionOK())
  119. {
  120. //创建成功
  121. }else{
  122. //创建失败
  123. Dbg("connect server fail,config or Servers Error!");
  124. closeClientConn();//断开连接
  125. }
  126. }
  127. if (!m_pConnection)
  128. {
  129. ScheduleTimer(1, 10000); // try 10 seconds later
  130. }
  131. else
  132. {
  133. PostEventLIFO(new FSMEvent(USER_EVT_JMP_ALARMUP));//跳转S1状态
  134. }
  135. }
  136. return 0;
  137. }
  138. void AlarmFSM::s1_on_entry()
  139. {
  140. //connect
  141. //if (!m_pConnection)
  142. //{
  143. // m_pConnection = new AlarmConnection(m_pEntity, this);
  144. // if (!m_pConnection->ConnectFromCentralSetting())
  145. // {
  146. // Dbg("connect server fail,config or Servers Error!");
  147. // PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT));
  148. // return;
  149. // }
  150. //}
  151. //if (m_pConnection->IsConnectionOK()) //upload
  152. //{
  153. // EnterCriticalSection(&cs);
  154. // alarm_t*alarm = list_first_entry(&m_uploading_alarm,alarm_t,entry);
  155. // if (alarm == NULL)
  156. // {
  157. // Dbg("get alarm error");
  158. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE));
  159. // }
  160. // m_pConnection->SendAlarm(alarm);
  161. // //add by zl 20180306, 添加到历史告警列表
  162. // add_UploadedAlarm(alarm);
  163. // list_del(&alarm->entry);
  164. // //delete alarm->Description;
  165. // //delete alarm->EntityName;
  166. // //delete alarm->SN;
  167. // //delete alarm;
  168. // //因使用malloc创建内存,用free释放
  169. // free(alarm->Description);
  170. // alarm->Description=NULL;
  171. // free(alarm->EntityName);
  172. // alarm->EntityName=NULL;
  173. // free(alarm->SN);
  174. // alarm->SN=NULL;
  175. // delete alarm;
  176. // alarm=NULL;
  177. // Dbg("send alarm success");
  178. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE));
  179. // LeaveCriticalSection(&cs);
  180. //}
  181. //else
  182. //{
  183. // //链接失效,需要先释放并清空链接,否一直不会重连
  184. // m_pConnection->Close();
  185. // m_pConnection->DecRefCount();
  186. // m_pConnection = NULL;
  187. // PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE));
  188. //}
  189. if(m_NewUploading_alarm.empty()){
  190. PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//为空时,跳回S0状态
  191. }else{
  192. Dbg("send alarm statistic m_iRec=%d , m_iThrow=%d , UnSend=%d , m_iSend=%d , m_iSucc=%d , m_iFail=%d",m_iRec,m_iThrow,m_NewUploading_alarm.size(),m_iSend,m_iSucc,m_iFail);
  193. m_iEachSend = 0;
  194. //发送告警信息
  195. if(SendAlarm()){
  196. m_iEachSend++;//发送成功
  197. }else{
  198. PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT));//发送失败时,跳回S0状态
  199. }
  200. }
  201. }
  202. void AlarmFSM::s1_on_exit()
  203. {
  204. CancelTimer(2);
  205. }
  206. unsigned int AlarmFSM::s1_on_event(FSMEvent* event)
  207. {
  208. //if (event->iEvt == USER_EVT_DISCONNECT)
  209. //{
  210. // Dbg("rx disconnect evt at alarmupload s1");
  211. // if (m_pConnection)
  212. // {
  213. // m_pConnection->Close();
  214. // m_pConnection->DecRefCount();
  215. // m_pConnection = NULL;
  216. // ScheduleTimer(2, 5000);
  217. // }
  218. //}
  219. //else if (event->iEvt == EVT_TIMER)
  220. //{
  221. // if (!m_pConnection)
  222. // {
  223. // m_pConnection = new AlarmConnection(m_pEntity, this);
  224. // if (!m_pConnection->ConnectFromCentralSetting())
  225. // {
  226. // Dbg("connect server fail,config or Servers Error!");
  227. // PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT));
  228. // }
  229. // }
  230. //}
  231. //else if (event->iEvt == EVT_TIMER)
  232. //{
  233. // //继续发送
  234. //}
  235. if (event->iEvt == USER_EVT_DISCONNECT_FAIL)
  236. {
  237. Dbg("disconnect 10s at alarmupload s1");
  238. closeClientConn();//断开连接
  239. ScheduleTimer(2, 10000); // try 10 seconds later
  240. }
  241. else if (event->iEvt == USER_EVT_DISCONNECT_SUCC)
  242. {
  243. Dbg("disconnect 3s at alarmupload s1");
  244. closeClientConn();//断开连接
  245. ScheduleTimer(2, 2000); // try 2 seconds later
  246. }
  247. else if (event->iEvt == EVT_TIMER)
  248. {
  249. PostEventLIFO(new FSMEvent(USER_EVT_JMP_START));//跳转S0状态
  250. }
  251. else if (event->iEvt ==USER_EVT_UPLOAD_ANS)
  252. {
  253. if(m_iEachSend<=50)
  254. {
  255. if(!m_NewUploading_alarm.empty()){
  256. if(SendAlarm()){
  257. m_iEachSend++;//发送成功
  258. }else{
  259. PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//发送失败时,跳回S0状态
  260. }
  261. }else{
  262. PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_FAIL));//为空时,跳回S0状态
  263. }
  264. }
  265. else
  266. {
  267. PostEventLIFO(new FSMEvent(USER_EVT_DISCONNECT_SUCC));//达到一定发送数量,主动断开,跳回S0状态
  268. }
  269. }
  270. return 0;
  271. }
  272. void AlarmFSM::s2_on_entry()
  273. {
  274. //connect
  275. if (!m_pConnection)
  276. {
  277. m_pConnection = new AlarmConnection(m_pEntity, this);
  278. if (!m_pConnection->ConnectFromCentralSetting())
  279. {
  280. Dbg("connect server fail,config or Servers Error!");
  281. }
  282. }
  283. if (m_pConnection->IsConnectionOK()) //upload alarm state
  284. {
  285. if (m_b_alarmstate)
  286. {
  287. m_pConnection->SendAlarmState(&m_uploading_alarmstate);
  288. Dbg("send alarmstate success");
  289. delete m_uploading_alarmstate.Description;
  290. PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE));
  291. }
  292. }
  293. else
  294. {
  295. //链接失效,需要先释放并清空链接,否则一直不会重连
  296. m_pConnection->Close();
  297. m_pConnection->DecRefCount();
  298. m_pConnection = NULL;
  299. PostEventLIFO(new FSMEvent(USER_EVT_JMP_RELEASE));
  300. }
  301. }
  302. void AlarmFSM::s2_on_exit()
  303. {
  304. m_b_alarmstate = FALSE;
  305. CancelTimer(3);
  306. }
  307. unsigned int AlarmFSM::s2_on_event(FSMEvent* event)
  308. {
  309. if (event->iEvt == USER_EVT_DISCONNECT)
  310. {
  311. Dbg("rx disconnect evt at alarm upload s2");
  312. if (m_pConnection)
  313. {
  314. m_pConnection->Close();
  315. m_pConnection->DecRefCount();
  316. m_pConnection = NULL;
  317. }
  318. ScheduleTimer(3, 10000);
  319. }
  320. return 0;
  321. }
  322. void AlarmFSM::s3_on_entry()
  323. {
  324. //modify by zl 20180314,发送完,马上断开链接可能会导致服务端无法接受到请求,改用长链接
  325. /*if (m_pConnection)
  326. {
  327. m_pConnection->Close();
  328. m_pConnection->DecRefCount();
  329. m_pConnection = NULL;
  330. LogEvent(Severity_Low,EVENT_MOD_ALARM_INITIATIVE_DISCONNECT,"Connecting Closed");
  331. }*/
  332. PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT));
  333. if (!m_pConnection)
  334. {
  335. ScheduleTimer(4, 1000); // try 30 seconds later
  336. }
  337. }
  338. void AlarmFSM::s3_on_exit()
  339. {
  340. CancelTimer(4);
  341. }
  342. unsigned int AlarmFSM::s3_on_event(FSMEvent* event)
  343. {
  344. if (event->iEvt == USER_EVT_DISCONNECT)
  345. {
  346. Dbg(" disconnect evt at alarm upload s3");
  347. /*if (m_pConnection)
  348. {
  349. m_pConnection->Close();
  350. m_pConnection->DecRefCount();
  351. m_pConnection = NULL;
  352. }*/
  353. }
  354. return 0;
  355. }
  356. //增加告警
  357. void AlarmFSM::add_alarm(alarm_t*alarm)
  358. {
  359. EnterCriticalSection(&cs);
  360. add_new_alarm(alarm,&m_uploading_alarm);
  361. LeaveCriticalSection(&cs);
  362. }
  363. //设置告警状态
  364. void AlarmFSM::set_alarm_state(const CUUID nLogID,DWORD LifeId,const SeverityLevelEnum eLevel,
  365. DWORD Item,const char *pszMessage)
  366. {
  367. m_uploading_alarmstate.SN = nLogID;
  368. _itoa((int)eLevel,&m_uploading_alarmstate.Level,16);
  369. m_uploading_alarmstate.LifeID = LifeId;
  370. m_uploading_alarmstate.Item = Item;
  371. char cDescription[512];
  372. strcpy(cDescription,pszMessage);
  373. m_uploading_alarmstate.Description = _strdup(cDescription);
  374. m_b_alarmstate = TRUE;
  375. }
  376. //获取告警数量
  377. bool AlarmFSM::is_alarm_empty()
  378. {
  379. EnterCriticalSection(&cs);
  380. bool i = list_empty(&m_uploading_alarm);
  381. LeaveCriticalSection(&cs);
  382. return i;
  383. }
  384. bool AlarmFSM::is_UploadedAlarm_empty()
  385. {
  386. EnterCriticalSection(&cs);
  387. bool i = list_empty(&m_uploaded_alarm);
  388. LeaveCriticalSection(&cs);
  389. return i;
  390. }
  391. static time_t NowTime()
  392. {
  393. time_t t_Now = time(0);
  394. struct tm* tm_Now = localtime(&t_Now);
  395. /*tm_Now->tm_hour =0;
  396. tm_Now->tm_min = 0;
  397. tm_Now->tm_sec = 0;*/
  398. return mktime(tm_Now);
  399. }
  400. void AlarmFSM::add_UploadedAlarm(alarm_t*alarm)
  401. {
  402. alarmUpgraded_t*upedAlarm = new alarmUpgraded_t();
  403. upedAlarm->EntityName = new char[32];
  404. if (NULL != upedAlarm->EntityName)
  405. {
  406. memset(upedAlarm->EntityName, 0, 32);
  407. }
  408. upedAlarm->SN = new char[20];
  409. if (NULL != upedAlarm->SN)
  410. {
  411. memset(upedAlarm->SN, 0, 20);
  412. }
  413. upedAlarm->Description = new char[512];
  414. if (NULL != upedAlarm->Description)
  415. {
  416. memset(upedAlarm->Description, 0, 512);
  417. }
  418. strcpy(upedAlarm->EntityName,alarm->EntityName);
  419. strcpy(upedAlarm->SN,alarm->SN);
  420. upedAlarm->LifeID = alarm->LifeID;
  421. upedAlarm->Item = alarm->Item;
  422. upedAlarm->UserCode = alarm->UserCode;
  423. upedAlarm->Level = alarm->Level;
  424. strcpy(upedAlarm->Description,alarm->Description);
  425. upedAlarm->time = NowTime();
  426. //如果是相同实体且相同描述,则更新告警。否则做为新告警添加
  427. if (!update_UploadedAlarm(upedAlarm))
  428. {
  429. EnterCriticalSection(&cs);
  430. add_new_upalarm(upedAlarm,&m_uploaded_alarm);
  431. LeaveCriticalSection(&cs);
  432. }
  433. }
  434. bool AlarmFSM::find_UploadedAlarm(alarm_t*alarm)
  435. {
  436. EnterCriticalSection(&cs);
  437. if (is_UploadedAlarm_empty())
  438. {
  439. return false;
  440. }
  441. //time_t tNow = NowTime();
  442. //获取时间报错,改为直接获取
  443. time_t t_Now = time(0);
  444. struct tm* tm_Now = localtime(&t_Now);
  445. time_t tNow = mktime(tm_Now);
  446. //Dbg("tNow[%d]", tNow);
  447. alarmUpgraded_t* uploadedAlarm;
  448. list_for_each_entry(uploadedAlarm, &m_uploaded_alarm, alarmUpgraded_t, entry)
  449. {
  450. if (0 == strcmp(uploadedAlarm->EntityName, alarm->EntityName)
  451. && 0 == strcmp(uploadedAlarm->Description, alarm->Description))
  452. {
  453. if (tNow > uploadedAlarm->time)
  454. {
  455. UINT nSecond = tNow - uploadedAlarm->time;
  456. UINT nMin = nSecond/60;
  457. if (nMin <= m_nDealWarningTime)
  458. {
  459. //在指定时间内(可配置),收到同一实体的同一告警,去重
  460. Dbg("find same uploaded alarm list, don't need to send again");
  461. return true;
  462. }
  463. }
  464. else
  465. {
  466. Dbg("uploadedAlarm->time[%d] >= tNow[%d], time is wrong", uploadedAlarm->time, tNow);
  467. }
  468. }
  469. }
  470. LeaveCriticalSection(&cs);
  471. return false;
  472. }
  473. bool AlarmFSM::update_UploadedAlarm(alarmUpgraded_t*alarm)
  474. {
  475. EnterCriticalSection(&cs);
  476. if (is_UploadedAlarm_empty())
  477. {
  478. return false;
  479. }
  480. alarmUpgraded_t* uploadedAlarm;
  481. list_for_each_entry(uploadedAlarm, &m_uploaded_alarm, alarmUpgraded_t, entry)
  482. {
  483. if (0 == strcmp(uploadedAlarm->EntityName, alarm->EntityName)
  484. || 0 == strcmp(uploadedAlarm->Description, alarm->Description))
  485. {
  486. update_upalarm(alarm, uploadedAlarm);
  487. //替换后,旧的对象需要清理
  488. //free(uploadedAlarm->Description);
  489. //free(uploadedAlarm->EntityName);
  490. //free(uploadedAlarm->SN);
  491. delete[] uploadedAlarm->Description;
  492. uploadedAlarm->Description=NULL;
  493. delete[] uploadedAlarm->EntityName;
  494. uploadedAlarm->EntityName=NULL;
  495. delete[] uploadedAlarm->SN;
  496. uploadedAlarm->SN=NULL;
  497. delete uploadedAlarm;
  498. uploadedAlarm=NULL;
  499. return true;
  500. }
  501. }
  502. LeaveCriticalSection(&cs);
  503. return false;
  504. }
  505. //增加消息到新告警列表
  506. void AlarmFSM::add_NewAlarm(alarm_t* alarm)
  507. {
  508. EnterCriticalSection(&cs);
  509. if(m_NewUploading_alarm.size()>=UPLOG_MAX_COUNT){
  510. //Dbg("队列已满,删除首元素");
  511. m_iThrow++;
  512. alarm_t* oldAlarm = (alarm_t*)(*m_NewUploading_alarm.begin());//集合首个元素
  513. m_NewUploading_alarm.erase(m_NewUploading_alarm.begin());//集合删除首元素
  514. free(oldAlarm->Description);
  515. oldAlarm->Description=NULL;
  516. free(oldAlarm->EntityName);
  517. oldAlarm->EntityName=NULL;
  518. free(oldAlarm->SN);
  519. oldAlarm->SN=NULL;
  520. delete oldAlarm;
  521. oldAlarm=NULL;
  522. }
  523. m_NewUploading_alarm.push_back(alarm);//加入队列
  524. LeaveCriticalSection(&cs);
  525. }
  526. //取出消息从新告警列表
  527. alarm_t* AlarmFSM::removeAlarm()
  528. {//加锁,取出先进的队列日志,注意释放内存空间
  529. alarm_t* dAlarm = NULL;
  530. EnterCriticalSection(&cs);
  531. if(m_NewUploading_alarm.empty()){
  532. //return NULL;
  533. }else{
  534. dAlarm = (alarm_t*)(*m_NewUploading_alarm.begin());//集合首个元素
  535. m_NewUploading_alarm.erase(m_NewUploading_alarm.begin());//集合删除首元素
  536. }
  537. LeaveCriticalSection(&cs);
  538. return dAlarm;//返回
  539. }
  540. //关闭连接
  541. void AlarmFSM::closeClientConn()
  542. {
  543. if(m_pConnection!=NULL){
  544. m_pConnection->Close();
  545. m_pConnection->DecRefCount();
  546. m_pConnection = NULL;
  547. }
  548. }
  549. //发送新告警信息
  550. bool AlarmFSM::SendAlarm(){
  551. alarm_t*alarm = removeAlarm();
  552. if (alarm == NULL)
  553. {
  554. Dbg("get alarm error");
  555. return false;
  556. }
  557. m_iSend++;//发送计数
  558. m_pConnection->SendAlarm(alarm);
  559. free(alarm->Description);
  560. alarm->Description=NULL;
  561. free(alarm->EntityName);
  562. alarm->EntityName=NULL;
  563. free(alarm->SN);
  564. alarm->SN=NULL;
  565. delete alarm;
  566. alarm=NULL;
  567. return true;
  568. }