DownloadFSM.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421
  1. #pragma once
  2. #include "SpBase.h"
  3. #include "SpFSM.h"
  4. #include "SpSecureClient.h"
  5. #include "download.h"
  6. #include <list>
  7. #include "Download_msg_g.h"
  8. using namespace Download;
  9. #pragma pack(1)
  10. // [StructName("LISTREQ")]
  11. struct ListReq
  12. {
  13. char TerminalNo[16];
  14. };
  15. //[StructName("LISTANS")]
  16. struct ListAns
  17. {
  18. int ResultCode;
  19. char ListXmlContent[0]; // no more than 32k
  20. };
  21. //新国密文件列表接口20200210 lwt
  22. // [StructName("LISTNREQ")]
  23. struct ListNReq
  24. {
  25. char TerminalNo[16];
  26. };
  27. //[StructName("LISTNANS")]
  28. struct ListNAns
  29. {
  30. int ResultCode;
  31. char ListXmlContent[0]; // no more than 50k
  32. };
  33. //[StructName("FILEREQ")]
  34. struct FileReq
  35. {
  36. //char FileName[64];
  37. char FileName[256];
  38. int BlockNo;
  39. };
  40. //[StructName("FILEANS")]
  41. struct FileAns
  42. {
  43. int ResultCode;
  44. //char FileName[64];
  45. char FileName[256];
  46. int BlockNo;
  47. char FileContent[0]; // no more than 32k
  48. };
  49. #pragma pack()
  50. enum DownloadCtlCode
  51. {
  52. Finish = 0, //完成
  53. Begin = 1, //开始下载
  54. Continua = 2, //文件已经存在,断点续传,按返回块开始传
  55. ErrorBlock = 3, //上块错误,重新传
  56. ReturnList = 4, //返回列表
  57. };
  58. #define USER_EVT_JMP_DISABLE EVT_USER+1
  59. #define USER_EVT_JMP_ENABLE EVT_USER+2
  60. #define USER_EVT_JMP_GETFILEINFO EVT_USER+3
  61. #define USER_EVT_FILEINO_ANS EVT_USER+4
  62. #define USER_EVT_FILE_ANS EVT_USER+5
  63. #define USER_EVT_DISCONNECT EVT_USER+6
  64. #define USER_EVT_JMP_SYNC EVT_USER+7
  65. #define USER_EVT_SYNC_FINISHED EVT_USER+8
  66. #define USER_EVT_NOTASK EVT_USER+9
  67. #define XML_US_ASCII_PREFIX "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\r\n"
  68. struct ListAnsEvent : public FSMEvent
  69. {
  70. ListAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_FILEINO_ANS) {
  71. int size = nLen;
  72. int nprefix = strlen(XML_US_ASCII_PREFIX);
  73. int offset = 0;
  74. if (memcmp(pBuf + sizeof(ListAns), "<?", 2) != 0) {
  75. size += nprefix;
  76. }
  77. LPBYTE pData = new BYTE[size+1];
  78. if (size != nLen) {
  79. memcpy(pData, pBuf, sizeof(ListAns));
  80. offset = sizeof(ListAns);
  81. memcpy(pData+offset, XML_US_ASCII_PREFIX, nprefix);
  82. offset += nprefix;
  83. memcpy(pData+offset, pBuf+sizeof(ListAns), nLen-sizeof(ListAns));
  84. offset += nLen-sizeof(ListAns);
  85. pData[offset] = 0;
  86. m_xml_length = nLen - sizeof(ListAns) + nprefix;
  87. } else {
  88. memcpy(pData, pBuf, nLen);
  89. pData[nLen] = 0;
  90. m_xml_length = nLen - sizeof(ListAns);
  91. }
  92. m_reply = (ListAns*)pData;
  93. }
  94. virtual ~ListAnsEvent() { delete (LPBYTE)m_reply; }
  95. ListAns *m_reply;
  96. int m_xml_length;
  97. };
  98. //新国密文件列表回应报文
  99. struct ListNAnsEvent : public FSMEvent
  100. {
  101. ListNAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_FILEINO_ANS) {
  102. int size = nLen;
  103. int nprefix = strlen(XML_US_ASCII_PREFIX);
  104. int offset = 0;
  105. if (memcmp(pBuf + sizeof(ListAns), "<?", 2) != 0) {
  106. size += nprefix;
  107. }
  108. LPBYTE pData = new BYTE[size+1];
  109. if (size != nLen) {
  110. memcpy(pData, pBuf, sizeof(ListAns));
  111. offset = sizeof(ListAns);
  112. memcpy(pData+offset, XML_US_ASCII_PREFIX, nprefix);
  113. offset += nprefix;
  114. memcpy(pData+offset, pBuf+sizeof(ListAns), nLen-sizeof(ListAns));
  115. offset += nLen-sizeof(ListAns);
  116. pData[offset] = 0;
  117. m_xml_length = nLen - sizeof(ListAns) + nprefix;
  118. } else {
  119. memcpy(pData, pBuf, nLen);
  120. pData[nLen] = 0;
  121. m_xml_length = nLen - sizeof(ListAns);
  122. }
  123. m_reply = (ListAns*)pData;
  124. }
  125. virtual ~ListNAnsEvent() { delete (LPBYTE)m_reply; }
  126. ListAns *m_reply;
  127. int m_xml_length;
  128. };
  129. struct FileAnsEvent : public FSMEvent
  130. {
  131. FileAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_FILE_ANS) {
  132. LPBYTE pData = new BYTE[nLen+1];
  133. memcpy(pData, pBuf, nLen);
  134. m_reply = (FileAns*)pData;
  135. pData[nLen] = 0;
  136. m_content_length = nLen - sizeof(FileAns);
  137. }
  138. virtual ~FileAnsEvent() { delete (LPBYTE)m_reply; }
  139. FileAns *m_reply;
  140. int m_content_length;
  141. };
  142. struct DownloadFileTask
  143. {
  144. CSimpleStringA FileName;
  145. DWORD ExpireTime;
  146. };
  147. class DownloadConnection;
  148. class DownloadFSM : public FSMImpl<DownloadFSM>, public IFSMStateHooker, public ISysVarListener
  149. {
  150. public:
  151. DownloadFSM();
  152. virtual ~DownloadFSM();
  153. virtual void OnStateTrans(int iSrcState, int iDstState);
  154. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName);
  155. virtual ErrorCodeEnum OnInit();
  156. virtual ErrorCodeEnum OnExit();
  157. enum {s0,s1,s2,s3,s4,s5};
  158. enum {SYNC_STATE = s5};
  159. BEGIN_FSM_STATE(DownloadFSM)
  160. FSM_STATE_ENTRY(s0,"Disable",s0_on_entry,s0_on_exit,s0_on_event)//判断可视柜台是否离线状态,否则等待10s再进行判断,成功则跳出不可用状态
  161. FSM_STATE_ENTRY(s1,"Enable",s1_on_entry,s1_on_exit,s1_on_event)//10秒内无连线状态则进入s2
  162. FSM_STATE_ENTRY(s2, "Active",s2_on_entry,s2_on_exit,s2_on_event)//连接中台服务,不成功则等待30s后再连接
  163. FSM_STATE_ENTRY(s3, "getFileInfo",s3_on_entry,s3_on_exit,s3_on_event)
  164. FSM_STATE_ENTRY(s4, "DownloadFile", s4_on_entry, s4_on_exit, s4_on_event)
  165. FSM_STATE_ENTRY(s5, "Synchronized", s5_on_entry, s5_on_exit, s5_on_event)
  166. END_FSM_STATE()
  167. BEGIN_FSM_RULE(DownloadFSM,s0)
  168. FSM_RULE_ENTRY_ANY(s0, s2, USER_EVT_JMP_ENABLE)
  169. //FSM_RULE_ENTRY_ANY(s0, s5, USER_EVT_JMP_SYNC)
  170. FSM_RULE_ENTRY_ANY(s1, s0, USER_EVT_JMP_DISABLE)
  171. FSM_RULE_ENTRY_ANY(s1, s2, EVT_TIMER)
  172. FSM_RULE_ENTRY_ANY(s2, s0, USER_EVT_JMP_DISABLE)
  173. FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_NOTASK)//无任务时跳回s1
  174. FSM_RULE_ENTRY_ANY(s2, s3, USER_EVT_JMP_GETFILEINFO)
  175. FSM_RULE_ENTRY(s3, s1, USER_EVT_FILEINO_ANS, 0)//获取信息列表失败,则跳回s1
  176. FSM_RULE_ENTRY(s3, s4, USER_EVT_FILEINO_ANS, 1)//需要下载
  177. FSM_RULE_ENTRY(s3, s5, USER_EVT_FILEINO_ANS, 2)//无信息列表,经过滤后无新任务需要下载,则跳到s5,等待一段时间下载
  178. FSM_RULE_ENTRY_ANY(s3, s1, USER_EVT_DISCONNECT)//通讯失败时跳回s1
  179. FSM_RULE_ENTRY_ANY(s3, s1, USER_EVT_NOTASK)//任务列表无任务时跳回s1
  180. FSM_RULE_ENTRY_ANY(s3, s0, USER_EVT_JMP_DISABLE)
  181. FSM_RULE_ENTRY_ANY(s4, s1, USER_EVT_DISCONNECT)//通讯失败时跳回s1
  182. FSM_RULE_ENTRY_ANY(s4, s0, USER_EVT_JMP_DISABLE)
  183. FSM_RULE_ENTRY_ANY(s4, s5, USER_EVT_JMP_SYNC)
  184. FSM_RULE_ENTRY_ANY(s5, s0, USER_EVT_SYNC_FINISHED)
  185. END_FSM_RULE()
  186. void s1_on_entry();
  187. void s1_on_exit();
  188. unsigned int s1_on_event(FSMEvent* event);
  189. void s0_on_entry();
  190. void s0_on_exit();
  191. unsigned int s0_on_event(FSMEvent* event);
  192. void s2_on_entry();
  193. void s2_on_exit();
  194. unsigned int s2_on_event(FSMEvent* event);
  195. void s3_on_entry();
  196. void s3_on_exit();
  197. unsigned int s3_on_event(FSMEvent* event);
  198. void s4_on_entry();
  199. void s4_on_exit();
  200. unsigned int s4_on_event(FSMEvent* event);
  201. void s5_on_entry();
  202. void s5_on_exit();
  203. unsigned int s5_on_event(FSMEvent* event);
  204. ErrorCodeEnum LoadDownloadFileList();//加载运行时文件任务
  205. bool checkFileStr(CSimpleStringA strFile,int count);//检查运行时文件是否正确
  206. ErrorCodeEnum SaveDownloadFileList();//保存运行时文件任务
  207. ErrorCodeEnum addDownLoadFileWork(CSimpleStringA fileName,DWORD expireTime);//添加下载任务
  208. ErrorCodeEnum deleteDownLoadFileWork(CSimpleStringA fileName);//取消下载任务
  209. ErrorCodeEnum deleteCurrentDownloadFile(CSimpleStringA fileName);//取消正在下载的任务
  210. ErrorCodeEnum checkWorkExpireTime();//过滤检查下载任务时效性
  211. ErrorCodeEnum returnDownloadFileResult(const char* filename,ErrorCodeEnum error,CSimpleStringA errorMsg);//广播下载文件结果
  212. ErrorCodeEnum returnDownloadProgress(download_file_t* file,download_storage_t * currentStorage);
  213. bool isDownloadTask(const char * filename);
  214. private:
  215. ErrorCodeEnum LoadServerConfig();
  216. void nextTask();
  217. private:
  218. DownloadConnection *m_pConnection;//中台连接
  219. download_storage_t *m_current; //正在下载的文件
  220. array_header_t *m_arr_downlist; //这次连接需要下载的文件列表
  221. char *m_last_filelist; // 缓存上次返回列表(废除)
  222. char m_base_path[MAX_PATH];
  223. CSimpleStringA m_server1;
  224. int m_server1_port;
  225. CSimpleStringA m_server2;
  226. int m_server2_port;
  227. std::list<DownloadFileTask*> *m_DFlist;//下载任务列表:多线程会改变里面的值
  228. CRITICAL_SECTION m_cs;//临界区变量
  229. std::list<download_file_t*> *m_currentFileTask;//当前正在下载的文件列表:只有单线程能改变里面的值
  230. bool isStartUp;
  231. public:
  232. CSimpleStringA m_currentFileName;//正在下载的文件名
  233. };
  234. class DownloadConnection : public SpSecureClient
  235. {
  236. public:
  237. DownloadConnection(CEntityBase *pEntity, DownloadFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM) {}
  238. void SendListReq()
  239. {
  240. ListReq req = {0};
  241. CSystemStaticInfo si;
  242. {
  243. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  244. }
  245. strcpy(&req.TerminalNo[0], si.strTerminalID);
  246. CSmartPointer<IPackage> pkt = CreateNewPackage("LISTREQ");
  247. pkt->AddStruct("LISTREQ", false, false, (LPBYTE)&req, sizeof(ListReq));
  248. SendPackage(pkt);
  249. }
  250. void SendListNReq()
  251. {
  252. ListNReq req = {0};
  253. CSystemStaticInfo si;
  254. {
  255. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  256. }
  257. strcpy(&req.TerminalNo[0], si.strTerminalID);
  258. CSmartPointer<IPackage> pkt = CreateNewPackage("LISTNREQ");
  259. pkt->AddStruct("LISTNREQ", false, false, (LPBYTE)&req, sizeof(ListNReq));
  260. SendPackage(pkt);
  261. }
  262. void SendFileReq(const char *file, int block_id)
  263. {
  264. FileReq req = {0};
  265. req.BlockNo = block_id;
  266. strcpy(req.FileName, file);
  267. //CSmartPointer<IPackage> pkt = CreateNewPackage("FILEREQ");
  268. //pkt->AddStruct("FILEREQ", false, false, (LPBYTE)&req, sizeof(FileReq));
  269. CSmartPointer<IPackage> pkt = CreateNewPackage("LFILEREQ");
  270. pkt->AddStruct("LFILEREQ", false, false, (LPBYTE)&req, sizeof(FileReq));
  271. SendPackage(pkt);
  272. }
  273. protected:
  274. virtual ~DownloadConnection() {}
  275. virtual void OnDisconnect()
  276. {
  277. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT));
  278. }
  279. virtual void OnPkgAnswer(const CSmartPointer<IPackage> &pRecvPkg)
  280. {
  281. //以前有问题,增加errmsg错误判断,
  282. DWORD dwSysCode, dwUserCode;
  283. string strErrMsg;
  284. ErrorCodeEnum rc = Error_Succeed;
  285. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg)){
  286. // 错误处理
  287. rc = (ErrorCodeEnum)dwSysCode;
  288. LogError(Severity_Middle, (ErrorCodeEnum)dwSysCode, dwUserCode, strErrMsg.c_str());
  289. string serviceCode = pRecvPkg->GetServiceCode();
  290. Dbg("receive %s ans packet is error,errormsg is %s", serviceCode.c_str(),strErrMsg.c_str());
  291. OnDisconnect();
  292. }else{
  293. // 正常处理
  294. string serviceCode = pRecvPkg->GetServiceCode();
  295. if (serviceCode == "LISTREQ") {
  296. int nLen = pRecvPkg->GetStructLen("LISTANS");
  297. if (nLen > 0) {
  298. BYTE *pBuf = new BYTE[nLen];
  299. memset(pBuf, 0, nLen);
  300. int nArrayNum = 0;
  301. if (pRecvPkg->GetStructData("LISTANS", pBuf, &nLen, &nArrayNum)) {
  302. FSMEvent *evt = new ListAnsEvent(pBuf, nLen);
  303. m_pFSM->PostEventFIFO(evt);
  304. } else {
  305. Dbg("create invalid fileInfo_Ans packet!");
  306. OnDisconnect();
  307. }
  308. delete[] pBuf;
  309. }
  310. } else if (serviceCode == "LISTNREQ") {//新国密列表文件
  311. int nLen = pRecvPkg->GetStructLen("LISTNANS");
  312. if (nLen > 0) {
  313. BYTE *pBuf = new BYTE[nLen];
  314. memset(pBuf, 0, nLen);
  315. int nArrayNum = 0;
  316. if (pRecvPkg->GetStructData("LISTNANS", pBuf, &nLen, &nArrayNum)) {
  317. FSMEvent *evt = new ListNAnsEvent(pBuf, nLen);
  318. m_pFSM->PostEventFIFO(evt);
  319. } else {
  320. Dbg("create invalid fileNewInfo_Ans packet!");
  321. OnDisconnect();
  322. }
  323. delete[] pBuf;
  324. }
  325. } else if (serviceCode == "LFILEREQ") {
  326. int nLen = pRecvPkg->GetStructLen("LFILEANS");
  327. if (nLen > 0) {
  328. BYTE *pBuf = new BYTE[nLen];
  329. memset(pBuf, 0, nLen);
  330. int nArrayNum = 0;
  331. if (pRecvPkg->GetStructData("LFILEANS", pBuf, &nLen, &nArrayNum)) {
  332. FSMEvent *evt = new FileAnsEvent(pBuf, nLen);
  333. m_pFSM->PostEventFIFO(evt);
  334. } else {
  335. Dbg("create invalid file_Ans packet!");
  336. OnDisconnect();
  337. }
  338. delete[] pBuf;
  339. }
  340. } else {
  341. Dbg("unknown service code!");
  342. OnDisconnect();
  343. }
  344. }
  345. }
  346. private:
  347. DownloadFSM *m_pFSM;
  348. };