#pragma once //用于定义实现一些模拟器通用的函数功能 #include #include #include #include #include #include #include #include #include "DeviceBaseClass.h" #include "path.h" #include "json/json.h" #include "CommSimulatorRestful.hpp" #include "RestfulFunc.h" #ifdef _MSC_VER #include #include #include #define FindLibName "cmblog4vendor.dll" #else #include #include //ntohl #include // Linux系统中 #include #include #include #include #include #include #include #endif using namespace std; #define DEFAULT_DATA_URL "http://emulatoruser.paasuat.cmbchina.cn/emulator/avs/retrieveEmulatorData" //获取模拟器库文件所在目录 string GetCurrentDirectory() { #ifdef _MSC_VER HMODULE hModule = GetModuleHandle(FindLibName); char path[MAX_PATH]; GetModuleFileName(hModule, path, MAX_PATH); string fullPath(path); size_t pos = fullPath.find_last_of("\\/"); return fullPath.substr(0, pos); #else Dl_info dlInfo; dladdr((void*)GetCurrentDirectory, &dlInfo); char* path = realpath(dlInfo.dli_fname, NULL); string fullPath(path); free(path); size_t pos = fullPath.find_last_of("/"); return fullPath.substr(0, pos); #endif } //读取配置文件功能类 class iniReader { public: iniReader() { } ~iniReader() { } bool ReadConfig(const string& filename) { settings_.clear(); ifstream infile(filename.c_str());//构造默认调用open,所以可以不调用open //ifstream infile; //infile.open(filename.c_str()); //bool ret = infile.is_open() if (!infile) { return false; } string line, key, value, section; map k_v; map >::iterator it; while (getline(infile, line)) { if (AnalyseLine(line, section, key, value)) { it = settings_.find(section); if (it != settings_.end()) { k_v[key] = value; it->second = k_v; } else { k_v.clear(); settings_.insert(make_pair(section, k_v)); } } key.clear(); value.clear(); } infile.close(); return true; } string ReadString(const char* section, const char* item, const char* default_value) { string tmp_s(section); string tmp_i(item); string def(default_value); map k_v; map::iterator it_item; map >::iterator it; it = settings_.find(tmp_s); if (it == settings_.end()) { //printf("111"); return def; } k_v = it->second; it_item = k_v.find(tmp_i); if (it_item == k_v.end()) { //printf("222"); return def; } return it_item->second; } int ReadInt(const char* section, const char* item, const int& default_value) { string tmp_s(section); string tmp_i(item); map k_v; map::iterator it_item; map >::iterator it; it = settings_.find(tmp_s); if (it == settings_.end()) { return default_value; } k_v = it->second; it_item = k_v.find(tmp_i); if (it_item == k_v.end()) { return default_value; } return atoi(it_item->second.c_str()); } float ReadFloat(const char* section, const char* item, const float& default_value) { string tmp_s(section); string tmp_i(item); map k_v; map::iterator it_item; map >::iterator it; it = settings_.find(tmp_s); if (it == settings_.end()) { return default_value; } k_v = it->second; it_item = k_v.find(tmp_i); if (it_item == k_v.end()) { return default_value; } return atof(it_item->second.c_str()); } private: bool IsSpace(char c) { if (' ' == c || '\t' == c) return true; return false; } bool IsCommentChar(char c) { switch (c) { case '#': return true; default: return false; } } void Trim(string& str) { if (str.empty()) { return; } int i, start_pos, end_pos; for (i = 0; i < str.size(); ++i) { if (!IsSpace(str[i])) { break; } } if (i == str.size()) { str = ""; return; } start_pos = i; for (i = str.size() - 1; i >= 0; --i) { if (!IsSpace(str[i])) { break; } } end_pos = i; str = str.substr(start_pos, end_pos - start_pos + 1); } bool AnalyseLine(const string& line, string& section, string& key, string& value) { if (line.empty()) return false; int start_pos = 0, end_pos = line.size() - 1, pos, s_startpos, s_endpos; if ((pos = line.find("#")) != -1) { if (0 == pos) { return false; } end_pos = pos - 1; } if (((s_startpos = line.find("[")) != -1) && ((s_endpos = line.find("]"))) != -1) { section = line.substr(s_startpos + 1, s_endpos - 1); return true; } string new_line = line.substr(start_pos, start_pos + 1 - end_pos); if ((pos = new_line.find('=')) == -1) return false; key = new_line.substr(0, pos); value = new_line.substr(pos + 1, end_pos + 1 - (pos + 1)); Trim(key); if (key.empty()) { return false; } Trim(value); if ((pos = value.find("\r")) > 0) { value.replace(pos, 1, ""); } if ((pos = value.find("\n")) > 0) { value.replace(pos, 1, ""); } return true; } private: //map settings_; map >settings_; }; //获取硬件模拟器数据服务地址 string GetSimulatorUrl() { string depCfgPath = GetCurrentDirectory() + SPLIT_SLASH_STR + "cmbsz.ini"; iniReader iniRead; bool ret = iniRead.ReadConfig(depCfgPath); if (!ret) { return DEFAULT_DATA_URL; } string urlStr = iniRead.ReadString("server", "url", ""); if (urlStr.length() <= 0) { urlStr = DEFAULT_DATA_URL; } return urlStr; } //读取本地IP功能函数 string GetLocalIP() { #ifdef _MSC_VER hostent* ent = gethostbyname(NULL); if (ent && ent->h_addr_list[0] != NULL) { int i = 0; for (; ent->h_addr_list[i] != NULL; ++i) { struct in_addr* in = (struct in_addr*)ent->h_addr_list[i]; if (in->S_un.S_un_b.s_b1 == 99 || in->S_un.S_un_b.s_b1 == 10) break; } if (ent->h_addr_list[i] == NULL) i = 0; auto in = (struct in_addr*)ent->h_addr_list[i]; char xIP[64] = {}; sprintf(xIP, "%d.%d.%d.%d", in->S_un.S_un_b.s_b1, in->S_un.S_un_b.s_b2, in->S_un.S_un_b.s_b3, in->S_un.S_un_b.s_b4); //LOG4VTM(INFO, ("ip:%s", xIP)); return string(xIP); } return ""; #else string re = ""; int sfd, intr; struct ifreq buf[16]; struct ifconf ifc; sfd = socket(AF_INET, SOCK_DGRAM, 0); if (sfd < 0) return "wrong 1: get ip socket failed"; ifc.ifc_len = sizeof(buf); ifc.ifc_buf = (caddr_t)buf; if (ioctl(sfd, SIOCGIFCONF, (char*)&ifc)) return "wrong 2: get ip ioctl failed"; intr = ifc.ifc_len / sizeof(struct ifreq); while (intr-- > 0 && ioctl(sfd, SIOCGIFADDR, (char*)&buf[intr])); close(sfd); unsigned long ip = ntohl(((struct sockaddr_in*)(&buf[intr].ifr_addr))->sin_addr.s_addr); //TODO: 不用delete ??? [Gifur@202585] char* str = new char[1024]; sprintf(str, "%u.%u.%u.%u", ip >> 24 & 0xFF, ip >> 16 & 0xFF, ip >> 8 & 0xFF, ip >> 0 & 0xFF); re = str; return re; #endif } ///////////////以下为模拟器通用http访问实现//////////////////// typedef struct SimulatorCommonReq { string ip; string entityName; string adapterInterName; JSONCONVERT2OBJECT_MEMEBER_REGISTER(ip, entityName, adapterInterName) }SimulatorCommonReq; typedef struct SimulatorDevCategoryAns { int errNum; string szType; //device type sth like "CMB.Printer.HP1234" string szModel; //device model string szVendor; //device vendor int eState; //device status struct DevSoftVersion { int wMajor; //release major version int wMinor; //release minor version int wRevision; //bug repair version with the major and minor version remains the same int wBuild; //compile version JSONCONVERT2OBJECT_MEMEBER_REGISTER(wMajor, wMinor, wRevision, wBuild) }version; //software version JSONCONVERT2OBJECT_MEMEBER_REGISTER(errNum, szType, szModel, szVendor, eState, version) }SimulatorDevCategoryAns; typedef struct SimulatorDevErrInfoAns { int errNum; int dwErrMsgLen; string szErrMsg; JSONCONVERT2OBJECT_MEMEBER_REGISTER(errNum, dwErrMsgLen, szErrMsg) }SimulatorDevErrInfoAns; ErrorCodeEnum SimulatorHttpFunction(string entityName, string devFuncName) { ErrorCodeEnum err = Error_NotImpl; SimulatorCommonReq simulatorCommonReq; simulatorCommonReq.ip = GetLocalIP(); simulatorCommonReq.entityName = entityName; simulatorCommonReq.adapterInterName = devFuncName; HttpClientResponseResult result; HttpClientRequestConfig config(HttpRequestMethod::POST, GetSimulatorUrl().c_str(), NULL); SP::Simulator::Restful::FulfillRequestJsonBody(&config, simulatorCommonReq); RestfulClient client = RestfulClient::getInstance(); config.PreDo(); config.SetTimeout(125); //访问后台Http目前最高设置延迟是120s,多5秒避免边界情况 client.Do(&config, &result); if (result.ResponseOK()) { SP::Simulator::Restful::CommSimulatorRes commRes; SP::Simulator::Restful::GetStatusFromDebranchResponse(result.content, commRes); err = (ErrorCodeEnum)commRes.errNum; } else { err = Error_NetBroken; } return err; } template ErrorCodeEnum SimulatorHttpFunction(string entityName, string devFuncName, T& obj) { ErrorCodeEnum err = Error_NotImpl; SimulatorCommonReq simulatorCommonReq; simulatorCommonReq.ip = GetLocalIP(); simulatorCommonReq.entityName = entityName; simulatorCommonReq.adapterInterName = devFuncName; HttpClientResponseResult result; HttpClientRequestConfig config(HttpRequestMethod::POST, GetSimulatorUrl().c_str(), NULL); SP::Simulator::Restful::FulfillRequestJsonBody(&config, simulatorCommonReq); RestfulClient client = RestfulClient::getInstance(); config.PreDo(); config.SetTimeout(125); client.Do(&config, &result); if (result.ResponseOK()) { SP::Simulator::Restful::CommSimulatorRes commRes; SP::Simulator::Restful::GetStatusFromDebranchResponse(result.content, commRes); err = (ErrorCodeEnum)commRes.errNum; if (err == Error_Succeed) { bool res = SP::Simulator::Restful::ExtractDataFromDebranchResponse(result.content, obj); //DEBUG if (!res) { err = Error_Bug; } } } else { err = Error_NetBroken; } return err; }