DownloadFSM.h 12 KB

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