|
@@ -19,16 +19,21 @@
|
|
|
#include <sys/reboot.h>
|
|
|
#endif //RVC_OS_WIN
|
|
|
|
|
|
-#include "toolkit.h"
|
|
|
#include <vector>
|
|
|
#include <iostream>
|
|
|
#include <fstream>
|
|
|
+#include <regex.h>
|
|
|
+#include "toolkit.h"
|
|
|
+#include "array.h"
|
|
|
+#include "fileutil.h"
|
|
|
+#include "iniutil.h"
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
#include "mod_healthmanager.h"
|
|
|
#include "CommEntityUtil.hpp"
|
|
|
#include "GetDevInfoHelper.h"
|
|
|
+#include "TerminalInfoQueryConn.h"
|
|
|
|
|
|
#if defined(RVC_OS_WIN)
|
|
|
#pragma comment( lib, "advapi32.lib" )
|
|
@@ -49,6 +54,21 @@ const DWORD HEALTHMANAGER_TIMER_INTERVAL_MINUTE = (HEALTHMANAGER_TIMER_INTERVAL/
|
|
|
#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
|
|
|
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
|
|
|
|
|
|
+#define DEPLOYSTATE_NOTINIT 0
|
|
|
+#define DEPLOYSTATE_DONE 1
|
|
|
+#define DEPLOYSTATE_FAILED 2
|
|
|
+
|
|
|
+
|
|
|
+#include "CenterSetting_client_g.h"
|
|
|
+using namespace CenterSetting;
|
|
|
+
|
|
|
+#include "Initializer_client_g.h"
|
|
|
+using namespace Initializer;
|
|
|
+
|
|
|
+//for defines in header file
|
|
|
+#include "CameraConfigManage_def_g.h"
|
|
|
+using namespace CameraConfigManage;
|
|
|
+
|
|
|
template<class T>
|
|
|
class TimerOutHelper : public ITimerListener
|
|
|
{
|
|
@@ -69,6 +89,24 @@ private:
|
|
|
FuncTimer m_pTimer;
|
|
|
bool m_bDeleteSelf;
|
|
|
};
|
|
|
+
|
|
|
+static void PrintTerminalRegistInfo(const TerminalRegistRet* info)
|
|
|
+{
|
|
|
+ Dbg("TerminalNo: %s", info->TerminalNo);
|
|
|
+ Dbg("DeviceNo: %s", info->DeviceNo);
|
|
|
+ Dbg("OutletNo: %s", info->OutletNo);
|
|
|
+ Dbg("Initializer: %s", info->Initializer);
|
|
|
+ Dbg("PadDeviceID: %s", info->PadDeviceID);
|
|
|
+ Dbg("MachineType: %s", info->MachineType);
|
|
|
+ Dbg("MachineVersion: %s", info->MachineVersion);
|
|
|
+ Dbg("Sites: %s", info->Sites);
|
|
|
+ Dbg("EnrolAddr: %s", info->EnrolAddr);
|
|
|
+ Dbg("Editor: %s", info->Editor);
|
|
|
+ Dbg("State: %c", info->State);
|
|
|
+ Dbg("PublicKey: %s", info->PublicKey);
|
|
|
+ Dbg("FingerPrint: %s", info->FingerPrint);
|
|
|
+}
|
|
|
+
|
|
|
void HealthManagerSession::Handle_EnterState(SpReqAnsContext<HealthManagerService_EnterState_Req, HealthManagerService_EnterState_Ans>::Pointer ctx)
|
|
|
{
|
|
|
LOG_FUNCTION();
|
|
@@ -105,13 +143,17 @@ void HealthManagerSession::Handle_ReadCenterConfigStr(SpReqAnsContext<HealthMana
|
|
|
{
|
|
|
LOG_FUNCTION();
|
|
|
}
|
|
|
-
|
|
|
void HealthManagerSession::Handle_ControlTerminalLife(
|
|
|
SpReqAnsContext<HealthManagerService_ControlTerminalLife_Req, HealthManagerService_ControlTerminalLife_Ans>::Pointer ctx)
|
|
|
{
|
|
|
LOG_FUNCTION();
|
|
|
m_pEntity->ControlTerminalLife(ctx);
|
|
|
}
|
|
|
+void HealthManagerSession::Handle_DeployTerminal(SpReqAnsContext<HealthManagerService_DeployTerminal_Req, HealthManagerService_DeployTerminal_Ans>::Pointer ctx)
|
|
|
+{
|
|
|
+ LOG_FUNCTION();
|
|
|
+ m_pEntity->DeployTerminal(ctx);
|
|
|
+}
|
|
|
|
|
|
bool CHealthManagerEntity::DoWatchDog(WatchDogOp eOp)
|
|
|
{
|
|
@@ -2059,6 +2101,319 @@ void CHealthManagerEntity::OnBroadcastEvent(CUUID SubID, const char *pszEntityNa
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+void CHealthManagerEntity::DeployTerminal(SpReqAnsContext<HealthManagerService_DeployTerminal_Req, HealthManagerService_DeployTerminal_Ans>::Pointer ctx)
|
|
|
+{
|
|
|
+
|
|
|
+ LOG_FUNCTION();
|
|
|
+
|
|
|
+ ErrorCodeEnum result(Error_Succeed);
|
|
|
+ int tmpResult = 0;
|
|
|
+ CSimpleStringA tmpMsg(true);
|
|
|
+
|
|
|
+ Dbg("Cmd: %d", ctx->Req.currStep);
|
|
|
+
|
|
|
+ switch (ctx->Req.currStep) {
|
|
|
+ case DeployStep_Begin:
|
|
|
+ result = Error_NotImpl;
|
|
|
+ break;
|
|
|
+ case DeployStep_GetTerminalInfo:
|
|
|
+ {
|
|
|
+ CTerminalInfoQuery* pCnn = new CTerminalInfoQuery(this);
|
|
|
+ CAutoArray<CSimpleStringA> arrs = ctx->Req.param4.Split('|');
|
|
|
+ const CSimpleStringA& terminalNo = arrs[0];
|
|
|
+ const CSimpleStringA& vendorType = arrs[1];
|
|
|
+ const CSimpleStringA& serverIP = ctx->Req.param3;
|
|
|
+ Dbg("server ip: %s, terminal no: %s, vendor: %s", serverIP.GetData(), (LPCTSTR)terminalNo, (LPCTSTR)vendorType);
|
|
|
+
|
|
|
+ /** 1050 是固定的服务端实体端口 [Gifur@20211013]*/
|
|
|
+ pCnn->ConnectServer(serverIP.GetData(), 1050);
|
|
|
+ Dbg("Connect finished!");
|
|
|
+ if (pCnn->IsConnectionOK()) {
|
|
|
+ Dbg("Connect OK!");
|
|
|
+ TerminalRegistRet info;
|
|
|
+ result = pCnn->GetTerminalInfo(terminalNo.GetData(), &info);
|
|
|
+ pCnn->Close();
|
|
|
+ PrintTerminalRegistInfo(&info);
|
|
|
+ if (strlen(info.TerminalNo) == 0) {
|
|
|
+ result = Error_NotExist;
|
|
|
+ } else if (terminalNo.Compare(info.TerminalNo) != 0) {
|
|
|
+ result = Error_MisMatched;
|
|
|
+ } else {
|
|
|
+ ErrorCodeEnum ec(Error_Succeed);
|
|
|
+ CSmartPointer<IConfigInfo> pConfig;
|
|
|
+ GetFunction()->OpenConfig(Config_Cache, pConfig);
|
|
|
+ do {
|
|
|
+ Dbg("record to cache...");
|
|
|
+ const ErrorCodeEnum ec0 = pConfig->WriteConfigValue("TerminalDeploy", "TerminalNo", terminalNo);
|
|
|
+ const ErrorCodeEnum ec1 = pConfig->WriteConfigValue("TerminalDeploy", "Manufacturer", vendorType);
|
|
|
+ const ErrorCodeEnum ec2 = pConfig->WriteConfigValue("TerminalDeploy", "ServerIP", serverIP);
|
|
|
+ const ErrorCodeEnum ec3 = pConfig->WriteConfigValueInt("TerminalDeploy", "CurrStep", ctx->Req.currStep);
|
|
|
+ if (!ec0 && !ec1 && !ec2 && !ec3) {
|
|
|
+ ec = pConfig->WriteConfigValueInt("TerminalDeploy", "CurrState", DEPLOYSTATE_DONE);
|
|
|
+ Dbg("record step: %s", SpStrError(ec));
|
|
|
+ } else {
|
|
|
+ Dbg("record failed: %s, %s, %s, %s", SpStrError(ec), SpStrError(ec1), SpStrError(ec2), SpStrError(ec3));
|
|
|
+ ec = Error_IO;
|
|
|
+ }
|
|
|
+
|
|
|
+ } while (false);
|
|
|
+
|
|
|
+ do {
|
|
|
+ CSimpleStringA strRootCfgPath;
|
|
|
+ ec = GetFunction()->GetPath("HardwareCfg", strRootCfgPath);
|
|
|
+ if (ec == Error_Succeed && !strRootCfgPath.IsNullOrEmpty()) {
|
|
|
+ CSimpleStringA strRootIniFullPath(strRootCfgPath.GetData());
|
|
|
+ strRootIniFullPath += SPLIT_SLASH_STR;
|
|
|
+ strRootIniFullPath += "root.ini";
|
|
|
+ if (ExistsFileA(strRootIniFullPath)) {
|
|
|
+ fileutil_copy_file(strRootIniFullPath + ".bak", strRootIniFullPath);
|
|
|
+ fileutil_delete_file(strRootIniFullPath);
|
|
|
+ Dbg("root.ini exists!");
|
|
|
+ }
|
|
|
+
|
|
|
+ array_header_t* subs = fileutil_get_sub_files_a(strRootCfgPath);
|
|
|
+ if (subs) {
|
|
|
+ regex_t reg;
|
|
|
+ CSimpleStringA machineType("Stand2S");
|
|
|
+ CSimpleStringA rootPattern("root");
|
|
|
+ CSimpleStringA pattern = rootPattern + "\\-" + machineType + "\\-" + vendorType + "\\-[a-zA-Z0-9_\\(\\)\\-]*" + ".ini";
|
|
|
+ int ret = regcomp(®, pattern, REG_EXTENDED | REG_NOSUB);
|
|
|
+ if (ret) {
|
|
|
+ char ebuff[256];
|
|
|
+ regerror(ret, ®, ebuff, 256);
|
|
|
+ Dbg("regex failed: %s", ebuff);
|
|
|
+ tmpMsg = CSimpleStringA::Format("内部错误:REGEX %s", ebuff);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Dbg("pattern: %s", pattern.GetData());
|
|
|
+ CSimpleStringA strRootChosenFile(true);
|
|
|
+ for (int i = 0; i < subs->nelts; ++i) {
|
|
|
+ char* filenamePath = ARRAY_IDX(subs, i, char*);
|
|
|
+ char* filename = &filenamePath[strRootCfgPath.GetLength() + 1];
|
|
|
+ Dbg("filename: %s", filename);
|
|
|
+ ret = regexec(®, filename, 0, NULL, 0);
|
|
|
+ if (0 == ret) {
|
|
|
+ Dbg("matched!");
|
|
|
+ strRootChosenFile = filenamePath;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ Dbg("not matched.");
|
|
|
+
|
|
|
+ }
|
|
|
+ toolkit_array_free2(subs);
|
|
|
+
|
|
|
+ if (!strRootChosenFile.IsNullOrEmpty()) {
|
|
|
+ CSimpleStringA strRootTmpFile = strRootIniFullPath + ".cur";
|
|
|
+ fileutil_copy_file(strRootTmpFile, strRootChosenFile);
|
|
|
+ inifile_write_str(strRootTmpFile, "Terminal", "TerminalNo", terminalNo);
|
|
|
+ //inifile_write_str(strRootTmpFile, "Terminal", "Manufacturer", vendorType);
|
|
|
+ //TODO: Addr
|
|
|
+ fileutil_copy_file(strRootIniFullPath, strRootTmpFile);
|
|
|
+ fileutil_delete_file(strRootTmpFile);
|
|
|
+
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrStep", ctx->Req.nextStep);
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrState", DEPLOYSTATE_NOTINIT);
|
|
|
+
|
|
|
+ } else {
|
|
|
+ tmpMsg = "找不到匹配的备选文件,请确认安装包完整性并尝试重新安装";
|
|
|
+ tmpResult = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ } while (false);
|
|
|
+
|
|
|
+ ctx->Ans.param2 = serverIP;
|
|
|
+ ctx->Ans.nextStep = ctx->Req.nextStep;
|
|
|
+ ctx->Ans.result = tmpResult;
|
|
|
+ ctx->Ans.additionalMsg = tmpMsg;
|
|
|
+ }
|
|
|
+
|
|
|
+ } else {
|
|
|
+ Dbg("Connect Failed!");
|
|
|
+ result = Error_ConnectFailed;
|
|
|
+ }
|
|
|
+ pCnn->DecRefCount();
|
|
|
+ pCnn = NULL;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DeployStep_FetchCenterSettings:
|
|
|
+ {
|
|
|
+ const CSimpleStringA& serverIP = ctx->Req.param3;
|
|
|
+ const int nPort = ctx->Req.param1;
|
|
|
+
|
|
|
+ if (serverIP.IsNullOrEmpty() || nPort <= 0) {
|
|
|
+ result = Error_Param;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ErrorCodeEnum ec(Error_Succeed);
|
|
|
+ CSmartPointer<IConfigInfo> pConfig;
|
|
|
+ GetFunction()->OpenConfig(Config_Cache, pConfig);
|
|
|
+
|
|
|
+ Dbg("to connect centersetting...%s::%d", serverIP.GetData(), nPort);
|
|
|
+ auto pCenterSettingClient = new CenterSettingService_ClientBase(this);
|
|
|
+ ec = pCenterSettingClient->Connect();
|
|
|
+ if (ec != Error_Succeed) {
|
|
|
+ tmpMsg = CSimpleStringA::Format("连接集中配置模块失败: %s", SpStrError(ec));
|
|
|
+ pCenterSettingClient->SafeDelete();
|
|
|
+ Dbg("connect to centersetting failed: %s", SpStrError(ec));
|
|
|
+ tmpResult = ec;
|
|
|
+ } else {
|
|
|
+ CenterSettingService_Download_Req req = {};
|
|
|
+ req.strAddr = serverIP;
|
|
|
+ req.nPort = nPort;
|
|
|
+ CenterSettingService_Download_Ans ans = {};
|
|
|
+ /**TODO(Gifur@10/14/2021): 未知行内还是行外的情况 */
|
|
|
+ Dbg("to download...");
|
|
|
+ ec = pCenterSettingClient->Download(req, ans, 10000);
|
|
|
+ if (ec != Error_Succeed) {
|
|
|
+ tmpMsg = CSimpleStringA::Format("集中配置模块调用失败: %s", SpStrError(ec));
|
|
|
+ tmpResult = ec;
|
|
|
+ Dbg("to download failed: %s", SpStrError(ec));
|
|
|
+ } else {
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrStep", ctx->Req.nextStep);
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrState", DEPLOYSTATE_NOTINIT);
|
|
|
+ }
|
|
|
+ pCenterSettingClient->GetFunction()->CloseSession();
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx->Ans.param2 = serverIP;
|
|
|
+ ctx->Ans.nextStep = ctx->Req.nextStep;
|
|
|
+ ctx->Ans.result = tmpResult;
|
|
|
+ ctx->Ans.additionalMsg = tmpMsg;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DeployStep_AccessAuthorize:
|
|
|
+ {
|
|
|
+ const CSimpleStringA& serverIP = ctx->Req.param3;
|
|
|
+ const int nPort = ctx->Req.param1;
|
|
|
+
|
|
|
+ if (serverIP.IsNullOrEmpty() || nPort <= 0) {
|
|
|
+ result = Error_Param;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ErrorCodeEnum ec(Error_Succeed);
|
|
|
+ CSmartPointer<IConfigInfo> pConfig;
|
|
|
+ GetFunction()->OpenConfig(Config_Cache, pConfig);
|
|
|
+
|
|
|
+ Dbg("to connect initializer...%s::%d", serverIP.GetData(), nPort);
|
|
|
+ auto pClient = new InitializerService_ClientBase(this);
|
|
|
+ ec = pClient->Connect();
|
|
|
+ if (ec != Error_Succeed) {
|
|
|
+ tmpMsg = CSimpleStringA::Format("连接初始化模块失败: %s", SpStrError(ec));
|
|
|
+ pClient->SafeDelete();
|
|
|
+ Dbg("connect to initializer module failed: %s", SpStrError(ec));
|
|
|
+ tmpResult = ec;
|
|
|
+ } else {
|
|
|
+ InitializerService_InitializeNew_Req req = {};
|
|
|
+ req.strAuthServer = serverIP;
|
|
|
+ req.nAuthPort = nPort;
|
|
|
+ req.strUserID = "admin";
|
|
|
+ req.strPassword = "88888888";
|
|
|
+
|
|
|
+ InitializerService_InitializeNew_Ans ans = {};
|
|
|
+ Dbg("to initializer...");
|
|
|
+ ec = pClient->InitializeNew(req, ans, 30000);
|
|
|
+ if (ec != Error_Succeed) {
|
|
|
+ tmpMsg = CSimpleStringA::Format("初始化调用失败: %s", SpStrError(ec));
|
|
|
+ tmpResult = ec;
|
|
|
+ Dbg("to initialize failed: %s", SpStrError(ec));
|
|
|
+ } else {
|
|
|
+
|
|
|
+ const int errUserCode = (int)(ans.Errcode);
|
|
|
+ if (errUserCode != 0) {
|
|
|
+ if (ans.ErrMsg.IsNullOrEmpty()) {
|
|
|
+ tmpMsg = CSimpleStringA::Format("%d", errUserCode);
|
|
|
+ } else {
|
|
|
+ tmpMsg = CSimpleStringA::Format("%s", ans.ErrMsg.GetData());
|
|
|
+ }
|
|
|
+ tmpResult = errUserCode;
|
|
|
+ Dbg("initialize failed: %s", (LPCTSTR)tmpMsg);
|
|
|
+ } else {
|
|
|
+ Dbg("initialize succ.");
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrStep", ctx->Req.nextStep);
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrState", DEPLOYSTATE_NOTINIT);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ pClient->GetFunction()->CloseSession();
|
|
|
+ }
|
|
|
+
|
|
|
+ ctx->Ans.param2 = serverIP;
|
|
|
+ ctx->Ans.nextStep = ctx->Req.nextStep;
|
|
|
+ ctx->Ans.result = tmpResult;
|
|
|
+ ctx->Ans.additionalMsg = tmpMsg;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DeployStep_MediaConfig:
|
|
|
+ {
|
|
|
+ ErrorCodeEnum ec(Error_Succeed);
|
|
|
+ CSmartPointer<IConfigInfo> pConfig, pRootConfig;
|
|
|
+
|
|
|
+ GetFunction()->OpenConfig(Config_Cache, pConfig);
|
|
|
+ GetFunction()->OpenConfig(Config_Root, pRootConfig);
|
|
|
+
|
|
|
+ for (int i = 0; i < ctx->Req.array1.GetCount(); ++i) {
|
|
|
+ CSimpleStringA key(true), value(ctx->Req.array2[i]);
|
|
|
+ const int type = ctx->Req.array1[i];
|
|
|
+ Dbg("%d: %s - %d", i, value.GetData(), type);
|
|
|
+ switch (type) {
|
|
|
+ case MediaDev_OutSpeaker:
|
|
|
+ key = "handfree_out_dev";
|
|
|
+ break;
|
|
|
+ case MediaDev_InSpeaker:
|
|
|
+ key = "pickup_out_dev";
|
|
|
+ break;
|
|
|
+ case MediaDev_OutMicrophone:
|
|
|
+ key = "handfree_in_dev";
|
|
|
+ break;
|
|
|
+ case MediaDev_InMicrophone:
|
|
|
+ key = "pickup_in_dev";
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ ec = Error_Param;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!key.IsNullOrEmpty()) {
|
|
|
+ ec = pRootConfig->WriteConfigValue("Audio", key, value);
|
|
|
+ Dbg("write %s=%s into root.ini: %s", key.GetData(), value.GetData(), SpStrError(ec));
|
|
|
+ } else {
|
|
|
+ Dbg("unrecognize: %d, %s", type, value.GetData());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrStep", DeployStep_MediaConfig);
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrState", (ec != Error_Succeed) ? DEPLOYSTATE_FAILED : DEPLOYSTATE_DONE);
|
|
|
+
|
|
|
+ ctx->Ans.nextStep = ctx->Req.nextStep;
|
|
|
+ ctx->Ans.result = ec;
|
|
|
+ ctx->Ans.additionalMsg = tmpMsg;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case DeployStep_Finished:
|
|
|
+ {
|
|
|
+ ErrorCodeEnum ec(Error_Succeed);
|
|
|
+ CSmartPointer<IConfigInfo> pConfig;
|
|
|
+ GetFunction()->OpenConfig(Config_Cache, pConfig);
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrStep", DeployStep_Finished);
|
|
|
+ pConfig->WriteConfigValueInt("TerminalDeploy", "CurrState", DEPLOYSTATE_DONE);
|
|
|
+ CSimpleStringA strRootCfgPath;
|
|
|
+ ec = GetFunction()->GetPath("HardwareCfg", strRootCfgPath);
|
|
|
+ CSimpleStringA strRootIniFullPath(strRootCfgPath.GetData());
|
|
|
+ strRootIniFullPath += SPLIT_SLASH_STR;
|
|
|
+ strRootIniFullPath += "root.ini";
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ result = Error_MisMatched;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ ctx->Answer(result);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
bool CHealthManagerEntity::IsTestMode()
|
|
|
{
|
|
|
static int flag = -1;
|