DeliverModule.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625
  1. #include "stdafx.h"
  2. #include "DeliverModule.h"
  3. #include <process.h>
  4. CDeliverModule::CDeliverModule(WriteLog* logFun)
  5. {
  6. m_SdcCommondvector.clear();
  7. m_CommondType.clear();
  8. m_hSendingThreadToggleEvent=NULL;
  9. m_bSendingCommandsThreadExit = false;
  10. m_SendingCommandsThread=NULL;
  11. m_hACKEvent=NULL;
  12. m_nAKRsubmit=0;
  13. m_bisNAK=false;
  14. m_hCPEvent=NULL;
  15. m_nCPRsubmit=0;
  16. m_bisNCP=false;
  17. m_ClientControl = NULL;
  18. m_pSendData=NULL;
  19. m_pLogFun = logFun;
  20. m_bIsGenErr=false;
  21. m_nAKResendTotalNum=3;
  22. m_nCPResendTotalNum=1;
  23. }
  24. CDeliverModule::~CDeliverModule(void)
  25. {
  26. }
  27. /////////////////////
  28. //设备初始化的时候要把等待AK的事件设置为手动激活
  29. //m_hACKEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
  30. //并建立发送线程
  31. //StartSendingCommandsThread(this);
  32. ///////////////////
  33. /////////////////////
  34. //退出的时候也要调用函数结束掉发送线程
  35. //StopSendingCommandsThread();
  36. ////////////////////
  37. void CDeliverModule::SetPriority(int nCommandType,bool IsWaitforACK,int WaitingTime,bool IsResend,bool IsClearSendVector,bool IsFirstSend,bool IsWaitforCP,int WatingCPtime,bool isClearSamePriority)
  38. {
  39. tagCommandTye proiority;
  40. proiority.nCommandType=nCommandType;
  41. proiority.IsWaitforACK=IsWaitforACK;
  42. proiority.WaitingTime=WaitingTime;
  43. proiority.IsResend=IsResend;
  44. proiority.IsClearSendVector=IsClearSendVector;
  45. proiority.IsFirstSend=IsFirstSend;
  46. proiority.IsWaitforCP=IsWaitforCP;
  47. proiority.WatingCPtime=WatingCPtime;
  48. proiority.isClearSamePriority=isClearSamePriority;
  49. m_CommondType.push_back(proiority);
  50. }
  51. void CDeliverModule::SetGenErrStatus(bool isGenErr)
  52. {
  53. m_bIsGenErr=isGenErr;
  54. }
  55. bool CDeliverModule::SetLogFun(WriteLog* logFun)
  56. {
  57. if(logFun != NULL)
  58. {
  59. m_pLogFun = logFun;
  60. return true;
  61. }
  62. return false;
  63. }
  64. bool CDeliverModule::InitSendModle(SendCommands* pSendData,void* lparam)
  65. {
  66. m_ClientControl = lparam;
  67. m_pSendData = pSendData;
  68. //设备初始化的时候要把等待AK的事件设置为手动激活
  69. m_hACKEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
  70. m_hCPEvent=CreateEvent(NULL, TRUE, FALSE, NULL);
  71. //并建立发送线程
  72. StartSendingCommandsThread(this);
  73. return true;
  74. }
  75. void CDeliverModule::EixtSendModle()
  76. {
  77. StopSendingCommandsThread();
  78. m_ClientControl = NULL;
  79. m_pSendData=NULL;
  80. m_SdcCommondvector.clear();
  81. m_CommondType.clear();
  82. }
  83. DWORD CDeliverModule::SendingCommandsThread(LPVOID pParam)
  84. {
  85. CDeliverModule* pCurrentGen = (CDeliverModule*) pParam;
  86. if (pCurrentGen == NULL)
  87. {
  88. if (pCurrentGen->m_pLogFun)
  89. {
  90. pCurrentGen->m_pLogFun("The pCurrentGen is NULL", LOG_V2_ERROR);
  91. }
  92. return 0;
  93. }
  94. DWORD event = 0;
  95. BOOL bExit = false;
  96. //indicating start thread success;
  97. SetEvent(pCurrentGen->m_hSendingThreadToggleEvent);
  98. //perform sending sedecal commands
  99. while (!pCurrentGen->m_bSendingCommandsThreadExit)
  100. {
  101. //query the command from the vector
  102. tagCommandStruct tempCommand;
  103. tempCommand.strCommand = "";
  104. tempCommand.nCommmandType = 0;
  105. if (pCurrentGen->m_SdcCommondvector.size() > 0)
  106. {
  107. std::unique_lock<std::mutex> uqeSection(pCurrentGen->m_iCriticalSection);
  108. tempCommand.nCommmandType = pCurrentGen->m_SdcCommondvector[0].nCommmandType;
  109. tempCommand.strCommand = pCurrentGen->m_SdcCommondvector[0].strCommand;
  110. pCurrentGen->m_SdcCommondvector.erase(pCurrentGen->m_SdcCommondvector.begin());//erase the first command
  111. uqeSection.unlock();
  112. if (tempCommand.strCommand != "")// with commnad
  113. {
  114. pCurrentGen->SendCommand(tempCommand.strCommand,tempCommand.nCommmandType);
  115. Sleep(50);
  116. }
  117. else
  118. {
  119. Sleep(10);//no commnad to send, so sleep 10 ms
  120. }
  121. // send command
  122. }
  123. else
  124. {
  125. Sleep(10);
  126. }
  127. }
  128. //indicating the end of thread;
  129. SetEvent(pCurrentGen->m_hSendingThreadToggleEvent);
  130. return 0;
  131. }
  132. //start timer to do offset calibration periodically;
  133. bool CDeliverModule::StartSendingCommandsThread(CDeliverModule* pCurrentGen)
  134. {
  135. //create thread;
  136. DWORD m_HardwareStatusID;
  137. m_SendingCommandsThread = CreateThread(0, 0, SendingCommandsThread, this, 0, &m_HardwareStatusID);
  138. if (NULL == m_SendingCommandsThread)
  139. {
  140. if (m_pLogFun)
  141. {
  142. m_pLogFun("Create sending commands thread failed!", LOG_V2_ERROR);
  143. }
  144. return false;
  145. }
  146. //wait till thread create successful;
  147. if (WaitForSingleObject(pCurrentGen->m_hSendingThreadToggleEvent,5000) == WAIT_OBJECT_0)
  148. {
  149. if (m_pLogFun)
  150. {
  151. m_pLogFun("detected the start of sending commands thread!", LOG_V2_INFO);
  152. }
  153. ResetEvent(pCurrentGen->m_hSendingThreadToggleEvent);
  154. }
  155. m_nSendingCommandsThreadId = m_HardwareStatusID;
  156. return true;
  157. }
  158. //stop sending commands thread periodically;
  159. void CDeliverModule::StopSendingCommandsThread()
  160. {
  161. if (m_pLogFun)
  162. {
  163. m_pLogFun("sending commands thread exiting...", LOG_V2_WARNING);
  164. }
  165. if (NULL != m_SendingCommandsThread)
  166. {
  167. m_bSendingCommandsThreadExit = true;
  168. if (::WaitForSingleObject(m_hSendingThreadToggleEvent,5000)==WAIT_OBJECT_0)
  169. {
  170. if (m_pLogFun)
  171. {
  172. m_pLogFun("detected the exit of sending commands thread!", LOG_V2_INFO);
  173. }
  174. ResetEvent(m_hSendingThreadToggleEvent);
  175. }
  176. else
  177. {
  178. DWORD exitCode = 0;
  179. //Retrieves the termination status of the specified thread;
  180. if (!GetExitCodeThread(m_SendingCommandsThread, &exitCode))
  181. {
  182. DWORD nError = ::GetLastError();
  183. std::string logstr;
  184. if (m_pLogFun)
  185. {
  186. logstr = std::format("GetExitCodeThread() error, error No is {:d}", nError);
  187. m_pLogFun(logstr.c_str(), LOG_V2_ERROR);
  188. }
  189. }
  190. TerminateThread(m_SendingCommandsThread,exitCode);
  191. }
  192. m_SendingCommandsThread = NULL;
  193. }
  194. }
  195. /*
  196. strCommand which will be send to gen side
  197. nType commnad type 0, no ACK , 1, with ACK, 2, apr command, 3, focus?(to be confirmed)
  198. */
  199. bool CDeliverModule::ProcessCommand(std::string strCommand,int nType)
  200. {
  201. std::unique_lock<std::mutex> uqeSection(m_iCriticalSection);
  202. m_SDCCommand.strCommand = strCommand;
  203. m_SDCCommand.nCommmandType = nType;
  204. /*std::string logstr;
  205. logstr = "strcommand is " + m_SDCCommand.strCommand;
  206. m_pGen->logfile->WriteLog(logstr,LOG_INFORMATION,LOG_DEBUG,true);
  207. logstr.Format("CommmandType is %d",nType);
  208. m_pGen->logfile->WriteLog(logstr,LOG_INFORMATION,LOG_DEBUG,true);*/
  209. int i=0;
  210. for (i=0;i<m_CommondType.size();i++)
  211. {
  212. if (m_SDCCommand.nCommmandType==m_CommondType[i].nCommandType)
  213. {
  214. m_SDCCommand.nCommmandType=i;//将设置的优先级对应到优先级列表中的位置,方便获取该优先级的属性
  215. /*std::string logstr;
  216. logstr.Format("CommmandType in list is %d",i);
  217. m_pGen->logfile->WriteLog(logstr,LOG_INFORMATION,LOG_DEBUG,true);*/
  218. break;
  219. }
  220. }
  221. if (i==m_CommondType.size())
  222. {
  223. uqeSection.unlock();
  224. return false;
  225. }
  226. std::string logstr;
  227. for(int j=0;j<m_SdcCommondvector.size();j++)
  228. {
  229. if(m_SdcCommondvector[j].strCommand==m_SDCCommand.strCommand)
  230. {
  231. m_SdcCommondvector.erase(m_SdcCommondvector.begin()+j);
  232. j--;
  233. }
  234. }
  235. if (m_CommondType[i].IsClearSendVector)
  236. {
  237. for(int j=0;j<m_SdcCommondvector.size();j++)
  238. {
  239. if(!m_CommondType[m_SdcCommondvector[j].nCommmandType].IsClearSendVector)
  240. {
  241. if (m_pLogFun)
  242. {
  243. logstr = std::format("Clear command to {}", j);
  244. m_pLogFun(logstr.c_str(), LOG_V2_INFO);
  245. }
  246. m_SdcCommondvector.erase(m_SdcCommondvector.begin()+j);
  247. j--;
  248. }
  249. }
  250. m_SdcCommondvector.push_back(m_SDCCommand);
  251. if (m_pLogFun)
  252. {
  253. logstr = std::format("Clear vector to {}", m_SdcCommondvector.size());
  254. m_pLogFun(logstr.c_str(), LOG_V2_INFO);
  255. }
  256. }
  257. else if (m_CommondType[i].IsFirstSend)
  258. {
  259. m_SdcCommondvector.push_front(m_SDCCommand);
  260. std::string logstr;
  261. if (m_pLogFun)
  262. {
  263. logstr = std::format("FirstSend to {}", 0);
  264. m_pLogFun(logstr.c_str(), LOG_V2_INFO);
  265. }
  266. }
  267. else if(m_CommondType[i].isClearSamePriority)
  268. {
  269. for(int j=0;j<m_SdcCommondvector.size();j++)
  270. {
  271. if(m_SdcCommondvector[j].nCommmandType==m_SDCCommand.nCommmandType)
  272. {
  273. if (m_pLogFun)
  274. {
  275. logstr = std::format("Clear same priority command: {}", m_SdcCommondvector[j].strCommand.c_str());
  276. m_pLogFun(logstr.c_str(), LOG_V2_INFO);
  277. }
  278. m_SdcCommondvector.erase(m_SdcCommondvector.begin()+j);
  279. j--;
  280. }
  281. }
  282. m_SdcCommondvector.push_back(m_SDCCommand);
  283. }
  284. else
  285. {
  286. m_SdcCommondvector.push_back(m_SDCCommand);
  287. }
  288. uqeSection.unlock();
  289. return true;
  290. }
  291. bool CDeliverModule::ReProcessCommand(tagCommandStruct strCommand)
  292. {
  293. m_SDCCommand.nCommmandType = strCommand.nCommmandType;
  294. m_SDCCommand.strCommand = strCommand.strCommand;
  295. if (!m_CommondType[strCommand.nCommmandType].IsResend||(m_bIsGenErr&&!m_CommondType[strCommand.nCommmandType].IsClearSendVector))
  296. {
  297. //不重发的命令,或者设备处于错误状态时不清空发送队列的命令,都不重发
  298. return true;
  299. }
  300. std::unique_lock<std::mutex> uqeSection(m_iCriticalSection);
  301. m_SdcCommondvector.push_front(m_SDCCommand);
  302. uqeSection.unlock();
  303. return true;
  304. }
  305. void CDeliverModule::SendCommand(std::string strcommand, int commandtype)
  306. {
  307. std::string strlog = "";
  308. if (m_bIsGenErr)
  309. {
  310. if(!m_CommondType[commandtype].IsClearSendVector)
  311. {
  312. if (m_pLogFun)
  313. {
  314. m_pLogFun("In error state,and the command is not nessesery", LOG_V2_WARNING);
  315. }
  316. return;
  317. }
  318. }
  319. if (m_strcurrentcmd.strCommand!=strcommand)
  320. {
  321. m_nAKRsubmit=0;
  322. m_nCPRsubmit=0;
  323. }
  324. m_strcurrentcmd.strCommand = strcommand;//保存当前发送的命令
  325. m_strcurrentcmd.nCommmandType=commandtype;
  326. ResetEvent(m_hACKEvent);
  327. ResetEvent(m_hCPEvent);
  328. m_bisNAK=false;//重置NAK状态
  329. m_bisNCP=false;
  330. bool isSend=false;
  331. //if(m_strcurrentcmd.strCommand.Mid(0,2)!="ST"&&m_strcurrentcmd.strCommand.Mid(0,2)!="HU")
  332. //{
  333. // std::string strMessage;
  334. // strMessage.Format("%s 是否发送成功!",GetCurrentCommand());
  335. // int result=AfxMessageBox(strMessage,MB_YESNO);
  336. // if (result==6)
  337. // {
  338. // isSend=true;
  339. // }
  340. // else if (result==7)
  341. // {
  342. // isSend=false;
  343. // }
  344. //}
  345. ////////////////////////
  346. //调用回调函数将指令发送
  347. if(m_pSendData)
  348. {
  349. //if(isSend)
  350. m_pSendData(m_strcurrentcmd.strCommand.c_str(),m_strcurrentcmd.strCommand.length(),m_ClientControl);
  351. }
  352. else
  353. return;
  354. ///////////////////////////
  355. //int AKTimeOut=0;
  356. //if (!isSend)
  357. //{
  358. // int result=AfxMessageBox("AK是否超时,选‘是’AK超时,选‘否’CP超时",MB_YESNO);
  359. // if (result==6)
  360. // {
  361. // AKTimeOut=1;
  362. // }
  363. // else if (result==7)
  364. // {
  365. // AKTimeOut=-1;
  366. // }
  367. //}
  368. if (m_CommondType[commandtype].IsWaitforACK)
  369. {
  370. //如果AK超时或者错,则在函数中重发,直接返回,不等CP
  371. //if(AKTimeOut==1)
  372. {
  373. if(!WaitforACK(m_CommondType[commandtype].WaitingTime))
  374. return;
  375. }
  376. }
  377. if (m_CommondType[commandtype].IsWaitforCP)
  378. {
  379. WaitforCP(m_CommondType[commandtype].WatingCPtime);
  380. }
  381. }
  382. bool CDeliverModule::ReceiveACK (bool IsACK)
  383. {
  384. if (IsACK)
  385. {
  386. m_bisNAK=false;
  387. if (m_pLogFun)
  388. {
  389. m_pLogFun("Receive AK!", LOG_V2_INFO);
  390. }
  391. }
  392. else
  393. {
  394. m_bisNAK=true;
  395. if (m_pLogFun)
  396. {
  397. m_pLogFun("Receive NAK!", LOG_V2_INFO);
  398. }
  399. }
  400. SetEvent(m_hACKEvent);
  401. return m_bisNAK;
  402. }
  403. bool CDeliverModule::WaitforACK(DWORD nWaitingTime)
  404. {
  405. if (WaitForSingleObject(m_hACKEvent,nWaitingTime) == WAIT_OBJECT_0)
  406. {
  407. if (m_bisNAK)
  408. {
  409. if (m_nAKRsubmit<m_nAKResendTotalNum)
  410. {
  411. m_nAKRsubmit++;
  412. ReProcessCommand(m_strcurrentcmd);
  413. std::string logstr;
  414. if (m_pLogFun)
  415. {
  416. logstr = std::format("wait NACK {}!", m_nAKRsubmit);
  417. m_pLogFun(logstr.c_str(), LOG_V2_INFO);
  418. }
  419. }
  420. else
  421. {
  422. //重发三次都是NAK,所以判断机架断开连接
  423. //AfxMessageBox("收到NAK,重发失败",MB_OK);
  424. std::string logstr;
  425. if (m_pLogFun)
  426. {
  427. logstr = std::format("Send failed {}!", 0);
  428. m_pLogFun(logstr.c_str(), LOG_V2_ERROR);
  429. }
  430. m_nAKRsubmit=0;
  431. }
  432. return false;
  433. }
  434. else
  435. {
  436. m_nAKRsubmit=0;
  437. ResetEvent(m_hACKEvent);
  438. return true;
  439. }
  440. }
  441. else
  442. {
  443. if (m_nAKRsubmit<m_nAKResendTotalNum)
  444. {
  445. m_nAKRsubmit++;
  446. std::string logstr;
  447. if (m_pLogFun)
  448. {
  449. logstr = std::format("wait ACK timeout {}!", m_nAKRsubmit);
  450. m_pLogFun(logstr.c_str(), LOG_V2_WARNING);
  451. }
  452. ReProcessCommand(m_strcurrentcmd);
  453. }
  454. else
  455. {
  456. //重发三次都是没有回复,所以判断机架断开连接
  457. //AfxMessageBox("AK超时,重发失败",MB_OK);
  458. std::string logstr;
  459. if (m_pLogFun)
  460. {
  461. logstr = std::format("Send failed {}!", 0);
  462. m_pLogFun(logstr.c_str(),LOG_V2_ERROR);
  463. }
  464. m_nAKRsubmit=0;
  465. }
  466. return false;
  467. }
  468. }
  469. bool CDeliverModule::WaitforCP(DWORD nWaitingTime)
  470. {
  471. if (WaitForSingleObject(m_hCPEvent,nWaitingTime) == WAIT_OBJECT_0)
  472. {
  473. if (m_bisNCP)
  474. {
  475. if (m_nCPRsubmit<m_nCPResendTotalNum)
  476. {
  477. m_nCPRsubmit++;
  478. std::string logstr;
  479. if (m_pLogFun)
  480. {
  481. logstr = std::format("Wait NCP{}", m_nCPRsubmit);
  482. m_pLogFun(logstr.c_str(), LOG_V2_INFO);
  483. }
  484. ReProcessCommand(m_strcurrentcmd);
  485. }
  486. else
  487. {
  488. //重发三次都是NAK,所以判断机架断开连接
  489. //AfxMessageBox("发送指令出错,重发失败",MB_OK);
  490. std::string logstr;
  491. if (m_pLogFun)
  492. {
  493. logstr = std::format("Send failed {}!", 0);
  494. m_pLogFun(logstr.c_str(), LOG_V2_ERROR);
  495. }
  496. m_nCPRsubmit=0;
  497. }
  498. return false;
  499. }
  500. else
  501. {
  502. m_nCPRsubmit=0;
  503. ResetEvent(m_hCPEvent);
  504. return true;
  505. }
  506. }
  507. else
  508. {
  509. if (m_nCPRsubmit<1)
  510. {
  511. m_nCPRsubmit++;
  512. std::string logstr;
  513. if (m_pLogFun)
  514. {
  515. logstr = std::format("Wait CP timeout {}!", m_nCPRsubmit);
  516. m_pLogFun(logstr.c_str(), LOG_V2_WARNING);
  517. }
  518. ReProcessCommand(m_strcurrentcmd);
  519. }
  520. else
  521. {
  522. std::string logstr;
  523. if (m_pLogFun)
  524. {
  525. logstr = std::format("Send failed {}!", 0);
  526. m_pLogFun(logstr.c_str(), LOG_V2_ERROR);
  527. }
  528. m_nCPRsubmit=0;
  529. }
  530. return false;
  531. }
  532. }
  533. bool CDeliverModule::ReceiveCP (bool IsCP)
  534. {
  535. if (IsCP)
  536. {
  537. m_bisNCP=false;
  538. if (m_pLogFun)
  539. {
  540. m_pLogFun("Receive CP!", LOG_V2_INFO);
  541. }
  542. }
  543. else
  544. {
  545. m_bisNCP=true;
  546. if (m_pLogFun)
  547. {
  548. m_pLogFun("Receive NCP!", LOG_V2_INFO);
  549. }
  550. }
  551. SetEvent(m_hCPEvent);
  552. return m_bisNCP;
  553. }
  554. std::string CDeliverModule::GetCurrentCommand()
  555. {
  556. std::string command;
  557. command = m_strcurrentcmd.strCommand;
  558. return command;
  559. }
  560. void CDeliverModule::SetAKResendNum(int ResendNum)
  561. {
  562. m_nAKResendTotalNum=ResendNum;
  563. }
  564. void CDeliverModule::SetCPResendNum(int ResendNum)
  565. {
  566. m_nCPResendTotalNum=ResendNum;
  567. }
  568. int CDeliverModule::GetCurrentCommandPriority()
  569. {
  570. int Priority=m_CommondType[m_strcurrentcmd.nCommmandType].nCommandType;
  571. return Priority;
  572. }
  573. bool CDeliverModule::GetCurrentErrorState()
  574. {
  575. return m_bIsGenErr;
  576. }