add function:upload and download device file ,modify interface function fix memleak
This commit is contained in:
@@ -322,6 +322,11 @@ std::string Topic_Reply_Topic = "";
|
||||
std::string Topic_Reply_Tag = "";
|
||||
std::string Topic_Reply_Key = "";
|
||||
|
||||
//lnk20260310添加文件管理的topic和tag
|
||||
std::string G_MQCONSUMER_TOPIC_FILE = "";//consumer topie
|
||||
std::string G_MQCONSUMER_TAG_FILE = "";//consumer tag
|
||||
std::string G_MQCONSUMER_KEY_FILE = "";//consumer key
|
||||
|
||||
int G_TEST_FLAG = 0;
|
||||
int G_TEST_NUM = 0;
|
||||
int G_TEST_TYPE = 0;
|
||||
@@ -709,6 +714,16 @@ void init_config() {
|
||||
G_CONNECT_TAG = strdup(ba.data());
|
||||
ba = settings.value("RocketMq/CONNECTKey", "").toString().toLatin1();
|
||||
G_CONNECT_KEY = strdup(ba.data());
|
||||
|
||||
//lnk20260310添加文件管理的topic和tag
|
||||
ba = settings.value("RocketMq/ConsumerTopicFile", "").toString().toLatin1();
|
||||
G_MQCONSUMER_TOPIC_FILE = strdup(ba.data());
|
||||
ba = settings.value("RocketMq/ConsumerTagFile", "").toString().toLatin1();
|
||||
G_MQCONSUMER_TAG_FILE = strdup(ba.data());
|
||||
ba = settings.value("RocketMq/ConsumerKeyFile", "").toString().toLatin1();
|
||||
G_MQCONSUMER_KEY_FILE = strdup(ba.data());
|
||||
|
||||
|
||||
//MQ测试
|
||||
G_TEST_FLAG = settings.value("RocketMq/Testflag", 0).toInt();
|
||||
G_TEST_NUM = settings.value("RocketMq/Testnum", 0).toInt();
|
||||
@@ -3198,8 +3213,21 @@ size_t req_reply_http(void* contents, size_t size, size_t nmemb, void* userp) {
|
||||
}
|
||||
|
||||
void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr) {
|
||||
//【修改点1】先校验 ptr 本身,避免空指针解引用
|
||||
if (ptr == NULL) {
|
||||
printf("SendJsonAPI_web error: ptr is NULL\n");
|
||||
return;
|
||||
}
|
||||
|
||||
//【修改点2】如果上层传进来的 *ptr 非空,先释放并置空,避免旧内存残留
|
||||
if (*ptr != NULL) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
|
||||
CURL* curl = curl_easy_init();
|
||||
CURLcode res;
|
||||
long http_code = 0; //【修改点3】增加 HTTP 状态码
|
||||
|
||||
// 初始化 *ptr 并分配空字符串
|
||||
*ptr = (char*)malloc(1);
|
||||
@@ -3211,8 +3239,8 @@ void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::str
|
||||
|
||||
if (curl) {
|
||||
char url[256];
|
||||
snprintf(url, sizeof(url), "%s?%s", strUrl.c_str(), code);
|
||||
//printf(">>>json %s\n", url);//减少不必要的打印
|
||||
//【修改点5】避免 code 为 NULL 时 snprintf 异常
|
||||
snprintf(url, sizeof(url), "%s?%s", strUrl.c_str(), (code != NULL ? code : ""));
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_http);
|
||||
@@ -3220,6 +3248,9 @@ void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::str
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
|
||||
|
||||
//【修改点6】建议禁用 signal,防止多线程里超时信号影响别的线程
|
||||
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
|
||||
|
||||
if (!json.empty()) {
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
|
||||
@@ -3231,9 +3262,31 @@ void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::str
|
||||
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
//【修改点7】先取 HTTP 状态码
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
if (res != CURLE_OK) {
|
||||
printf("web failed res code: %s\n", curl_easy_strerror(res));
|
||||
} else {
|
||||
}
|
||||
//【修改点9】即使 curl 成功,HTTP 非 200 也按失败处理
|
||||
/*else if (http_code != 200) {
|
||||
printf("web http failed, http_code: %ld\n", http_code);
|
||||
|
||||
if (*ptr != NULL) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
}*/
|
||||
//【修改点10】即使 HTTP 200,但返回内容为空串,也按失败处理
|
||||
else if (*ptr == NULL || (*ptr)[0] == '\0') {
|
||||
printf("web response is empty\n");
|
||||
|
||||
if (*ptr != NULL) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
//printf(">>> web return str: %s \n", *ptr);
|
||||
}
|
||||
|
||||
@@ -3241,70 +3294,14 @@ void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::str
|
||||
curl_easy_cleanup(curl);
|
||||
} else {
|
||||
printf(">>> web curl init failed\n");
|
||||
|
||||
//【修改点11】curl 初始化失败时,也要释放之前分配的空串并置 NULL
|
||||
if (*ptr != NULL) {
|
||||
free(*ptr);
|
||||
*ptr = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
/*void SendJsonAPI_web(const std::string& strUrl, const char* code, const std::string& json, char** ptr) {
|
||||
// curl 初始化
|
||||
CURL* curl = curl_easy_init();
|
||||
CURLcode res;
|
||||
|
||||
if (curl) {
|
||||
char url[100];
|
||||
sprintf(url, "%s?%s", strUrl.c_str(), code);
|
||||
printf(">>>json %s\n", url);
|
||||
|
||||
// 设置 URL
|
||||
curl_easy_setopt(curl, CURLOPT_URL, url);
|
||||
|
||||
// 设置数据接收和写入函数
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_web);
|
||||
|
||||
// 数据接收
|
||||
std::string resPost0;
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void*)&resPost0);
|
||||
|
||||
// 设置超时时间
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 10);
|
||||
|
||||
if(json != ""){
|
||||
// 设置 HTTP 方法为 POST
|
||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
|
||||
// 设置 JSON 格式的 body 数据
|
||||
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
struct curl_slist* headers = NULL;
|
||||
headers = curl_slist_append(headers, "Content-Type: application/json");
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
|
||||
|
||||
// 执行请求
|
||||
res = curl_easy_perform(curl);
|
||||
|
||||
// 检查请求是否成功
|
||||
if (res != CURLE_OK) {
|
||||
printf("web failed res code: %s\n", curl_easy_strerror(res));
|
||||
} else {
|
||||
printf(">>> web return str: %s \n", resPost0.c_str());
|
||||
|
||||
// 分配内存并复制返回结果
|
||||
*ptr = (char*)malloc(resPost0.size() + 1); // 分配足够的内存空间
|
||||
if (*ptr != NULL) {
|
||||
strcpy(*ptr, resPost0.c_str());
|
||||
} else {
|
||||
printf("Memory allocation failed!\n");
|
||||
}
|
||||
}
|
||||
|
||||
// 清理请求头
|
||||
curl_slist_free_all(headers);
|
||||
} else {
|
||||
printf(">>> web curl init failed");
|
||||
}
|
||||
curl_easy_cleanup(curl);
|
||||
}*/
|
||||
|
||||
// 打印 terminal_dev_map 中所有内容的函数
|
||||
void printTerminalDevMap(const QMap<QString, terminal_dev*>& terminal_dev_map) {
|
||||
@@ -3796,90 +3793,23 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
|
||||
cJSON* root = NULL;
|
||||
|
||||
// 发送 API 请求
|
||||
/*SendJsonAPI_web(WEB_DEVICE, "",parm.c_str(), &ptr);
|
||||
|
||||
if (ptr == NULL) {
|
||||
std::cerr << "Error: Received NULL response from SendJsonAPI_web." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 调试用
|
||||
printf("ptr:%s\n", ptr);
|
||||
|
||||
cJSON* root = cJSON_Parse(ptr); //json格式序列化
|
||||
|
||||
int retry = 0;
|
||||
|
||||
if (root == NULL) {
|
||||
printf("web error %s\n", cJSON_GetErrorPtr());
|
||||
|
||||
//重发多次
|
||||
while(root == NULL){
|
||||
// 在重试前释放之前的 ptr 以避免内存泄漏
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
//测试用url参数
|
||||
//SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr);
|
||||
SendJsonAPI_web(WEB_DEVICE, "",parm.c_str(), &ptr);
|
||||
|
||||
if(ptr == NULL){
|
||||
std::cerr << "Error: Received NULL response from SendJsonAPI_web in retry" << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
root = cJSON_Parse(ptr);
|
||||
retry++;
|
||||
if(retry > 3){
|
||||
break;
|
||||
}
|
||||
}
|
||||
// 如果重试后仍然失败,确保退出前释放任何已分配的内存
|
||||
if (root == NULL) {
|
||||
printf("web error after 3 retry\n");
|
||||
//return 1; // 根据需要返回适当的错误码
|
||||
//三次重试过后尝试读取本地台账文件
|
||||
char* ledger = NULL;
|
||||
read_latest_ledger_file(&ledger);
|
||||
if (ledger != NULL) {
|
||||
root = cJSON_Parse(ledger);
|
||||
free(ledger);
|
||||
}
|
||||
|
||||
//记录上送日志
|
||||
|
||||
//读取台账文件也失败则启用定时器5分钟等待下一次读取台账和文件,不要退出死掉
|
||||
if (root == NULL) {
|
||||
printf("read local ledger failed, wait 5 min to retry...\n");
|
||||
apr_sleep(apr_time_from_sec(300)); // 睡眠 5 分钟
|
||||
|
||||
// 重新请求
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
SendJsonAPI_web(WEB_DEVICE, "", parm.c_str(), &ptr);
|
||||
if (ptr != NULL) {
|
||||
root = cJSON_Parse(ptr);
|
||||
if (root == NULL) {
|
||||
printf("still failed after sleep retry\n");
|
||||
return 1;
|
||||
}
|
||||
} else {
|
||||
printf("no response after sleep retry\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
//记录上送日志
|
||||
}
|
||||
}*/
|
||||
while (1) {
|
||||
|
||||
//防止泄露lnk20260312
|
||||
if (root != NULL) {
|
||||
cJSON_Delete(root);
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
// 请求接口
|
||||
SendJsonAPI_web(WEB_DEVICE, "", parm.c_str(), &ptr);
|
||||
|
||||
if (ptr != NULL) {
|
||||
if (ptr != NULL && ptr[0] != '\0') {
|
||||
|
||||
// 调试用
|
||||
printf("ptr:%s\n", ptr);
|
||||
@@ -3909,7 +3839,7 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
}
|
||||
|
||||
// 解析失败,尝试重试
|
||||
printf("web error %s\n", cJSON_GetErrorPtr());
|
||||
//printf("web error %s\n", cJSON_GetErrorPtr());
|
||||
retry++;
|
||||
|
||||
if (retry > 3) {
|
||||
@@ -3922,6 +3852,11 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
}
|
||||
|
||||
// 读取本地台账文件
|
||||
if (root != NULL) {
|
||||
cJSON_Delete(root);
|
||||
root = NULL;
|
||||
}
|
||||
|
||||
char* ledger = NULL;
|
||||
read_latest_ledger_file(&ledger);
|
||||
if (ledger != NULL) {
|
||||
@@ -3959,6 +3894,9 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
retry = 0; // 重置 retry 重新开始循环
|
||||
continue;
|
||||
}
|
||||
|
||||
//每次重试等2秒
|
||||
apr_sleep(apr_time_from_sec(2));
|
||||
}
|
||||
|
||||
// 获取 "code" 和 "msg"
|
||||
@@ -4011,64 +3949,79 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
cJSON* id = cJSON_GetObjectItem(item, "id"); // terminal_id
|
||||
if (id && id->type == cJSON_String) strncpy(dev->terminal_id, id->valuestring, sizeof(dev->terminal_id) - 1);
|
||||
else strncpy(dev->terminal_id, "N/A", sizeof(dev->terminal_id) - 1);
|
||||
dev->terminal_id[sizeof(dev->terminal_id) - 1] = '\0';
|
||||
|
||||
cJSON* ip = cJSON_GetObjectItem(item, "ip"); // addr_str
|
||||
if (ip && ip->type == cJSON_String) strncpy(dev->addr_str, ip->valuestring, sizeof(dev->addr_str) - 1);
|
||||
else strncpy(dev->addr_str, "N/A", sizeof(dev->addr_str) - 1);
|
||||
dev->addr_str[sizeof(dev->addr_str) - 1] = '\0';
|
||||
|
||||
cJSON* terminalCode = cJSON_GetObjectItem(item, "name"); // terminal_code
|
||||
if (terminalCode && terminalCode->type == cJSON_String) strncpy(dev->terminal_code, terminalCode->valuestring, sizeof(dev->terminal_code) - 1);
|
||||
else strncpy(dev->terminal_code, "N/A", sizeof(dev->terminal_code) - 1);
|
||||
dev->terminal_code[sizeof(dev->terminal_code) - 1] = '\0';
|
||||
|
||||
cJSON* orgName = cJSON_GetObjectItem(item, "org_name"); // org_name
|
||||
if (orgName && orgName->type == cJSON_String) strncpy(dev->org_name, orgName->valuestring, sizeof(dev->org_name) - 1);
|
||||
else strncpy(dev->org_name, "N/A", sizeof(dev->org_name) - 1);
|
||||
dev->org_name[sizeof(dev->org_name) - 1] = '\0';
|
||||
|
||||
cJSON* maintName = cJSON_GetObjectItem(item, "maint_name"); // maint_name
|
||||
if (maintName && maintName->type == cJSON_String) strncpy(dev->maint_name, maintName->valuestring, sizeof(dev->maint_name) - 1);
|
||||
else strncpy(dev->maint_name, "N/A", sizeof(dev->maint_name) - 1);
|
||||
dev->maint_name[sizeof(dev->maint_name) - 1] = '\0';
|
||||
|
||||
cJSON* stationName = cJSON_GetObjectItem(item, "stationName"); // station_name
|
||||
if (stationName && stationName->type == cJSON_String) strncpy(dev->station_name, stationName->valuestring, sizeof(dev->station_name) - 1);
|
||||
else strncpy(dev->station_name, "N/A", sizeof(dev->station_name) - 1);
|
||||
dev->station_name[sizeof(dev->station_name) - 1] = '\0';
|
||||
|
||||
cJSON* manufacturer = cJSON_GetObjectItem(item, "manufacturer"); // tmnl_factory
|
||||
if (manufacturer && manufacturer->type == cJSON_String) strncpy(dev->tmnl_factory, manufacturer->valuestring, sizeof(dev->tmnl_factory) - 1);
|
||||
else strncpy(dev->tmnl_factory, "N/A", sizeof(dev->tmnl_factory) - 1);
|
||||
dev->tmnl_factory[sizeof(dev->tmnl_factory) - 1] = '\0';
|
||||
|
||||
cJSON* status = cJSON_GetObjectItem(item, "status"); // tmnl_status
|
||||
if (status && status->type == cJSON_String) strncpy(dev->tmnl_status, status->valuestring, sizeof(dev->tmnl_status) - 1);
|
||||
else strncpy(dev->tmnl_status, "N/A", sizeof(dev->tmnl_status) - 1);
|
||||
dev->tmnl_status[sizeof(dev->tmnl_status) - 1] = '\0';
|
||||
|
||||
cJSON* devType = cJSON_GetObjectItem(item, "devType"); // dev_type
|
||||
if (devType && devType->type == cJSON_String) strncpy(dev->dev_type, devType->valuestring, sizeof(dev->dev_type) - 1);
|
||||
else strncpy(dev->dev_type, "N/A", sizeof(dev->dev_type) - 1);
|
||||
dev->dev_type[sizeof(dev->dev_type) - 1] = '\0';
|
||||
|
||||
cJSON* devKey = cJSON_GetObjectItem(item, "devKey"); // dev_key
|
||||
if (devKey && devKey->type == cJSON_String) strncpy(dev->dev_key, devKey->valuestring, sizeof(dev->dev_key) - 1);
|
||||
else strncpy(dev->dev_key, "N/A", sizeof(dev->dev_key) - 1);
|
||||
dev->dev_key[sizeof(dev->dev_key) - 1] = '\0';
|
||||
|
||||
cJSON* series = cJSON_GetObjectItem(item, "series"); // dev_series
|
||||
if (series && series->type == cJSON_String) strncpy(dev->dev_series, series->valuestring, sizeof(dev->dev_series) - 1);
|
||||
else strncpy(dev->dev_series, "N/A", sizeof(dev->dev_series) - 1);
|
||||
dev->dev_series[sizeof(dev->dev_series) - 1] = '\0';
|
||||
|
||||
//lnk20250210台账进程号
|
||||
cJSON* processNo = cJSON_GetObjectItem(item, "processNo"); // processNo转为字符串
|
||||
if (processNo && processNo->type == cJSON_Number) snprintf(dev->processNo, sizeof(dev->processNo), "%d", processNo->valueint);
|
||||
else strncpy(dev->processNo, "N/A", sizeof(dev->processNo) - 1);
|
||||
dev->processNo[sizeof(dev->processNo) - 1] = '\0';
|
||||
|
||||
//20250513进程数量
|
||||
cJSON* maxProcessNum = cJSON_GetObjectItem(item, "maxProcessNum"); // maxProcessNum转为字符串
|
||||
if (maxProcessNum && maxProcessNum->type == cJSON_Number) snprintf(dev->maxProcessNum, sizeof(dev->maxProcessNum), "%d", maxProcessNum->valueint);
|
||||
else strncpy(dev->maxProcessNum, "N/A", sizeof(dev->maxProcessNum) - 1);
|
||||
dev->maxProcessNum[sizeof(dev->maxProcessNum) - 1] = '\0';
|
||||
|
||||
cJSON* port = cJSON_GetObjectItem(item, "port"); // port
|
||||
if (port && port->type == cJSON_String) strncpy(dev->port, port->valuestring, sizeof(dev->port) - 1);
|
||||
else strncpy(dev->port, "N/A", sizeof(dev->port) - 1);
|
||||
dev->port[sizeof(dev->port) - 1] = '\0';
|
||||
|
||||
cJSON* updateTime = cJSON_GetObjectItem(item, "updateTime"); // timestamp
|
||||
if (updateTime && updateTime->type == cJSON_String) strncpy(dev->timestamp, updateTime->valuestring, sizeof(dev->timestamp) - 1);
|
||||
else strncpy(dev->timestamp, "N/A", sizeof(dev->timestamp) - 1);
|
||||
dev->timestamp[sizeof(dev->timestamp) - 1] = '\0';
|
||||
|
||||
cJSON* logLevel = cJSON_GetObjectItem(item, "log_level"); // log_level
|
||||
int tmp_level = -1;
|
||||
@@ -4100,29 +4053,35 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
cJSON* monitor_id = cJSON_GetObjectItem(monitorItem, "id"); // monitor_id
|
||||
if (monitor_id && monitor_id->type == cJSON_String) strncpy(dev->line[j].monitor_id, monitor_id->valuestring, sizeof(dev->line[j].monitor_id) - 1);
|
||||
else strncpy(dev->line[j].monitor_id, "N/A", sizeof(dev->line[j].monitor_id) - 1);
|
||||
dev->line[j].monitor_id[sizeof(dev->line[j].monitor_id) - 1] = '\0';
|
||||
|
||||
cJSON* monitor_name = cJSON_GetObjectItem(monitorItem, "name"); // monitor_name
|
||||
if (monitor_name && monitor_name->type == cJSON_String) strncpy(dev->line[j].monitor_name, monitor_name->valuestring, sizeof(dev->line[j].monitor_name) - 1);
|
||||
else strncpy(dev->line[j].monitor_name, "N/A", sizeof(dev->line[j].monitor_name) - 1);
|
||||
dev->line[j].monitor_name[sizeof(dev->line[j].monitor_name) - 1] = '\0';
|
||||
|
||||
cJSON* lineNo = cJSON_GetObjectItem(monitorItem, "lineNo"); // logical_device_seq
|
||||
if (lineNo && lineNo->type == cJSON_String) strncpy(dev->line[j].logical_device_seq, lineNo->valuestring, sizeof(dev->line[j].logical_device_seq) - 1);
|
||||
else strncpy(dev->line[j].logical_device_seq, "N/A", sizeof(dev->line[j].logical_device_seq) - 1);
|
||||
dev->line[j].logical_device_seq[sizeof(dev->line[j].logical_device_seq) - 1] = '\0';
|
||||
|
||||
cJSON* voltageLevel = cJSON_GetObjectItem(monitorItem, "voltageLevel"); // voltage_level
|
||||
if (voltageLevel && voltageLevel->type == cJSON_String) strncpy(dev->line[j].voltage_level, voltageLevel->valuestring, sizeof(dev->line[j].voltage_level) - 1);
|
||||
else strncpy(dev->line[j].voltage_level, "N/A", sizeof(dev->line[j].voltage_level) - 1);
|
||||
dev->line[j].voltage_level[sizeof(dev->line[j].voltage_level) - 1] = '\0';
|
||||
|
||||
cJSON* ptType = cJSON_GetObjectItem(monitorItem, "ptType"); // terminal_connect
|
||||
if (ptType && ptType->type == cJSON_String) strncpy(dev->line[j].terminal_connect, ptType->valuestring, sizeof(dev->line[j].terminal_connect) - 1);
|
||||
else strncpy(dev->line[j].terminal_connect, "N/A", sizeof(dev->line[j].terminal_connect) - 1);
|
||||
dev->line[j].terminal_connect[sizeof(dev->line[j].terminal_connect) - 1] = '\0';
|
||||
|
||||
// 添加监测点状态
|
||||
cJSON* monitorstatus = cJSON_GetObjectItem(monitorItem, "status"); // status
|
||||
if (monitorstatus && monitorstatus->type == cJSON_String) strncpy(dev->line[j].status, monitorstatus->valuestring, sizeof(dev->line[j].status) - 1);
|
||||
else strncpy(dev->line[j].status, "N/A", sizeof(dev->line[j].status) - 1);
|
||||
dev->line[j].status[sizeof(dev->line[j].status) - 1] = '\0';
|
||||
|
||||
cJSON* logLevel_m = cJSON_GetObjectItem(item, "log_level"); // log_level
|
||||
cJSON* logLevel_m = cJSON_GetObjectItem(monitorItem, "log_level"); // log_level
|
||||
int tmp_level = -1;
|
||||
if (logLevel_m && logLevel_m->type == cJSON_Number) {
|
||||
tmp_level = logLevel_m->valueint;
|
||||
@@ -4134,7 +4093,7 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
if (tmp_level >= 0 && tmp_level <= 3) {
|
||||
dev->line[j].log_level = tmp_level;
|
||||
} else {
|
||||
dev->line[j].log_level = 1; // 默认 WARN
|
||||
dev->line[j].log_level = dev->log_level; // 默认 WARN
|
||||
}
|
||||
printf("line[%d].log_level: %d\n", j, dev->line[j].log_level);
|
||||
|
||||
@@ -4145,6 +4104,9 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
// 准备键
|
||||
QString key = QString(dev->terminal_id);//用id而不是code区分:有的code存在乱码
|
||||
|
||||
//lnk20260312防止内存泄漏
|
||||
bool inserted = false;
|
||||
|
||||
// 检查是否存在重复键
|
||||
if (terminal_dev_map->contains(key)) {
|
||||
std::cerr << "Duplicate terminal_code found: " << key.toStdString() << std::endl;
|
||||
@@ -4159,23 +4121,31 @@ int terminal_ledger_web(QMap<QString, terminal_dev*>* terminal_dev_map,
|
||||
if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号
|
||||
//调试用
|
||||
std::cout<< "process num match" << std::endl;
|
||||
terminal_dev_map->insert(key, dev);}//后续修改为只有进程号匹配上index才录入当前进程
|
||||
terminal_dev_map->insert(key, dev);
|
||||
inserted = true;
|
||||
}//后续修改为只有进程号匹配上index才录入当前进程
|
||||
} else {
|
||||
// 插入新的 terminal_dev 对象
|
||||
if(atoi(dev->processNo) == g_front_seg_index || g_front_seg_index == 0){//lnk20250210匹配进程号
|
||||
//调试用
|
||||
std::cout<< "process num match" << std::endl;
|
||||
terminal_dev_map->insert(key, dev);}//后续修改为只有进程号匹配上index才录入当前进程
|
||||
terminal_dev_map->insert(key, dev);
|
||||
inserted = true;
|
||||
}//后续修改为只有进程号匹配上index才录入当前进程
|
||||
//调试用
|
||||
//std::cout << "i = " << i << std::endl;
|
||||
//std::cout << "terminal_dev_map.size:" << terminal_dev_map->size() << std::endl;
|
||||
}//如果出现重复项,日志要有体现方便排查
|
||||
|
||||
|
||||
if (!inserted) {
|
||||
delete dev;
|
||||
dev = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//读取台账有效,保存或更新到台账文件20250513lnk
|
||||
if(g_node_id == STAT_DATA_BASE_NODE_ID && g_front_seg_index == 1){
|
||||
if(g_node_id == STAT_DATA_BASE_NODE_ID && g_front_seg_index == 1 && ptr != NULL && ptr[0] != '\0'){
|
||||
save_ledger_json(ptr);
|
||||
//普通日志,更新本地台账
|
||||
}
|
||||
@@ -4621,14 +4591,17 @@ int parse_model_web(QMap<QString, icd_model*>* icd_model_map,const std::vector<s
|
||||
|
||||
char* ptr=NULL;
|
||||
|
||||
//测试用url参数
|
||||
//SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr);
|
||||
SendJsonAPI_web(WEB_ICD,"",parm.c_str(),&ptr);
|
||||
|
||||
// 检查 ptr 是否为 NULL,避免 std::string 初始化失败
|
||||
if (ptr == NULL) {
|
||||
// 处理 ptr 为 NULL 的情况,例如日志记录或错误处理
|
||||
std::cout << "Error: Received NULL response"<< std::endl;
|
||||
if (ptr == NULL || ptr[0] == '\0') {
|
||||
std::cout << "Error: Received NULL or empty response" << std::endl;
|
||||
|
||||
//【修改点2】ptr 非空时要释放,避免泄漏
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -4649,17 +4622,23 @@ int parse_model_web(QMap<QString, icd_model*>* icd_model_map,const std::vector<s
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
//测试用url参数
|
||||
//SendJsonAPI_web("http://192.168.1.149:8091/powerQuality/getProperties", parm.c_str(), "",&ptr);
|
||||
|
||||
sleep(2);
|
||||
|
||||
SendJsonAPI_web(WEB_ICD,"",parm.c_str(),&ptr);
|
||||
if(ptr == NULL){
|
||||
if(ptr == NULL || ptr[0] == '\0'){
|
||||
retry++;if(retry>3)break;
|
||||
continue;
|
||||
}
|
||||
root = cJSON_Parse(ptr);
|
||||
retry++;if(retry>3)break;
|
||||
retry++;
|
||||
if(retry>3)break;
|
||||
}
|
||||
if (root == NULL) {
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
printf("web error %s\n", cJSON_GetErrorPtr());
|
||||
return 1;
|
||||
}
|
||||
@@ -4669,8 +4648,8 @@ int parse_model_web(QMap<QString, icd_model*>* icd_model_map,const std::vector<s
|
||||
cJSON* msgItem = cJSON_GetObjectItem(root, "msg");
|
||||
|
||||
// 使用 std::string 获取值
|
||||
std::string code = (codeItem != NULL) ? codeItem->valuestring : "not found";
|
||||
std::string msg = (msgItem != NULL) ? msgItem->valuestring : "not found";
|
||||
std::string code = (codeItem != NULL && codeItem->valuestring != NULL) ? codeItem->valuestring : "not found";
|
||||
std::string msg = (msgItem != NULL && msgItem->valuestring != NULL) ? msgItem->valuestring : "not found";
|
||||
|
||||
// 打印结果
|
||||
std::cout << "code: " << code << std::endl;
|
||||
@@ -4680,30 +4659,72 @@ int parse_model_web(QMap<QString, icd_model*>* icd_model_map,const std::vector<s
|
||||
if (data && data->type == cJSON_Array) {
|
||||
cJSON* item;
|
||||
cJSON_ArrayForEach(item, data) {
|
||||
icd_model* model = new icd_model;
|
||||
icd_model* model = new icd_model();
|
||||
|
||||
cJSON* id = cJSON_GetObjectItem(item, "id");//model_id
|
||||
if (id && id->type == cJSON_String) strncpy(model->model_id, id->valuestring, sizeof(model->model_id) - 1);
|
||||
|
||||
if (id && id->type == cJSON_String) {
|
||||
strncpy(model->model_id, id->valuestring, sizeof(model->model_id) - 1);
|
||||
model->model_id[sizeof(model->model_id) - 1] = '\0';
|
||||
}
|
||||
|
||||
cJSON* fileName = cJSON_GetObjectItem(item, "fileName");//file_name
|
||||
if (fileName && fileName->type == cJSON_String) strncpy(model->file_name, fileName->valuestring, sizeof(model->file_name) - 1);
|
||||
if (fileName && fileName->type == cJSON_String) {
|
||||
strncpy(model->file_name, fileName->valuestring, sizeof(model->file_name) - 1);
|
||||
model->file_name[sizeof(model->file_name) - 1] = '\0';
|
||||
}
|
||||
|
||||
cJSON* filePath = cJSON_GetObjectItem(item, "filePath");//新增
|
||||
if (filePath && filePath->type == cJSON_String) strncpy(model->file_path, filePath->valuestring, sizeof(model->file_path) - 1);
|
||||
if (filePath && filePath->type == cJSON_String) {
|
||||
strncpy(model->file_path, filePath->valuestring, sizeof(model->file_path) - 1);
|
||||
model->file_path[sizeof(model->file_path) - 1] = '\0';
|
||||
}
|
||||
|
||||
cJSON* devType = cJSON_GetObjectItem(item, "devType");//tmnl_type
|
||||
if (devType && devType->type == cJSON_String) strncpy(model->tmnl_type, devType->valuestring, sizeof(model->tmnl_type) - 1);
|
||||
if (devType && devType->type == cJSON_String) {
|
||||
strncpy(model->tmnl_type, devType->valuestring, sizeof(model->tmnl_type) - 1);
|
||||
model->tmnl_type[sizeof(model->tmnl_type) - 1] = '\0';
|
||||
}
|
||||
|
||||
cJSON* updateTime = cJSON_GetObjectItem(item, "updateTime");//timestamp
|
||||
if (updateTime && updateTime->type == cJSON_String) strncpy(model->timestamp, updateTime->valuestring, sizeof(model->timestamp) - 1);
|
||||
if (updateTime && updateTime->type == cJSON_String) {
|
||||
strncpy(model->timestamp, updateTime->valuestring, sizeof(model->timestamp) - 1);
|
||||
model->timestamp[sizeof(model->timestamp) - 1] = '\0';
|
||||
}
|
||||
|
||||
// 添加到 QMap
|
||||
icd_model_map->insert(model->model_id, model);
|
||||
if (model->model_id[0] != '\0') {
|
||||
icd_model_map->insert(model->model_id, model);
|
||||
} else {
|
||||
delete model;
|
||||
model = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
std::cout << "Error: 'data' is not an array or is missing" << std::endl;
|
||||
cJSON_Delete(root);
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (cJSON_GetArraySize(data) == 0) {
|
||||
std::cout << "Error: 'data' array is empty" << std::endl;
|
||||
cJSON_Delete(root);
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
cJSON_Delete(root);
|
||||
free(ptr); // 如果 SendJsonAPI_web 分配了内存,记得释放
|
||||
if (ptr != NULL) {
|
||||
free(ptr);
|
||||
ptr = NULL;
|
||||
}
|
||||
|
||||
return 0; // 确保函数有返回值
|
||||
}
|
||||
@@ -4776,7 +4797,7 @@ int parse_model_cfg_web()
|
||||
char tmnl_type[64];
|
||||
char file_name[128];
|
||||
char file_path[128];
|
||||
otl_datetime timestamp;
|
||||
otl_datetime timestamp = {};
|
||||
|
||||
// 遍历终端台账容器
|
||||
QMap<QString, icd_model*>::iterator it;
|
||||
@@ -4791,6 +4812,12 @@ int parse_model_cfg_web()
|
||||
strncpy(file_path, value->file_path, sizeof(file_path) - 1);
|
||||
strncpy(file_name, value->file_name, sizeof(file_name) - 1);
|
||||
|
||||
//lnk20260311
|
||||
model_id[sizeof(model_id) - 1] = '\0';
|
||||
tmnl_type[sizeof(tmnl_type) - 1] = '\0';
|
||||
file_path[sizeof(file_path) - 1] = '\0';
|
||||
file_name[sizeof(file_name) - 1] = '\0';
|
||||
|
||||
std::cout << "model_id" << model_id << std::endl;
|
||||
std::cout << "tmnl_type" << tmnl_type << std::endl;
|
||||
std::cout << "filepath" << file_path << std::endl;
|
||||
@@ -5445,6 +5472,84 @@ void SOEFileWeb_test()
|
||||
SOEFileWeb(localpath,cloudpath,wavepath);
|
||||
std::cout << "wavepath:" << wavepath << std::endl;
|
||||
}
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////lnk20260310
|
||||
static size_t write_file_callback(void* ptr, size_t size, size_t nmemb, void* stream)
|
||||
{
|
||||
FILE* fp = (FILE*)stream;
|
||||
return fwrite(ptr, size, nmemb, fp);
|
||||
}
|
||||
/*
|
||||
* 从 WEB_FILEDOWNLOAD 下载 path 对应的文件到 localpath
|
||||
* 成功返回 0,失败返回 -1
|
||||
*/
|
||||
int DownloadFileWeb(const std::string& strUrl,
|
||||
const char* remotePath,
|
||||
const char* localpath)
|
||||
{
|
||||
if (remotePath == NULL || localpath == NULL)
|
||||
return -1;
|
||||
|
||||
CURL* curl = curl_easy_init();
|
||||
if (!curl)
|
||||
{
|
||||
std::cerr << "curl init failed" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
FILE* fp = fopen(localpath, "wb");
|
||||
if (fp == NULL)
|
||||
{
|
||||
std::cerr << "open local file failed: " << localpath << std::endl;
|
||||
curl_easy_cleanup(curl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* encodedPath = curl_easy_escape(curl, remotePath, 0);
|
||||
if (encodedPath == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
curl_easy_cleanup(curl);
|
||||
return -1;
|
||||
}
|
||||
|
||||
std::string fullUrl = strUrl;
|
||||
if (fullUrl.find('?') == std::string::npos)
|
||||
fullUrl += "?path=";
|
||||
else
|
||||
fullUrl += "&path=";
|
||||
fullUrl += encodedPath;
|
||||
|
||||
curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
|
||||
curl_easy_setopt(curl, CURLOPT_HTTPGET, 1L);
|
||||
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
|
||||
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60L);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_file_callback);
|
||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, fp);
|
||||
|
||||
CURLcode res = curl_easy_perform(curl);
|
||||
|
||||
long http_code = 0;
|
||||
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
|
||||
|
||||
curl_free(encodedPath);
|
||||
fclose(fp);
|
||||
curl_easy_cleanup(curl);
|
||||
|
||||
if (res != CURLE_OK)
|
||||
{
|
||||
std::cerr << "DownloadFileWeb failed: " << curl_easy_strerror(res) << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (http_code != 200)
|
||||
{
|
||||
std::cerr << "DownloadFileWeb http code: " << http_code << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*/////////////////////////////////////////////////////////lnk10-24根据web接口修改/////////////////////////////////////////////////////////////*/
|
||||
/*封装C可调用的台账更新函数 */////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
Reference in New Issue
Block a user