UploadFSM.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. #ifndef RVC_MOD_UPLOAD_UPLOADFSM_H_
  2. #define RVC_MOD_UPLOAD_UPLOADFSM_H_
  3. #include "SpBase.h"
  4. #include "SpFSM.h"
  5. #include "SpSecureClient.h"
  6. #include "upload.h"
  7. #include <list>
  8. #define USER_EVT_JMP_DISABLE EVT_USER+1
  9. #define USER_EVT_JMP_ENABLE EVT_USER+2
  10. #define USER_EVT_JMP_CONNECT EVT_USER+3
  11. #define USER_EVT_DISCONNECT EVT_USER+4
  12. #define USER_EVT_UPLOAD_ANS EVT_USER+5
  13. #define USER_EVT_BLOCK_ANS EVT_USER+6
  14. #define USER_EVT_JMP_UPLOAD EVT_USER+7
  15. using namespace std;
  16. #pragma pack(1)
  17. // [StructName("UPREQ")]
  18. struct UploadReq
  19. {
  20. char TerminalNo[16];
  21. char FileName[64];
  22. char FileType[16];
  23. int FileLength;
  24. int FileCreatDate;
  25. };
  26. // [StructName("UPANS")]
  27. struct UploadReply
  28. {
  29. int ResultCode;
  30. char UploadID[16];
  31. int BeginBlock;
  32. };
  33. //[StructName("BLKREQ")]
  34. struct BlockReq
  35. {
  36. char TerminalNo[16];
  37. char FileName[64];
  38. char UploadID[16];
  39. int BlockNo;
  40. char Data[0];
  41. };
  42. //[StructName("BLKANS")]
  43. struct BlockReply
  44. {
  45. char UploadID[16];
  46. int ResultCode;
  47. };
  48. #pragma pack()
  49. enum UploadCtlCode
  50. {
  51. Finish = 0, //完成(BLOCK)
  52. Begin = 1, //开始上传(UPLOAD)
  53. Continua = 2, //文件已经存在,断点续传,按返回块开始传(UPLOAD)(BLOCK)
  54. ErrorBlock = 3, //上块错误,重新传(BLOCK)
  55. ErrorType = 4, //错误的类型(UPLOAD)
  56. Timeout = 5, //过期(UPLOAD)
  57. ErrorUploadId = 6, //错误的上传id(BLOCK)
  58. };
  59. //上传请求回应
  60. struct UploadAnsEvent : public FSMEvent
  61. {
  62. UploadAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_UPLOAD_ANS) {
  63. memcpy(&m_reply, pBuf, sizeof(UploadReply));
  64. }
  65. virtual ~UploadAnsEvent() {}
  66. UploadReply m_reply;
  67. };
  68. //上传块请求回应
  69. struct BlockAnsEvent : public FSMEvent
  70. {
  71. BlockAnsEvent(BYTE *pBuf, int nLen) : FSMEvent(USER_EVT_BLOCK_ANS) {
  72. memcpy(&m_reply, pBuf, sizeof(BlockReply));
  73. }
  74. virtual ~BlockAnsEvent() {}
  75. BlockReply m_reply;
  76. };
  77. struct UploadProgress
  78. {
  79. int uploadState;
  80. int uploadNumber;
  81. CSimpleStringA elapseTime;
  82. };
  83. class UploadConnection;
  84. class UploadFSM : public FSMImpl<UploadFSM>, public IFSMStateHooker, public ISysVarListener
  85. {
  86. public:
  87. enum {s0,s1,s2,s3,s4,s5,s6};
  88. BEGIN_FSM_STATE(UploadFSM)
  89. FSM_STATE_ENTRY(s0,"Starting",s0_on_entry,s0_on_exit,s0_on_event)
  90. FSM_STATE_ENTRY(s1, "Disable",s1_on_entry,s1_on_exit,s1_on_event)
  91. FSM_STATE_ENTRY(s2, "Enable", s2_on_entry, s2_on_exit, s2_on_event)
  92. FSM_STATE_ENTRY(s3, "Connect", s3_on_entry, s3_on_exit, s3_on_event)
  93. FSM_STATE_ENTRY(s4, "Upload", s4_on_entry, s4_on_exit, s4_on_event)
  94. FSM_STATE_ENTRY(s5, "Release", s5_on_entry, s5_on_exit, s5_on_event)
  95. FSM_STATE_ENTRY(s6, "DisConnect", s6_on_entry, s6_on_exit, s6_on_event)//添加断连等待时间状态
  96. END_FSM_STATE()
  97. BEGIN_FSM_RULE(UploadFSM,s0)
  98. FSM_RULE_ENTRY_ANY(s0, s1, USER_EVT_JMP_DISABLE)
  99. FSM_RULE_ENTRY_ANY(s0, s2, USER_EVT_JMP_ENABLE)
  100. FSM_RULE_ENTRY_ANY(s1, s2, USER_EVT_JMP_ENABLE)
  101. FSM_RULE_ENTRY_ANY(s2, s3, USER_EVT_JMP_CONNECT)
  102. FSM_RULE_ENTRY_ANY(s2, s1, USER_EVT_JMP_DISABLE)
  103. FSM_RULE_ENTRY_ANY(s3, s4, USER_EVT_JMP_UPLOAD)
  104. FSM_RULE_ENTRY_ANY(s3, s1, USER_EVT_JMP_DISABLE)
  105. FSM_RULE_ENTRY(s4, s5, USER_EVT_UPLOAD_ANS, 1)
  106. FSM_RULE_ENTRY(s4, s6, USER_EVT_DISCONNECT, 1)//断连时跳转到S6
  107. FSM_RULE_ENTRY(s4, s5, USER_EVT_BLOCK_ANS, 1)
  108. FSM_RULE_ENTRY_ANY(s4, s5, EVT_TIMER)
  109. FSM_RULE_ENTRY_ANY(s4, s1, USER_EVT_JMP_DISABLE)
  110. FSM_RULE_ENTRY_ANY(s5, s2, EVT_TIMER)
  111. FSM_RULE_ENTRY_ANY(s5, s2, USER_EVT_DISCONNECT)
  112. FSM_RULE_ENTRY_ANY(s5, s1, USER_EVT_JMP_DISABLE)
  113. FSM_RULE_ENTRY_ANY(s6, s2, EVT_TIMER)//等待一段时间进入S2
  114. FSM_RULE_ENTRY_ANY(s6, s1, USER_EVT_JMP_DISABLE)
  115. END_FSM_RULE()
  116. UploadFSM();
  117. ~UploadFSM();
  118. virtual void OnStateTrans(int iSrcState, int iDstState);
  119. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName);
  120. virtual ErrorCodeEnum OnInit();
  121. virtual ErrorCodeEnum OnExit();
  122. void s0_on_entry();
  123. void s0_on_exit();
  124. unsigned int s0_on_event(FSMEvent* event);
  125. void s1_on_entry();
  126. void s1_on_exit();
  127. unsigned int s1_on_event(FSMEvent* event);
  128. void s2_on_entry();
  129. void s2_on_exit();
  130. unsigned int s2_on_event(FSMEvent* event);
  131. void s3_on_entry();
  132. void s3_on_exit();
  133. unsigned int s3_on_event(FSMEvent* event);
  134. void s4_on_entry();
  135. void s4_on_exit();
  136. unsigned int s4_on_event(FSMEvent* event);
  137. void s5_on_entry();
  138. void s5_on_exit();
  139. unsigned int s5_on_event(FSMEvent* event);
  140. void s6_on_entry();
  141. void s6_on_exit();
  142. unsigned int s6_on_event(FSMEvent* event);
  143. private:
  144. ErrorCodeEnum LoadServerConfig();
  145. file_t *find_first_upload_file();
  146. void post_process();
  147. int getUploadFileNum(int &fileSumlen);
  148. public:
  149. int getCheckDirFile(int silentTime);//检查文件夹文件个数
  150. void getUploadProgress(UploadProgress &progress);//获取上传文件状态
  151. bool clearUploadDate();//清空上传日期
  152. ErrorCodeEnum SaveUploadDate();//保存上传日期
  153. ErrorCodeEnum getUploadDate(CAutoArray<CSimpleStringA> &strList);//获取上传日期
  154. ErrorCodeEnum insertUploadDate();//插入上传日期
  155. bool uploadDate_exist(CSimpleStringA uploadDate);
  156. private:
  157. UploadConnection *m_pConnection;
  158. file_t *m_uploading_file; //当前正在上传的文件
  159. int m_uploading_block_id; //正在上传的块号
  160. #ifdef RVC_OS_WIN
  161. HANDLE m_uploading_handle;
  162. #else()
  163. FILE* m_uploading_handle;
  164. #endif // RVC_OS_WIN
  165. char m_upload_id[16];
  166. CSimpleStringA m_terminalNo;
  167. CSimpleStringA m_server1;
  168. int m_server1_port;
  169. CSimpleStringA m_server2;
  170. int m_server2_port;
  171. struct list_head m_updir_list;//文件夹配置列表
  172. //添加lwt
  173. list<CSimpleStringA>* m_check_dir;//重点文件夹的列表
  174. DWORD m_dBeginTime;//统计上传速度开始时间
  175. DWORD m_dEndTime;//统计上传速度结束时间
  176. int m_iSpeed;//单位k/ms
  177. CRITICAL_SECTION m_cs;//临界区变量
  178. list<CSimpleStringA>* m_uploadDateList;//上传日期文件列表
  179. };
  180. class UploadConnection : public SpSecureClient
  181. {
  182. public:
  183. UploadConnection(CEntityBase *pEntity, UploadFSM *pFSM) : SpSecureClient(pEntity), m_pFSM(pFSM) {}
  184. void SendUpReq(file_t *file)
  185. {
  186. UploadReq req = {0};
  187. CSystemStaticInfo si;
  188. {
  189. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  190. }
  191. strcpy(&req.TerminalNo[0], si.strTerminalID);
  192. strcpy(&req.FileType[0], file->owner->name);
  193. strcpy(&req.FileName[0], file->name);
  194. req.FileLength = file->length;
  195. req.FileCreatDate = file->create_time;
  196. CSmartPointer<IPackage> pkt = CreateNewPackage("UPREQ");
  197. pkt->AddStruct("UPREQ", false, false, (LPBYTE)&req, sizeof(UploadReq));
  198. SendPackage(pkt);
  199. }
  200. #ifdef RVC_OS_WIN
  201. bool SendBlockReq(file_t* file, HANDLE hFile, const char* upload_id, int block_id)
  202. {
  203. bool ret = true;
  204. int nLen = sizeof(BlockReq) + 0x8000;
  205. BlockReq* req = (BlockReq*)new BYTE[nLen];
  206. memset(req, 0, nLen);
  207. CSystemStaticInfo si;
  208. {
  209. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  210. }
  211. req->BlockNo = block_id;
  212. strcpy(&req->TerminalNo[0], si.strTerminalID);
  213. strcpy(&req->FileName[0], file->name);
  214. memcpy(req->UploadID, upload_id, sizeof(req->UploadID));
  215. DWORD dwOffset = block_id << 15; // 32k once
  216. DWORD dwLength = min(file->length - dwOffset, 1 << 15);
  217. SetFilePointer(hFile, dwOffset, NULL, FILE_BEGIN);
  218. BOOL bRet = ReadFile(hFile, &req->Data[0], dwLength, &dwLength, NULL);
  219. if (bRet) {
  220. //Dbg("block len:%d", dwLength);
  221. CSmartPointer<IPackage>pkt = CreateNewPackage("BLKREQ");
  222. pkt->AddStruct("BLKREQ", false, false, (LPBYTE)req, sizeof(BlockReq) + dwLength);
  223. SendPackage(pkt);
  224. ret = true;
  225. }
  226. else {
  227. //增加跳出分支,防止状态机跳不出
  228. DWORD err = GetLastError();
  229. Dbg("SendBlockReq is error file name [%s] , block_id [%d] , GetLastError = %d", file->name, block_id, err);
  230. ret = false;
  231. }
  232. delete req;
  233. return ret;
  234. }
  235. #else
  236. bool SendBlockReq(file_t* file, FILE* hFile, const char* upload_id, int block_id)
  237. {
  238. bool ret = true;
  239. int nLen = sizeof(BlockReq) + 0x8000;
  240. BlockReq* req = (BlockReq*)new BYTE[nLen];
  241. memset(req, 0, nLen);
  242. CSystemStaticInfo si;
  243. {
  244. m_pEntity->GetFunction()->GetSystemStaticInfo(si);
  245. }
  246. req->BlockNo = block_id;
  247. strcpy(&req->TerminalNo[0], si.strTerminalID);
  248. strcpy(&req->FileName[0], file->name);
  249. memcpy(req->UploadID, upload_id, sizeof(req->UploadID));
  250. DWORD dwOffset = block_id << 15; // 32k once
  251. //DWORD dwLength = min(file->length - dwOffset, 1 << 15);
  252. DWORD dwLength = ((file->length - dwOffset) < (1 << 15)) ? (file->length - dwOffset) : (1 << 15);
  253. if (fseek(hFile, dwOffset, SEEK_SET)==0) {
  254. int bRet = fread(&req->Data[0], dwLength, 1, hFile);
  255. if (bRet == 1) {
  256. CSmartPointer<IPackage>pkt = CreateNewPackage("BLKREQ");
  257. pkt->AddStruct("BLKREQ", false, false, (LPBYTE)req, sizeof(BlockReq) + dwLength);
  258. SendPackage(pkt);
  259. ret = true;
  260. }
  261. else {
  262. //增加跳出分支,防止状态机跳不出
  263. Dbg("SendBlockReq fread fail, is error file name [%s] , block_id [%d] ", file->name, block_id);
  264. ret = false;
  265. }
  266. }
  267. else {
  268. //增加跳出分支,防止状态机跳不出
  269. Dbg("SendBlockReq fseek fail, is error file name [%s] , block_id [%d] GetLastError = %d", file->name, block_id,errno);
  270. ret = false;
  271. }
  272. delete req;
  273. return ret;
  274. }
  275. #endif // RVC_OS_WIN
  276. protected:
  277. virtual ~UploadConnection() {}
  278. virtual void OnDisconnect()
  279. {
  280. m_pFSM->PostEventFIFO(new FSMEvent(USER_EVT_DISCONNECT));
  281. }
  282. virtual void OnPkgAnswer(const CSmartPointer<IPackage> &pRecvPkg)
  283. {
  284. string serviceCode = pRecvPkg->GetServiceCode();
  285. if (serviceCode == "UPREQ")
  286. {
  287. DWORD dwSysCode, dwUserCode;
  288. string strErrMsg;
  289. ErrorCodeEnum rc = Error_Succeed;
  290. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  291. {
  292. rc = (ErrorCodeEnum)dwSysCode;
  293. LogError(Severity_Middle, rc, dwUserCode, CSimpleStringA::Format("create up packet Fail!, %s", strErrMsg.c_str()));
  294. //Sleep(3000);
  295. OnDisconnect();
  296. }
  297. else
  298. {
  299. int nLen = pRecvPkg->GetStructLen("UPANS");
  300. if (nLen > 0)
  301. {
  302. BYTE *pBuf = new BYTE[nLen];
  303. memset(pBuf, 0, nLen);
  304. int nArrayNum = 0;
  305. if (pRecvPkg->GetStructData("UPANS", pBuf, &nLen, &nArrayNum))
  306. {
  307. FSMEvent *evt = new UploadAnsEvent(pBuf, nLen);
  308. m_pFSM->PostEventFIFO(evt);
  309. }
  310. else
  311. {
  312. Dbg("create invalid upans packet!");
  313. OnDisconnect();
  314. }
  315. delete pBuf;
  316. }else{
  317. //nlen增加跳出分支
  318. Dbg("upans packet len is error len=%d",nLen);
  319. //Sleep(1000);
  320. OnDisconnect();
  321. }
  322. }
  323. }
  324. else if (serviceCode == "BLKREQ")
  325. {
  326. DWORD dwSysCode, dwUserCode;
  327. string strErrMsg;
  328. ErrorCodeEnum rc = Error_Succeed;
  329. if (pRecvPkg->GetErrMsg(dwSysCode, dwUserCode, strErrMsg))
  330. {
  331. rc = (ErrorCodeEnum)dwSysCode;
  332. LogError(Severity_Middle, rc, dwUserCode, CSimpleStringA::Format("create up blk Fail!, %s", strErrMsg.c_str()));
  333. //Sleep(3000);
  334. OnDisconnect();
  335. }
  336. else
  337. {
  338. int nLen = pRecvPkg->GetStructLen("BLKANS");
  339. if (nLen > 0)
  340. {
  341. BYTE *pBuf = new BYTE[nLen];
  342. memset(pBuf, 0, nLen);
  343. int nArrayNum = 0;
  344. if (pRecvPkg->GetStructData("BLKANS", pBuf, &nLen, &nArrayNum))
  345. {
  346. FSMEvent *evt = new BlockAnsEvent(pBuf, nLen);
  347. m_pFSM->PostEventFIFO(evt);
  348. }
  349. else
  350. {
  351. Dbg("create invalid blkans packet!");
  352. OnDisconnect();
  353. }
  354. delete pBuf;
  355. }else{
  356. //nlen增加跳出分支
  357. Dbg("blkans packet len is error len=%d",nLen);
  358. //Sleep(1000);
  359. OnDisconnect();
  360. }
  361. }
  362. }
  363. else
  364. {
  365. Dbg("unknown service code! code= %s",serviceCode.c_str());
  366. //Sleep(2000);
  367. OnDisconnect();
  368. }
  369. }
  370. private:
  371. UploadFSM *m_pFSM;
  372. };
  373. #endif // RVC_MOD_UPLOAD_UPLOADFSM_H_