UploadFSM.h 12 KB

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