PinPadFSM.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391
  1. #ifndef __PINPAD_FSM_H
  2. #define __PINPAD_FSM_H
  3. #pragma once
  4. #include "SpFSM.h"
  5. #include "toolkit.h"
  6. #include "SpUtility.h"
  7. #include "DevFSMCommBase.hpp"
  8. #include "CommEntityUtil.hpp"
  9. #include "PinPad_UserErrorCode.h"
  10. #include "json/json.h"
  11. enum EvtType
  12. {
  13. USER_EVT_TEST = EVT_USER+1,
  14. USER_EVT_ANY_INPUT_TIMER,
  15. USER_EVT_QUIT,
  16. USER_EVT_INIT,
  17. USER_EVT_INITFINISHED,
  18. USER_EVT_SETACCOUNT,
  19. USER_EVT_SETACCOUNTFINISHED,
  20. USER_EVT_INPUTCANCEL,
  21. USER_EVT_INPUTWAITINGMORE,
  22. USER_EVT_EXIT,
  23. USER_EVT_GETINPUT_SM,
  24. USER_EVT_GETINPUT_SM_FINISHED,
  25. USER_EVT_LOADKEY_SM,
  26. USER_EVT_LOADKEY_SM_FINISHED,
  27. USER_EVT_ENCRYPT_SM,
  28. USER_EVT_ENCRYPT_SM_FINISHED,
  29. USER_EVT_GET_CHECKCODE,
  30. USER_EVT_GET_CHECKCODE_FINISHED,
  31. USER_EVT_TODO_INIT,
  32. USER_EVT_TODO_INIT_FINISHED,
  33. USER_EVT_GETINPUT_JS,
  34. USER_EVT_GETINPUT_JS_FINISHED,
  35. };
  36. #include "PinPad_server_g.h"
  37. #include "PinPad_msg_g.h"
  38. #include "PinPadClass.h"
  39. #include "DeviceBaseHelper.h"
  40. using namespace PinPad;
  41. #include <map>
  42. using namespace std;
  43. #include "DeviceBaseHelper.h"
  44. struct CtxInfo
  45. {
  46. int dataSize;
  47. LPVOID pCtx;
  48. };
  49. class CPinPadEntity;
  50. class CPinPadFSM;
  51. unsigned int __stdcall DoWork(void* pData);
  52. class PinPadInitFinishedEvent : public FSMEvent
  53. {
  54. public:
  55. PinPadInitFinishedEvent() : FSMEvent(USER_EVT_INITFINISHED){}
  56. ~PinPadInitFinishedEvent(){}
  57. };
  58. class InputCancelEvent : public FSMEvent
  59. {
  60. public:
  61. InputCancelEvent() : FSMEvent(USER_EVT_INPUTCANCEL){}
  62. ~InputCancelEvent(){}
  63. };
  64. class InputWaitingMoreEvent : public FSMEvent
  65. {
  66. public:
  67. InputWaitingMoreEvent() : FSMEvent(USER_EVT_INPUTWAITINGMORE){}
  68. ~InputWaitingMoreEvent(){}
  69. };
  70. class GetInputSMEvent : public FSMEvent
  71. {
  72. public:
  73. GetInputSMEvent() : FSMEvent(USER_EVT_GETINPUT_SM){}
  74. ~GetInputSMEvent(){}
  75. SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctx;
  76. virtual void OnUnhandled()
  77. {
  78. if (ctx != NULL) {
  79. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetInputSMEvent")("InvalidState");
  80. ctx->Answer(Error_InvalidState);
  81. }
  82. }
  83. };
  84. class GetInputJSEvent : public FSMEvent
  85. {
  86. public:
  87. GetInputJSEvent() : FSMEvent(USER_EVT_GETINPUT_JS) {}
  88. ~GetInputJSEvent() {}
  89. SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctx;
  90. virtual void OnUnhandled()
  91. {
  92. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("InvalidState");
  93. }
  94. };
  95. class LoadKeySMEvent : public FSMEvent
  96. {
  97. public:
  98. LoadKeySMEvent() : FSMEvent(USER_EVT_LOADKEY_SM){}
  99. ~LoadKeySMEvent(){}
  100. SpReqAnsContext<PinPadService_LoadKeysSM_Req, PinPadService_LoadKeysSM_Ans>::Pointer ctx;
  101. virtual void OnUnhandled()
  102. {
  103. if (ctx != NULL) {
  104. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("LoadKeySMEvent")("InvalidState");
  105. ctx->Answer(Error_InvalidState);
  106. }
  107. }
  108. };
  109. class EncryptSMEvent : public FSMEvent
  110. {
  111. public:
  112. EncryptSMEvent() : FSMEvent(USER_EVT_ENCRYPT_SM){}
  113. ~EncryptSMEvent(){}
  114. SpReqAnsContext<PinPadService_EncryptDataSM_Req, PinPadService_EncryptDataSM_Ans>::Pointer ctx;
  115. virtual void OnUnhandled()
  116. {
  117. if (ctx != NULL) {
  118. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("EncryptSMEvent")("InvalidState");
  119. ctx->Answer(Error_InvalidState);
  120. }
  121. }
  122. };
  123. class GetCheckCodeEvent : public FSMEvent
  124. {
  125. public:
  126. GetCheckCodeEvent() : FSMEvent(USER_EVT_GET_CHECKCODE){}
  127. ~GetCheckCodeEvent(){}
  128. SpReqAnsContext<PinPadService_GetCheckCode_Req, PinPadService_GetCheckCode_Ans>::Pointer ctx;
  129. virtual void OnUnhandled()
  130. {
  131. if (ctx != NULL) {
  132. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI("GetCheckCodeEvent")("InvalidState");
  133. ctx->Answer(Error_InvalidState);
  134. }
  135. }
  136. };
  137. class CPinPadFSM : public CCommDevFSM<CPinPadFSM, PinPadClass>
  138. {
  139. public:
  140. enum {s0,s1,s2,s3,s4,s5,s6};
  141. BEGIN_FSM_STATE(CPinPadFSM)
  142. FSM_STATE_ENTRY(s0, "Init", s0_on_entry, s0_on_exit, s0_on_event)
  143. FSM_STATE_ENTRY(s1, "Initializing", s1_on_entry, s1_on_exit, s1_on_event)
  144. FSM_STATE_ENTRY(s2, "Idle", s2_on_entry, s2_on_exit, s2_on_event)
  145. FSM_STATE_ENTRY(s3, "Input", s3_on_entry, s3_on_exit, s3_on_event)
  146. FSM_STATE_ENTRY(s4, "AccessAuth", s4_on_entry, s4_on_exit, s4_on_event)
  147. FSM_STATE_ENTRY(s5, "Failed", s5_on_entry, s5_on_exit, s5_on_event)
  148. FSM_STATE_ENTRY(s6, "InitFailed", s6_on_entry, s6_on_exit, s6_on_event)
  149. END_FSM_STATE()
  150. BEGIN_FSM_RULE(CPinPadFSM, s0)
  151. FSM_RULE_ENTRY(s0, s1, USER_EVT_INIT, 0)
  152. FSM_RULE_ENTRY(s1, s2, USER_EVT_INITFINISHED, 0)
  153. FSM_RULE_ENTRY(s1, s6, USER_EVT_INITFINISHED, 1)
  154. FSM_RULE_ENTRY(s2, s3, USER_EVT_GETINPUT_SM, 0)
  155. FSM_RULE_ENTRY(s2, s3, USER_EVT_GETINPUT_JS, 0)
  156. FSM_RULE_ENTRY(s2, s4, USER_EVT_LOADKEY_SM, 2)
  157. FSM_RULE_ENTRY(s2, s4, USER_EVT_ENCRYPT_SM, 2)
  158. FSM_RULE_ENTRY(s2, s0, USER_EVT_TODO_INIT_FINISHED, 0)
  159. FSM_RULE_ENTRY(s3, s2, USER_EVT_GETINPUT_SM_FINISHED, 0)
  160. FSM_RULE_ENTRY(s3, s2, USER_EVT_GETINPUT_JS_FINISHED, 0)
  161. FSM_RULE_ENTRY(s3, s2, USER_EVT_EXIT, 0)
  162. FSM_RULE_ENTRY(s4, s2, USER_EVT_LOADKEY_SM_FINISHED, 0)
  163. FSM_RULE_ENTRY(s4, s2, USER_EVT_ENCRYPT_SM_FINISHED, 0)
  164. FSM_RULE_ENTRY(s5, s0, USER_EVT_TODO_INIT_FINISHED, 0)
  165. FSM_RULE_ENTRY(s6, s0, USER_EVT_TODO_INIT_FINISHED, 0)
  166. END_FSM_RULE()
  167. CPinPadFSM() : m_bFrontCancel(false),
  168. m_bWaitingMore(false), m_bExit(false), m_bPlainPin(true),
  169. m_bEntityExit(false), m_bPinInput(false), m_bLoadKey(false), m_bEncrypt(false)
  170. , m_dwDevCommFailCount(0), m_dwPinPadRunCount(0), m_eDevState(DEVICE_STATUS_NOT_READY), m_encryptkey(1)
  171. , m_bSM(false), m_bSMLoaded(false), m_iInWhatPage(PageType_Other), m_szModel(""), m_szType("")
  172. , m_szVendor(""),m_csMachineType(true), m_csSite(true), m_terminalNo(true), m_port(true), m_Baudrate(true)
  173. , m_devSN(""), m_bPinInputJS(false){
  174. HARDWARE_ENTITY_RESET_ENTITYID(m_entCode, 0x206);
  175. ZeroMemory(&m_adapterInfo, sizeof(m_adapterInfo));
  176. }
  177. ~CPinPadFSM(){
  178. m_bEntityExit = true;
  179. }
  180. virtual ErrorCodeEnum OnInit();
  181. virtual ErrorCodeEnum OnExit();
  182. //void DoWork();
  183. void s0_on_entry();
  184. void s0_on_exit();
  185. unsigned int s0_on_event(FSMEvent* event);
  186. void s1_on_entry();
  187. void s1_on_exit();
  188. unsigned int s1_on_event(FSMEvent* event);
  189. void s2_on_entry();
  190. void s2_on_exit();
  191. unsigned int s2_on_event(FSMEvent* event);
  192. void s3_on_entry();
  193. void s3_on_exit();
  194. unsigned int s3_on_event(FSMEvent* event);
  195. void s4_on_entry();
  196. void s4_on_exit();
  197. unsigned int s4_on_event(FSMEvent* event);
  198. void s5_on_entry();
  199. void s5_on_exit();
  200. unsigned int s5_on_event(FSMEvent* event);
  201. void s6_on_entry();
  202. void s6_on_exit();
  203. unsigned int s6_on_event(FSMEvent* event);
  204. int Initial();
  205. void push_char(char *buf, int *len, int c);
  206. void PushInputChar(char *buf, int c);
  207. void pop_char(char *buf, int *len,bool bClear=true);
  208. void clear_char(char *buf, int *len);
  209. bool Get12Account(char *szAcc);
  210. int GetInput(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctxSM);
  211. ErrorCodeEnum GetEncryptText(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctxSM);
  212. bool GetDevInitFlag(){ return m_bOpened;}
  213. void ResetDevInitFlag() { m_bOpened = false; }
  214. void SetExitFlag(){m_bExit = true;}
  215. bool GetEntityExit() { return m_bEntityExit;}
  216. void SetCtx(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer ctxSM)
  217. {
  218. m_inputSMCtx = ctxSM;
  219. m_bPinInput = true;
  220. }
  221. bool GetCtx(SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer& ctxSM)
  222. {
  223. if (m_inputSMCtx == NULL)
  224. {
  225. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ctxSM is null");
  226. return false;
  227. }
  228. ctxSM = m_inputSMCtx;
  229. return true;
  230. }
  231. void SetJSCtx(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS)
  232. {
  233. m_inputJSCtx = ctxJS;
  234. m_bPinInputJS = true;
  235. }
  236. bool GetJSCtx(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer& ctxJS)
  237. {
  238. if (m_inputJSCtx == NULL)
  239. {
  240. DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM)("ctxJS is null");
  241. return false;
  242. }
  243. ctxJS = m_inputJSCtx;
  244. return true;
  245. }
  246. int GetInputJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS);
  247. ErrorCodeEnum GetEncryptTextJS(SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer ctxJS);
  248. bool GetDevInfo(DevCategoryInfo &devInfo);
  249. int LoadKeySM(SpReqAnsContext<PinPadService_LoadKeysSM_Req, PinPadService_LoadKeysSM_Ans>::Pointer ctx);
  250. int EncryptSM(SpReqAnsContext<PinPadService_EncryptDataSM_Req, PinPadService_EncryptDataSM_Ans>::Pointer ctx);
  251. ErrorCodeEnum GetCheckCode(SpReqAnsContext<PinPadService_GetCheckCode_Req, PinPadService_GetCheckCode_Ans>::Pointer ctx);
  252. int GetEncryptKey(int &devFunc,int &loadFunc)
  253. {
  254. devFunc = loadFunc = 0;
  255. devFunc = m_encryptkey;
  256. int tmp = 0;
  257. if (m_bSMLoaded)
  258. tmp += 2;
  259. if (m_bSMLoaded)
  260. loadFunc = 2;
  261. else
  262. loadFunc = tmp;
  263. return 0;
  264. }
  265. void SetInWhatPage(int iPageType);
  266. void SelfTest(EntityTestEnum eTestType,CSmartPointer<ITransactionContext> pTransactionContext);
  267. void ToLogWarnInfoAboutTermCustom();
  268. bool IsInGetInputJS() { return m_bPinInputJS; }
  269. public:
  270. SP::Toolkit::CConditionVarPlus m_hInputConVar;
  271. SP::Toolkit::CConditionVarPlus m_hInitConVar;
  272. private:
  273. SpReqAnsContext<PinPadService_GetInputSM_Req, PinPadService_GetInputSM_Ans>::Pointer m_inputSMCtx;
  274. SpReqAnsContext<PinPadService_GetInputJS_Req, PinPadService_GetInputJS_Ans>::Pointer m_inputJSCtx;
  275. char m_szAccount[MAX_ACCOUNT_LEN];
  276. bool m_bFrontCancel,m_bWaitingMore,m_bExit,m_bPlainPin,m_bEntityExit
  277. ,m_bPinInput,m_bLoadKey,m_bEncrypt,m_bSM,m_bSMLoaded, m_bPinInputJS;
  278. ULLINT m_ullBeginTime, m_ullEndTime,m_ullConnectCost;
  279. CSimpleStringA m_deviceNo, m_port, m_Baudrate, m_devCheckData,m_keySNSM,m_szModel,m_szType,m_szVendor,m_devSN/*fwb SN*/;
  280. char m_buf[4];
  281. ErrorCodeEnum m_testResult;
  282. DWORD m_dwDevCommFailCount,m_dwPinPadRunCount;
  283. DevStateEnum m_eDevState;
  284. int m_encryptkey;
  285. int m_iInWhatPage/*在哪个页面,区分首页,用户桌面,其他页*/;
  286. CSimpleStringA m_csMachineType, m_csSite, m_terminalNo,m_lastCheckCode;
  287. CSystemStaticInfo m_sysStaticInfo;
  288. CSimpleStringA m_csAlarmMsg;
  289. bool IsInBusiness() { return (m_iInWhatPage == PageType_Other); }
  290. };
  291. struct InitTask : public ITaskSp
  292. {
  293. CPinPadFSM *fsm;
  294. InitTask(CPinPadFSM* f) : fsm(f) {}
  295. void Process()
  296. {
  297. FSMEvent *e = new FSMEvent(USER_EVT_INITFINISHED);
  298. e->param1 = fsm->Initial();
  299. fsm->PostEventFIFO(e);
  300. }
  301. };
  302. struct LoadKeySMTask : public ITaskSp
  303. {
  304. CPinPadFSM* fsm;
  305. SpReqAnsContext<PinPadService_LoadKeysSM_Req, PinPadService_LoadKeysSM_Ans>::Pointer ctx;
  306. LoadKeySMTask(CPinPadFSM* f) : fsm(f) {}
  307. void Process()
  308. {
  309. LOG_FUNCTION();
  310. FSMEvent *e = new FSMEvent(USER_EVT_LOADKEY_SM_FINISHED);
  311. e->param1 = fsm->LoadKeySM(ctx);
  312. fsm->PostEventFIFO(e);
  313. }
  314. };
  315. struct EncryptSMTask : public ITaskSp
  316. {
  317. CPinPadFSM* fsm;
  318. SpReqAnsContext<PinPadService_EncryptDataSM_Req, PinPadService_EncryptDataSM_Ans>::Pointer ctx;
  319. EncryptSMTask(CPinPadFSM* f) : fsm(f) {}
  320. void Process()
  321. {
  322. LOG_FUNCTION();
  323. FSMEvent *e = new FSMEvent(USER_EVT_ENCRYPT_SM_FINISHED);
  324. e->param1 = fsm->EncryptSM(ctx);
  325. fsm->PostEventFIFO(e);
  326. }
  327. };
  328. struct GetCheckCodeTask : public ITaskSp
  329. {
  330. CPinPadFSM* fsm;
  331. SpReqAnsContext<PinPadService_GetCheckCode_Req, PinPadService_GetCheckCode_Ans>::Pointer ctx;
  332. GetCheckCodeTask(CPinPadFSM* f) : fsm(f) {}
  333. void Process()
  334. {
  335. FSMEvent *e = new FSMEvent(USER_EVT_GET_CHECKCODE_FINISHED);
  336. e->param1 = fsm->GetCheckCode(ctx);
  337. fsm->PostEventFIFO(e);
  338. }
  339. };
  340. template<class T>
  341. class TimerOutHelper : public ITimerListener
  342. {
  343. public:
  344. typedef void (T::*FuncTimer)(void *pUserdata);
  345. TimerOutHelper(T *p, FuncTimer pTimerFunc, void *pUserData, bool bDeleteSelf = false)
  346. : m_pObject(p), m_pUserData(pUserData), m_pTimer(pTimerFunc), m_bDeleteSelf(bDeleteSelf) {}
  347. virtual void OnTimeout(DWORD dwTimerID)
  348. {
  349. (m_pObject->*m_pTimer)(m_pUserData);
  350. if (m_bDeleteSelf)
  351. delete this;
  352. }
  353. private:
  354. void *m_pUserData;
  355. T *m_pObject;
  356. FuncTimer m_pTimer;
  357. bool m_bDeleteSelf;
  358. };
  359. #endif //__PINPAD_FSM_H