1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159 |
- #include "stdafx.h"
- #include "DownloadFSM.h"
- #include "Event.h"
- #include "Download_msg_g.h"
- #include <fileutil.h>
- #include <strutil.h>
- #include "SpIni.h"
- #include "EventCode.h"
- static ErrorCodeEnum ParseIPAddress(const char *str, CSimpleStringA &ip, int &port)
- {
- ErrorCodeEnum Error = Error_Unexpect;
- if (str) {
- char tmp1[32] = {};
- char tmp2[16] = {};
- sscanf(str, "%s %s", tmp1, tmp2);
- if (tmp1[0] != 0 && tmp2[0] != 0)
- {
- ip = tmp1;
- port = atoi(tmp2);
- Error = Error_Succeed;
- }
- else
- return Error;
- }
- return Error;
- }
- static ErrorCodeEnum ParseBoolean(const char *str, BOOL &bValue)
- {
- ErrorCodeEnum Error = Error_Unexpect;
- if (str) {
- if (_stricmp(str, "false") == 0) {
- bValue = FALSE;
- Error = Error_Succeed;
- } else if (_stricmp(str, "true") == 0) {
- bValue = TRUE;
- Error = Error_Succeed;
- } else {
- Dbg("unknown boolean value:%s", str);
- }
- }
- return Error;
- }
- DownloadFSM::DownloadFSM()
- : m_pConnection(NULL), m_arr_downlist(NULL), m_current(NULL)
- , m_last_filelist(NULL),m_DFlist(NULL),m_currentFileTask(NULL)
- {
- isStartUp =false;
- }
- DownloadFSM::~DownloadFSM()
- {
- if (m_last_filelist)
- free(m_last_filelist);
- if (m_DFlist!=NULL){
- std::list<DownloadFileTask*>::iterator iter;
- for(iter=m_DFlist->begin();iter!=m_DFlist->end();++iter){
- delete *iter;
- }
- m_DFlist->clear();
- delete m_DFlist;
- }
- if (m_currentFileTask!=NULL){
- std::list<download_file_t*>::iterator iter;
- for(iter=m_currentFileTask->begin();iter!=m_currentFileTask->end();++iter){
- delete *iter;
- }
- m_currentFileTask->clear();
- delete m_currentFileTask;
- }
-
- }
- ErrorCodeEnum DownloadFSM::LoadServerConfigFromCenterSetting()
- {
- CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
- CSmartPointer<IConfigInfo> spConfig;
- ErrorCodeEnum Error = spFunction->OpenConfig(Config_CenterSetting, spConfig);
- if (Error == Error_Succeed) {
- CSimpleStringA str;
- Error = spConfig->ReadConfigValue("Download", "Server", str);
- if (Error == Error_Succeed) {
- Error = ParseIPAddress(str, m_server1, m_server1_port);
- }
- if (Error == Error_Succeed)
- {
- ErrorCodeEnum ErrorCode;
- ErrorCode = spConfig->ReadConfigValue("Download", "Server_Backup", str);
- if (ErrorCode == Error_Succeed)
- {
- ErrorCode = ParseIPAddress(str, m_server2, m_server2_port);
- }
- if (ErrorCode!=Error_Succeed)
- {
- m_server2 = NULL;
- m_server2_port = 0;
- }
- }
- }
- return Error;
- }
- bool DownloadFSM::checkFileStr(CSimpleStringA strFile,int count)
- {
- bool flag =true;
- CAutoArray<CSimpleStringA> fList = strFile.Split('$');
- if(fList.GetCount() == count){
- for(int i=0; i<fList.GetCount(); i++){
- CAutoArray<CSimpleStringA> info = fList[i].Split('|');
- if(info.GetCount() != 2){
- Dbg("downloadFile.ini fileList fileInfo param is error");
- flag=false;
- break;
- }
- }
- }else{
- Dbg("downloadFile.ini fileList param is error, flist num not equal count");
- flag=false;
- }
- return flag;
- }
- //加载运行时文件任务
- ErrorCodeEnum DownloadFSM::LoadDownloadFileList()
- { //时间戳|文件名$
- //lwt 修改成日志文件互备模式:当运行时文件破坏时,用备份文件替代,当运行文件正常时,覆盖更新下备份文件,以防止备份文件之前是错误的。
- CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();
- CSmartPointer<IConfigInfo> spConfig;
- ErrorCodeEnum Error = spFunction->OpenConfig(Config_Run, spConfig);
- if (Error != Error_Succeed) {
- Dbg("open downloadFile.ini fail, please check out downloadFile.ini!");
- return Error_IO;
- }
- int count=0;
- CSimpleStringA strFile="";
- CSimpleStringA strFileBack="";
- CSimpleStringA strFinalFile="";//最终需要加载的文件列表
- int tmpCount;
- Error = spConfig->ReadConfigValueInt("downloadFile", "count", tmpCount);
- if(Error != Error_Succeed){
- Dbg("read downloadFile.ini param count fail!");
- return Error_IO;
- }else{
- count= tmpCount;
- Dbg("downloadFile count is %d",count);
- }
- Error = spConfig->ReadConfigValue("downloadFile", "fileList", strFile);
- if(Error != Error_Succeed){
- Dbg("read downloadFile.ini param fileList fail!");
- return Error_IO;
- }else{
- Dbg("downloadFile fileList is [%s]",strFile.GetData());
- }
- Error = spConfig->ReadConfigValue("downloadFile", "fileListBack", strFileBack);
- if(Error != Error_Succeed){
- Dbg("read downloadFile.ini param fileListBack fail!");
- return Error_IO;
- }else{
- Dbg("downloadFile fileListBack is [%s]",strFileBack.GetData());
- }
- if(count == 0){
- //因可能文件不存在,也返回0,默认初始化下文件,保证文件创建和字段创建
- spConfig->WriteConfigValueInt("downloadFile", "count", count);
- spConfig->WriteConfigValue("downloadFile", "fileList", strFile.GetData());
- }
- //判断是否读入数据效验成功,成功则用运行时文件覆盖写入备份文件,否则用备份文件写回运行时文件
- if(checkFileStr(strFile,count)){
- strFinalFile=strFile;
- //运行时通过检验
- if(spConfig->WriteConfigValue("downloadFile", "fileListBack", strFile.GetData())==Error_Succeed){
- Dbg("downloadFile fileListBack is rewrite success! content is [%s]",strFile.GetData());
- }else{
- Dbg("downloadFile fileListBack is rewrite fail! content is [%s]",strFile.GetData());
- }
- }else{
- CAutoArray<CSimpleStringA> fListback = strFileBack.Split('$');
- //备份文件是否效验通过,不通过,则运行时和备份文件全部清空
- if(checkFileStr(strFileBack,fListback.GetCount())){
- //备份通过检验
- strFinalFile=strFileBack;
- if(spConfig->WriteConfigValueInt("downloadFile", "count", fListback.GetCount())==Error_Succeed){
- Dbg("downloadFile count is rewrite success! content is [%d]",fListback.GetCount());
- }else{
- Dbg("downloadFile count is rewrite fail! content is [%d]",fListback.GetCount());
- return Error_IO;
- }
- if(spConfig->WriteConfigValue("downloadFile", "fileList", strFileBack.GetData())==Error_Succeed){
- Dbg("downloadFile fileList is rewrite success! content is [%s]",strFileBack.GetData());
- }else{
- Dbg("downloadFile fileList is rewrite fail! content is [%s]",strFileBack.GetData());
- return Error_IO;
- }
- }else{
- //未通过检验,则全部置空
- strFinalFile="";
- Dbg("downloadFile.ini reset");
- if(spConfig->WriteConfigValueInt("downloadFile", "count", 0)!=Error_Succeed){
- Dbg("downloadFile count reset fail");
- }
- if(spConfig->WriteConfigValue("downloadFile", "fileList", "")!=Error_Succeed){
- Dbg("downloadFile fileList reset fail");
- }
- if(spConfig->WriteConfigValue("downloadFile", "fileListBack", "")!=Error_Succeed){
- Dbg("downloadFile fileListBack reset fail");
- }
- }
- }
- Dbg("downloadFile final filelist content [%s]",strFinalFile.GetData());
- //装载文件到内存中
- CAutoArray<CSimpleStringA> fList = strFinalFile.Split('$');
- for(int i=0; i<fList.GetCount(); i++){
- CAutoArray<CSimpleStringA> info = fList[i].Split('|');
- CSimpleStringA expireTime = info[0];
- CSimpleStringA fileName= info[1];
- //加入任务队列
- DownloadFileTask *pTask = new DownloadFileTask();
- pTask->FileName=fileName;
- pTask->ExpireTime = (DWORD)atoi(expireTime.GetData());
- m_DFlist->push_back(pTask);
- CSmallDateTime expire(pTask->ExpireTime);
- Dbg("initial load task: expiretime[%d],expiredate[%s],filename[%s]",pTask->ExpireTime, expire.ToTimeString().GetData(), pTask->FileName.GetData());
- }
- return Error_Succeed;
- }
- //保存运行时文件任务
- ErrorCodeEnum DownloadFSM::SaveDownloadFileList()
- {
- ErrorCodeEnum ret = Error_Succeed;
- CSmartPointer<IEntityFunction> spFunction = m_pEntity->GetFunction();;
- CSmartPointer<IConfigInfo> spConfig;
- ErrorCodeEnum Error = spFunction->OpenConfig(Config_Run, spConfig);
- if (Error == Error_Succeed) {
- int count = m_DFlist->size();
- std::list<DownloadFileTask*>::iterator iter;
- CSimpleStringA str = "";
- for(iter=m_DFlist->begin();iter!=m_DFlist->end();++iter){
- DownloadFileTask* p = *iter;
- CSimpleStringA s1 = CSimpleStringA::Format("%d|",p->ExpireTime);
- CSimpleStringA s2 = CSimpleStringA::Format("%s$",p->FileName.GetData());
- Dbg("prepare save download file expiretime is %d, name is %s",p->ExpireTime,p->FileName.GetData());
- str.Append(s1.GetData());
- str.Append(s2.GetData());
- }
- Dbg("prepare write downloadFile/count : %d",count);
- Dbg("prepare write downloadFile/fileList : %s",str.GetData());
- Dbg("prepare write downloadFile/fileListBack : %s",str.GetData());
- Error = spConfig->WriteConfigValueInt("downloadFile", "count", count);
- if(Error!=Error_Succeed){
- Dbg("write downloadFile/count fail : %d",count);
- ret=Error_IO;
- }
- Error = spConfig->WriteConfigValue("downloadFile", "fileList", str.GetData());
- if(Error!=Error_Succeed){
- Dbg("write downloadFile/fileList fail : %s",str.GetData());
- ret=Error_IO;
- }
- Error = spConfig->WriteConfigValue("downloadFile", "fileListBack", str.GetData());
- if(Error!=Error_Succeed){
- Dbg("write downloadFile/fileListBack fail : %s",str.GetData());
- ret=Error_IO;
- }
-
- return ret;
- }else{
- Dbg("SaveDownloadFileList is fail , open downloadFile.ini fail!");
- return Error_Exception;
- }
- }
- //添加下载任务:加锁
- ErrorCodeEnum DownloadFSM::addDownLoadFileWork(CSimpleStringA fileName,DWORD expireTime)
- {
- EnterCriticalSection(&m_cs);
- //查询是否存在文件名,文件名唯一,不存在则加入,存在则忽略
- //先删除再加入
- std::list<DownloadFileTask*>::iterator iter;
- //删除所有文件名相同的文件
- for(iter=m_DFlist->begin();iter!=m_DFlist->end();){
- DownloadFileTask* p = *iter;
- if(p->FileName==fileName){
- iter = m_DFlist->erase(iter);
- delete p;
- }else{
- ++iter;
- }
- }
- //添加新的任务
- DownloadFileTask *pTask= new DownloadFileTask();
- pTask->FileName = fileName;
- pTask->ExpireTime = expireTime;
- m_DFlist->push_back(pTask);
- //保存队列到文件
- ErrorCodeEnum Error = SaveDownloadFileList();
- if(Error==Error_Succeed){
- Dbg("addDownLoadFileWork is success,fileName: %s",fileName.GetData());
- }else{
- Dbg("addDownLoadFileWork is fail,fileName: %s",fileName.GetData());
- }
-
- LeaveCriticalSection(&m_cs);
- return Error;
- }
- //取消下载任务:加锁
- ErrorCodeEnum DownloadFSM::deleteDownLoadFileWork(CSimpleStringA fileName)
- {
- EnterCriticalSection(&m_cs);
- Dbg("deleteDownLoadFileWork file [%s] prepare delete ",fileName.GetData());
- int iCount=m_DFlist->size();
- Dbg("deleteDownLoadFileWork prepare delete m_DFlist count is %d ",iCount);
- //查询是否存在文件名,存在则删除,不存在则忽略
- std::list<DownloadFileTask*>::iterator iter;
- for(iter=m_DFlist->begin();iter!=m_DFlist->end();++iter){
- DownloadFileTask* p = *iter;
- //尝试修改先移除后delete,看是否还出现问题
- if(strcmp(p->FileName.GetData(),fileName.GetData())==0){
- Dbg("deleteDownLoadFileWork file [%s] is deleted",fileName.GetData());
- iter = m_DFlist->erase(iter);
- delete p;
- break;
- }
- }
- iCount = m_DFlist->size();
- Dbg("deleteDownLoadFileWork deleted m_DFlist count is %d ",iCount);
- //保存队列到文件
- ErrorCodeEnum Error = SaveDownloadFileList();
- if(Error==Error_Succeed){
- Dbg("deleteDownLoadFileWork is success,fileName: %s",fileName.GetData());
- }else{
- Dbg("deleteDownLoadFileWork is fail,fileName: %s",fileName.GetData());
- }
- LeaveCriticalSection(&m_cs);
- return Error;
- }
- ErrorCodeEnum DownloadFSM::deleteCurrentDownloadFile(CSimpleStringA fileName){
- EnterCriticalSection(&m_cs);
- //表明是当前正在文件,则把当前文件置空,并删除零时文件,否则之不需要删除当前文件
- if(m_current!=NULL){
- if(m_currentFileName==fileName){
- Dbg("current downloadfile prepare delete ,filename is [%s]",fileName.GetData());
- download_storage_close(m_current,false,true);//删除
- m_currentFileName="";
- m_current=NULL;
- Dbg("current downloadfile is deleted ,filename is [%s]",fileName.GetData());
- }
- }
- //删除对应的对象
- std::list<download_file_t*>::iterator fIter;
- for(fIter=m_currentFileTask->begin();fIter!=m_currentFileTask->end();++fIter){
- download_file_t* p = *fIter;
- if(strcmp(LPCSTR(p->name),fileName.GetData())==0){
- delete p;
- fIter = m_currentFileTask->erase(fIter);
- break;
- }
- }
- LeaveCriticalSection(&m_cs);
- return Error_Succeed;
- }
- //过滤检查下载任务时效性:加锁
- ErrorCodeEnum DownloadFSM::checkWorkExpireTime()
- {
- EnterCriticalSection(&m_cs);
- Dbg("checkWorkExpireTime begin exec");
- std::list<DownloadFileTask*>::iterator iter=m_DFlist->begin();
- bool bDelete = false;
- while(iter!=m_DFlist->end()){
- DownloadFileTask* p = *iter;
- CSimpleStringA fileName = p->FileName;
- DWORD expireTime = p->ExpireTime;
- CSmallDateTime expire(expireTime);
- //判断是否超过时效性,超时的去除,并广播
- if(CSmallDateTime::GetNow()>expire){
- CSimpleStringA strExpireTime = expire.ToTimeString();
- Dbg("send broadcast for file [%s] downloadResult status : Error_timeOut , expiretime [%s]", fileName.GetData(), strExpireTime.GetData());
- returnDownloadFileResult(fileName.GetData(),Error_TimeOut,"downloadFile expireTime is timeOut");
- delete p;
- iter = m_DFlist->erase(iter);
- bDelete=true;
- }else{
- ++iter;
- }
- }
- //保存队列到文件
- ErrorCodeEnum Error=Error_Succeed;
- if(bDelete){
- Error = SaveDownloadFileList();
- if(Error==Error_Succeed){
- Dbg("checkWorkExpireTime is success");
- }else{
- Dbg("checkWorkExpireTime is fail");
- }
- }
- LeaveCriticalSection(&m_cs);
- return Error;
- }
- bool DownloadFSM::isDownloadTask(const char * filename){
- EnterCriticalSection(&m_cs);
- bool isTask=false;
- std::list<DownloadFileTask*>::iterator iter;
- for(iter = m_DFlist->begin();iter!=m_DFlist->end();++iter){
- DownloadFileTask* p = *iter;
- if(strcmp(p->FileName.GetData(),filename)==0){
- isTask=true;
- break;
- }
- }
- LeaveCriticalSection(&m_cs);
- return isTask;
- }
- ErrorCodeEnum DownloadFSM::returnDownloadFileResult(const char* filename,ErrorCodeEnum error,CSimpleStringA errorMsg){
- DownloadResult result;
- result.errorCode = error;
- result.errorMsg = errorMsg ;
- ErrorCodeEnum retError = SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(DownloadResult), SP_MSG_SIG_OF(DownloadResult), result);
- return retError;
- }
- ErrorCodeEnum DownloadFSM::returnDownloadProgress(download_file_t* file,download_storage_t * currentStorage){
- DownloadProgress dProgress;
- dProgress.currentFile = file->name;
- dProgress.fileNum = (int)m_DFlist->size();
- dProgress.progress=0;
- int temp10 = (int)((file->length>>15)/10);//10%左右的块号
-
- int block = currentStorage->offset_block_id;//当前块号
- bool isBroadcast =false;
- if(block==1){
- dProgress.progress=0;
- isBroadcast =true;
-
- }else if(block==temp10){
- dProgress.progress=10;
- isBroadcast =true;
-
- }else if(block==temp10*2){
- dProgress.progress=20;
- isBroadcast =true;
- }else if(block==temp10*3){
- dProgress.progress=30;
- isBroadcast =true;
- }else if(block==temp10*4){
- dProgress.progress=40;
- isBroadcast =true;
- }else if(block==temp10*5){
- dProgress.progress=50;
- isBroadcast =true;
- }else if(block==temp10*6){
- dProgress.progress=60;
- isBroadcast =true;
- }else if(block==temp10*7){
- dProgress.progress=70;
- isBroadcast =true;
- }else if(block==temp10*8){
- dProgress.progress=80;
- isBroadcast =true;
- }else if(block==temp10*9){
- dProgress.progress=90;
- isBroadcast =true;
- }else if(block<<15 >= file->length){
- dProgress.progress=100;
- isBroadcast =true;
- }
- ErrorCodeEnum retError=Error_Succeed;
- if(isBroadcast){
- Dbg("file [%s] progress is %d",(LPCSTR)file->name,dProgress.progress);
- ErrorCodeEnum retError = SpSendBroadcast(GetEntityBase()->GetFunction(), SP_MSG_OF(DownloadProgress), SP_MSG_SIG_OF(DownloadProgress), dProgress);
- }
- return retError;
- }
- void DownloadFSM::OnStateTrans( int iSrcState, int iDstState )
- { //告警状态跳转
- Dbg("trans from %s to %s", GetStateName(iSrcState), GetStateName(iDstState));
- }
- void DownloadFSM::OnSysVarEvent( const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName )
- {
- if(strcmp("CallState",pszKey)==0){
- Dbg("rx sysvar %s from %s, %s to %s", pszKey, pszEntityName, pszOldValue, pszValue);
- if (pszValue[0] == 'O') {
- Dbg("download state prepare jump enable ");
- PostEventFIFO(new FSMEvent(USER_EVT_JMP_ENABLE));
- } else {
- Dbg("download state prepare jump disable");
- PostEventFIFO(new FSMEvent(USER_EVT_JMP_DISABLE));
- }
- }
- if(strcmp("UIState",pszKey)==0){
- Dbg("rx sysvar %s from %s, %s to %s", pszKey, pszEntityName, pszOldValue, pszValue);
- //public enum UIState : int
- //{
- // Menu = 'M', //目录浏览
- // RandomAd = 'A', //随机广告
- // TargetAd = 'T', //目标广告
- // FillOut = 'F', //业务填单
- // Confirm = 'C', //交易确认
- // Submitting = 'S', //业务提交
- // Respone = 'R', //请求回报
- // Frozen = 'Z' //暂停响应
- //}
- if(!isStartUp){
- if(pszValue[0] == 'M'){
- isStartUp = true;
- Dbg("system page isStartup");
- }
- }
- }
-
- }
- ErrorCodeEnum DownloadFSM::OnInit()
- {
- ErrorCodeEnum Error;
- //初始化列表
- m_DFlist = new std::list<DownloadFileTask*>();
- m_currentFileTask = new std::list<download_file_t*>();
- Error=LoadDownloadFileList();
- //if (Error == Error_Succeed) {
- // LOG_TRACE("load fileList success!");
- //}
- //Error=Error_CheckSum;
- if (Error != Error_Succeed) {
- LOG_TRACE("load fileList failed!");
- return Error;
- }
- //初始化临界区
- InitializeCriticalSection(&m_cs);
- //初始化中台服务器地址
- Error = LoadServerConfigFromCenterSetting();
- if (Error != Error_Succeed) {
- LogWarn(Severity_High, Error, 0, "从集中配置读取配置信息失败");
- return Error;
- }
- //初始化终端文件夹地址
- CSimpleStringA str;
- m_pEntity->GetFunction()->GetPath("Download", str);
- strcpy(m_base_path, str.GetData());
- //订阅callState
- Error = m_pEntity->GetFunction()->RegistSysVarEvent("CallState", this);
- if(Error!=Error_Succeed){
- LOG_TRACE("RegistSysVarEvent CallState fail");
- return Error;
- }
- //订阅MenuChoice:判断是否页面在主菜单
- Error = m_pEntity->GetFunction()->RegistSysVarEvent("UIState",this);
-
- if(Error!=Error_Succeed){
- LOG_TRACE("RegistSysVarEvent UIState fail");
- return Error;
- }
- if (Error == Error_Succeed) {
- AddStateHooker(this);
- }
- //......
- return Error;
- }
- ErrorCodeEnum DownloadFSM::OnExit()
- {
- //取消callState订阅
- m_pEntity->GetFunction()->UnregistSysVarEvent("CallState");
- //订阅MenuChoice:判断是否页面在主菜单
- m_pEntity->GetFunction()->UnregistSysVarEvent("UIState");
- //删除列表
- if (m_DFlist!=NULL){
- std::list<DownloadFileTask*>::iterator iter;
- for(iter=m_DFlist->begin();iter!=m_DFlist->end();++iter){
- delete *iter;
- }
- m_DFlist->clear();
- delete m_DFlist;
- }
- if (m_currentFileTask!=NULL){
- std::list<download_file_t*>::iterator iter;
- for(iter=m_currentFileTask->begin();iter!=m_currentFileTask->end();++iter){
- delete *iter;
- }
- m_currentFileTask->clear();
- delete m_currentFileTask;
- }
- //释放临界区
- DeleteCriticalSection(&m_cs);
- return Error_Succeed;
- }
- void DownloadFSM::s0_on_entry()
- {
- LOG_FUNCTION();
- //通过直接获取变量值来判断是否进入了启动界面
- if(!isStartUp){
- CSimpleStringA strState;
- ErrorCodeEnum Error2 = m_pEntity->GetFunction()->GetSysVar("UIState",strState);
- if(Error2 == Error_Succeed&&strState=="M"){
- isStartUp =true;
- Dbg("system page isStartup");
- }
- }
- CSimpleStringA strValue;
- //连线状态CallState。定义客户和柜员连线电话状态。有6种状态:离线O、尝试连线柜员C、免提通话H、连线失败F、断线B。
- //初始状态为O。详细见“连线状态管理-连线状态转移图”部分
- ErrorCodeEnum Error = m_pEntity->GetFunction()->GetSysVar("CallState", strValue);
- if (Error == Error_Succeed && strValue[0] == 'O' && isStartUp)
- {
- // only download when CallState in offline state
- PostEventLIFO(new FSMEvent(USER_EVT_JMP_ENABLE));
- }
- else
- {
- ScheduleTimer(1, 10000);
- }
- }
- void DownloadFSM::s0_on_exit()
- {
- LOG_FUNCTION();
- CancelTimer(1);
- }
- unsigned int DownloadFSM::s0_on_event(FSMEvent* event)
- {
- if (event->iEvt == EVT_TIMER)
- {
- //通过直接获取变量值来判断是否进入了启动界面
- if(!isStartUp){
- CSimpleStringA strState;
- ErrorCodeEnum Error2 = m_pEntity->GetFunction()->GetSysVar("UIState",strState);
- if(Error2 == Error_Succeed&&strState=="M"){
- isStartUp =true;
- Dbg("system page isStartup");
- }
- }
- // 检查呼叫状态
- CSimpleStringA strValue;
- ErrorCodeEnum Error = m_pEntity->GetFunction()->GetSysVar("CallState", strValue);
- if (Error == Error_Succeed && strValue[0] == 'O' && isStartUp)
- {
- // only download when CallState in offline state
- PostEventLIFO(new FSMEvent(USER_EVT_JMP_ENABLE));
- }
- else
- {
- ScheduleTimer(1, 10000);
- }
- }
- return 0;
- }
- void DownloadFSM::s1_on_entry()
- {
- LOG_FUNCTION();
- ScheduleTimer(1, 30000);
- }
- void DownloadFSM::s1_on_exit()
- {
- LOG_FUNCTION();
- CancelTimer(1);
- }
- unsigned int DownloadFSM::s1_on_event(FSMEvent* event)
- {
- return 0;
- }
- void DownloadFSM::s2_on_entry()
- {
- LOG_FUNCTION();
- //过滤任务列表中超过时效任务
- ErrorCodeEnum error = checkWorkExpireTime();
- //当有任务时创建连接
- if(m_DFlist->size()>0){
- if (!m_pConnection) {
- m_pConnection = new DownloadConnection(m_pEntity, this);
- if(m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK()){
- //创建成功
- }else{
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- }
- }
- if (!m_pConnection) {
- ScheduleTimer(2, 30000); // try 30 seconds later
- } else {
- PostEventLIFO(new FSMEvent(USER_EVT_JMP_GETFILEINFO));
- }
- }else{
- PostEventFIFO(new FSMEvent(USER_EVT_NOTASK)); // 跳回S1状态
- }
- }
- void DownloadFSM::s2_on_exit()
- {
- CancelTimer(2);
- }
- unsigned int DownloadFSM::s2_on_event(FSMEvent* event)
- {
- if (event->iEvt == EVT_TIMER) {
- //过滤任务列表中超过时效任务
- ErrorCodeEnum error = checkWorkExpireTime();
- //当有任务时创建连接
- if(m_DFlist->size()>0){
- m_pConnection = new DownloadConnection(m_pEntity, this);
- if(m_pConnection->ConnectFromCentralSetting() && m_pConnection->IsConnectionOK()){
- //创建成功
- }else{
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- }
- if (!m_pConnection) {
- ScheduleTimer(2, 30000); // try 30 seconds later
- } else {
- PostEventLIFO(new FSMEvent(USER_EVT_JMP_GETFILEINFO));
- }
- }else{
- PostEventFIFO(new FSMEvent(USER_EVT_NOTASK)); // 跳回S1状态
- }
- }
- return 0;
- }
- void DownloadFSM::s3_on_entry()
- {
- LOG_FUNCTION();
- m_arr_downlist = NULL;
-
- //复制任务
- EnterCriticalSection(&m_cs);
- std::list<download_file_t*>::iterator fIter;
- for(fIter= m_currentFileTask->begin();fIter!=m_currentFileTask->end();++fIter){
- delete *fIter;
- }
- m_currentFileTask->clear();//清空之前批次的任务
-
- std::list<DownloadFileTask*>::iterator dIter;
- for(dIter=m_DFlist->begin();dIter!=m_DFlist->end();++dIter){
- //加入任务队列
- DownloadFileTask* p = *dIter;
- download_file_t* f = new download_file_t();
- //strcpy_s(f->name,64,p->FileName);//copy filename
- strcpy_s(f->name,256,p->FileName);//copy filename
- m_currentFileTask->push_back(f);
- }
- LeaveCriticalSection(&m_cs);
- if(m_currentFileTask->size()>0){
- Dbg("sendListreq ,count [%d]",m_currentFileTask->size());
- //m_pConnection->SendListReq();//发送获取文件列表请求
- m_pConnection->SendListNReq();//发送获取新国密文件列表请求
- }else{
- //无任务时跳回S1
- Dbg("no new files to download");
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- PostEventFIFO(new FSMEvent(USER_EVT_NOTASK)); // 跳回S1状态
- }
- }
- void DownloadFSM::s3_on_exit()
- {
- LOG_FUNCTION();
- //释放m_arr_downlist;
- if(m_arr_downlist!=NULL){
- download_free_filelist(m_arr_downlist);
- m_arr_downlist = NULL;
- }
- }
- unsigned int DownloadFSM::s3_on_event(FSMEvent* event)
- {
- if (event->iEvt == USER_EVT_FILEINO_ANS) {
- ListAnsEvent *ans = (ListAnsEvent*)event;
- if (ans->m_reply->ResultCode == DownloadCtlCode::ReturnList) {
- //解析中台返回的xml信息,得到下载文件信息列表。
- m_arr_downlist = download_parse_filelist(ans->m_reply->ListXmlContent, ans->m_xml_length);
-
- if(m_arr_downlist!=NULL){
- Dbg("return fileInfo list count is [%d]",m_arr_downlist->nelts);
- //如果存在返回值则检查
- if(m_arr_downlist->nelts>0){
- //循环判断需要下载的文件,对于已经下载完成的文件,则广播通知成功,不存在的则去除,其他都下载
- std::list<download_file_t*>::iterator iter=m_currentFileTask->begin();
- while(iter!=m_currentFileTask->end()){
- download_file_t* f = *iter;
- CSimpleStringA filename=f->name;
- int i=new_download_check_filelist(m_base_path, m_arr_downlist,f);
- //文件不在列表中,去除
- if(i==0){
- Dbg("file [%s] is not exist in filelist , wait a moment download ", f->name);
- delete f;//删除对象内容
- iter = m_currentFileTask->erase(iter);
- }
- //下载完成,广播通知
- if(i==2){
- Dbg("send broadcast for file [%s] downloadResult status success 1", f->name);
- returnDownloadFileResult(filename.GetData(),Error_Succeed,"downloadFile success");
- deleteDownLoadFileWork(filename);
- delete f;//删除对象内容
- iter = m_currentFileTask->erase(iter);
- }
- //准备后面下载的文件
- if(i==1){
- //先删除已下载的文件
- if(download_delete_file(m_base_path,f)){
- Dbg("file [%s] prepare download ", f->name);
- ++iter;//下一个
- }else{
- //删除原文件失败,则去除此次下载
- delete f;//删除对象内容
- iter = m_currentFileTask->erase(iter);
- }
-
- }
- }
- //判断是否需要下载新文件
- if(m_currentFileTask->size()>0){
- Dbg("find %d new files to download", m_currentFileTask->size());
- return 1; // goto s4
- }else{
- Dbg("no new files to download");
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- return 2; // goto s5
- }
- }else{
- //无信息列表,返回S1
- Dbg("download list return empty");
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- return 2; // goto s5
- }
- }else{
- Dbg("download list return NULL");
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL; // goto s1
- }
- } else {
- Dbg("FileInfo ans result code:%d", ans->m_reply->ResultCode);
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL; // goto s1
- }
- } else if (event->iEvt == USER_EVT_DISCONNECT) {
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- } else if (event->iEvt == USER_EVT_JMP_DISABLE) {
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- }
- return 0;
- }
- void DownloadFSM::s4_on_entry()
- {
- //获取新下载任务开始下载
- m_isDisable = false;//设置可用
- LogEvent(Severity_Middle, EVENT_MOD_DOWNLOAD_STARTSYNC, "开始同步下载");
- //Sleep(3000000);
- nextTask();
- }
- void DownloadFSM::s4_on_exit()
- {
- LOG_FUNCTION();
- if (m_pConnection) {
- m_pConnection->Close();
- m_pConnection->DecRefCount();
- m_pConnection = NULL;
- }
- //清空任务
- std::list<download_file_t*>::iterator iterTemp;
- for(iterTemp= m_currentFileTask->begin();iterTemp!=m_currentFileTask->end();++iterTemp){
- delete *iterTemp;
- }
- m_currentFileTask->clear();
- }
- unsigned int DownloadFSM::s4_on_event(FSMEvent* event)
- {
- //循环下载
- if (event->iEvt == USER_EVT_FILE_ANS){
- //判断是否需要推出
- if (!m_isDisable) {
- download_file_t* file;
- FileAnsEvent* ans = (FileAnsEvent*)event;
- //可能外部把当前的任务给删除了,通过m_current是否为空来判断,如果不为空,则继续下载,否则下一个文件下载
- if (m_current != NULL) {
- std::list<download_file_t*>::iterator fIter = m_currentFileTask->begin();//默认获取第一个,
- file = *fIter;
- CSimpleStringA filename = file->name;
- if (ans->m_reply->ResultCode != DownloadCtlCode::ErrorBlock) {
- download_storage_update(m_current, ans->m_reply->FileContent, ans->m_content_length);
- //广播进度给前台显示,块号,总长度
- returnDownloadProgress(file, m_current);
- if (m_current->offset_block_id << 15 >= file->length) {
- //因需要计算md5值,故需要先关闭前面连接句柄,否则打开文件失败
- #ifdef RVC_OS_WIN
- if (m_current->temp_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(m_current->temp_handle);
- m_current->temp_handle = INVALID_HANDLE_VALUE;
- }
- #else
- if (m_current->temp_handle != NULL) {
- fclose(m_current->temp_handle);
- m_current->temp_handle = NULL;
- }
- #endif // RVC_OS_WIN
- //判断是否MD5一致,一致则下载成功,否则删除临时文件,重新等待下次下载
- int flag = download_check_MD5(m_current, file);
- if (flag == 0) {
- download_storage_close(m_current, true, false);//改名
- Dbg("send broadcast for file [%s] downloadResult status : success 2", file->name);
- returnDownloadFileResult(filename.GetData(), Error_Succeed, "downloadFile success");
- deleteDownLoadFileWork(filename);//下载任务列表中任务删除
- Dbg("file download success! [%s]", file->name);
- }
- else {
- download_storage_close(m_current, false, true);//删除
- Dbg("file download fail! file MD5 is error ,file is delete and wait a moment download again [%s]", (LPCSTR)file->name);
- }
- delete file;
- m_currentFileTask->erase(fIter);//删除已完成的
- m_current = NULL;
- nextTask();// goto S4
- }
- else {
- m_pConnection->SendFileReq((LPCSTR)file->name, m_current->offset_block_id); // continue goto S4
- }
- }
- else {
- //块号传输错误,删除错误的临时文件,跳转到S5,并等待一段时间下载
- Dbg("file download fail! file download error [%s] , errorcode [%d]", m_current->temp_path, ans->m_reply->ResultCode);
- download_storage_close(m_current, false, true);//删除
- m_current = NULL;
- m_currentFileName = "";
- PostEventLIFO(new FSMEvent(USER_EVT_JMP_SYNC));//goto S5
- }
- }
- else {
- //获取下一个下载文件
- Dbg("current downloadfile is deleted , download next file");
- nextTask();
- }
- }
- else {
- Dbg("CallState is online ,prepare to disable");
- PostEventFIFO(new FSMEvent(USER_EVT_JMP_DISABLE_S0));
- }
- }else if (event->iEvt == USER_EVT_DISCONNECT) {
- if (m_current) {
- download_storage_close(m_current,false,false);//关闭
- m_current = NULL;
- }
- m_currentFileName="";
- } else if (event->iEvt == USER_EVT_JMP_DISABLE_S0) {
- if (m_current) {
- download_storage_close(m_current,false,false);//关闭
- m_current = NULL;
- }
- m_currentFileName="";
- }
- else if (event->iEvt == USER_EVT_JMP_DISABLE) {
- m_isDisable = true;//设置disable标志位
- }
- return 0;
- }
- void DownloadFSM::s5_on_entry()
- {
- LOG_FUNCTION();
- //清理临时文件
- array_header_t *arr = fileutil_get_sub_files_a(m_base_path);
- if (arr) {
- int i;
- for (i = 0; i < arr->nelts; ++i) {
- char *path = (char*)ARRAY_IDX(arr, i, char*);
- if (str_has_suffix(path, ".temp") || str_has_suffix(path, ".info")) {
- #ifdef RVC_OS_WIN
- DeleteFileA(path);
- #else
- remove(path);
- #endif // RVC_OS_WIN
- }
- }
- toolkit_array_free2(arr);
- }
- LogEvent(Severity_Middle, EVENT_MOD_DOWNLOAD_SYNCHRONIZED, "下载目录同步完成");
- ScheduleTimer(5, 180000); // 3分钟后再次同步目录
- }
- void DownloadFSM::s5_on_exit()
- {
- LOG_FUNCTION();
- CancelTimer(5);
- }
- unsigned int DownloadFSM::s5_on_event(FSMEvent* event)
- {
- if (event->iEvt == EVT_TIMER)
- {
- PostEventLIFO(new FSMEvent(USER_EVT_SYNC_FINISHED));
- }
- return 0;
- }
- void DownloadFSM::nextTask(){
- download_file_t *file=NULL;
- m_current = NULL;
- std::list<download_file_t*>::iterator fIter=m_currentFileTask->begin();
- while(fIter!=m_currentFileTask->end()){
- file = *fIter;
- CSimpleStringA filename = file->name;
- m_current = download_storage_open(m_base_path, file);
- m_currentFileName = (LPCSTR)file->name;
- if(m_current!=NULL){
- //打开文件成功,判断是否完成
- if (m_current->offset_block_id<<15 >= file->length) { // finished!
- //因需要计算md5值,故需要先关闭前面连接句柄,否则打开文件失败
- #ifdef RVC_OS_WIN
- if (m_current->temp_handle != INVALID_HANDLE_VALUE) {
- CloseHandle(m_current->temp_handle);
- m_current->temp_handle = INVALID_HANDLE_VALUE;
- }
- #else
- if (m_current->temp_handle != NULL) {
- fclose(m_current->temp_handle);
- m_current->temp_handle = NULL;
- }
- #endif // RVC_OS_WIN
- int flag = download_check_MD5(m_current,file);
- //判断是否MD5一致,一致则下载成功,否则删除临时文件,重新等待下次下载
- if(flag==0){
- download_storage_close(m_current,true,false);//改名
- Dbg("send broadcast for file [%s] downloadResult status success 3", (LPCSTR)file->name);
- returnDownloadFileResult(filename.GetData(),Error_Succeed,"downloadFile success");
- deleteDownLoadFileWork(filename);//下载任务列表中任务删除
- Dbg("file download success! [%s]", (LPCSTR)file->name);
- }else{
- //删除临时文件
- download_storage_close(m_current,false,true);//删除
- Dbg("file download fail! file MD5 is error ,file is delete and wait a moment download again [%s]", (LPCSTR)file->name);
- }
- m_current = NULL;
- delete file;//删除对象内容
- fIter = m_currentFileTask->erase(fIter);//正在下载的文件列表去除文件,并指向下一个文件
- } else {
- break;//进行任务下载
- }
- }else{
- //打开文件失败,接着下一个任务
- Dbg("file download fail! file storage open fail [%s]", (LPCSTR)file->name);
- delete file;//删除对象内容
- fIter = m_currentFileTask->erase(fIter);//正在下载的文件列表去除文件,并指向下一个文件
- }
- }
- if (m_current) {
- Dbg("begin download file: %s", file->name);
- m_pConnection->SendFileReq(file->name, m_current->offset_block_id);
- } else {
- //下载完成
- m_currentFileName = "";
- PostEventLIFO(new FSMEvent(USER_EVT_JMP_SYNC));//goto S5
- }
- }
|