UpgradeTaskFSM.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. #ifndef RVC_MOD_UPGRADETASK_FSM_H_
  2. #define RVC_MOD_UPGRADETASK_FSM_H_
  3. #include "stdafx.h"
  4. #include "SimpleString.h"
  5. #include "SpBase.h"
  6. #include "SpFSM.h"
  7. #include <list>
  8. #include <map>
  9. #include <queue>
  10. #include "IHttpFunc.h"
  11. #define DOWNLOAD_CONTENT_EACH_LEN 2*1024*1024
  12. #define DOWNLOAD_TIMEOUT 2*60
  13. #define QUERY_NO_TASK_WARN_LIMIT 5
  14. using namespace std;
  15. namespace HttpStruct
  16. {
  17. //发送文件hash列表接口
  18. struct SendSM3TaskReq : CHTTPReq {
  19. string m_reqStr;
  20. string ToJson() {
  21. return m_reqStr;
  22. }
  23. };
  24. struct SendSM3TaskRet : CHTTPRet {
  25. string m_retStr;
  26. bool Parse(string strData) {
  27. m_retStr=strData;
  28. return true;
  29. }
  30. };
  31. //更新任务状态接口
  32. struct UpdateTaskStatusReq : CHTTPReq {
  33. string m_reqStr;
  34. string ToJson() {
  35. return m_reqStr;
  36. }
  37. };
  38. struct UpdateTaskStatusRet : CHTTPRet {
  39. string m_retStr;
  40. bool Parse(string strData) {
  41. m_retStr=strData;
  42. return true;
  43. }
  44. };
  45. //查询当前任务
  46. struct QueryCurrTaskReq : CHTTPReq {
  47. string m_reqStr;
  48. string ToJson() {
  49. return m_reqStr;
  50. }
  51. };
  52. struct QueryCurrTaskRet : CHTTPRet {
  53. string m_retStr;
  54. bool Parse(string strData) {
  55. m_retStr=strData;
  56. return true;
  57. }
  58. };
  59. //查询新任务
  60. struct QueryNewTaskReq : CHTTPReq {
  61. string m_reqStr;
  62. string ToJson() {
  63. return m_reqStr;
  64. }
  65. };
  66. struct QueryNewTaskRet : CHTTPRet {
  67. string m_retStr;
  68. bool Parse(string strData) {
  69. m_retStr=strData;
  70. return true;
  71. }
  72. };
  73. //断点下载升级包
  74. struct DownloadPackTaskRet{
  75. long content_length;
  76. long origin_file_length;
  77. bool bfinish;
  78. string sm3;
  79. };
  80. }
  81. // 升级任务状态机
  82. class CUpgradeTaskFSM : public FSMImpl<CUpgradeTaskFSM>, public IFSMStateHooker, public ISysVarListener
  83. {
  84. public:
  85. enum
  86. {
  87. Event_Start = EVT_USER+1,
  88. Event_StartDealTask,
  89. Event_DealCurrTask,
  90. Event_EndUpdateTask,
  91. Event_EndQueryCurrTask,
  92. Event_StartPoll,
  93. Event_EndPoll,
  94. Event_EndSendSM3Task,
  95. Event_StartDownload,
  96. Event_EndQueryTaskStatus,
  97. Event_Download_Idle,
  98. Event_EndDownload,
  99. Event_Download_Fail,
  100. Event_CancelTask,
  101. Event_StartInstall,
  102. Event_EndUnzipPackTask,
  103. Event_EndStopMediaPlayTask,
  104. Event_EndInstallPackTask,
  105. Event_EndInstall,
  106. Event_StartSwitch,
  107. Event_PreRestart,
  108. };
  109. struct SendSM3TaskEvent:public FSMEvent
  110. {
  111. bool isSucc;//是否写入成功
  112. SendSM3TaskEvent(bool isSendSucc)
  113. : FSMEvent(Event_EndSendSM3Task), isSucc(isSendSucc)
  114. {}
  115. };
  116. struct UpdateTaskStatusEvent:public FSMEvent
  117. {
  118. bool isSucc;//是否更新成功
  119. UpdateTaskStatusEvent(bool isSendSucc)
  120. : FSMEvent(Event_EndUpdateTask), isSucc(isSendSucc)
  121. {}
  122. };
  123. struct QueryCurrTaskEvent:public FSMEvent
  124. {
  125. bool isSucc;//是否查询成功
  126. bool isTask_valid;//任务是否有效
  127. QueryCurrTaskEvent(bool isSendSucc,bool isValid)
  128. : FSMEvent(Event_EndQueryCurrTask), isSucc(isSendSucc),isTask_valid(isValid)
  129. {}
  130. };
  131. struct QueryNewTaskEvent:public FSMEvent
  132. {
  133. bool isSucc;//是否查询成功
  134. QueryNewTaskEvent(bool isSendSucc)
  135. : FSMEvent(Event_EndPoll), isSucc(isSendSucc)
  136. {}
  137. };
  138. struct QueryTaskStatusEvent:public FSMEvent
  139. {
  140. bool isSucc;//是否查询成功
  141. bool isTask_valid;//任务是否有效
  142. QueryTaskStatusEvent(bool isSendSucc,bool isValid)
  143. : FSMEvent(Event_EndQueryTaskStatus), isSucc(isSendSucc),isTask_valid(isValid)
  144. {}
  145. };
  146. struct DownloadPackTaskEvent:public FSMEvent
  147. {
  148. bool isSucc;
  149. DownloadPackTaskEvent(bool isDownloadSucc)
  150. : FSMEvent(Event_EndDownload), isSucc(isDownloadSucc)
  151. {}
  152. };
  153. struct DownloadPackTaskFailEvent:public FSMEvent
  154. {
  155. string errMsg;//错误信息
  156. DownloadPackTaskFailEvent(string errorMsg)
  157. : FSMEvent(Event_Download_Fail), errMsg(errorMsg)
  158. {}
  159. };
  160. struct StopMediaPlayTaskEvent:public FSMEvent
  161. {
  162. bool isSucc;
  163. StopMediaPlayTaskEvent(bool isStopSucc)
  164. : FSMEvent(Event_EndStopMediaPlayTask), isSucc(isStopSucc)
  165. {}
  166. };
  167. struct UnzipPackTaskEvent:public FSMEvent
  168. {
  169. bool isSucc;
  170. UnzipPackTaskEvent(bool isUnzipSucc)
  171. : FSMEvent(Event_EndUnzipPackTask), isSucc(isUnzipSucc)
  172. {}
  173. };
  174. struct InstallPackTaskEvent:public FSMEvent
  175. {
  176. bool isSucc;
  177. CSimpleStringA errMsg;
  178. int failStatus;
  179. InstallPackTaskEvent(bool isInstallSucc,CSimpleStringA errMsgStr,int iFailStatus)
  180. : FSMEvent(Event_EndInstallPackTask), isSucc(isInstallSucc),errMsg(errMsgStr),failStatus(iFailStatus)
  181. {}
  182. };
  183. struct CInstallStep
  184. {
  185. //不存储到运行时
  186. int stepSeq; //步骤序号
  187. CSimpleStringA cmdType; //升级安装需执行命令类型:Delete、Copy、Run
  188. int cmdFail; //0:执行失败认为升级失败 1:执行失败忽略继续升级
  189. CSimpleStringA srcPathType; //0:相对路径 1:绝对路径 2:当前版本相对路径 3:升级包相对路径
  190. CSimpleStringA srcPath;
  191. CSimpleStringA dstPathType; //0:相对路径 1:绝对路径 2:当前版本相对路径 3:升级版本相对路径 4:升级包相对路径
  192. CSimpleStringA dstPath;
  193. };
  194. // 待安装任务信息(运行时保存的中间变量)
  195. struct CTaskInfo
  196. { //存储到运行时
  197. CSimpleStringA upgradeTaskId; //升级任务编号
  198. CSimpleStringA createTaskVersion;//创建升级任务时的版本号
  199. CSimpleStringA cPendingState; // 已下载D、安装中I、等待切换S、任务结果确认T
  200. CSimpleStringA NewVersion; // 任务升级后的版本号
  201. CSimpleStringA pack_name; //升级包名
  202. //不存储到运行时
  203. CSimpleStringA pack_version; //升级包指定的版本号
  204. //CSimpleStringA to_copy; //拷贝文件列表
  205. //CSimpleStringA to_run; //体系外运行脚本文件名称
  206. bool stop_media_play; //停止广告播放(0:不停止 1:停止)
  207. int reboot_type; //重启策略类型(0:不启动 1:重启框架 2:重启系统)
  208. CSimpleStringA file_path; //升级包路径
  209. CSimpleStringA download_url; //升级包下载地址
  210. CSimpleStringA pack_hash; //升级包hash值
  211. long pack_length; //升级包长度(服务端暂时不传)
  212. queue<CInstallStep*> install_step;//安装步骤队列
  213. };
  214. struct CTaskProcess
  215. {
  216. CSimpleStringA strPackName;//包名
  217. CSimpleStringA installVersion;//安装版本号
  218. CVersion CurrentVersion;//当前版本号
  219. CSimpleStringA cInstallState;//升级状态
  220. CSimpleStringA strInstallComment;//升级状态备注
  221. };
  222. struct CenterUrl
  223. {
  224. string updateTaskUrl; //更新升级任务url
  225. string queryCurrTaskUrl; //查询当前任务url
  226. string queryNewTaskUrl; //查询新任务url
  227. string queryTaskStatus; //查询当前任务是否有效url
  228. string sendSM3TaskUrl; //发送文件hashurl
  229. };
  230. struct HashScanSet
  231. {
  232. CSimpleStringA relativeDir; //相对路径
  233. CSimpleStringA absoluteDir; //绝对路径
  234. CSimpleStringA currVerDir; //当前版本相对路径
  235. CSimpleStringA blackFile; //不纳入扫描的文件名称
  236. CSimpleStringA blackDir; //不纳入扫描的文件夹
  237. };
  238. public:
  239. CUpgradeTaskFSM(){
  240. isSendHash = false;//默认查询策略不发送hash
  241. m_isSM3HashSucc = false;//默认hash计算失败
  242. m_bDownloadIdle = false;
  243. m_bTaskCancel=false;
  244. m_fileSM3ListHash="";//终端hash列表64位hash值
  245. m_fileSM3List = "";
  246. m_eachDownloadLen=DOWNLOAD_CONTENT_EACH_LEN;
  247. m_newEachDownloadLen=DOWNLOAD_CONTENT_EACH_LEN;
  248. m_PrintHttpLog =false;
  249. m_startFlag = false;
  250. }
  251. ~CUpgradeTaskFSM(){}
  252. //具体实现方法
  253. //ErrorCodeEnum UpdatePackInstall(string updatePackName,CSimpleStringA &strErrMsg);//系统升级包安装
  254. ErrorCodeEnum CreateNewVersion(CVersion NewSoftwareVersion,CSimpleStringA &strErrInfo);//创建新版本
  255. ErrorCodeEnum ClearUpgradeFailVersion(CVersion NewSoftwareVersion);//清理升级新版本临时文件
  256. //int SysPackInstall(string sysPackName, CSimpleStringA &strErrMsg);//体系外升级包安装 0:失败 1:成功 -1:未知
  257. bool GetSysUpgradeResult(const char *pszResultLog, CSimpleStringA &eErrorCode, CSimpleStringA &strErrMsg);//从体系外生成的result.log文件中获取结果
  258. //ErrorCodeEnum LightPackInstall(string LightPackName, CSimpleStringA &strErrMsg);//轻量升级包安装
  259. //安装执行步骤方法
  260. int ExecInstall(CSimpleStringA &strErrMsg);//升级安装 0:失败 1:成功 -1:未知
  261. int ExecRunCmd(CSimpleStringA &strErrMsg,CInstallStep* ins);
  262. bool ExecDeleteCmd(CSimpleStringA &strErrMsg,CInstallStep* ins);
  263. bool ExecCpoyCmd(CSimpleStringA &strErrMsg,CInstallStep* ins);
  264. bool GetRootTypePath(int rootType,CSimpleStringA &rootPath);//1:相对路径 2:当前版本相对路径 3:升级版本相对路径 4:升级包相对路径
  265. ErrorCodeEnum CopyFileOperate(const char* srcPath, const char* destPath, int nCopyMode, CSimpleStringA &strErrMsg);
  266. //ErrorCodeEnum CopyFileToNewVersion(string updatePackPath,const char *pszRelativeFile,const char * newVersion, int nCopyMode);//拷贝增量文件到新版本
  267. ErrorCodeEnum SetRunSucceed(const char* pPackFile);//成功切换新版本
  268. ErrorCodeEnum UpgradeToNewVersion();//设置新版本状态
  269. ErrorCodeEnum RollBackToHistoryVersion(CVersion historyVersion);//回退到某个历史版本
  270. //ErrorCodeEnum CopyFolder(CSimpleStringA strSourcePath, CSimpleStringA strDestPath);
  271. void RecursiveGetSubFiles(const char *pszDir, const char *pszTrimStart, list<CSimpleStringA>& retList);
  272. bool IsFileMatch(const char *pszFilter, const char *pszFileName);
  273. bool RecursiveCopyDir(const char *pszSourceDir, const char *pszDestDir,CSimpleStringA &strErrInfo);//可以合并
  274. CSimpleStringA GetFileDirectory(const char *pszFullPath);//查找文件的父路径
  275. bool IsWow64Process();//判断是否是64位windows程序
  276. int system_on(string cmdFilePath, bool isWait,CSimpleStringA &errMsg);//cmd窗口程序
  277. int waitSystem(string cmd, const char * par, bool nShow,CSimpleStringA &errMsg);//起进程执行cmd
  278. char* ConvertUtf8ToGBK(const char* strUtf8);
  279. void ConvertUtf8ToGBK(std::string &str);
  280. char* ConvertGBKToUtf8(const char* gbk, int *n);
  281. void ConvertGBKToUtf8(std::string &str);
  282. bool is_str_utf8(const char* str);
  283. ErrorCodeEnum UnzipPack(const char* unZipPackName);//解压文件
  284. ErrorCodeEnum DeleteUnzipDir();//清理临时解压包文件
  285. void SendUpgradeTaskProgress(CTaskProcess &process);
  286. ErrorCodeEnum GetRunConfigStrValue(const char *pszSection, const char *pszKey, CSimpleStringA &strValue);
  287. ErrorCodeEnum SetRunConfigStrValue(const char *pszSection, const char *pszKey, const char *pszValue);
  288. bool ClearCurrTaskInfo();//任务无效清除运行时记录和残留下载包
  289. bool ClearInstallStep();//清理历史任务安装步骤
  290. ErrorCodeEnum LoadPersistTaskInfo();//启动开始加载运行时文件
  291. ErrorCodeEnum LoadCfgInfo();//启动开始加载配置文件
  292. ErrorCodeEnum loadCenterCfgInfo();//启动开始加载集中配置文件
  293. bool GetFileLength(const char* filePath,long &fileLen);//获取文件长度
  294. ErrorCodeEnum GetSM3List(CSimpleStringA &strSM3List);//获取版本文件hash集合字符串
  295. //ErrorCodeEnum SM3Folder(CSimpleStringA strFolderPath,CSimpleStringA replaceStr,CSimpleStringA prefix,bool isDepDir=false);
  296. ErrorCodeEnum ScanSM3ByType(int type,CSimpleStringA pathFilter);
  297. ErrorCodeEnum NewSM3Folder(CSimpleStringA scanFilter,CSimpleStringA replaceDir);//新的hash扫描文件夹实现
  298. //新国密SM3函数,isSub表示是否截取新国密中间一段密文
  299. ErrorCodeEnum SM3FileToStr(CSimpleStringA strFilePath, CSimpleStringA &strSM3,bool isSub);
  300. ErrorCodeEnum SM3DataToStr(CSimpleStringA strData, CSimpleStringA &strSM3,bool isSub);
  301. ErrorCodeEnum SM3_Str(CSimpleStringA &strSM3,BYTE * SM3Byte,bool isSub);
  302. bool IsPackDownloaded(const char *pPackName,const char* packHash,long packLen);//判断安装包是否已下载成功
  303. bool DownloadFileWrite(byte* content,long contentLen,const char* filePath);
  304. bool CheckIfCanSwitchNow();//是否允许切换
  305. ErrorCodeEnum SwitchUpgradeNow();//切换版本
  306. ErrorCodeEnum DownloadProgress(long tempFileLen,long fileSumLen);//返回下载进度
  307. char GetInstallState(int nState);//根据状态机获取升级状态
  308. ErrorCodeEnum GetUpgradeState(bool &bInstalling, CSimpleStringA &strPackFile, CSimpleStringA &strExecID,
  309. char &cInstallState, bool &bSysInstall, bool &bLightPack, CSimpleStringA &strNewVersion);
  310. static void HttpsLogCallBack(const char* logtxt);
  311. bool isWork();
  312. int changeFileAtt(const char* path);
  313. private:
  314. virtual void OnStateTrans(int iSrcState, int iDstState);
  315. virtual void OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName);
  316. virtual ErrorCodeEnum OnInit();
  317. virtual ErrorCodeEnum OnExit();
  318. enum{s1, s2, s3, s4, s5, s6, s7};
  319. BEGIN_FSM_STATE(CUpgradeTaskFSM)
  320. FSM_STATE_ENTRY(s1, "Start",s1_on_entry,s1_on_exit,s1_on_event)//计算hash值
  321. FSM_STATE_ENTRY(s2, "DealTask",s2_on_entry,s2_on_exit,s2_on_event)//处理上个任务,反馈任务结果,并根据任务状态跳转到其他状态
  322. FSM_STATE_ENTRY(s3, "Poll",s3_on_entry,s3_on_exit,s3_on_event)//查询任务
  323. FSM_STATE_ENTRY(s4, "Download", s4_on_entry, s4_on_exit, s4_on_event)//下载安装包
  324. FSM_STATE_ENTRY(s5, "Install", s5_on_entry, s5_on_exit, s5_on_event)//安装升级包
  325. FSM_STATE_ENTRY(s6, "Switch", s6_on_entry, s6_on_exit, s6_on_event)//进行版本切换
  326. FSM_STATE_ENTRY(s7, "Disable", s7_on_entry, s7_on_exit, s7_on_event)//静止状态
  327. END_FSM_STATE()
  328. BEGIN_FSM_RULE(CUpgradeTaskFSM,s1)
  329. FSM_RULE_ENTRY_ANY(s1, s2, Event_StartDealTask)
  330. FSM_RULE_ENTRY_ANY(s2, s3, Event_StartPoll)
  331. FSM_RULE_ENTRY(s2, s4, Event_EndQueryCurrTask, 4)
  332. FSM_RULE_ENTRY(s2, s5, Event_EndQueryCurrTask, 5)
  333. FSM_RULE_ENTRY(s2, s6, Event_EndQueryCurrTask, 6)
  334. FSM_RULE_ENTRY_ANY(s3, s4, Event_StartDownload)
  335. FSM_RULE_ENTRY_ANY(s4, s5, Event_StartInstall)
  336. FSM_RULE_ENTRY_ANY(s4, s3, Event_StartPoll)//任务取消进入S3
  337. FSM_RULE_ENTRY_ANY(s4, s2, Event_StartDealTask)//下载失败进入S2
  338. FSM_RULE_ENTRY_ANY(s5, s6, Event_StartSwitch)
  339. FSM_RULE_ENTRY_ANY(s5, s2, Event_StartDealTask)//安装失败进入S2
  340. FSM_RULE_ENTRY_ANY(s6, s2, Event_StartDealTask)//无需重启框架和系统切换成功进入S2
  341. FSM_RULE_ENTRY_ANY(s6, s3, Event_StartPoll)//取消任务进入S3
  342. FSM_RULE_ENTRY_ANY(s6, s7, Event_PreRestart)//重启服务
  343. END_FSM_RULE()
  344. private:
  345. //完成
  346. void s1_on_entry();
  347. void s1_on_exit();
  348. unsigned int s1_on_event(FSMEvent* event);
  349. //完成
  350. void s2_on_entry();
  351. void s2_on_exit();
  352. unsigned int s2_on_event(FSMEvent* event);
  353. //完成
  354. void s3_on_entry();
  355. void s3_on_exit();
  356. unsigned int s3_on_event(FSMEvent* event);
  357. //完成
  358. void s4_on_entry();
  359. void s4_on_exit();
  360. unsigned int s4_on_event(FSMEvent* event);
  361. //完成
  362. void s5_on_entry();
  363. void s5_on_exit();
  364. unsigned int s5_on_event(FSMEvent* event);
  365. //完成
  366. void s6_on_entry();
  367. void s6_on_exit();
  368. unsigned int s6_on_event(FSMEvent* event);
  369. //
  370. void s7_on_entry();
  371. void s7_on_exit();
  372. unsigned int s7_on_event(FSMEvent* event);
  373. private:
  374. list<CSimpleStringA> m_DepWhitelist; //dep文件夹白名单
  375. list<CSimpleStringA> m_DirBlacklist; //整体文件夹黑名单
  376. list<CSimpleStringA> m_FileBlacklist; //整体文件黑名单
  377. public:
  378. map<CSimpleStringA, CSimpleStringA> m_fileSM3Map; // 版本文件hash值集合
  379. CTaskInfo m_currentTask; //当前的任务缓存变量
  380. CVersion m_currentVersion; //当前终端版本
  381. CenterUrl m_centerUrl;//访问总行的url地址集合
  382. int m_eachDownloadLen;//每次下载数据长度阈值(M)
  383. int m_newEachDownloadLen;//新的每次下载数据长度阈值(k)
  384. bool m_PrintHttpLog; //是否打印通讯日志
  385. bool m_startFlag; //升级实体启动标志位,默认是不开,
  386. HashScanSet m_hashScanSet;//扫描文件hash设置
  387. bool m_isSM3HashSucc;//hash是否计算成功
  388. bool isSendHash;//hash是否发送
  389. CSimpleStringA m_fileSM3ListHash;//SM3 64位hash
  390. CSimpleStringA m_fileSM3List;//版本文件hash集合字符串
  391. DWORD m_beginSendSM3Time;//开始发送sm3hahs时间
  392. int m_queryNewTaskCount;//查询新任务时无任务次数
  393. bool m_bDownloadIdle; //是否下载空闲 true: 不能下载,false: 可下载
  394. bool m_bTaskCancel; //是否任务取消 true: 任务取消,false: 未取消
  395. };
  396. #endif //RVC_MOD_UPGRADETASK_FSM_H_