#include "stdafx.h" #include "mod_UpgradeMgr.h" #include "LocalMediaPlay_client_g.h" #include "fileutil.h" #include #include "RVCComm.h" #ifdef RVC_OS_WIN #include #else #include #include #include #endif #include "EventCode.h" #include "json/json.h" namespace Task { //查询灰度控制 struct QueryUpgradeControlTaskReq : CHTTPReq { string m_reqStr; string ToJson() { return m_reqStr; } }; struct QueryUpgradeControlTaskRet : CHTTPRet { string m_retStr; bool Parse(string strData) { m_retStr=strData; return true; } }; struct InitFSMTask : public ITaskSp{ CUpgradeMgrEntity* Mgr; explicit InitFSMTask(CUpgradeMgrEntity* e) : Mgr(e) {} void Process(){ LOG_FUNCTION(); Mgr->bNewUpgradeMgr = true;//默认新模式 LogWarn(Severity_Low, Error_Exception, WARN_TASK_START_NEW_MODE, "init new upgradeTaskMgr"); if(Mgr->bNewUpgradeMgr){ ErrorCodeEnum rc =Mgr->m_taskFSM.Init(Mgr);//启动新状态机 if (rc != Error_Succeed) { LogWarn(Severity_Middle, Error_Exception, ERR_TASK_INIT_NEW_UPGRADE, "init new upgradeTaskMgr FSM fail"); Mgr->m_testResult=Error_InvalidState;//自检失败 return; }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("InitFSMTask")("init new upgradeTaskMgr FSM succ"); Mgr->m_initSucc = true; } Mgr->m_beginSM3HashTime = CSmallDateTime::GetNow(); }else{ LogWarn(Severity_Low, Error_Exception, WARN_TASK_START_OLD_MODE, "init old upgradeTaskMgr"); } } }; struct RollBackTask : public ITaskSp { CUpgradeMgrEntity* Mgr; CVersion historyVersion; explicit RollBackTask(CUpgradeMgrEntity* e, CVersion version) : Mgr(e) { historyVersion = version; } void Process() { bool loop = true; while (loop) { //判断是否继续执行 CSmartPointer spConfig; ErrorCodeEnum ret = Mgr->GetFunction()->OpenConfig(Config_CenterSetting, spConfig); int rollbackTemp = 0; if (ret == Error_Succeed) { spConfig->ReadConfigValueInt("UpgradeManager", "RollbackFlag", rollbackTemp); DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("get centerSetting RollbackFlag=%d", rollbackTemp); } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("get centerSetting RollbackFlag fail"); } if (rollbackTemp == 0) { //立即回退模式 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("Immediate mode,begin rollback version"); ErrorCodeEnum rc = Mgr->m_taskFSM.RollBackToHistoryVersion(historyVersion); if (rc == Error_Succeed) { // 通过事件通知健康实体 LogEvent(Severity_Middle, Event_Req_Framework_Rollback, "rollback upgrade succeed"); } else { LogError(Severity_Low, rc, 0, "rollback upgrade fail"); } loop = false;//退出 } else { //等待首页回退模式 CSimpleStringA strValue; if (Mgr->GetFunction()->GetSysVar("UIState", strValue) == Error_Succeed && strValue.Compare("M") == 0) { // 已经进入首页,开始回退 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("enter main page, begin rollback version"); ErrorCodeEnum rc = Mgr->m_taskFSM.RollBackToHistoryVersion(historyVersion); if (rc == Error_Succeed) { // 通过事件通知健康实体 LogEvent(Severity_Middle, Event_Req_Framework_Rollback, "rollback upgrade succeed"); } else { LogError(Severity_Low, rc, 0, "rollback upgrade fail"); } loop = false;//退出 } else { Sleep(30 * 1000);//继续循环 DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("enter not main page, rollback version delay 30s"); } } } Mgr->m_taskFSM.m_bRollbackTask = false;//线程退出 } }; } // 升级管理 UpgradeManager 0x506 void CUpgradeMgrEntity::OnStarted() { // 初始化状态机 //m_fsm.Init(this); auto pFunc = GetFunction(); // 监视准入状态 ErrorCodeEnum rc; CSimpleStringA strValue; if (pFunc->GetSysVar("UIState", strValue) == Error_Succeed && strValue.Compare("M") ==0) { // 已经进入首页状态 DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnStarted")("system page isStartup 1"); m_bStartUp =true; } else { // 否则启动监控 rc= pFunc->RegistSysVarEvent("UIState", this); if (rc != Error_Succeed) { LogWarn(Severity_Middle, rc, ERR_WRAN_REGIST_SYS_VAR_FAIL, CSimpleStringA::Format("RegistSysVarEvent UIState is fail,%d",(int)rc).GetData()); m_testResult=Error_InvalidState;//自检失败 }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnStarted")("RegistSysVarEvent UIState succ"); } } if (pFunc->GetSysVar("RunState", strValue) == Error_Succeed && strValue.Compare("N") ==0) { // 已经进入终端启动成功状态 DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnStarted")("====framework is start up 1===="); m_bSystemStartUp =true; } else { // 否则启动监控RunState rc= pFunc->RegistSysVarEvent("RunState", this); if (rc != Error_Succeed) { LogWarn(Severity_Middle, rc, ERR_WRAN_REGIST_SYS_VAR_FAIL, CSimpleStringA::Format("RegistSysVarEvent RunState is fail,%d",(int)rc).GetData()); m_testResult=Error_InvalidState;//自检失败 }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnStarted")("RegistSysVarEvent RunState succ"); } } //启动灰度控制判断,看启动什么状态机 Task::InitFSMTask* task = new Task::InitFSMTask(this); rc = this->GetFunction()->PostThreadPoolTask(task); if (rc != Error_Succeed) { LogError(Severity_Middle, rc, 0, CSimpleStringA::Format("Post InitFSMTask task to Thread is fail,%d",(int)rc).GetData()); m_testResult=Error_InvalidState;//自检失败 } } void CUpgradeMgrEntity::OnSelfTest(EntityTestEnum eTestType,CSmartPointer pTransactionContext) { if (Test_ShakeHand == eTestType) { //根据不同情况返回握手情况,监控实体根据不同情况杀死实体进程 pTransactionContext->SendAnswer(m_testResult); } } void CUpgradeMgrEntity::OnPreClose(EntityCloseCauseEnum eCloseCause,CSmartPointer pTransactionContext) { GetFunction()->UnsubscribeBroadcast("Download"); GetFunction()->UnsubscribeBroadcast("UpgradeRun"); pTransactionContext->SendAnswer(Error_Succeed); } void CUpgradeMgrEntity::OnSysVarEvent(const char *pszKey, const char *pszValue,const char *pszOldValue,const char *pszEntityName) { if(strcmp("UIState",pszKey)==0){ if(!m_bStartUp){ if (strcmp(pszValue, "M") ==0){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnSysVarEvent")("system page isStartup 2"); m_bStartUp = true; } } } if(strcmp("RunState",pszKey)==0){ if(!m_bSystemStartUp){ if (strcmp(pszValue, "N") ==0){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("OnSysVarEvent")("====framework is start up 2===="); m_bSystemStartUp = true; } } } } char CUpgradeMgrEntity::GetInstallStateVal(const InstallStateEnum enumVal) { const struct { int ch; InstallStateEnum val; } tbl[] = { {'A', Install_Active}, {'I', Install_Pending}, {'S', Install_SetToStart}, {'F', Install_FailRun}, {'R', Install_RollBack}, {'U', Install_Upgraded}, {'C',Install_Cancelled}, {'W',Install_WaitConfirm}, {'D', Install_Installed}, }; int i; for (i = 0; i < sizeof(tbl)/sizeof(tbl[0]); ++i) { if (tbl[i].val == enumVal) { return tbl[i].ch; } } return ' '; // error } //新状态机不处理 ErrorCodeEnum CUpgradeMgrEntity::RegistLocalPack(const CSimpleStringA &strPackFile) { if(m_initSucc){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RegistLocalPack")("RegistLocalPack new UpgradeMgr is not deal with"); return Error_NotImpl; }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("RegistLocalPack")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } //新状态机不处理 DWORD CUpgradeMgrEntity::RegistManualPack(const CSimpleStringA &strPackFile) { if(m_initSucc){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RegistManualPack")("RegistManualPack new UpgradeMgr is not deal with"); return UPGRADE_MGR_NOT_IMPLEMENT; }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("RegistManualPack")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } //新状态机不处理 ErrorCodeEnum CUpgradeMgrEntity::CancelUpdate(const CSimpleStringA &strPackFile) { if(m_initSucc){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("CancelUpdate")("CancelUpdate new UpgradeMgr is not deal with"); return Error_NotImpl; }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("CancelUpdate")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } //新状态机处理 ErrorCodeEnum CUpgradeMgrEntity::RollbackUpdate(const CSimpleStringA &strVersion) { if(m_initSucc){ if(bNewUpgradeMgr){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("RollbackUpdate new UpgradeMgr deal with"); if(strVersion.GetLength()==0){ LogError(Severity_Low, Error_NotImpl, 0, "version is empty , rollback upgrade fail"); return Error_NotImpl; }else{ ErrorCodeEnum rc = Error_Succeed; DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("try rollback to version: [%s]", (const char*)strVersion); int w1, w2, w3, w4; int ret = sscanf(strVersion, "%d.%d.%d.%d", &w1, &w2, &w3, &w4); if (ret <4) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("version [%s] parse fail", (const char*)strVersion); rc= Error_Param; } else { //回退放入线程当中 if (!m_taskFSM.m_bRollbackTask) { Task::RollBackTask* rTask = new Task::RollBackTask(this, CVersion(w1, w2, w3, w4)); ErrorCodeEnum rc = this->GetFunction()->PostThreadPoolTask(rTask); if (Error_Succeed == rc) { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("RollbackFlag thread start succ"); m_taskFSM.m_bRollbackTask = true;//启动线程 } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("RollbackFlag thread start fail : %d",(int)rc); } } else { DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("RollbackFlag thread is exist"); return Error_Succeed; } } } }else{ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("RollbackUpdate old UpgradeMgr deal not with"); return Error_Succeed; } }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("RollbackUpdate")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } //新状态机不处理 DWORD CUpgradeMgrEntity::GetManualPacks(CSimpleStringA &strManualPacks) { if(m_initSucc){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetManualPacks")("GetManualPacks new UpgradeMgr is not deal with"); return UPGRADE_MGR_NOT_IMPLEMENT; }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("GetManualPacks")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } CServerSessionBase* CUpgradeMgrEntity::OnNewSession(const char* /*pszRemoteEntityName*/, const char * /*pszParam*/) { return new CUpgradeMgrSession(this); } //新状态机不处理 ErrorCodeEnum CUpgradeMgrEntity::SwitchUpgrade(const CSimpleStringA &strPack) { if(m_initSucc){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("SwitchUpgrade")("SwitchUpgrade new UpgradeMgr is not deal with"); return Error_NotImpl; }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("SwitchUpgrade")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } //新状态机处理 ErrorCodeEnum CUpgradeMgrEntity::GetUpgradeState(bool &bInstalling, CSimpleStringA &strPackFile, CSimpleStringA &strExecID, char &cInstallState, bool &bSysInstall, bool &bLightPack, CSimpleStringA &strNewVersion) { if(m_initSucc){ DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI("GetUpgradeState")("GetUpgradeState new UpgradeMgr deal with"); return m_taskFSM.GetUpgradeState(bInstalling, strPackFile, strExecID, cInstallState, bSysInstall, bLightPack, strNewVersion); }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("GetUpgradeState")("initFSM is not end"); return Error_Pending;//状态机还未启动 } } ErrorCodeEnum CUpgradeMgrEntity::testActive() { CSimpleStringA rootVerPath; ErrorCodeEnum rc = this->GetFunction()->GetPath("RootVer",rootVerPath);//获取version根路径 if(rc!=Error_Succeed){ LogWarn(Severity_Middle, Error_Exception, ERR_WRAN_OPEN_ACTIVE_FAIL,"testActive fail , get RootVer path is fai"); return Error_Bug; } CSimpleStringA strActiveFile = CSimpleStringA::Format("%s" SPLIT_SLASH_STR "active.txt", rootVerPath.GetData()); FILE* fp = fopen(strActiveFile.GetData(),"rb+"); if(fp==NULL){ #ifdef RVC_OS_WIN LogWarn(Severity_Middle, Error_Exception, ERR_WRAN_OPEN_ACTIVE_FAIL,CSimpleStringA::Format("open write active.txt fail,please edit active attribute, err=%d",(int)GetLastError()).GetData()); #else LogWarn(Severity_Middle, Error_Exception, ERR_WRAN_OPEN_ACTIVE_FAIL,CSimpleStringA::Format("open write active.txt fail,please edit active attribute, err=%d",errno).GetData()); #endif return Error_Unexpect; } fclose(fp); return Error_Succeed; } ErrorCodeEnum CUpgradeMgrEntity::NewStopMediaPlay() { #ifdef RVC_OS_WIN // 通知媒体停止播放广告和声音 LocalMediaPlay::PlayService_ClientBase *pClient = new LocalMediaPlay::PlayService_ClientBase(this); ErrorCodeEnum rc = pClient->Connect(); if (rc == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("NewStopMediaPlay")("connect to entity [LocalMediaPlay] succeed, start StopMediaPlay now"); //采用新接口停止所有音视频播放 LocalMediaPlay::PlayService_StopPlayAllMedias_Req req1 = {}; LocalMediaPlay::PlayService_StopPlayAllMedias_Ans ans1 = {}; if (Error_Succeed == (*pClient)(EntityResource::getLink().upgradeLink())->StopPlayAllMedias(req1, ans1, 10000)) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("NewStopMediaPlay")("StopPlayAllMedias success"); }else{ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("NewStopMediaPlay")("StopPlayAllMedias fail"); pClient->GetFunction()->CloseSession(); pClient->SafeDelete(); return rc; } pClient->GetFunction()->CloseSession(); } else { LogError(Severity_Low, rc, 0, "connect to entity [LocalMediaPlay] fail"); } pClient->SafeDelete(); return rc; #else // 通知媒体停止播放广告和声音 LocalMediaPlay::PlayService_ClientBase *pClient = new LocalMediaPlay::PlayService_ClientBase(this); ErrorCodeEnum rc = pClient->Connect(); if (rc == Error_Succeed) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("NewStopMediaPlay")("connect to entity [LocalMediaPlay] succeed, start StopMediaPlay now"); LocalMediaPlay::PlayService_StopPlayVideo_Req req1 = {}; LocalMediaPlay::PlayService_StopPlayVideo_Ans ans1 = {}; req1.CfgInx = 1; rc = (*pClient)(EntityResource::getLink().upgradeLink())->StopPlayVideo(req1, ans1, 10000); if (Error_Succeed == rc) { DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("NewStopMediaPlay")("StopPlayVideo success"); }else{ Dbg("StopPlayVideo fail"); pClient->GetFunction()->CloseSession(); pClient->SafeDelete(); return rc; } LocalMediaPlay::PlayService_StopPlayAudio_Req req2 = {}; LocalMediaPlay::PlayService_StopPlayAudio_Ans ans2 = {}; rc = (*pClient)(EntityResource::getLink().upgradeLink())->StopPlayAudio(req2, ans2, 10000); if (Error_Succeed == rc) { Dbg("StopPlayAudio success"); }else{ Dbg("StopPlayAudio fail"); pClient->GetFunction()->CloseSession(); pClient->SafeDelete(); return rc; } pClient->GetFunction()->CloseSession(); } else { LogError(Severity_Low, rc, 0, "connect to entity [LocalMediaPlay] fail"); pClient->SafeDelete(); } return rc; #endif } SP_BEGIN_ENTITY_MAP() SP_ENTITY(CUpgradeMgrEntity) SP_END_ENTITY_MAP() void CUpgradeMgrEntity::HttpsLogCallBack(const char* logtxt) { if(logtxt!=NULL){ DbgWithLink(LOG_LEVEL_INFO,LOG_TYPE_SYSTEM).setAPI("HttpsLogCallBack")("http dbg: %s",logtxt); } }