ContactlessFSM.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. #ifndef _CONTACTLESS_FSM_H
  2. #define _CONTACTLESS_FSM_H
  3. #pragma once
  4. #include "SpFSM.h"
  5. #include "CommEntityUtil.hpp"
  6. #include "DevFSMCommBase.hpp"
  7. #include "RFICClass.h"
  8. #include "CardAssist.h"
  9. #include "ICDataElement.h"
  10. #include "ContactlessCard_server_g.h"
  11. #include "ContactlessCard_msg_g.h"
  12. #include "ContactlessCard_UserErrorCode.h"
  13. #include "json/json.h"
  14. enum EvtType
  15. {
  16. USER_EVT_TEST = EVT_USER+1,
  17. USER_EVT_QUIT,
  18. USER_EVT_INIT,
  19. USER_EVT_INITFINISHED,
  20. USER_EVT_ACCEPT,
  21. USER_EVT_ACCEPT_CANCEL,
  22. USER_EVT_ACCEPTFINISHED,
  23. USER_EVT_EJECT,
  24. USER_EVT_EJECTFINISHED,
  25. USER_EVT_WAITFINISHED,
  26. USER_EVT_CAPTUREFINISHED,
  27. USER_EVT_WAITFETCHINGTIMEOUT,
  28. USER_EVT_PREONLINE,
  29. USER_EVT_POSTONLINE,
  30. USER_EVT_PREONLINEFINISHED,
  31. USER_EVT_POSTONLINEFINISHED,
  32. USER_EVT_RESET,
  33. USER_EVT_RESETFINISHED,
  34. USER_EVT_EXIT,
  35. USER_EVT_READ,
  36. USER_EVT_READ_FINISHED,
  37. USER_EVT_QUERY_CARD_INFO,
  38. USER_EVT_QUERY_CARD_INFO_FINISHED,
  39. };
  40. using namespace ContactlessCard;
  41. #ifdef RVC_OS_WIN
  42. typedef int(*lpCMBdecodeMag2)(char* Mag2Data, char * data);
  43. typedef int(*lpCMBdecodeEx)( char* MagData, char * type, char * data);
  44. #else
  45. using lpCMBdecodeMag2 = int(*)(char* mag2Data, char* data);
  46. using lpCMBdecodeEx = int(*)(char* magData, char* type, char* data);
  47. #endif
  48. class CContactlessCardEntity;
  49. class CContactlessCardFSM;
  50. struct Track2Data
  51. {
  52. int status;
  53. CSimpleStringA t2Account;
  54. CSimpleStringA t2Region;
  55. CSimpleStringA t2CardSerial;
  56. CSimpleStringA t2CVC;
  57. CSimpleStringA t2ExpireDate;
  58. };
  59. struct CMBBin
  60. {
  61. CSimpleStringA bin;//6 byte long
  62. bool bIC;//IC:true or mag:false
  63. bool bDC;//debit:true,credit:false
  64. };
  65. class CardAcceptEvent : public FSMEvent
  66. {
  67. public:
  68. CardAcceptEvent() : FSMEvent(USER_EVT_ACCEPT){}
  69. ~CardAcceptEvent(){}
  70. SpReqAnsContext<ContactlessCardService_Insert_Req, ContactlessCardService_Insert_Ans>::Pointer ctx;
  71. virtual void OnUnhandled()
  72. {
  73. if (ctx != NULL)
  74. {
  75. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_USER)("card accept unhandled");
  76. ctx->Answer(Error_InvalidState);
  77. }
  78. }
  79. };
  80. class PreOnlineEvent : public FSMEvent
  81. {
  82. public:
  83. PreOnlineEvent() : FSMEvent(USER_EVT_PREONLINE){}
  84. ~PreOnlineEvent(){}
  85. SpReqAnsContext<ContactlessCardService_PreOnline_Req,ContactlessCardService_PreOnline_Ans>::Pointer ctx;
  86. virtual void OnUnhandled()
  87. {
  88. if (ctx != NULL)
  89. ctx->Answer(Error_InvalidState);
  90. }
  91. protected:
  92. private:
  93. };
  94. class PostOnlineEvent : public FSMEvent
  95. {
  96. public:
  97. PostOnlineEvent() : FSMEvent(USER_EVT_POSTONLINE){}
  98. ~PostOnlineEvent(){}
  99. SpReqAnsContext<ContactlessCardService_PostOnline_Req,ContactlessCardService_PostOnline_Ans>::Pointer ctx;
  100. virtual void OnUnhandled()
  101. {
  102. if (ctx != NULL)
  103. ctx->Answer(Error_InvalidState);
  104. }
  105. protected:
  106. private:
  107. };
  108. class CardEjectEvent : public FSMEvent
  109. {
  110. public:
  111. CardEjectEvent() : FSMEvent(USER_EVT_EJECT){}
  112. ~CardEjectEvent(){}
  113. SpReqAnsContext<ContactlessCardService_Eject_Req,ContactlessCardService_Eject_Ans>::Pointer ctx;
  114. virtual void OnUnhandled()
  115. {
  116. if (ctx != NULL)
  117. ctx->Answer(Error_InvalidState);
  118. }
  119. protected:
  120. private:
  121. };
  122. class ResetDeviceEvent : public FSMEvent
  123. {
  124. public:
  125. ResetDeviceEvent() : FSMEvent(USER_EVT_RESET){}
  126. ~ResetDeviceEvent(){}
  127. protected:
  128. private:
  129. };
  130. class ResetFinishedEvent : public FSMEvent
  131. {
  132. public:
  133. ResetFinishedEvent() : FSMEvent(USER_EVT_RESETFINISHED){}
  134. ~ResetFinishedEvent(){}
  135. protected:
  136. private:
  137. };
  138. class QueryCardInfoEvent : public FSMEvent
  139. {
  140. public:
  141. QueryCardInfoEvent() : FSMEvent(USER_EVT_QUERY_CARD_INFO){}
  142. ~QueryCardInfoEvent(){}
  143. SpReqAnsContext<ContactlessCardService_QueryCardInfo_Req,ContactlessCardService_QueryCardInfo_Ans>::Pointer ctx;
  144. virtual void OnUnhandled()
  145. {
  146. if (ctx != NULL)
  147. ctx->Answer(Error_InvalidState);
  148. }
  149. protected:
  150. private:
  151. };
  152. class CContactlessCardFSM : public CCommDevFSM<CContactlessCardFSM, RFICClass>
  153. {
  154. public:
  155. enum {s0,s1,s2,s3,s4,s5,s6,s7,s8,s9};
  156. BEGIN_FSM_STATE(CContactlessCardFSM)
  157. FSM_STATE_ENTRY(s0,"Init",s0_on_entry,s0_on_exit,s0_on_event)
  158. FSM_STATE_ENTRY(s1,"Initializing",s1_on_entry,s1_on_exit,s1_on_event)
  159. FSM_STATE_ENTRY(s2,"Idle",s2_on_entry,s2_on_exit,s2_on_event)
  160. FSM_STATE_ENTRY(s3,"Accepting",s3_on_entry,s3_on_exit,s3_on_event)
  161. FSM_STATE_ENTRY(s4,"Hold",s4_on_entry,s4_on_exit,s4_on_event)
  162. FSM_STATE_ENTRY(s5,"Reading",s5_on_entry,s5_on_exit,s5_on_event)
  163. FSM_STATE_ENTRY(s6,"Ejecting",s6_on_entry,s6_on_exit,s6_on_event)
  164. FSM_STATE_ENTRY(s7,"WaitFetching",s7_on_entry,s7_on_exit,s7_on_event)
  165. FSM_STATE_ENTRY(s8,"Capturing",s8_on_entry,s8_on_exit,s8_on_event)
  166. FSM_STATE_ENTRY(s9,"Failed",s9_on_entry,s9_on_exit,s9_on_event)
  167. END_FSM_STATE()
  168. BEGIN_FSM_RULE(CContactlessCardFSM,s0)
  169. FSM_RULE_ENTRY(s0,s1,USER_EVT_INIT,0)
  170. FSM_RULE_ENTRY(s0, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  171. FSM_RULE_ENTRY(s1,s2,USER_EVT_INITFINISHED,0)
  172. FSM_RULE_ENTRY(s1,s9,USER_EVT_INITFINISHED,1)
  173. FSM_RULE_ENTRY(s1, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  174. FSM_RULE_ENTRY(s2,s3,USER_EVT_ACCEPT,0)
  175. // FSM_RULE_ENTRY(s2,s9,USER_EVT_ACCEPT,1)
  176. FSM_RULE_ENTRY(s2, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  177. FSM_RULE_ENTRY(s2, s6, USER_EVT_EJECT, 0)
  178. FSM_RULE_ENTRY(s3,s4,USER_EVT_ACCEPTFINISHED,0)
  179. FSM_RULE_ENTRY(s3,s9,USER_EVT_ACCEPTFINISHED,1)
  180. FSM_RULE_ENTRY(s3,s2,USER_EVT_ACCEPTFINISHED,2)
  181. FSM_RULE_ENTRY(s3,s2,USER_EVT_ACCEPTFINISHED,3)
  182. FSM_RULE_ENTRY(s3,s7,USER_EVT_ACCEPTFINISHED,4)
  183. FSM_RULE_ENTRY(s3, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  184. //FSM_RULE_ENTRY(s4,s5,USER_EVT_READ,0)
  185. //FSM_RULE_ENTRY(s4,s5,USER_EVT_READ,0)
  186. FSM_RULE_ENTRY(s4,s6,USER_EVT_EJECT,0)
  187. FSM_RULE_ENTRY(s4,s6,USER_EVT_EXIT,0)
  188. //FSM_RULE_ENTRY(s4,s2,USER_EVT_ACCEPT,0)
  189. FSM_RULE_ENTRY(s4,s2,USER_EVT_QUERY_CARD_INFO_FINISHED,0)
  190. FSM_RULE_ENTRY(s4, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  191. FSM_RULE_ENTRY(s5,s4,USER_EVT_READ_FINISHED,0)
  192. FSM_RULE_ENTRY(s5,s9,USER_EVT_READ_FINISHED,1)
  193. FSM_RULE_ENTRY(s5,s2,USER_EVT_READ_FINISHED,2)
  194. FSM_RULE_ENTRY(s5, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  195. FSM_RULE_ENTRY(s5, s6, USER_EVT_EXIT, 0)
  196. FSM_RULE_ENTRY(s6,s7,USER_EVT_EJECTFINISHED,1)
  197. FSM_RULE_ENTRY(s6,s7,USER_EVT_EJECTFINISHED,0)
  198. FSM_RULE_ENTRY(s6,s7,USER_EVT_EJECTFINISHED,2)
  199. FSM_RULE_ENTRY(s6,s2,USER_EVT_EXIT,0)
  200. FSM_RULE_ENTRY(s6, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  201. FSM_RULE_ENTRY(s7,s2,USER_EVT_WAITFINISHED,0)
  202. FSM_RULE_ENTRY(s7,s2,USER_EVT_WAITFINISHED,2)
  203. //FSM_RULE_ENTRY(s7,s9,USER_EVT_WAITFINISHED,1)
  204. //FSM_RULE_ENTRY(s7,s8,USER_EVT_WAITFINISHED,2)
  205. FSM_RULE_ENTRY(s7, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  206. //FSM_RULE_ENTRY(s8,s2,USER_EVT_CAPTUREFINISHED,0)
  207. //FSM_RULE_ENTRY(s8,s9,USER_EVT_CAPTUREFINISHED,1)
  208. FSM_RULE_ENTRY(s8, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  209. //FSM_RULE_ENTRY(s9, s2, USER_EVT_RESETFINISHED, 0)
  210. FSM_RULE_ENTRY(s9, FSM_STATE_EXIT, USER_EVT_QUIT, 0)
  211. FSM_RULE_ENTRY(s9, s2, USER_EVT_RESETFINISHED, 0)
  212. FSM_RULE_ENTRY(s9, s2, USER_EVT_RESETFINISHED, 1)
  213. END_FSM_RULE()
  214. CContactlessCardFSM() : m_bCancelAccept(false),m_bWaitingAccept(false),
  215. m_bWaitAccepteMore(false),m_bExit(false),m_resetTimes(0),m_testResult(Error_Succeed)
  216. ,m_bCDA(false),m_pDataToARQC(NULL), m_csMachineType(true), m_csDevNo(""),m_devInit(false), m_repeatErrTimes(0)
  217. {
  218. HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x213);
  219. cmdDecodeMag2 = NULL;
  220. cmdDecodeEx = NULL;
  221. m_aidList.Init(3);
  222. m_aidList[0] = "A000000333";
  223. m_aidList[1] = "A0000000108888";
  224. m_aidList[2] = "A000000790";
  225. }
  226. ~CContactlessCardFSM(){}
  227. virtual ErrorCodeEnum OnInit();
  228. virtual ErrorCodeEnum OnExit();
  229. void s0_on_entry();
  230. void s0_on_exit();
  231. unsigned int s0_on_event(FSMEvent* event);
  232. void s1_on_entry();
  233. void s1_on_exit();
  234. unsigned int s1_on_event(FSMEvent* event);
  235. void s2_on_entry();
  236. void s2_on_exit();
  237. unsigned int s2_on_event(FSMEvent* event);
  238. void s3_on_entry();
  239. void s3_on_exit();
  240. unsigned int s3_on_event(FSMEvent* event);
  241. void s4_on_entry();
  242. void s4_on_exit();
  243. unsigned int s4_on_event(FSMEvent* event);
  244. void s5_on_entry();
  245. void s5_on_exit();
  246. unsigned int s5_on_event(FSMEvent* event);
  247. void s6_on_entry();
  248. void s6_on_exit();
  249. unsigned int s6_on_event(FSMEvent* event);
  250. void s7_on_entry();
  251. void s7_on_exit();
  252. unsigned int s7_on_event(FSMEvent* event);
  253. void s8_on_entry();
  254. void s8_on_exit();
  255. unsigned int s8_on_event(FSMEvent* event);
  256. void s9_on_entry();
  257. void s9_on_exit();
  258. unsigned int s9_on_event(FSMEvent* event);
  259. int Initial();
  260. ErrorCodeEnum Load();
  261. bool GetDevStatus(bool bPrint=true);
  262. int InternalAcceptCard();
  263. int AcceptCard(SpReqAnsContext<ContactlessCardService_Insert_Req, ContactlessCardService_Insert_Ans>::Pointer ctx);
  264. //int ReadCard(SpReqAnsContext<ContactlessCardService_Read_Req,ContactlessCardService_Read_Ans>::Pointer ctx);
  265. int PreOnline(SpReqAnsContext<ContactlessCardService_PreOnline_Req,ContactlessCardService_PreOnline_Ans>::Pointer ctx);
  266. int PostOnline(SpReqAnsContext<ContactlessCardService_PostOnline_Req,ContactlessCardService_PostOnline_Ans>::Pointer ctx);
  267. int EjectCard(SpReqAnsContext<ContactlessCardService_Eject_Req,ContactlessCardService_Eject_Ans>::Pointer ctx);
  268. int Reset();
  269. int WaitFetchingCard();
  270. int QueryCardInfo(SpReqAnsContext<ContactlessCardService_QueryCardInfo_Req, ContactlessCardService_QueryCardInfo_Ans>::Pointer ctx);
  271. bool GetWaitFlag(){return m_bWaitingAccept;}
  272. void SetWaitMore(){m_bWaitAccepteMore = true;}
  273. void SetExitFlag(bool bFlag=true){m_bExit = bFlag;}
  274. void ToLogWarnInfoAboutTermCustom();
  275. bool LoadCMBPrint(CSimpleStringA csBinPath);
  276. void GetCardProcessLastErr(ErrorCodeEnum& eErrCode, CSimpleStringA& lastApiName, CSimpleStringA& alarmMsg, CSimpleStringA& csErrMsgWithReturnCode);
  277. void SelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext)
  278. {
  279. pTransactionContext->SendAnswer(m_testResult);
  280. }
  281. protected:
  282. int m_iInsertTries;
  283. int m_resetTries;
  284. int m_ejectTries;
  285. private:
  286. ///
  287. int m_resetTimes;
  288. lpCMBdecodeMag2 cmdDecodeMag2;
  289. lpCMBdecodeEx cmdDecodeEx;
  290. bool m_devInit, m_bCancelAccept, m_bWaitingAccept, m_bWaitAccepteMore, m_bExit, m_bIssued;
  291. ErrorCodeEnum m_testResult;
  292. CSimpleStringA m_csMachineType;
  293. DevCategoryInfo m_devCatInfo;
  294. int m_CardInit,m_CardRemains,m_CardIssued,m_CardCaptured,m_CardMixed,m_CardPercent;
  295. RFICReaderStatus devStatus;
  296. CCardProcess *m_pCardProcess;
  297. char *m_pDataToARQC;
  298. long xxTest;
  299. CAutoArray<CSimpleStringA> m_aidList;
  300. char m_AuthCode[2];
  301. bool m_bCDA;
  302. CSimpleStringA m_csDevNo;
  303. int SplitTrack2(CSimpleStringA pTrack2,Track2Data &decodeData);
  304. int m_repeatErrTimes;
  305. };
  306. struct InitTask : public ITaskSp
  307. {
  308. CContactlessCardFSM* fsm;
  309. InitTask(CContactlessCardFSM* f) : fsm(f) {}
  310. void Process()
  311. {
  312. FSMEvent *e = new FSMEvent(USER_EVT_INITFINISHED);
  313. e->param1 = fsm->Initial();
  314. fsm->PostEventFIFO(e);
  315. }
  316. };
  317. struct AcceptTask : public ITaskSp
  318. {
  319. CContactlessCardFSM* fsm;
  320. SpReqAnsContext<ContactlessCardService_Insert_Req, ContactlessCardService_Insert_Ans>::Pointer ctx;
  321. AcceptTask(CContactlessCardFSM* f) : fsm(f) {}
  322. void Process()
  323. {
  324. LOG_FUNCTION();
  325. FSMEvent *e = new FSMEvent(USER_EVT_ACCEPTFINISHED);
  326. e->param1 = fsm->AcceptCard(ctx);
  327. fsm->PostEventFIFO(e);
  328. }
  329. };
  330. struct PreOnlineTask : public ITaskSp
  331. {
  332. SpReqAnsContext<ContactlessCardService_PreOnline_Req,ContactlessCardService_PreOnline_Ans>::Pointer ctx;
  333. CContactlessCardFSM* fsm;
  334. PreOnlineTask(CContactlessCardFSM* f) : fsm(f) {}
  335. void Process()
  336. {
  337. FSMEvent *e = new FSMEvent(USER_EVT_PREONLINEFINISHED);
  338. e->param1 = fsm->PreOnline(ctx);
  339. fsm->PostEventFIFO(e);
  340. }
  341. };
  342. struct PostOnlineTask : public ITaskSp
  343. {
  344. SpReqAnsContext<ContactlessCardService_PostOnline_Req,ContactlessCardService_PostOnline_Ans>::Pointer ctx;
  345. CContactlessCardFSM* fsm;
  346. PostOnlineTask(CContactlessCardFSM* f) : fsm(f) {}
  347. void Process()
  348. {
  349. FSMEvent *e = new FSMEvent(USER_EVT_POSTONLINEFINISHED);
  350. e->param1 = fsm->PostOnline(ctx);
  351. fsm->PostEventFIFO(e);
  352. }
  353. };
  354. struct EjectTask : public ITaskSp
  355. {
  356. SpReqAnsContext<ContactlessCardService_Eject_Req,ContactlessCardService_Eject_Ans>::Pointer ctx;
  357. CContactlessCardFSM* fsm;
  358. EjectTask(CContactlessCardFSM* f) : fsm(f) {}
  359. void Process()
  360. {
  361. FSMEvent *e = new FSMEvent(USER_EVT_EJECTFINISHED);
  362. e->param1 = fsm->EjectCard(ctx);
  363. fsm->PostEventFIFO(e);
  364. }
  365. };
  366. struct WaitFetchingTask : public ITaskSp
  367. {
  368. CContactlessCardFSM* fsm;
  369. WaitFetchingTask(CContactlessCardFSM* f) : fsm(f) {}
  370. void Process()
  371. {
  372. FSMEvent *e = new FSMEvent(USER_EVT_WAITFINISHED);
  373. e->param1 = fsm->WaitFetchingCard();
  374. fsm->PostEventFIFO(e);
  375. }
  376. };
  377. struct ResetTask : public ITaskSp
  378. {
  379. CContactlessCardFSM* fsm;
  380. ResetTask(CContactlessCardFSM* f) : fsm(f) {}
  381. void Process()
  382. {
  383. ResetFinishedEvent *e = new ResetFinishedEvent();
  384. e->param1 = fsm->Reset();
  385. fsm->PostEventFIFO(e);
  386. }
  387. };
  388. struct QueryCardInfoTask : public ITaskSp
  389. {
  390. SpReqAnsContext<ContactlessCardService_QueryCardInfo_Req,ContactlessCardService_QueryCardInfo_Ans>::Pointer ctx;
  391. CContactlessCardFSM* fsm;
  392. QueryCardInfoTask(CContactlessCardFSM* f) : fsm(f) {}
  393. void Process()
  394. {
  395. FSMEvent *e = new FSMEvent(USER_EVT_QUERY_CARD_INFO_FINISHED);
  396. e->param1 = fsm->QueryCardInfo(ctx);
  397. fsm->PostEventFIFO(e);
  398. }
  399. };
  400. #endif //_CONTACTLESS_FSM_H