#include "sp_httpDefine.h" #include "sp_cfg.h" #include "json/json.h" #include #include "SpBase.h" #include #include #include #include #include #include #include "SpUtility.h" //#include "cpp-httplib/httplib.h" #define QUERY_TERMINAL_MAX_WAIT_TIME 10000 std::string trim(const std::string& str) { size_t first = str.find_first_not_of(' '); size_t last = str.find_last_not_of(' '); // 如果字符串全是空白字符或为空,则返回空字符串 if (first == std::string::npos || last == std::string::npos || first > last) { return ""; } return str.substr(first, (last - first + 1)); } CAutoArray generateUrlArr(CSimpleString url, CSimpleString appendStr) { auto urlArr = url.Split('|'); for (int i = 0; i < urlArr.GetCount(); i++) urlArr[i].Append(appendStr); return urlArr; } bool VTMErrMsgCfgRet::Parse(string strData) { Json::Value root; Json::Reader reader; reader.parse(strData, root, false); if (root["code"].isString()) { std::string return_code = root["code"].asString(); if (return_code != "SUC0000") DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet Failed , code:%s", return_code.c_str()); } do { //judge success if (root["success"].isBool()) { m_result = root["success"].asBool(); if (root["error_msg"].isString()) error_msg = root["error_msg"].asString(); if (!m_result) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::success False"); break; } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::success not bool"); break; } //judge data if (!root[TOTALCONFIG_HEAD].isObject()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::data not object"); break; } auto json_data = root[TOTALCONFIG_HEAD]; //get total if (json_data[VTMERRMSG_CONFIG_TOTAL].isInt()) total = json_data[VTMERRMSG_CONFIG_TOTAL].asInt(); else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::data::%s not int", VTMERRMSG_CONFIG_TOTAL); break; } //get version_no if (json_data[VTMERRMSG_CONFIG_VERSION].isString()) version_no = json_data[VTMERRMSG_CONFIG_VERSION].asString(); else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::data::%s not string", VTMERRMSG_CONFIG_VERSION); break; } //get page_total if (json_data[VTMERRMSG_CONFIG_PAGETOTAL].isInt()) page_total = json_data[VTMERRMSG_CONFIG_PAGETOTAL].asInt(); else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::data::%s not int", VTMERRMSG_CONFIG_PAGETOTAL); break; } if (!json_data[VTMERRMSG_CONFIG_CONFIG].isArray()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get VTMErrMsgCfgRet::data::%s not array", VTMERRMSG_CONFIG_CONFIG); break; } //parse config auto vtmerrmsg_config = json_data[VTMERRMSG_CONFIG_CONFIG]; for (Json::Value::ArrayIndex i = 0; i != vtmerrmsg_config.size(); i++) { std::string errorCode = vtmerrmsg_config[i][VTMERRMSG_CONFIG_ERRORCODE].asString(); std::string description = vtmerrmsg_config[i][VTMERRMSG_CONFIG_DESCRIPETION].asString(); std::string remark = vtmerrmsg_config[i][VTMERRMSG_CONFIG_REMARK].asString(); errorCodeArr.push_back(errorCode); descriptionArr.push_back(description); remarkArr.push_back(remark); } return true; } while (false); return false; } bool TerminalCfgRet::Parse(string strData) { Json::Value root; Json::Reader reader; reader.parse(strData, root, false); if (root["code"].isString()) { std::string return_code = root["code"].asString(); if (return_code != "SUC0000") DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get RootCfgRet Failed , code:%s", return_code.c_str()); } do { //judge success if (root["success"].isBool()) { m_result = root["success"].asBool(); if (!m_result) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::success False"); break; } } else { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::success not bool"); break; } //judge data if (!root[TOTALCONFIG_HEAD].isObject()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data not object"); break; } auto json_data = root[TOTALCONFIG_HEAD]; if (!json_data[TOTALCONFIG_CENTER_HEAD].isObject()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::%s not object", TOTALCONFIG_CENTER_HEAD); break; } if (!json_data[TOTALCONFIG_ROOT_HEAD].isObject()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::%s not object", TOTALCONFIG_ROOT_HEAD); break; } if (!json_data[TOTALCONFIG_SHELL_HEAD].isObject()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::%s not object", TOTALCONFIG_SHELL_HEAD); break; } //parse center_config auto terminal_config = json_data[TOTALCONFIG_CENTER_HEAD]; if (!terminal_config[TOTALCONFIG_CENTER_UPDATE].isBool()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::center_config_dto::update not Bool"); break; } if (!terminal_config[TOTALCONFIG_CENTER_RESET].isBool()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::center_config_dto::reset not Bool"); break; } center_update = terminal_config[TOTALCONFIG_CENTER_UPDATE].asBool(); center_reset = terminal_config[TOTALCONFIG_CENTER_RESET].asBool(); //只有有center_update时才进行解析 if (center_update) { if (!terminal_config[TOTALCONFIG_CENTER_VERSION].isString()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::center_config_dto::sm3 not string"); break; } if (!terminal_config[TOTALCONFIG_CONFIG_HEAD].isArray()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::center_config_dto::config not array"); break; } center_version = terminal_config[TOTALCONFIG_CENTER_VERSION].asString(); auto tmp_center_config = terminal_config[TOTALCONFIG_CONFIG_HEAD]; for (Json::Value::ArrayIndex i = 0; i != tmp_center_config.size(); i++) { std::string module = tmp_center_config[i][TOTALCONFIG_CONFIG_MODULE].asString(); std::string name = tmp_center_config[i][TOTALCONFIG_CONFIG_NAME].asString(); std::string value = tmp_center_config[i][TOTALCONFIG_CONFIG_VALUE].asString(); if (center_config.find(module) == center_config.end()) center_config.insert(std::make_pair(module, std::map())); center_config[module][name] = value; } } //parse root_config auto root_config_json = json_data[TOTALCONFIG_ROOT_HEAD]; if (!root_config_json[TOTALCONFIG_ROOT_UPDATE].isBool()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::root_config_dto::update not Bool"); break; } root_update = root_config_json[TOTALCONFIG_ROOT_UPDATE].asBool(); if (root_update)//坑爹啊,竟然说这个root_update==false就是终端没有上收 { if (!root_config_json[TOTALCONFIG_ROOT_VERSION].isString()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::root_config_dto::version_no not string"); break; } if (!root_config_json[TOTALCONFIG_CONFIG_HEAD].isArray()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::root_config_dto::config not array"); break; } root_version = root_config_json[TOTALCONFIG_ROOT_VERSION].asString(); auto tmp_root_config = root_config_json[TOTALCONFIG_CONFIG_HEAD]; for (Json::Value::ArrayIndex i = 0; i != tmp_root_config.size(); i++) { std::string module = tmp_root_config[i][TOTALCONFIG_CONFIG_MODULE].asString(); std::string name = tmp_root_config[i][TOTALCONFIG_CONFIG_NAME].asString(); std::string value = tmp_root_config[i][TOTALCONFIG_CONFIG_VALUE].asString(); if (root_config.find(module) == root_config.end()) root_config.insert(std::make_pair(module, std::map())); root_config[module][name] = value; } } //parse shell_config auto shell_config_json = json_data[TOTALCONFIG_SHELL_HEAD]; if (!shell_config_json[TOTALCONFIG_SHELL_UPDATE].isBool()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::shell_config_dto::update not Bool"); break; } shell_update = shell_config_json[TOTALCONFIG_SHELL_UPDATE].asBool(); if (shell_update) { if(!shell_config_json[TOTALCONFIG_SHELL_VERSION].isString()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::shell_config_dto::version_no not string"); break; } if (!shell_config_json[TOTALCONFIG_CONFIG_HEAD].isArray()) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("get TerminalCfgRet::data::shell_config_dto::config not string"); break; } shell_version = shell_config_json[TOTALCONFIG_SHELL_VERSION].asString(); auto tmp_shell_config = shell_config_json[TOTALCONFIG_CONFIG_HEAD]; for (Json::Value::ArrayIndex i = 0; i != tmp_shell_config.size(); i++) { std::string module = tmp_shell_config[i][TOTALCONFIG_CONFIG_MODULE].asString(); std::string name = tmp_shell_config[i][TOTALCONFIG_CONFIG_NAME].asString(); std::string value = tmp_shell_config[i][TOTALCONFIG_CONFIG_VALUE].asString(); if (shell_config.find(module) == shell_config.end()) shell_config.insert(std::make_pair(module, std::map())); shell_config[module][name] = value; } } return true; } while (false); return false; } std::pair VTMErrMsgCfgRet::saveVTMErrToFile(const std::string fileName) { // 转换为Json::Value Json::Value root; Json::Value config; for (int i = 0; i < errorCodeArr.size(); i++) { Json::Value error; error[VTMERRMSG_CONFIG_ERRORCODE] = errorCodeArr[i]; error[VTMERRMSG_CONFIG_DESCRIPETION] = descriptionArr[i]; error[VTMERRMSG_CONFIG_REMARK] = remarkArr[i]; config.append(error); } root[VTMERRMSG_CONFIG_CONFIG] = config; Json::StyledWriter writer; // 或者 Json::FastWriter writer; std::string output = writer.write(root); std::ofstream outputFile(fileName); if (!outputFile.is_open()) return std::make_pair(false, "file open failed"); outputFile << output; outputFile.close(); return std::make_pair(true, output); } std::string TerminalCfgRet::ConvertMapMapConfigToStr(const std::map>& tmpMap) { // 转换为Json::Value Json::Value jsonMap; std::map>::const_iterator outer_it = tmpMap.begin(); std::map>::const_iterator outer_end = tmpMap.end(); for (; outer_it != outer_end; ++outer_it) { Json::Value innerMap; std::map::const_iterator inner_it = outer_it->second.begin(); std::map::const_iterator inner_end = outer_it->second.end(); for (; inner_it != inner_end; ++inner_it) { innerMap[inner_it->first] = inner_it->second; } jsonMap[outer_it->first] = innerMap; } // 生成std::string Json::StyledWriter writer; // 或者 Json::FastWriter writer; std::string output = writer.write(jsonMap); return output; } bool TerminalCfgRet::saveMapMapToFile(const std::string fileName, const std::map>& tmpMap) { std::ofstream outputFile(fileName); if (!outputFile.is_open()) return false; std::string cur = TerminalCfgRet::ConvertMapMapConfigToStr(tmpMap); /*for test std::map> testConfig; ConvertStrToDeviceConfigMap(cur, testConfig); */ outputFile << cur; outputFile.close(); return true; } string TerminalCfgRet::readStrFromFile(const std::string fileName) { std::ifstream inputFile(fileName); if (!inputFile.is_open()) { return ""; } std::string str((std::istreambuf_iterator(inputFile)), std::istreambuf_iterator()); inputFile.close(); return str; } string VTMErrMsgCfgReq::ToJson() { Json::Value root; root["terminal_no"] = terminal_no; root["page_num"] = page_num; Json::FastWriter writer; std::string json_str = writer.write(root); return json_str; } string TerminalCfgReq::ToJson() { // 创建一个json对象,并把结构体的数据复制到json对象中 Json::Value root; root["terminal_no"] = terminalNo; if (center_version.length() > 0 && center_config.size() > 0) { root["center_version"] = center_version; Json::Value center_sub(Json::arrayValue); for (auto p = center_config.begin(); p != center_config.end(); p++) { for (auto q = p->second.begin(); q != p->second.end(); q++) { Json::Value tmp; tmp["module"] = p->first; tmp["name"] = q->first; tmp["value"] = q->second; center_sub.append(tmp); } } root["center_config"] = center_sub; } if (root_version.length() > 0 && root_config.size() > 0) { root["root_version"] = root_version; Json::Value root_sub(Json::arrayValue); for (auto p = root_config.begin(); p != root_config.end(); p++) { for (auto q = p->second.begin(); q != p->second.end(); q++) { Json::Value tmp; tmp["module"] = p->first; tmp["name"] = q->first; tmp["value"] = q->second; root_sub.append(tmp); } } root["root_config"] = root_sub; } if (shell_version.length() > 0 && shell_config.size() > 0) { root["shell_version"] = root_version; Json::Value shell_sub(Json::arrayValue); for (auto p = shell_config.begin(); p != shell_config.end(); p++) { for (auto q = p->second.begin(); q != p->second.end(); q++) { Json::Value tmp; tmp["module"] = p->first; tmp["name"] = q->first; tmp["value"] = q->second; shell_sub.append(tmp); } } root["shell_config"] = shell_sub; } // 创建一个json写入器,并把json对象转换为字符串 Json::FastWriter writer; std::string json_str = writer.write(root); return json_str; } bool QueryTokenHTTPRet::Parse(std::string strData) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("QueryTokenHTTPRet: data = %s", strData.c_str()); Json::Value root; Json::Reader reader; reader.parse(strData, root); if (root.isNull() || root["data"].isNull()) return false; m_token = root["data"].asString(); return true; } string QueryTokenHTTPReq::ToJson() { CSimpleString businessId_str = CSimpleString::Format("{\"installVersion\":\"%s\",\"terminalNo\":\"%s\"}", installVersion.c_str(), businessId.c_str()); Json::Value root; root["channelId"] = channelId; root["clientSecret"] = tokenSecret; root["businessId"] = businessId_str.GetData(); Json::FastWriter writer; std::string json_str = writer.write(root); //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("QueryTokenHTTPReq:%s", json_str.c_str()); return json_str; } string TerminalVerUpdateReq::ToJson() { Json::Value root; root["terminal_no"] = terminal_no; root["center_config_version"] = center_config_version; root["root_config_version"] = root_config_version; root["terminal_update_time"] = terminal_update_time; root["shell_config_version"] = shell_config_version; Json::FastWriter writer; std::string json_str = writer.write(root); return json_str; } bool TerminalVerUpdateRet::Parse(string strData) { Json::Value root; Json::Reader reader; reader.parse(strData, root, false); if (root["code"].isString()) { std::string t_code = root["code"].asString(); if (t_code != "SUC0000") DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("Can not get TerminalVerUpdateRet info , code:%d, data:%s", t_code.c_str(), strData.c_str()); } if (root["success"].isBool()) m_result = root["success"].asBool(); return m_result; } DWORD getTerminalCfgInfoThread(LPVOID param) { TerminalCfgReq* req = (TerminalCfgReq*)param; IHttpFunc* http_client = create_http(LogCallback); if (http_client != NULL) { PROCESS_LINK_CONTEXT("LR0402000GetTerminalCfg") bool ret = http_client->Post(*req, req->ret, &nextLink); http_client->Destory(); if (!ret) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("getTerminalCfgInfoThread failed, url:%s, terminalNo:%s, center_version:%s, root_version:%s", req->m_url.c_str(), req->terminalNo.c_str(), req->center_version.c_str(), req->root_version.c_str()); else return req->ret.m_result ? 0 : -1; } Sleep(QUERY_TERMINAL_MAX_WAIT_TIME);//触发timeout return -1; } DWORD getVTMErrMsgCfgInfoThread(LPVOID param) { VTMErrMsgCfgReq* req = (VTMErrMsgCfgReq*)param; IHttpFunc* http_client = create_http(LogCallback); if (http_client != NULL) { PROCESS_LINK_CONTEXT("LR0402000GetVTMErrCfg") bool ret = http_client->Post(*req, req->ret, &nextLink); http_client->Destory(); if (!ret) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("getVTMErrMsgCfgInfoThread failed, url:%s, terminalNo:%s, page_num:%d", req->m_url.c_str(), req->terminal_no.c_str(), req->page_num); else return req->ret.m_result ? 0 : -1; } Sleep(QUERY_TERMINAL_MAX_WAIT_TIME);//触发timeout return -1; } DWORD getTokenThread(LPVOID param) { QueryTokenHTTPReq* req = (QueryTokenHTTPReq*)param; IHttpFunc* http_client = create_http(LogCallback); if (http_client != NULL) { PROCESS_LINK_CONTEXT("LR0402000GetToken") bool ret = http_client->Post(*req, req->ret, &nextLink); http_client->Destory(); if (ret && req->ret.m_token.length() > 0) { //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM)("update token success"/*, req->ret.m_token.c_str()*/); //DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM)("update token success, %s", req->ret.m_token.c_str()); return 0; } else { Sleep(10000);//触发timeout return -1; } } Sleep(10000);//触发timeout return -1; } std::pair refreshToken(std::string terminalNo, std::string installVersion,std::string channelId, std::string tokenSecret, std::string commonUrl) { //只要调用这个接口,就会获取新的token //判断是否应该刷新,在其他逻辑中判断 CSimpleString tmpUrl = commonUrl.c_str(); auto urlArr = tmpUrl.Split('|'); static std::vector reqArr;//避免函数结束被析构 reqArr.clear(); for (int i = 0; i < urlArr.GetCount(); i++) { CSimpleString curUrl = urlArr[i]; if (curUrl.GetLength() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("QueryToken error, pos:%d, %s", i, tmpUrl.GetData()); continue; } QueryTokenHTTPReq req; req.channelId = channelId; req.tokenSecret = tokenSecret; req.businessId = terminalNo; req.installVersion = installVersion; req.m_url = curUrl.GetData(); req.m_url.append("/api/auth/v2/token"); req.m_headers.emplace(std::make_pair("Content-Type", "application/json")); reqArr.emplace_back(req); } std::vector threadArr;//创建多个线程获取token for (int i = 0; i < reqArr.size(); i++) threadArr.push_back(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&getTokenThread, &(reqArr[i]), 0, NULL)); bool t_isGetTokenSuccess = false; auto tokenRet = WaitForMultipleObjects(threadArr.size(), threadArr.data(), false, 10000); if (tokenRet >= WAIT_OBJECT_0 && tokenRet <= WAIT_OBJECT_0 + threadArr.size()) { DWORD exitCode = INT_MAX; GetExitCodeThread(threadArr[tokenRet - WAIT_OBJECT_0], &exitCode); if (exitCode == 0) { t_isGetTokenSuccess = true; //DbgWithLink(LOG_LEVEL_INFO, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("total getToken success from url %s", reqArr[tokenRet - WAIT_OBJECT_0].m_url.c_str()); //Token_Save::channelId = channelId.c_str(); //Token_Save::token = reqArr[tokenRet - WAIT_OBJECT_0].ret.m_token; return std::make_pair(true, reqArr[tokenRet - WAIT_OBJECT_0].ret.m_token); } } LogWarn(Severity_Low, Error_Bug, GET_TOKEN_ERR, "total getToken failed"); return std::make_pair(false, ""); } std::pair GetVTMErrMsgCfgFromUrl(CSimpleString url, const std::string& t_terminalNo) { bool ret = false; VTMErrMsgCfgRet dst; std::string rightUrl; auto urlArr = generateUrlArr(url, "/api/unify/config/query/error"); if (urlArr.GetCount() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetTerminalCfgFromUrl::urlArr is null"); return std::make_pair(false, dst); } static std::vector reqArr; reqArr.clear(); //每次需清理,避免多次范文 std::string terminalNo = trim(t_terminalNo); for (int i = 0; i < urlArr.GetCount(); i++) { auto curUrl = urlArr[i]; if (curUrl.GetLength() == 0 || terminalNo.length() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetVTMErrMsgCfgFromUrl::urlArr may be wrong, pos:%d, %s", i, url.GetData()); continue; } VTMErrMsgCfgReq req; req.m_url = curUrl; req.terminal_no = terminalNo; req.page_num = 1;//the first time ,get the first page of VTM err msg list. req.m_timeOut = QUERY_TERMINAL_MAX_WAIT_TIME; reqArr.push_back(req); } std::vector threadArr;//创建多个线程访问 for (int i = 0; i < reqArr.size(); i++) threadArr.push_back(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&getVTMErrMsgCfgInfoThread, &(reqArr[i]), 0, NULL)); auto grayRet = WaitForMultipleObjects(threadArr.size(), threadArr.data(), false, QUERY_TERMINAL_MAX_WAIT_TIME); if (grayRet >= WAIT_OBJECT_0 && grayRet <= WAIT_OBJECT_0 + threadArr.size()) { DWORD exitCode = INT_MAX; GetExitCodeThread(threadArr[grayRet - WAIT_OBJECT_0], &exitCode); if (exitCode == 0) { ret = true; dst = reqArr[grayRet - WAIT_OBJECT_0].ret; rightUrl = reqArr[grayRet - WAIT_OBJECT_0].m_url; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetVTMErrMsgCfgFromUrl success from url %s", reqArr[grayRet - WAIT_OBJECT_0].m_url.c_str()); } } for (auto it = threadArr.begin(); it != threadArr.end(); it++) CloseHandle(*it); //after first time get page 2, then get the other pages for (int i = 2; i <= dst.page_total; i++) { VTMErrMsgCfgReq req; req.m_url = rightUrl; req.terminal_no = terminalNo; req.page_num = i; req.m_timeOut = QUERY_TERMINAL_MAX_WAIT_TIME; IHttpFunc* http_client = create_http(LogCallback); if (http_client != NULL) { PROCESS_LINK_CONTEXT("LR0402000GetVTMErrCfg") ret = http_client->Post(req, req.ret, &nextLink); http_client->Destory(); if (!ret) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("getVTMErrMsgCfgInfoThread failed, url:%s, terminalNo:%s, page_num:%d", req.m_url.c_str(), req.terminal_no.c_str(), req.page_num); break; } dst.descriptionArr.insert(dst.descriptionArr.end(), req.ret.descriptionArr.begin(), req.ret.descriptionArr.end()); dst.errorCodeArr.insert(dst.errorCodeArr.end(), req.ret.errorCodeArr.begin(), req.ret.errorCodeArr.end()); dst.remarkArr.insert(dst.remarkArr.end(), req.ret.remarkArr.begin(), req.ret.remarkArr.end()); } } return std::make_pair(ret, dst); } std::pair GetTerminalCfgFromUrl(CSimpleString url, const std::string& t_terminalNo, const std::string& center_version, const std::string& root_version, const std::string& shell_version, const std::map>& tmp_centerConfig, const std::map>& tmp_rootConfig, const std::map>& tmd_shellConfig) { bool ret = false; TerminalCfgRet dst; auto urlArr = generateUrlArr(url, "/api/unify/config/query"); if (urlArr.GetCount() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetTerminalCfgFromUrl::urlArr is null"); return std::make_pair(false, dst); } static std::vector reqArr; reqArr.clear(); //每次需清理,避免多次范文 std::string terminalNo = trim(t_terminalNo); for (int i = 0; i < urlArr.GetCount(); i++) { auto curUrl = urlArr[i]; if (curUrl.GetLength() == 0 || terminalNo.length() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetTerminalCfgFromUrl::urlArr may be wrong, pos:%d, url:%s, terminalNo:%s", i, url.GetData(), terminalNo.c_str()); continue; } TerminalCfgReq req; req.m_url = curUrl; req.terminalNo = terminalNo; req.center_version = center_version; req.root_version = root_version; req.shell_version = shell_version; req.center_config = tmp_centerConfig; req.root_config = tmp_rootConfig; req.shell_config = tmd_shellConfig; req.m_timeOut = QUERY_TERMINAL_MAX_WAIT_TIME; reqArr.emplace_back(req); } std::vector threadArr;//创建多个线程访问 for (int i = 0; i < reqArr.size(); i++) threadArr.push_back(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&getTerminalCfgInfoThread, &(reqArr[i]), 0, NULL)); auto grayRet = WaitForMultipleObjects(threadArr.size(), threadArr.data(), false, QUERY_TERMINAL_MAX_WAIT_TIME); if (grayRet >= WAIT_OBJECT_0 && grayRet <= WAIT_OBJECT_0 + threadArr.size()) { DWORD exitCode = INT_MAX; GetExitCodeThread(threadArr[grayRet - WAIT_OBJECT_0], &exitCode); if (exitCode == 0) { ret = true; dst = reqArr[grayRet - WAIT_OBJECT_0].ret; DbgWithLink(LOG_LEVEL_DEBUG, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("GetTerminalCfgFromUrl success from url %s, update:%d", reqArr[grayRet - WAIT_OBJECT_0].m_url.c_str(), dst.update); } } for(auto it = threadArr.begin(); it != threadArr.end(); it++) CloseHandle(*it); return std::make_pair(ret, dst); } DWORD uploadTerminalVersionThread(LPVOID param) { TerminalVerUpdateReq* req = (TerminalVerUpdateReq*)param; TerminalVerUpdateRet dst; IHttpFunc* http_client = create_http(LogCallback); if (http_client != NULL) { PROCESS_LINK_CONTEXT("LR0402000UploadTerminalVersion") bool ret = http_client->Post(*req, dst, &nextLink); http_client->Destory(); if (!ret) DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("uplaodTerminalVersionThread failed, url:%s, terminalNo:%s, rootVer:%s, centerVer:%s", req->m_url.c_str(), req->terminal_no.c_str(), req->root_config_version.c_str(), req->center_config_version.c_str()); else return dst.m_result ? 0 : -1; } Sleep(QUERY_TERMINAL_MAX_WAIT_TIME);//触发timeout return -1; } bool UploadTerminalVersionFromUrl(CSimpleString url, std::string t_terminalNo, std::string center_config_version, std::string root_config_version, std::string shell_config_version) { bool ret = false; auto urlArr = generateUrlArr(url, "/api/unify/config/add/version"); if (urlArr.GetCount() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("UploadTerminalVersionFromUrl::urlArr is null"); return false; } static std::vector reqArr; reqArr.clear(); //每次需清理,避免多次 auto getTimeStr = []() -> std::string { std::time_t now = std::time(nullptr); std::tm local_time = *std::localtime(&now); // 将时间格式化为字符串 std::ostringstream oss; oss << std::put_time(&local_time, "%Y-%m-%d %H:%M:%S"); std::string local_time_str = oss.str(); return local_time_str; }; std::string terminalNo = trim(t_terminalNo); for (int i = 0; i < urlArr.GetCount(); i++) { auto curUrl = urlArr[i]; if (curUrl.GetLength() == 0 || terminalNo.length() == 0) { DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("UploadTerminalVersionFromUrl::urlArr may be wrong, pos:%d, %s", i, url.GetData()); continue; } TerminalVerUpdateReq req; req.m_url = curUrl; req.terminal_no = terminalNo; req.center_config_version = center_config_version; req.root_config_version = root_config_version; req.shell_config_version = shell_config_version; req.terminal_update_time = getTimeStr(); reqArr.emplace_back(req); } std::vector threadArr;//创建多个线程访问 for (int i = 0; i < reqArr.size(); i++) threadArr.push_back(CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&uploadTerminalVersionThread, &(reqArr[i]), 0, NULL)); auto grayRet = WaitForMultipleObjects(threadArr.size(), threadArr.data(), false, QUERY_TERMINAL_MAX_WAIT_TIME); if (grayRet >= WAIT_OBJECT_0 && grayRet <= WAIT_OBJECT_0 + threadArr.size()) { DWORD exitCode = INT_MAX; GetExitCodeThread(threadArr[grayRet - WAIT_OBJECT_0], &exitCode); if (exitCode == 0) { ret = true; DbgWithLink(LOG_LEVEL_WARN, LOG_TYPE_SYSTEM).setAPI(__FUNCTION__)("UploadTerminalVersionFromUrl success from url %s", reqArr[grayRet - WAIT_OBJECT_0].m_url.c_str()); } } for (auto it = threadArr.begin(); it != threadArr.end(); it++) CloseHandle(*it); return ret; } int ConvertStrToVTMErrMsg(std::string input, CAutoArray& strErrorCodeArr , CAutoArray& strDescriptionArr, CAutoArray& strRemarkArr) { // 解析为Json::Value Json::Reader reader; Json::Value jsonValue; bool success = reader.parse(input, jsonValue); if (!success) return Error_Param; if (!jsonValue[VTMERRMSG_CONFIG_CONFIG].isArray()) return Error_NotSupport; const Json::Value &config = jsonValue[VTMERRMSG_CONFIG_CONFIG]; std::vector errorCodeArr, descriptionArr, remarkArr; for (auto it = config.begin(); it != config.end(); it++) { CSimpleString errorCode = (*it)[VTMERRMSG_CONFIG_ERRORCODE].asString().c_str(); CSimpleString description = (*it)[VTMERRMSG_CONFIG_DESCRIPETION].asString().c_str(); CSimpleString remark = SP::Utility::ToLower((*it)[VTMERRMSG_CONFIG_REMARK].asString()).c_str(); errorCodeArr.push_back(errorCode); descriptionArr.push_back(description); remarkArr.push_back(remark); } strErrorCodeArr.Init(errorCodeArr.size()); strDescriptionArr.Init(errorCodeArr.size()); strRemarkArr.Init(errorCodeArr.size()); for (int i = 0; i < errorCodeArr.size(); i++) { strErrorCodeArr[i] = errorCodeArr[i]; strDescriptionArr[i] = descriptionArr[i]; strRemarkArr[i] = remarkArr[i]; } return Error_Succeed; } std::pair ConvertStrToDeviceConfigMap(std::string input, std::map>& m_deviceConfig) { // 解析为Json::Value Json::Reader reader; Json::Value jsonValue; bool success = reader.parse(input, jsonValue); if (!success) return std::make_pair(false, CSimpleStringA::Format("ConvertStrToDeviceConfig Failed to parse input: %s", reader.getFormattedErrorMessages().c_str()).GetData()); // 转换为std::map m_deviceConfig.clear(); Json::Value::Members outer_members = jsonValue.getMemberNames(); for (Json::Value::Members::iterator outer_it = outer_members.begin(); outer_it != outer_members.end(); ++outer_it) { const std::string& outer_key = *outer_it; const Json::Value& inner_value = jsonValue[outer_key]; std::map inner_map; Json::Value::Members inner_members = inner_value.getMemberNames(); for (Json::Value::Members::iterator inner_it = inner_members.begin(); inner_it != inner_members.end(); ++inner_it) { const std::string& inner_key = *inner_it; const std::string& inner_value = jsonValue[outer_key][inner_key].asString(); inner_map.insert(std::make_pair(inner_key, inner_value)); } m_deviceConfig.insert(std::make_pair(outer_key, inner_map)); } // 输出结果 return std::make_pair(true, ""); } /* std::pair readTerminalNo_byHttpServer() { httplib::Server server; std::string terminalNo; server.Post("/set_terminal", (httplib::Server::Handler)[&](const httplib::Request& req, httplib::Response& res) { if (req.headers.find("Content-Type") != req.headers.end() && req.headers.find("Content-Type")->second == "application/json") { // Parse JSON payload terminalNo = req.body.c_str(); server.stop(); return; } // Respond with an error if parsing or validation fails res.status = 400; res.set_content("Invalid JSON or missing terminalNo", "text/plain"); }); server.listen("0.0.0.0", 8080); return std::make_pair(true, terminalNo); } */