PinPadFSM.h 12 KB

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