From 15cbbd1c241ba626324dcf3d5c7c584d735e8fcf Mon Sep 17 00:00:00 2001 From: lnk Date: Mon, 30 Mar 2026 15:32:14 +0800 Subject: [PATCH 1/3] fix cloudtopic msg proc --- LFtid1056/cloudfront/code/cfg_parser.cpp | 128 ++++++++++++++++++++++- LFtid1056/cloudfront/code/main.cpp | 2 + LFtid1056/cloudfront/code/rocketmq.cpp | 68 +++++++++--- LFtid1056/cloudfront/code/rocketmq.h | 5 + LFtid1056/dealMsg.cpp | 30 +++++- 5 files changed, 213 insertions(+), 20 deletions(-) diff --git a/LFtid1056/cloudfront/code/cfg_parser.cpp b/LFtid1056/cloudfront/code/cfg_parser.cpp index 4e14265..890ed82 100644 --- a/LFtid1056/cloudfront/code/cfg_parser.cpp +++ b/LFtid1056/cloudfront/code/cfg_parser.cpp @@ -68,7 +68,7 @@ extern std::map xmlinfo_list2;//保存所有型号角形 ////////////////////////////////////////////////////////////////////////////////////////////////// extern time_t ConvertToTimestamp(const tagTime& time); - +extern std::vector read_file_as_bytes(const std::string& file_path); ///////////////////////////////////////////////////////////////////////////////////////////////// @@ -173,6 +173,10 @@ std::string Topic_Reply_Topic = ""; std::string Topic_Reply_Tag = ""; std::string Topic_Reply_Key = ""; +std::string Cloud_Reply_Topic = ""; +std::string Cloud_Reply_Tag = ""; +std::string Cloud_Reply_Key = ""; + //消费者 std::string G_ROCKETMQ_CONSUMER = "";//rocketmq consumer std::string G_MQCONSUMER_IPPORT = "";//consumer ip+port @@ -381,6 +385,10 @@ void loadConfig(const std::string& filename) { strMap["RocketMq.ConsumerTagCLOUD"] = &G_MQCONSUMER_TAG_CLOUD; strMap["RocketMq.ConsumerKeyCLOUD"] = &G_MQCONSUMER_KEY_CLOUD; + strMap["RocketMq.Cloud_Reply_Topic"] = &Cloud_Reply_Topic; + strMap["RocketMq.Cloud_Reply_Tag"] = &Cloud_Reply_Tag; + strMap["RocketMq.Cloud_Reply_Key"] = &Cloud_Reply_Key; + strMap["RocketMq.Topic_Test"] = &G_ROCKETMQ_TOPIC_TEST; strMap["RocketMq.Tag_Test"] = &G_ROCKETMQ_TAG_TEST; strMap["RocketMq.Key_Test"] = &G_ROCKETMQ_KEY_TEST; @@ -3924,7 +3932,7 @@ bool send_set_value_reply(const std::string &dev_id, unsigned char mp_index, con // Detail nlohmann::json detail; - detail["Type"] = 0x2106; // 设备数据 + detail["Type"] = 1103; // 设备数据 // Msg nlohmann::json msg; @@ -4048,7 +4056,7 @@ bool send_internal_value_reply(const std::string &dev_id, const std::vector& FileList // 构造 Detail 部分 nlohmann::json detail; - detail["Type"] = 0x2131; // 读取目录 + detail["Type"] = 1101; // 读取目录 detail["Msg"] = { {"DirInfo", dirArray} }; detail["Code"] = 200; // 请求成功 @@ -6450,6 +6458,116 @@ void on_device_response_minimal(int response_code, break; } + // ================= 新增:预升级处理 ================= + case DeviceState::SET_PREUPGRADE: { + std::lock_guard lk(ledgermtx); + + terminal_dev* dev = nullptr; + for (auto& d : terminal_devlist) { + if (d.terminal_id == id) { + dev = &d; + break; + } + } + + if (!dev) { + std::cout << "[SET_PREUPGRADE] dev not found, terminal_id=" + << id << " rc=" << response_code << std::endl; + break; + } + + const int bt = dev->busytype; + + // 只有当前业务类型确实还是预升级,才继续处理 + if (bt != static_cast(DeviceState::SET_PREUPGRADE)) { + std::cout << "[SET_PREUPGRADE] busytype mismatch, terminal_id=" << id + << " dev->busytype=" << bt + << " expect=" << static_cast(DeviceState::SET_PREUPGRADE) + << std::endl; + break; + } + + // 返回 OK,执行升级 + if (ok) { + std::cout << "[SET_PREUPGRADE] OK, start upgrade, terminal_id=" + << id << std::endl; + + try { + if(dev->isbusy == 2){ + // 读取升级文件 + std::vector file_data = read_file_as_bytes("pqs_arm2.bin"); + + // 下发升级指令 + ClientManager::instance().send_upgrade_action_to_device(id, file_data, 10240); + + dev->isbusy = 1; // 完成了预校验但是仍处于忙碌,因为还要升级 + }else if(dev->isbusy == 1){ + std::cout << "[SET_PREUPGRADE] already upgrade OK, terminal_id=" + << id << std::endl; + send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); + send_reply_to_queue(dev->guid, response_code, + "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) + "," + ResponseCodeToString(response_code) + "停止该业务处理"); + //成功结束业务 + dev->guid.clear(); // 清空 guid + dev->busytype = 0; // 业务类型归零 + dev->isbusy = 0; // 清空业务标志 + dev->busytimecount = 0; // 计时归零 + std::cout << "[clear_terminal_runtime_state] Cleared runtime state for terminal_id=" + << id << std::endl; + + } + else { + std::cout << "[SET_PREUPGRADE] status error" <guid, dev->mac); + send_reply_to_queue(dev->guid, response_code, + "终端 id: " + dev->terminal_id + + "进行业务:" + get_type_by_state(dev->busytype) + + ",处理逻辑错误,停止该业务处理"); + dev->guid.clear(); + dev->busytype = 0; + dev->isbusy = 0; + dev->busytimecount = 0; + } + + + } catch (const std::exception& e) { + std::cout << "[SET_PREUPGRADE] read/send failed: " + << e.what() << std::endl; + + send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); + send_reply_to_queue(dev->guid, response_code, + "终端 id: " + dev->terminal_id + + "进行业务:" + get_type_by_state(dev->busytype) + + "," + ResponseCodeToString(response_code) + "停止该业务处理"); + + // 失败也要清状态 + dev->guid.clear(); + dev->busytype = 0; + dev->isbusy = 0; + dev->busytimecount = 0; + } + + } else { + // 失败 → 直接结束业务 + std::cout << "[SET_PREUPGRADE] FAIL, stop business, terminal_id=" + << id << std::endl; + + send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); + send_reply_to_queue(dev->guid, response_code, + "终端 id: " + dev->terminal_id + + "进行业务:" + get_type_by_state(dev->busytype) + + "," + ResponseCodeToString(response_code) + "停止该业务处理"); + + dev->guid.clear(); + dev->busytype = 0; + dev->isbusy = 0; + dev->busytimecount = 0; + } + + break; + } + // ================= 其它状态统一处理 ================= default: { @@ -6460,7 +6578,7 @@ void on_device_response_minimal(int response_code, } if (dev) { //直接根据输入响应mq - //send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); + send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); send_reply_to_queue(dev->guid, response_code, "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) + "," + ResponseCodeToString(response_code) + "停止该业务处理"); //其他的错误和成功都会结束业务 diff --git a/LFtid1056/cloudfront/code/main.cpp b/LFtid1056/cloudfront/code/main.cpp index 389bb58..4976961 100644 --- a/LFtid1056/cloudfront/code/main.cpp +++ b/LFtid1056/cloudfront/code/main.cpp @@ -565,6 +565,8 @@ void Front::mqconsumerThread() subscriptions.emplace_back(G_MQCONSUMER_TOPIC_SET, FRONT_INST, myMessageCallbackset); subscriptions.emplace_back(G_MQCONSUMER_TOPIC_LOG, FRONT_INST, myMessageCallbacklog); + subscriptions.emplace_back(G_MQCONSUMER_TOPIC_CLOUD, FRONT_INST, cloudMessageCallback); + m_mqConsumer = make_unique(consumerGroup); diff --git a/LFtid1056/cloudfront/code/rocketmq.cpp b/LFtid1056/cloudfront/code/rocketmq.cpp index 9bde627..60c09e8 100644 --- a/LFtid1056/cloudfront/code/rocketmq.cpp +++ b/LFtid1056/cloudfront/code/rocketmq.cpp @@ -2071,11 +2071,37 @@ bool parseJsonMessageCLOUD(const std::string &body, std::string &devid, std::string &guid, nlohmann::json &detailObj, // 这里返回整个 Detail - std::string &front_ip, // 新增:返回 FrontIP + std::string &front_id, // 新增:返回 FrontId int &node) // 新增:返回 Node { try { - auto j = nlohmann::json::parse(body); + // ====== 先解析外层 JSON ====== + auto outer = nlohmann::json::parse(body); + + // ====== 提取 messageBody 字符串 ====== + if (!outer.contains("messageBody") || !outer["messageBody"].is_string()) { + std::cerr << "[parseJsonMessageCLOUD] 'messageBody' is missing or is not a string\n"; + guid.clear(); + devid.clear(); + front_ip.clear(); + node = 0; + detailObj = nlohmann::json::object(); + return false; + } + + std::string messageBodyStr = outer["messageBody"].get(); + if (messageBodyStr.empty()) { + std::cerr << "[parseJsonMessageCLOUD] 'messageBody' is empty\n"; + guid.clear(); + devid.clear(); + front_ip.clear(); + node = 0; + detailObj = nlohmann::json::object(); + return false; + } + + // ====== 再解析 messageBody 内层 JSON ====== + auto j = nlohmann::json::parse(messageBodyStr); // guid if (j.contains("guid") && j["guid"].is_string()) { @@ -2084,9 +2110,9 @@ bool parseJsonMessageCLOUD(const std::string &body, guid.clear(); } - // FrontIP - if (j.contains("FrontIP") && j["FrontIP"].is_string()) { - front_ip = j["FrontIP"].get(); + // FrontId + if (j.contains("FrontId") && j["FrontId"].is_string()) { + front_ip = j["FrontId"].get(); } else { front_ip.clear(); } @@ -2171,7 +2197,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: if (detailObj.contains("Type")) { if (detailObj["Type"].is_string()) { try { - parsed.type = std::stoi(detailObj["Type"].get(), nullptr, 0); // 支持 "0x2106" 格式 + parsed.type = std::stoi(detailObj["Type"].get(), nullptr, 0); // 支持 "1103" 格式 } catch (...) { return false; } @@ -2195,7 +2221,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: try { switch (parsed.type) { - case 0x2131: { // 读取目录 + case 1101: { // 读取目录 if(!recordguid(devid,guid,static_cast(DeviceState::READING_FILEMENU),1)){ return true; @@ -2212,7 +2238,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: return true; } - case 0x2132: { // 下载文件 + case 1102: { // 下载文件 if(!recordguid(devid,guid,static_cast(DeviceState::READING_FILEDATA),1)){ return true; @@ -2229,7 +2255,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: return true; } - case 0x2106: { // 定值/内部定值 + case 1103: { // 定值/内部定值 if (!msgObj.contains("Cldid") || !msgObj["Cldid"].is_number_integer()) return false; if (!msgObj.contains("DataType") || !msgObj["DataType"].is_number_integer()) return false; if (!msgObj.contains("Operate") || !msgObj["Operate"].is_number_integer()) return false; @@ -2403,11 +2429,25 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: std::cout << "[parsemsg] reboot device, devid=" << devid << ", guid=" << guid << std::endl; - if (!recordguid(devid, guid, static_cast(DeviceState::SET_CTRL), 2)) {//分两步,一步校验一步重启 + if (!recordguid(devid, guid, static_cast(DeviceState::SET_CTRL), 1)) { return true; } - ClientManager::instance().set_ctrl_action_to_device(devid,0x01,0x00);//尝试装置重启指令!第一步校验 + ClientManager::instance().set_ctrl_action_to_device(devid,0x01,0x00);//尝试装置重启指令! + return true; + } + + case 1115: { // 升级 + parsed.ok = true; + + std::cout << "[parsemsg] upgrade device, devid=" << devid + << ", guid=" << guid << std::endl; + + if (!recordguid(devid, guid, static_cast(DeviceState::SET_PREUPGRADE), 2)) { + return true; + } + + ClientManager::instance().set_preupgrade_action_to_device(devid, "");//尝试装置升级指令!第一步校验 return true; } @@ -2461,10 +2501,10 @@ void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, co // ---- 入队发送 ---- queue_data_t connect_info; - connect_info.strTopic = Topic_Reply_Topic; + connect_info.strTopic = Cloud_Reply_Topic; connect_info.strText = obj.dump(); // 序列化为字符串 - connect_info.tag = Topic_Reply_Tag; - connect_info.key = Topic_Reply_Key; + connect_info.tag = Cloud_Reply_Tag; + connect_info.key = Cloud_Reply_Key; { std::lock_guard lock(queue_data_list_mutex); diff --git a/LFtid1056/cloudfront/code/rocketmq.h b/LFtid1056/cloudfront/code/rocketmq.h index 681b2a6..62d3561 100644 --- a/LFtid1056/cloudfront/code/rocketmq.h +++ b/LFtid1056/cloudfront/code/rocketmq.h @@ -94,6 +94,10 @@ extern std::string G_MQCONSUMER_TOPIC_CLOUD; extern std::string G_MQCONSUMER_TAG_CLOUD; extern std::string G_MQCONSUMER_KEY_CLOUD; +extern std::string Cloud_Reply_Topic; +extern std::string Cloud_Reply_Tag; +extern std::string Cloud_Reply_Key; + extern std::string G_LOG_TOPIC; extern std::string G_LOG_TAG; extern std::string G_LOG_KEY; @@ -336,6 +340,7 @@ rocketmq::ConsumeStatus myMessageCallbackrtdata(const rocketmq::MQMessageExt& ms rocketmq::ConsumeStatus myMessageCallbackupdate(const rocketmq::MQMessageExt& msg); rocketmq::ConsumeStatus myMessageCallbackset(const rocketmq::MQMessageExt& msg); rocketmq::ConsumeStatus myMessageCallbacklog(const rocketmq::MQMessageExt& msg); +rocketmq::ConsumeStatus cloudMessageCallback(const rocketmq::MQMessageExt& msg); void send_heartbeat_to_queue(const std::string& status); diff --git a/LFtid1056/dealMsg.cpp b/LFtid1056/dealMsg.cpp index dade921..b165e4e 100644 --- a/LFtid1056/dealMsg.cpp +++ b/LFtid1056/dealMsg.cpp @@ -2073,6 +2073,9 @@ void process_received_message(string mac, string id,const char* data, size_t len //设置装置对时(主动对时) if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { std::cout << "set success" << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SET_RIGHTTIME_2)); + //对时设置成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } @@ -2082,11 +2085,13 @@ void process_received_message(string mac, string id,const char* data, size_t len std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; // 装置否定应答,对时设置失败 + on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::SET_RIGHTTIME_2)); // 设置对时失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问异常 + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_RIGHTTIME_2)); // 设置对时失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } @@ -2347,6 +2352,7 @@ void process_received_message(string mac, string id,const char* data, size_t len } else { std::cout << "***ctrl fail" << mac << std::endl; + on_device_response_minimal(static_cast(ResponseCode::UNAUTHORIZED), id, 0, static_cast(DeviceState::SET_CTRL)); //控制命令校验不合法,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } @@ -2354,15 +2360,19 @@ void process_received_message(string mac, string id,const char* data, size_t len else if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { std::cout << "***ctrl success" << mac << std::endl; //控制命令执行完毕,调整为空闲,处理后续工作。 + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SET_CTRL)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { std::cout << "***ctrl fail" << mac << std::endl; //控制命令执行失败,调整为空闲,处理后续工作。 + on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::SET_CTRL)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问异常 + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_CTRL)); // 控制命令失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } @@ -2445,15 +2455,19 @@ void process_received_message(string mac, string id,const char* data, size_t len if (generatedCrc != crc) { //crc 校验失败 后续升级停止! std::cerr << "CRC verify failed." << std::endl; + on_device_response_minimal(static_cast(ResponseCode::UNAUTHORIZED), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); break; } + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); + // 预升级校验结束成功,调整为空闲,处理后续工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问异常 + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); // 预升级校验失败,调整为空闲状态,处理下一项工作。 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } @@ -2474,23 +2488,33 @@ void process_received_message(string mac, string id,const char* data, size_t len //接收文件错误! std::cout << "*** upgrade 0x02 fail ***!" << mac << std::endl; // 升级流程失败,调整为空闲状态,处理下一项工作。 + + on_device_response_minimal(static_cast(ResponseCode::NOT_FOUND), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[9] == 0x55) { //升级流程成功,等候装置重启 std::cout << "*** upgrade 0x55 success ***!" << mac << std::endl; - // 升级流程失败,调整为空闲状态,处理下一项工作。 + // 升级流程成功,调整为空闲状态,处理下一项工作。 + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[9] == 0xAA) { // 升级流程失败! std::cout << "*** upgrade 0xAA fail ***!" << mac << std::endl; // 升级流程失败,调整为空闲状态,处理下一项工作。 + + on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { std::cout << "*** upgrade ?? error ***!" << mac << std::endl; // 升级流程失败,调整为空闲状态,处理下一项工作。 + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); } } @@ -2511,6 +2535,7 @@ void process_received_message(string mac, string id,const char* data, size_t len if (!ok) { //组装后续升级报文时出现异常,无法发送后续帧文件 std::cout << "获取下一帧失败\n"; + on_device_response_minimal(static_cast(ResponseCode::NOT_FOUND), id, 0, static_cast(DeviceState::SET_UPGRADE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (!packet.empty()) { @@ -2532,18 +2557,21 @@ void process_received_message(string mac, string id,const char* data, size_t len else { // 理论上不该走到这里,防御处理 std::cout << "未获取到有效升级报文\n"; + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_UPGRADE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); } } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { std::cout << "*** upgrade 0x41 fail ***!" << mac << std::endl; // 升级流程失败,调整为空闲状态,处理下一项工作。 + on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::SET_PREUPGRADE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问异常 std::cout << "*** upgrade ?? fail ***!" << mac << std::endl; // 升级流程失败,调整为空闲状态,处理下一项工作。 + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SET_UPGRADE)); ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; From b11105f91cf40b3f2fca56d4569299203291a543 Mon Sep 17 00:00:00 2001 From: lnk Date: Wed, 1 Apr 2026 15:30:52 +0800 Subject: [PATCH 2/3] add interface --- LFtid1056/cloudfront/code/cfg_parser.cpp | 286 ++++++++++++++++------- LFtid1056/cloudfront/code/interface.cpp | 29 ++- LFtid1056/cloudfront/code/interface.h | 2 +- LFtid1056/cloudfront/code/rocketmq.cpp | 263 ++++++++++++++++++--- LFtid1056/dealMsg.cpp | 74 +++--- 5 files changed, 485 insertions(+), 169 deletions(-) diff --git a/LFtid1056/cloudfront/code/cfg_parser.cpp b/LFtid1056/cloudfront/code/cfg_parser.cpp index 890ed82..a4d2f5e 100644 --- a/LFtid1056/cloudfront/code/cfg_parser.cpp +++ b/LFtid1056/cloudfront/code/cfg_parser.cpp @@ -81,6 +81,16 @@ std::map, std::string> g_recall_file_index; std::mutex g_last_ts_mtx; std::unordered_map g_last_ts_by_devid; +//文件下载缓存 +struct FileDownloadReplyInfo +{ + std::string local_name; // 本地名,对应 JSON 的 Name + std::string remote_name; // 远端名,对应 JSON 的 RemoteName +}; + +static std::mutex g_filedownload_cache_mtx; +static std::map g_filedownload_cache; + //目录信息缓存 static std::mutex g_filemenu_cache_mtx; std::map> g_filemenu_cache; @@ -3568,7 +3578,7 @@ void check_device_busy_timeout() } //发送超时响应 - //send_reply_to_cloud(static_cast(ResponseCode::TIMEOUT),dev.terminal_id,get_type_by_state(dev.busytype),dev.guid,dev.mac); + send_reply_to_cloud(static_cast(ResponseCode::TIMEOUT),dev.terminal_id,dev.busytype,dev.guid,dev.mac); send_reply_to_queue(dev.guid, static_cast(ResponseCode::TIMEOUT), "终端 id: " + dev.terminal_id + "进行业务:" + get_type_by_state(dev.busytype) +"超时600秒,停止该业务处理"); @@ -3616,7 +3626,7 @@ void check_device_busy_timeout() } //发送超时响应 - //send_reply_to_cloud(static_cast(ResponseCode::TIMEOUT),dev.terminal_id,get_type_by_state(dev.busytype),dev.guid,dev.mac); + send_reply_to_cloud(static_cast(ResponseCode::TIMEOUT),dev.terminal_id,dev.busytype,dev.guid,dev.mac); send_reply_to_queue(dev.guid, static_cast(ResponseCode::TIMEOUT), "终端 id: " + dev.terminal_id + "进行业务:" + get_type_by_state(dev.busytype) +"超时30秒,停止该业务处理"); @@ -3937,7 +3947,7 @@ bool send_set_value_reply(const std::string &dev_id, unsigned char mp_index, con // Msg nlohmann::json msg; msg["Cldid"] = mp_index; //测点序号 - msg["DataType"] = 0x0C; //定值 + msg["DataType"] = 1; //定值 // DataArray(对象数组):逐个填充,DZ_Value 严格按 set_values 顺序 nlohmann::json dataArray = nlohmann::json::array(); @@ -3975,10 +3985,10 @@ bool send_set_value_reply(const std::string &dev_id, unsigned char mp_index, con // 6) 入队发送 queue_data_t connect_info; - connect_info.strTopic = Topic_Reply_Topic; + connect_info.strTopic = Cloud_Reply_Topic; connect_info.strText = j.dump(); // 序列化为字符串 - connect_info.tag = Topic_Reply_Tag; - connect_info.key = Topic_Reply_Key; + connect_info.tag = Cloud_Reply_Tag; + connect_info.key = Cloud_Reply_Key; { std::lock_guard lock(queue_data_list_mutex); @@ -4058,7 +4068,7 @@ bool send_internal_value_reply(const std::string &dev_id, const std::vector lock(queue_data_list_mutex); @@ -5653,6 +5663,75 @@ bool enqueue_direct_download(const std::string& dev_id, return true; } +//////////////////////////////////////////////////////////////////////////////////////////////////////////文件下载响应处理 +void filedownload_cache_put(const std::string& dev_id, + const std::string& local_name, + const std::string& remote_name) +{ + std::lock_guard lk(g_filedownload_cache_mtx); + g_filedownload_cache[dev_id] = FileDownloadReplyInfo{ local_name, remote_name }; +} + +bool filedownload_cache_take(const std::string& dev_id, FileDownloadReplyInfo& out) +{ + std::lock_guard lk(g_filedownload_cache_mtx); + auto it = g_filedownload_cache.find(dev_id); + if (it == g_filedownload_cache.end()) return false; + + out = std::move(it->second); + g_filedownload_cache.erase(it); + return true; +} + +bool send_file_download_reply(terminal_dev* dev, + const std::string& local_name, + const std::string& remote_name) +{ + if (!dev) { + std::cerr << "[send_file_download_reply] dev=nullptr\n"; + return false; + } + + // 判断 isbusy==1 且 busytype==READING_FILEDATA + if (dev->isbusy != 1 || dev->busytype != static_cast(DeviceState::READING_FILEDATA)) { + std::cerr << "[send_file_download_reply] device not in READING_FILEDATA state." << std::endl; + return false; + } + + // 构造 JSON 报文 + nlohmann::json j; + j["guid"] = dev->guid; + j["FrontId"] = FRONT_INST; + j["Node"] = g_front_seg_index; + j["Dev_mac"] = normalize_mac(dev->addr_str); + + nlohmann::json detail; + detail["Type"] = 1102; + detail["Msg"] = { + {"Name", local_name}, + {"RemoteName", remote_name} + }; + detail["Code"] = 200; + + j["Detail"] = detail; + + std::cout << j.dump(4) << std::endl; + + // ---- 入队发送 ---- + queue_data_t connect_info; + connect_info.strTopic = Cloud_Reply_Topic; + connect_info.strText = j.dump(); + connect_info.tag = Cloud_Reply_Tag; + connect_info.key = Cloud_Reply_Key; + { + std::lock_guard lock(queue_data_list_mutex); + queue_data_list.push_back(std::move(connect_info)); + } + + std::cout << "[send_file_download_reply] queued: " << j.dump() << std::endl; + + return true; +} ///////////////////////////////////////////////////////////////////////////////////////////////////////////目录响应处理 void filemenu_cache_put(const std::string& dev_id, @@ -5719,10 +5798,10 @@ bool send_file_list(terminal_dev* dev, const std::vector& FileList // ---- 入队发送 ---- queue_data_t connect_info; - connect_info.strTopic = Topic_Reply_Topic; + connect_info.strTopic = Cloud_Reply_Topic; connect_info.strText = j.dump(); // 序列化为字符串 - connect_info.tag = Topic_Reply_Tag; - connect_info.key = Topic_Reply_Key; + connect_info.tag = Cloud_Reply_Tag; + connect_info.key = Cloud_Reply_Key; { std::lock_guard lock(queue_data_list_mutex); queue_data_list.push_back(std::move(connect_info)); @@ -5811,10 +5890,10 @@ bool send_running_info(terminal_dev* dev, const RunningInformation& info) { // ---- 入队发送 ---- queue_data_t connect_info; - connect_info.strTopic = Topic_Reply_Topic; + connect_info.strTopic = Cloud_Reply_Topic; connect_info.strText = j.dump(); - connect_info.tag = Topic_Reply_Tag; - connect_info.key = Topic_Reply_Key; + connect_info.tag = Cloud_Reply_Tag; + connect_info.key = Cloud_Reply_Key; { std::lock_guard lock(queue_data_list_mutex); queue_data_list.push_back(std::move(connect_info)); @@ -5919,10 +5998,10 @@ bool send_version_info(terminal_dev* dev, const DeviceVersionInfo& info) { // ---- 入队发送 ---- queue_data_t connect_info; - connect_info.strTopic = Topic_Reply_Topic; + connect_info.strTopic = Cloud_Reply_Topic; connect_info.strText = j.dump(); - connect_info.tag = Topic_Reply_Tag; - connect_info.key = Topic_Reply_Key; + connect_info.tag = Cloud_Reply_Tag; + connect_info.key = Cloud_Reply_Key; { std::lock_guard lock(queue_data_list_mutex); queue_data_list.push_back(std::move(connect_info)); @@ -6079,12 +6158,12 @@ void on_device_response_minimal(int response_code, //发送目录 send_file_list(dev,names); - + std::cout << "[RESP][FILEMENU->FILEMENU][OK] dev=" << id << std::endl; } else { // 失败:响应web并复位为空闲 - //send_reply_to_cloud(static_cast(ResponseCode::BAD_REQUEST), id, static_cast(DeviceState::READING_FILEMENU),dev->guid,dev->mac); - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"失败,停止该业务处理"); + send_reply_to_cloud(static_cast(ResponseCode::BAD_REQUEST), id, device_state_int,dev->guid,dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"失败,停止该业务处理"); std::cout << "[RESP][FILEMENU->FILEMENU][WARN] dev=" << id << " names missing in cache" << std::endl; } @@ -6094,12 +6173,12 @@ void on_device_response_minimal(int response_code, dev->isbusy = 0; dev->busytype = 0; dev->busytimecount = 0; - std::cout << "[RESP][FILEMENU->FILEMENU][OK] dev=" << id << std::endl; + } else { // 失败:响应web并复位为空闲 - //send_reply_to_cloud(response_code, id, static_cast(DeviceState::READING_FILEMENU),dev->guid,dev->mac); - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"失败,停止该业务处理"); + send_reply_to_cloud(response_code, id, device_state_int,dev->guid,dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"失败,停止该业务处理"); dev->guid.clear(); dev->isbusy = 0; @@ -6218,20 +6297,33 @@ void on_device_response_minimal(int response_code, // ====== 分支 A:当前业务就是“读取文件数据” ====== if (ok) { // 成功:复位 - //send_reply_to_cloud(static_cast(ResponseCode::OK), id, static_cast(DeviceState::READING_FILEDATA),dev->guid,dev->mac); - send_reply_to_queue(dev->guid, static_cast(ResponseCode::OK), - "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"成功,停止该业务处理"); + FileDownloadReplyInfo file_info; + if (filedownload_cache_take(id, file_info)) { + send_file_download_reply(dev, file_info.local_name, file_info.remote_name); + std::cout << "[RESP][FILEDATA->FILEDATA][OK][CACHE] dev=" << id + << " local_name=" << file_info.local_name + << " remote_name=" << file_info.remote_name + << std::endl; + + } else {//取不到结果,即使上传了文件也当做失败处理 + send_reply_to_cloud(static_cast(ResponseCode::BAD_REQUEST), id, device_state_int, dev->guid, dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + + // get_type_by_state(dev->busytype) + "失败,停止该业务处理"); + + std::cout << "[RESP][FILEDATA->FILEDATA][FAIL][NO_CACHE] dev=" << id << std::endl; + } dev->guid.clear(); dev->isbusy = 0; dev->busytype = 0; dev->busytimecount = 0; - std::cout << "[RESP][FILEDATA->FILEDATA][OK] dev=" << id << std::endl; + } else { // 失败:响应web并复位 - //send_reply_to_cloud(response_code, id, static_cast(DeviceState::READING_FILEDATA),dev->guid,dev->mac); - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"失败,停止该业务处理"); + send_reply_to_cloud(response_code, id, device_state_int,dev->guid,dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) +"失败,停止该业务处理"); dev->guid.clear(); dev->isbusy = 0; @@ -6365,10 +6457,13 @@ void on_device_response_minimal(int response_code, // 发送运行信息 send_running_info(dev, info); + std::cout << "[RESP][RUNNINGINFO][OK] dev=" << id << std::endl; + } else { - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + - get_type_by_state(dev->busytype) + "失败,运行状态缓存不存在"); + send_reply_to_cloud(static_cast(ResponseCode::BAD_REQUEST), id, device_state_int, dev->guid, dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + + // get_type_by_state(dev->busytype) + "失败,运行状态缓存不存在"); std::cout << "[RESP][RUNNINGINFO][WARN] dev=" << id << " running info missing in cache" << std::endl; @@ -6379,11 +6474,12 @@ void on_device_response_minimal(int response_code, dev->busytype = 0; dev->busytimecount = 0; - std::cout << "[RESP][RUNNINGINFO][OK] dev=" << id << std::endl; + } else { - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + - get_type_by_state(dev->busytype) + "失败,停止该业务处理"); + send_reply_to_cloud(response_code, id, device_state_int,dev->guid,dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + + // get_type_by_state(dev->busytype) + "失败,停止该业务处理"); dev->guid.clear(); dev->isbusy = 0; @@ -6426,10 +6522,13 @@ void on_device_response_minimal(int response_code, // 发送版本信息 send_version_info(dev, info); + std::cout << "[RESP][VERSIONINFO][OK] dev=" << id << std::endl; + } else { - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + - get_type_by_state(dev->busytype) + "失败,版本信息缓存不存在"); + send_reply_to_cloud(static_cast(ResponseCode::BAD_REQUEST), id, device_state_int, dev->guid, dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + + // get_type_by_state(dev->busytype) + "失败,版本信息缓存不存在"); std::cout << "[RESP][VERSIONINFO][WARN] dev=" << id << " version info missing in cache" << std::endl; @@ -6440,11 +6539,12 @@ void on_device_response_minimal(int response_code, dev->busytype = 0; dev->busytimecount = 0; - std::cout << "[RESP][VERSIONINFO][OK] dev=" << id << std::endl; + } else { - send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), - "终端 id: " + dev->terminal_id + "进行业务:" + - get_type_by_state(dev->busytype) + "失败,停止该业务处理"); + send_reply_to_cloud(response_code, id, device_state_int,dev->guid,dev->mac); + //send_reply_to_queue(dev->guid, static_cast(ResponseCode::BAD_REQUEST), + // "终端 id: " + dev->terminal_id + "进行业务:" + + // get_type_by_state(dev->busytype) + "失败,停止该业务处理"); dev->guid.clear(); dev->isbusy = 0; @@ -6500,30 +6600,36 @@ void on_device_response_minimal(int response_code, // 下发升级指令 ClientManager::instance().send_upgrade_action_to_device(id, file_data, 10240); + //正在处理 + send_reply_to_cloud(static_cast(ResponseCode::PROCESSING), id, device_state_int, dev->guid, dev->mac); + dev->isbusy = 1; // 完成了预校验但是仍处于忙碌,因为还要升级 - }else if(dev->isbusy == 1){ - std::cout << "[SET_PREUPGRADE] already upgrade OK, terminal_id=" + + std::cout << "[SET_PREUPGRADE] already upgrade prepare finish, terminal_id=" << id << std::endl; - send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); - send_reply_to_queue(dev->guid, response_code, - "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) + "," + ResponseCodeToString(response_code) + "停止该业务处理"); + }else if(dev->isbusy == 1){ + + //升级成功 + send_reply_to_cloud(static_cast(ResponseCode::OK), id, device_state_int, dev->guid, dev->mac); + //send_reply_to_queue(dev->guid, response_code, + // "终端 id: " + dev->terminal_id + "进行业务:" + get_type_by_state(dev->busytype) + "," + ResponseCodeToString(response_code) + "停止该业务处理"); //成功结束业务 dev->guid.clear(); // 清空 guid dev->busytype = 0; // 业务类型归零 dev->isbusy = 0; // 清空业务标志 dev->busytimecount = 0; // 计时归零 - std::cout << "[clear_terminal_runtime_state] Cleared runtime state for terminal_id=" - << id << std::endl; - + + std::cout << "[SET_PREUPGRADE] already upgrade OK, terminal_id=" + << id << std::endl; } else { std::cout << "[SET_PREUPGRADE] status error" <guid, dev->mac); - send_reply_to_queue(dev->guid, response_code, - "终端 id: " + dev->terminal_id + - "进行业务:" + get_type_by_state(dev->busytype) + - ",处理逻辑错误,停止该业务处理"); + send_reply_to_cloud(static_cast(ResponseCode::BAD_REQUEST), id, device_state_int, dev->guid, dev->mac); + //send_reply_to_queue(dev->guid, response_code, + // "终端 id: " + dev->terminal_id + + // "进行业务:" + get_type_by_state(dev->busytype) + + // ",处理逻辑错误,停止该业务处理"); dev->guid.clear(); dev->busytype = 0; dev->isbusy = 0; @@ -6535,11 +6641,12 @@ void on_device_response_minimal(int response_code, std::cout << "[SET_PREUPGRADE] read/send failed: " << e.what() << std::endl; - send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); - send_reply_to_queue(dev->guid, response_code, - "终端 id: " + dev->terminal_id + - "进行业务:" + get_type_by_state(dev->busytype) + - "," + ResponseCodeToString(response_code) + "停止该业务处理"); + //未知原因失败,直接结束业务 + send_reply_to_cloud(static_cast(ResponseCode::FORBIDDEN), id, device_state_int, dev->guid, dev->mac); + //send_reply_to_queue(dev->guid, response_code, + // "终端 id: " + dev->terminal_id + + // "进行业务:" + get_type_by_state(dev->busytype) + + // "," + ResponseCodeToString(response_code) + "停止该业务处理"); // 失败也要清状态 dev->guid.clear(); @@ -6554,10 +6661,10 @@ void on_device_response_minimal(int response_code, << id << std::endl; send_reply_to_cloud(response_code, id, device_state_int, dev->guid, dev->mac); - send_reply_to_queue(dev->guid, response_code, - "终端 id: " + dev->terminal_id + - "进行业务:" + get_type_by_state(dev->busytype) + - "," + ResponseCodeToString(response_code) + "停止该业务处理"); + //send_reply_to_queue(dev->guid, response_code, + // "终端 id: " + dev->terminal_id + + // "进行业务:" + get_type_by_state(dev->busytype) + + // "," + ResponseCodeToString(response_code) + "停止该业务处理"); dev->guid.clear(); dev->busytype = 0; @@ -7276,39 +7383,40 @@ bool SendFileWebAuto(const std::string& id, if (dev_ptr) { const int bt = dev_ptr->busytype; - // 若处于“事件文件/统计文件”补招阶段,则使用补招专用上传目录:comtrade/wave/... + // 若处于补招阶段,不在这边上传 if (bt == static_cast(DeviceState::READING_EVENTFILE) || bt == static_cast(DeviceState::READING_STATSFILE)) { - - std::string rel = dirname_with_slash(local_path); // 例如:download/00:B7:.../ - // 将 download/ 前缀替换为 wave/ - if (!replace_prefix(rel, "download/", "wave/")) { - // 若不是以 download/ 开头,兜底拼 wave/ + 原目录 - rel = "wave/" + rel; - } - - file_cloudpath = "comtrade/" + rel; // 目标:comtrade/wave/00:B7:.../ - std::cout << "[SendFileWebAuto] dev=" << id << " busytype=" << bt - << " -> use recall upload URL (cloud path=" << file_cloudpath << ")\n"; - } else { + << " -> skip upload (recall file)\n"; + return true; // 认为成功,外层业务继续处理(但不上传) + } else if(bt == static_cast(DeviceState::READING_FILEDATA)) { // 非补招场景沿用原来的 download 目录 - file_cloudpath = dirname_with_slash(local_path); // 保持原逻辑 + file_cloudpath = dirname_with_slash(local_path); std::cout << "[SendFileWebAuto] dev=" << id << " busytype=" << bt << " -> use default upload URL (cloud path=" << file_cloudpath << ")\n"; + + // 实际上传调用 + SendFileWeb(WEB_FILEUPLOAD, local_path, file_cloudpath, out_filename,2); + + std::cout << "[SendFileWebAuto] File upload complete: " << out_filename << std::endl; + + //记录下载的文件名到列表中,后续发送响应 + filedownload_cache_put(id, + sanitize(local_path), + sanitize(out_filename)); + } + else { + std::cout << "[SendFileWebAuto][WARN] dev=" << id + << " busytype=" << bt + << " -> no upload (unsupported state)\n"; } } else { std::cout << "[SendFileWebAuto][WARN] device not found for id=" << id << ", fallback to default URL\n"; - file_cloudpath = dirname_with_slash(local_path); } - // 实际上传调用 - SendFileWeb(WEB_FILEUPLOAD, local_path, file_cloudpath, out_filename); - - std::cout << "[SendFileWebAuto] File upload complete: " << out_filename << std::endl; return true; } catch (const std::exception& e) { diff --git a/LFtid1056/cloudfront/code/interface.cpp b/LFtid1056/cloudfront/code/interface.cpp index 06e8f82..54ca5c6 100644 --- a/LFtid1056/cloudfront/code/interface.cpp +++ b/LFtid1056/cloudfront/code/interface.cpp @@ -136,7 +136,7 @@ void SendJsonAPI_web(const std::string& strUrl, //接口路径 ////////////////////////////////////////////////////////////////////////////////////////////////////////上传文件接口 //处理文件上传响应 -void handleUploadResponse(const std::string& response, std::string& wavepath) { +void handleUploadResponse(const std::string& response, std::string& wavepath, int type) { using nlohmann::json; //把 nlohmann::json 这个名字带到当前作用域 @@ -183,13 +183,22 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) { // 找到最后一个 '.' size_t pos = name.find_last_of('.'); std::string nameWithoutExt; - if (pos != std::string::npos) { - // 截取去掉后缀的部分 - nameWithoutExt = name.substr(0, pos); - } else { - // 如果没有后缀,直接使用原文件名 - nameWithoutExt = name; + if(1 == type) { + if (pos != std::string::npos) { + // 截取去掉后缀的部分 + nameWithoutExt = name.substr(0, pos); //去掉路径后缀的名 + } else { + // 如果没有后缀,直接使用原文件名 + nameWithoutExt = name; + } } + else if(2 == type) { + nameWithoutExt = name;//带路径全名 + } + else{ + nameWithoutExt = fileName;//没有路径的全名 + } + // 拷贝到 wavepath wavepath = nameWithoutExt; @@ -199,7 +208,7 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) { } //上传文件 -void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath) { +void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath, int type) { // 基本存在性检查 if (access(localpath.c_str(), F_OK) != 0) { @@ -274,7 +283,7 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const DIY_ERRORLOG_CODE("process",0,LOG_CODE_CONFIG, "通过文件接口上传文件 %s 失败",localpath.c_str()); } else { std::cout << "http web success, response: " << resPost0 << std::endl; - handleUploadResponse(resPost0, wavepath); // 处理响应 + handleUploadResponse(resPost0, wavepath, type); // 处理响应 } // 清理 @@ -289,7 +298,7 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const //上传暂态文件 void SOEFileWeb(std::string& localpath,std::string& cloudpath, std::string& wavepath) { - SendFileWeb(WEB_FILEUPLOAD,localpath,cloudpath,wavepath); + SendFileWeb(WEB_FILEUPLOAD,localpath,cloudpath,wavepath,1); } //上传文件测试函数 diff --git a/LFtid1056/cloudfront/code/interface.h b/LFtid1056/cloudfront/code/interface.h index 08c5624..b63007f 100644 --- a/LFtid1056/cloudfront/code/interface.h +++ b/LFtid1056/cloudfront/code/interface.h @@ -718,7 +718,7 @@ bool save_internal_value(const std::string &dev_id, const std::vector &f bool save_set_value(const std::string &dev_id, unsigned char mp_index, const std::vector &fabsf); //发送文件 -void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath); +void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath,int Type); //状态翻转 void connect_status_update(const std::string& id, int status); diff --git a/LFtid1056/cloudfront/code/rocketmq.cpp b/LFtid1056/cloudfront/code/rocketmq.cpp index 60c09e8..1b769d2 100644 --- a/LFtid1056/cloudfront/code/rocketmq.cpp +++ b/LFtid1056/cloudfront/code/rocketmq.cpp @@ -2083,7 +2083,7 @@ bool parseJsonMessageCLOUD(const std::string &body, std::cerr << "[parseJsonMessageCLOUD] 'messageBody' is missing or is not a string\n"; guid.clear(); devid.clear(); - front_ip.clear(); + front_id.clear(); node = 0; detailObj = nlohmann::json::object(); return false; @@ -2094,7 +2094,7 @@ bool parseJsonMessageCLOUD(const std::string &body, std::cerr << "[parseJsonMessageCLOUD] 'messageBody' is empty\n"; guid.clear(); devid.clear(); - front_ip.clear(); + front_id.clear(); node = 0; detailObj = nlohmann::json::object(); return false; @@ -2112,9 +2112,9 @@ bool parseJsonMessageCLOUD(const std::string &body, // FrontId if (j.contains("FrontId") && j["FrontId"].is_string()) { - front_ip = j["FrontId"].get(); + front_id = j["FrontId"].get(); } else { - front_ip.clear(); + front_id.clear(); } // Node @@ -2154,7 +2154,7 @@ bool parseJsonMessageCLOUD(const std::string &body, std::cerr << "[parseJsonMessageCLOUD] JSON parse error: " << e.what() << "\n"; guid.clear(); devid.clear(); - front_ip.clear(); + front_id.clear(); node = 0; detailObj = nlohmann::json::object(); return false; @@ -2222,10 +2222,23 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: try { switch (parsed.type) { case 1101: { // 读取目录 - - if(!recordguid(devid,guid,static_cast(DeviceState::READING_FILEMENU),1)){ + int ret = recordguid(devid,guid,static_cast(DeviceState::READING_FILEMENU),1); + if(-1 == ret){ //0记录成功往下执行,1装置正忙,-1未找到装置 + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), //响应 + "未找到该装置,读取目录指令执行失败"); + DIY_ERRORLOG_CODE(devid,1,LOG_CODE_CLOUD, "未找到该装置,读取目录指令执行失败"); //日志记录 return true; } + else if(ret > 0){ + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,读取目录指令执行失败"); + DIY_WARNLOG_CODE(devid,1,LOG_CODE_CLOUD, "该装置正忙,读取目录指令执行失败"); + return true; + } + else{ + std::cout << "记录装置状态成功,准备读取目录" << std::endl; //调试输出 + DIY_INFOLOG_CODE(devid,1,LOG_CODE_CLOUD, "记录装置状态成功,准备读取目录"); + } if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; parsed.name = msgObj["Name"].get(); @@ -2240,8 +2253,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: case 1102: { // 下载文件 - if(!recordguid(devid,guid,static_cast(DeviceState::READING_FILEDATA),1)){ - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::READING_FILEDATA), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,下载文件指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,下载文件指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,下载文件指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,下载文件指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备下载文件" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备下载文件"); + } } if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; @@ -2276,7 +2305,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: parsed.dataArray_us.clear(); switch (parsed.datatype) { - case 0x0C: { // 定值(float 阵列) + case 1: { // 定值(float 阵列) for (const auto& v : msgObj["DataArray"]) { if (!v.is_number()) return false; @@ -2285,7 +2314,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } // 打印 DataArray - std::cout << "[0x0C] DataArray=["; + std::cout << "[1] DataArray=["; for (size_t i = 0; i < parsed.dataArray_f.size(); ++i) { std::cout << parsed.dataArray_f[i] << (i + 1 < parsed.dataArray_f.size() ? ", " : ""); } @@ -2297,8 +2326,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: switch (parsed.operate) { case 1: { // 读 - if(!recordguid(devid,guid,static_cast(DeviceState::READING_FIXEDVALUE),2)){ - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::READING_FIXEDVALUE), 2); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,读取定值指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取定值指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,读取定值指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取定值指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备读取定值" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取定值"); + } } ClientManager::instance().get_fixedvalue_action_to_device( @@ -2308,8 +2353,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } case 2: { // 写 - if(!recordguid(devid,guid,static_cast(DeviceState::SET_FIXEDVALUE),1)){ - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SET_FIXEDVALUE), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,写定值指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,写定值指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,写定值指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,写定值指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备写定值" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备写定值"); + } } ClientManager::instance().set_fixedvalue_action_to_device( @@ -2322,7 +2383,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: break; } - case 0x0D: { // 内部定值(uint16_t 阵列) + case 2: { // 内部定值(uint16_t 阵列) for (const auto& v : msgObj["DataArray"]) { if (!v.is_number_integer() && !v.is_number_unsigned()) return false; // 范围校验 [0, 65535] @@ -2332,7 +2393,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } // 打印 DataArray - std::cout << "[0x0D] DataArray=["; + std::cout << "[2] DataArray=["; for (size_t i = 0; i < parsed.dataArray_us.size(); ++i) { std::cout << parsed.dataArray_us[i] << (i + 1 < parsed.dataArray_us.size() ? ", " : ""); } @@ -2344,8 +2405,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: switch (parsed.operate) { case 1: { // 读 - if(!recordguid(devid,guid,static_cast(DeviceState::READING_INTERFIXEDVALUE),3)){ - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::READING_INTERFIXEDVALUE), 3); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,读取内部定值指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取内部定值指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,读取内部定值指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取内部定值指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备读取内部定值" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取内部定值"); + } } ClientManager::instance().get_interfixedvalue_action_to_device(devid); // 获取内部定值 @@ -2355,8 +2432,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } case 2: { // 写 - if(!recordguid(devid,guid,static_cast(DeviceState::SET_INTERFIXEDVALUE),1)){ - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SET_INTERFIXEDVALUE), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,写内部定值指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,写内部定值指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,写内部定值指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,写内部定值指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备写内部定值" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备写内部定值"); + } } ClientManager::instance().set_interfixedvalue_action_to_device(devid, parsed.dataArray_us); @@ -2384,8 +2477,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: << ", guid=" << guid << std::endl; // - if (!recordguid(devid, guid, static_cast(DeviceState::READING_RUNNINGINFORMATION_1), 1)) { - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::READING_RUNNINGINFORMATION_1), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,读取运行状态指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取运行状态指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,读取运行状态指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取运行状态指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备读取运行状态" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取运行状态"); + } } // @@ -2399,8 +2508,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: std::cout << "[parsemsg] read version info, devid=" << devid << ", guid=" << guid << std::endl; - if (!recordguid(devid, guid, static_cast(DeviceState::READING_DEVVERSION), 1)) { - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::READING_DEVVERSION), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,读取版本信息指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取版本信息指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,读取版本信息指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取版本信息指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备读取版本信息" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取版本信息"); + } } ClientManager::instance().read_devversion_action_to_device(devid); @@ -2413,11 +2538,27 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: std::cout << "[parsemsg] time sync, devid=" << devid << ", guid=" << guid << std::endl; - if (!recordguid(devid, guid, static_cast(DeviceState::SET_RIGHTTIME_2), 1)) { - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SET_RIGHTTIME_2), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,对时指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,对时指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,对时指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,对时指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备对时" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备对时"); + } } - // 方案A:Msg 为空,直接使用当前系统时间下发 + // ClientManager::instance().set_righttime_action_to_device(devid); return true; @@ -2429,8 +2570,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: std::cout << "[parsemsg] reboot device, devid=" << devid << ", guid=" << guid << std::endl; - if (!recordguid(devid, guid, static_cast(DeviceState::SET_CTRL), 1)) { - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SET_CTRL), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,重启指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,重启指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,重启指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,重启指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备重启装置" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备重启装置"); + } } ClientManager::instance().set_ctrl_action_to_device(devid,0x01,0x00);//尝试装置重启指令! @@ -2443,8 +2600,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: std::cout << "[parsemsg] upgrade device, devid=" << devid << ", guid=" << guid << std::endl; - if (!recordguid(devid, guid, static_cast(DeviceState::SET_PREUPGRADE), 2)) { - return true; + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SET_PREUPGRADE), 2); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,升级指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,升级指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,升级指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,升级指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备执行升级预校验" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行升级预校验"); + } } ClientManager::instance().set_preupgrade_action_to_device(devid, "");//尝试装置升级指令!第一步校验 @@ -2465,7 +2638,29 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } } -//心跳和其他响应 +//////////////////////////////////////////////////////////////////////////////////////////////////////////云响应 +static int get_cloud_type_by_state(int type) +{ + switch (static_cast(type)) { + case DeviceState::READING_FILEMENU: return 1101; // 读取文件目录 + case DeviceState::READING_FILEDATA: return 1102; // 下载文件数据 + + case DeviceState::READING_FIXEDVALUE: return 1103; // 读取测点定值 + case DeviceState::SET_FIXEDVALUE: return 1103; // 设置测点定值 + case DeviceState::READING_INTERFIXEDVALUE: return 1103; // 读取内部定值 + case DeviceState::SET_INTERFIXEDVALUE: return 1103; // 设置内部定值 + + case DeviceState::READING_RUNNINGINFORMATION_1: return 1111; // 主动读取运行状态 + case DeviceState::READING_DEVVERSION: return 1112; // 读取版本信息 + case DeviceState::SET_RIGHTTIME_2: return 1113; // 主动对时 + case DeviceState::SET_CTRL: return 1114; // 控制/重启 + case DeviceState::SET_PREUPGRADE: return 1115; // 升级预校验 + + default: + return type; // 其他未映射的,保持原值,避免影响现有逻辑 + } +} + void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, const std::string& guid, const std::string& mac) { try { /*std::string guid = find_guid_index_from_dev_id(dev_id);*/ @@ -2487,7 +2682,7 @@ void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, co // ---- 构造 Detail ---- nlohmann::json detail; - detail["Type"] = type; + detail["Type"] = get_cloud_type_by_state(type); // Msg nlohmann::json msg; diff --git a/LFtid1056/dealMsg.cpp b/LFtid1056/dealMsg.cpp index b165e4e..34df4ea 100644 --- a/LFtid1056/dealMsg.cpp +++ b/LFtid1056/dealMsg.cpp @@ -979,45 +979,49 @@ void process_received_message(string mac, string id,const char* data, size_t len //调试用 // 若是 .cfg,先查看并打印内容(限长) - { - auto dot = file_path.find_last_of('.'); - std::string ext = (dot == std::string::npos) ? "" : file_path.substr(dot); - // 转小写比较 - for (auto& c : ext) c = static_cast(std::tolower(static_cast(c))); - if (ext == ".cfg") { - std::ifstream fin(file_path, std::ios::binary); - if (!fin) { - std::cerr << "[CFG] open failed: " << file_path << " (" << std::strerror(errno) << ")\n"; - } else { - // 读取前 8KB 作为预览,避免日志过大 - constexpr size_t kMaxPreview = 8 * 1024; - std::string buf; - buf.resize(kMaxPreview); - fin.read(&buf[0], static_cast(kMaxPreview)); - std::streamsize got = fin.gcount(); - buf.resize(static_cast(got)); - - std::cout << "================ [CFG PREVIEW BEGIN] ================\n"; - std::cout << "path=" << file_path << ", size=" << file_data.size() - << " bytes, preview=" << got << " bytes\n"; - // 直接打印文本预览;如果包含不可见字符,会按原样输出 - std::cout.write(buf.data(), static_cast(buf.size())); - if (static_cast(got) == kMaxPreview && fin.peek() != EOF) { - std::cout << "\n...[truncated]\n"; - } - std::cout << "\n================ [CFG PREVIEW END] ==================\n"; - } - } - } + { + auto dot = file_path.find_last_of('.'); + std::string ext = (dot == std::string::npos) ? "" : file_path.substr(dot); + // 转小写比较 + for (auto& c : ext) c = static_cast(std::tolower(static_cast(c))); + if (ext == ".cfg") { + std::ifstream fin(file_path, std::ios::binary); + if (!fin) { + std::cerr << "[CFG] open failed: " << file_path << " (" << std::strerror(errno) << ")\n"; + } else { + // 读取前 8KB 作为预览,避免日志过大 + constexpr size_t kMaxPreview = 8 * 1024; + std::string buf; + buf.resize(kMaxPreview); + fin.read(&buf[0], static_cast(kMaxPreview)); + std::streamsize got = fin.gcount(); + buf.resize(static_cast(got)); + + std::cout << "================ [CFG PREVIEW BEGIN] ================\n"; + std::cout << "path=" << file_path << ", size=" << file_data.size() + << " bytes, preview=" << got << " bytes\n"; + // 直接打印文本预览;如果包含不可见字符,会按原样输出 + std::cout.write(buf.data(), static_cast(buf.size())); + if (static_cast(got) == kMaxPreview && fin.peek() != EOF) { + std::cout << "\n...[truncated]\n"; + } + std::cout << "\n================ [CFG PREVIEW END] ==================\n"; + } + } + } //使用接口上送文件lnk20250826 std::string filename; - //SendFileWebAuto(id, file_path, file_path, filename);//如果是补招文件的下载,下载后也是直接上传,这样单纯补招波形也可以保证传文件 - std::cout << "File download success wait for upload: " << filename << std::endl; - - //通知文件上传 - on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::READING_FILEDATA)); + if(SendFileWebAuto(id, file_path, file_path, filename)){//如果是补招文件的下载则不会在这边上送 + std::cout << "File upload success: " << filename << std::endl; + //通知文件上传 + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::READING_FILEDATA)); + } + else{ + on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::READING_FILEDATA)); + std::cerr << "File download success but upload failed: " << filename << std::endl; + } } else { on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::READING_FILEDATA)); From ea176eceafc22cd172e0856f8dc812939bb60203 Mon Sep 17 00:00:00 2001 From: lnk Date: Thu, 2 Apr 2026 16:23:15 +0800 Subject: [PATCH 3/3] add interface --- LFtid1056/cloudfront/code/interface.cpp | 174 +++++++++++++++++++++ LFtid1056/cloudfront/code/interface.h | 2 +- LFtid1056/cloudfront/code/log4.cpp | 37 +++-- LFtid1056/cloudfront/code/log4.h | 2 + LFtid1056/cloudfront/code/rocketmq.cpp | 200 +++++++++++++++++++++++- LFtid1056/dealMsg.cpp | 55 +++++++ 6 files changed, 457 insertions(+), 13 deletions(-) diff --git a/LFtid1056/cloudfront/code/interface.cpp b/LFtid1056/cloudfront/code/interface.cpp index 54ca5c6..0b62917 100644 --- a/LFtid1056/cloudfront/code/interface.cpp +++ b/LFtid1056/cloudfront/code/interface.cpp @@ -133,6 +133,81 @@ void SendJsonAPI_web(const std::string& strUrl, //接口路径 } } +////////////////////////////////////////////////////////////////////////////////////////////////////////下载文件流式接口 +size_t req_reply_file_web(void* ptr, size_t size, size_t nmemb, void* userdata) +{ + std::ofstream* out = static_cast(userdata); + size_t total = size * nmemb; + + if (out && out->is_open()) { + out->write(static_cast(ptr), total); + } + + return total; +} +bool DownloadFileAPI_web(const std::string& strUrl, // 接口路径 + const std::string& code, // URL参数 + const std::string& json, // POST body,可为空 + const std::string& save_path)// 本地保存路径 +{ + CURL* curl = curl_easy_init(); + CURLcode res; + + if (!curl) { + std::cerr << ">>> web curl init failed" << std::endl; + return false; + } + + std::ofstream outFile(save_path.c_str(), std::ios::out | std::ios::binary); + if (!outFile.is_open()) { + std::cerr << ">>> open file failed: " << save_path << std::endl; + curl_easy_cleanup(curl); + return false; + } + + std::string fullUrl = strUrl + "?" + code; + std::cout << ">>>file " << fullUrl << std::endl; + + curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_file_web); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &outFile); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10); + curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60); + + if (!json.empty()) { + curl_easy_setopt(curl, CURLOPT_POST, 1L); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str()); + } + + struct curl_slist* headers = nullptr; + headers = curl_slist_append(headers, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + + res = curl_easy_perform(curl); + + long http_code = 0; + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + + outFile.close(); + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + + if (res != CURLE_OK) { + std::cerr << "web failed, res code: " << curl_easy_strerror(res) << std::endl; + remove(save_path.c_str()); // 下载失败删除残文件 + return false; + } + + if (http_code != 200) { + std::cerr << "web http failed, http_code: " << http_code << std::endl; + remove(save_path.c_str()); + return false; + } + + std::cout << ">>> file download success: " << save_path << std::endl; + return true; +} + ////////////////////////////////////////////////////////////////////////////////////////////////////////上传文件接口 //处理文件上传响应 @@ -311,6 +386,105 @@ void Fileupload_test() std::cout << "wavepath:" << wavepath << std::endl; } +/////////////////////////////////////////////////////////////////////////////////////////////////////下载文件接口通用 +// 下载文件:从远端路径下载到本地,并返回本地文件路径 +// 入参:dev(设备)、remote_path(远端完整路径) +// 返回:本地保存路径(失败返回空字符串) +std::string getfilefromweb(const std::string& devid, const std::string& remote_path) +{ + try { + terminal_dev* dev = nullptr; + { + std::lock_guard lock(ledgermtx); + for (auto& d : terminal_devlist) { + if (d.terminal_id == devid) { + dev = &d; + break; + } + } + } + + if (!dev) { + std::cerr << "[getfile][ERROR] dev not found, id=" << devid << std::endl; + return ""; + } + //【1】清洗远端路径(防止 \0 问题) + std::string clean_remote = sanitize(remote_path); + + //【2】提取文件名(去掉路径,只保留最后一段) + auto get_filename = [](const std::string& path) -> std::string { + size_t pos1 = path.find_last_of('/'); + size_t pos2 = path.find_last_of('\\'); + size_t pos = std::string::npos; + + if (pos1 == std::string::npos) pos = pos2; + else if (pos2 == std::string::npos) pos = pos1; + else pos = std::max(pos1, pos2); + + return (pos == std::string::npos) ? path : path.substr(pos + 1); + }; + + std::string filename = get_filename(clean_remote); + + //【3】构造本地保存路径 + std::string mac = sanitize(normalize_mac(dev->addr_str)); + std::string save_dir = std::string(FRONT_PATH) + "/bin/upload/" + mac + "/"; + + if (!create_directory_recursive(save_dir)) { + std::cerr << "[getfile][ERROR] create dir failed: " << save_dir << std::endl; + return ""; + } + + std::string save_path = save_dir + filename; + + std::cout << "[getfile] remote: " << clean_remote + << " -> local: " << save_path << std::endl; + + //【4】构造接口入参 + //std::string fileContent; + std::string fullPath = "filePath=" + clean_remote; + + std::cout << "[getfile] request param: " << fullPath << std::endl; + + //【5】调用下载接口 + if (!DownloadFileAPI_web(WEB_FILEDOWNLOAD, fullPath, "", save_path)) { + std::cerr << "[getfile][ERROR] download failed: " << clean_remote << std::endl; + return ""; + } + /*SendJsonAPI_web(WEB_FILEDOWNLOAD, fullPath.c_str(), "", fileContent); + + + //【6】判断返回 + if (fileContent.empty()) { + std::cerr << "[getfile][ERROR] download failed, empty content" << std::endl; + return ""; + } + + //【7】写文件 + std::ofstream outFile(save_path, std::ios::out | std::ios::binary); + if (!outFile.is_open()) { + std::cerr << "[getfile][ERROR] cannot open file: " << save_path << std::endl; + return ""; + } + + outFile.write(fileContent.c_str(), fileContent.size()); + outFile.close();*/ + + std::cout << "[getfile] File saved successfully: " << save_path << std::endl; + + //【8】返回本地路径 + return save_path; + } + catch (const std::exception& e) { + std::cerr << "[getfile][EXCEPTION] " << e.what() << std::endl; + } + catch (...) { + std::cerr << "[getfile][EXCEPTION] unknown error" << std::endl; + } + + return ""; +} + //////////////////////////////////////////////////////////////////////////////////////////////////////映射文件下载接口 void download_xml_for_icd(const std::string& MODEL_ID, const std::string& TMNL_TYPE, diff --git a/LFtid1056/cloudfront/code/interface.h b/LFtid1056/cloudfront/code/interface.h index b63007f..0b4c364 100644 --- a/LFtid1056/cloudfront/code/interface.h +++ b/LFtid1056/cloudfront/code/interface.h @@ -687,7 +687,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std:: //上送文件列表接口 bool send_file_list(terminal_dev* dev, const std::vector &FileList); - +std::string getfilefromweb(const std::string& devid, const std::string& remote_path); //提取mac std::string normalize_mac(const std::string& mac); diff --git a/LFtid1056/cloudfront/code/log4.cpp b/LFtid1056/cloudfront/code/log4.cpp index 8d7d4c0..e42ac67 100644 --- a/LFtid1056/cloudfront/code/log4.cpp +++ b/LFtid1056/cloudfront/code/log4.cpp @@ -92,16 +92,35 @@ std::string build_debug_key(const std::string& id, const std::string& level, int // 递归创建目录 -bool create_directory_recursive(const std::string& path) { - size_t pos = 0; +bool create_directory_recursive(const std::string& path) +{ + if (path.empty()) return false; + std::string current; - while (pos != std::string::npos) { - pos = path.find('/', pos + 1); - current = path.substr(0, pos); - if (!current.empty() && access(current.c_str(), F_OK) != 0) { - if (mkdir(current.c_str(), 0755) != 0) { - perror(("mkdir failed: " + current).c_str()); - return false; + current.reserve(path.size()); + + for (size_t i = 0; i < path.size(); ++i) { + current += path[i]; + + // 遇到 '/' 或最后一个字符时创建 + if (path[i] == '/' || i == path.size() - 1) { + if (current.empty()) continue; + + // 去掉末尾 '/' + std::string dir = current; + if (dir.back() == '/' && dir.size() > 1) { + dir.pop_back(); + } + + struct stat st; + if (stat(dir.c_str(), &st) != 0) { + if (mkdir(dir.c_str(), 0755) != 0) { + // 如果已经存在(并发场景),忽略 + if (errno != EEXIST) { + perror(("mkdir failed: " + dir).c_str()); + return false; + } + } } } } diff --git a/LFtid1056/cloudfront/code/log4.h b/LFtid1056/cloudfront/code/log4.h index 7b4e33c..c569c8a 100644 --- a/LFtid1056/cloudfront/code/log4.h +++ b/LFtid1056/cloudfront/code/log4.h @@ -97,6 +97,8 @@ void update_log_entries_countdown(); void refresh_log_level_cache_locked(); +bool create_directory_recursive(const std::string& path); + extern "C" { #endif void remove_loggers_by_terminal_id(const std::string& terminal_id_cstr); diff --git a/LFtid1056/cloudfront/code/rocketmq.cpp b/LFtid1056/cloudfront/code/rocketmq.cpp index 1b769d2..8ddba0d 100644 --- a/LFtid1056/cloudfront/code/rocketmq.cpp +++ b/LFtid1056/cloudfront/code/rocketmq.cpp @@ -2222,6 +2222,8 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: try { switch (parsed.type) { case 1101: { // 读取目录 + if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; + int ret = recordguid(devid,guid,static_cast(DeviceState::READING_FILEMENU),1); if(-1 == ret){ //0记录成功往下执行,1装置正忙,-1未找到装置 send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), //响应 @@ -2240,7 +2242,6 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: DIY_INFOLOG_CODE(devid,1,LOG_CODE_CLOUD, "记录装置状态成功,准备读取目录"); } - if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; parsed.name = msgObj["Name"].get(); parsed.ok = true; @@ -2252,7 +2253,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } case 1102: { // 下载文件 - + if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; { int ret = recordguid(devid, guid, static_cast(DeviceState::READING_FILEDATA), 1); if (-1 == ret) { @@ -2273,7 +2274,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } } - if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; + parsed.name = msgObj["Name"].get(); parsed.ok = true; @@ -2625,7 +2626,200 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann: } ////////lnk20260312新增读取运行状态、版本、对时、重启 + ////////lnk20260402新增目录新建、删除,文件删除,文件上传 + case 1116: { // 文件上送 + if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; + if (!msgObj.contains("RemoteName") || !msgObj["RemoteName"].is_string()) return false; + parsed.ok = true; + + std::cout << "[parsemsg] send file, devid=" << devid + << ", guid=" << guid << std::endl; + + //【1】recordguid + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SEND_FILE), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,文件上送指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,文件上送指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,文件上送指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,文件上送指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备执行文件上送" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行文件上送"); + } + } + + //【2】取参数(加 sanitize) + std::string remote_path = sanitize(msgObj["Name"].get()); // 云端路径 + std::string dest_file_path = sanitize(msgObj["RemoteName"].get()); // 装置路径 + + std::cout << "[parsemsg][1116] remote=" << remote_path + << ", dest=" << dest_file_path << std::endl; + + //【3】先下载到本地 + std::string local_path = getfilefromweb(devid, remote_path); + + if (local_path.empty()) { + send_reply_to_queue(guid, static_cast(ResponseCode::BAD_REQUEST), + "文件上送失败,下载源文件失败: " + remote_path); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件发送装置失败,下载源文件失败"); + return true; + } + + //【4】读取本地文件 + std::ifstream in(local_path.c_str(), std::ios::in | std::ios::binary); + if (!in.is_open()) { + send_reply_to_queue(guid, static_cast(ResponseCode::BAD_REQUEST), + "文件上送失败,无法打开本地文件: " + local_path); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件发送装置失败,无法打开本地文件"); + return true; + } + + std::vector file_data; + + in.seekg(0, std::ios::end); + std::streamoff file_size = in.tellg(); + in.seekg(0, std::ios::beg); + + if (file_size < 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BAD_REQUEST), + "文件上送失败,读取文件大小异常: " + local_path); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件发送装置失败,读取文件大小异常"); + return true; + } + + file_data.resize(static_cast(file_size)); + if (file_size > 0) { + in.read(reinterpret_cast(&file_data[0]), file_size); + } + in.close(); + + //【5】下发到装置 + if (!ClientManager::instance().send_file_action_to_device( + devid, file_data, 10240, dest_file_path)) { + + send_reply_to_queue(guid, static_cast(ResponseCode::BAD_REQUEST), + "文件上送指令下发失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件上送指令下发失败"); + return true; + } + + return true; + } + case 1117: { // 文件删除 + if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; + parsed.ok = true; + + std::cout << "[parsemsg] delete file, devid=" << devid + << ", guid=" << guid << std::endl; + + { + int ret = recordguid(devid, guid, static_cast(DeviceState::DEL_FILE), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,文件删除指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,文件删除指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,文件删除指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,文件删除指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备执行文件删除" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行文件删除"); + } + } + + + std::string dev_file_name = msgObj["Name"].get(); + + std::cout << "[parsemsg][1117] Name=" << dev_file_name << std::endl; + + ClientManager::instance().add_file_delete_action_to_device(devid, dev_file_name); + return true; + } + case 1118: { // 目录创建 + if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; + parsed.ok = true; + + std::cout << "[parsemsg] create menu, devid=" << devid + << ", guid=" << guid << std::endl; + + { + int ret = recordguid(devid, guid, static_cast(DeviceState::SEND_MENU), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,目录创建指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,目录创建指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,目录创建指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,目录创建指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备执行目录创建" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行目录创建"); + } + } + + + std::string dir_name = msgObj["Name"].get(); + + std::cout << "[parsemsg][1118] Name=" << dir_name << std::endl; + + ClientManager::instance().add_menu_set_action_to_device(devid, dir_name); + return true; + } + case 1119: { // 目录删除 + if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false; + parsed.ok = true; + + std::cout << "[parsemsg] delete menu, devid=" << devid + << ", guid=" << guid << std::endl; + + { + int ret = recordguid(devid, guid, static_cast(DeviceState::DEL_MENU), 1); + if (-1 == ret) { + send_reply_to_queue(guid, static_cast(ResponseCode::NOT_FOUND), + "未找到该装置,目录删除指令执行失败"); + DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,目录删除指令执行失败"); + return true; + } + else if (ret > 0) { + send_reply_to_queue(guid, static_cast(ResponseCode::BUSY), + "该装置正忙,目录删除指令执行失败"); + DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,目录删除指令执行失败"); + return true; + } + else { + std::cout << "记录装置状态成功,准备执行目录删除" << std::endl; + DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行目录删除"); + } + } + + + std::string dir_name = msgObj["Name"].get(); + + std::cout << "[parsemsg][1119] Name=" << dir_name << std::endl; + + ClientManager::instance().add_menu_del_action_to_device(devid, dir_name); + return true; + } + ////////lnk20260402新增目录新建、删除,文件删除,文件上传 default: return false; } diff --git a/LFtid1056/dealMsg.cpp b/LFtid1056/dealMsg.cpp index f55c09c..d9f4eed 100644 --- a/LFtid1056/dealMsg.cpp +++ b/LFtid1056/dealMsg.cpp @@ -904,6 +904,19 @@ void process_received_message(string mac, string id,const char* data, size_t len // 处理完成后重置状态 ClientManager::instance().change_device_state(id, DeviceState::IDLE); } + else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { + // 文件目录为空 + std::cout << "*** empty ***! " << mac << std::endl; + + //传入空的list表示目录为空 + std::vector FileList; + + filemenu_cache_put(id,FileList); + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::READING_FILEMENU)); + + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } else { std::cout << "reason code: " << static_cast(udata[8]) << "-" << static_cast(udata[9]) << "-" << static_cast(udata[10]) << "-" << static_cast(udata[11]) << std::endl; // 装置答非所问异常 @@ -918,6 +931,9 @@ void process_received_message(string mac, string id,const char* data, size_t len if(udata[8] == static_cast(MsgResponseType::Response_File_Send)){ //文件应答最后一帧后,再回复的结束帧 std::cout << "*** send file success ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SEND_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { @@ -937,6 +953,9 @@ void process_received_message(string mac, string id,const char* data, size_t len if (!ok) { // 组装后续文件上送报文失败 std::cout << "*** send file get next packet fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::BAD_REQUEST), id, 0, static_cast(DeviceState::SEND_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (!packet.empty()) { @@ -959,17 +978,26 @@ void process_received_message(string mac, string id,const char* data, size_t len else { // 理论上不应出现 std::cout << "*** send file invalid next packet ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SEND_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { // 当前帧被拒收,文件上送失败 std::cout << "*** send file 0x41 fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::REJECTED_BUSY), id, 0, static_cast(DeviceState::SEND_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问 std::cout << "*** send file ?? fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SEND_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; @@ -979,16 +1007,25 @@ void process_received_message(string mac, string id,const char* data, size_t len if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { //文件删除完毕! std::cout << "*** del file success ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::DEL_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { // 当前帧被拒收,文件删除失败 std::cout << "*** del file 0x41 fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::REJECTED_BUSY), id, 0, static_cast(DeviceState::DEL_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问 std::cout << "*** del file ?? fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::DEL_FILE)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; @@ -998,16 +1035,25 @@ void process_received_message(string mac, string id,const char* data, size_t len if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { //创建目录完毕! std::cout << "*** send menu success ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::SEND_MENU)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { // 当前帧被拒收,创建目录失败 std::cout << "*** send menu 0x41 fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::REJECTED_BUSY), id, 0, static_cast(DeviceState::SEND_MENU)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问 std::cout << "*** send menu ?? fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::SEND_MENU)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break; @@ -1017,16 +1063,25 @@ void process_received_message(string mac, string id,const char* data, size_t len if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { //删除目录完毕! std::cout << "*** del menu success ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::OK), id, 0, static_cast(DeviceState::DEL_MENU)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else if (udata[8] == static_cast(MsgResponseType::Response_NewNACK)) { // 当前帧被拒收,删除目录失败 std::cout << "*** del menu 0x41 fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::REJECTED_BUSY), id, 0, static_cast(DeviceState::DEL_MENU)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } else { // 装置答非所问 std::cout << "*** del menu ?? fail ***! " << mac << std::endl; + + on_device_response_minimal(static_cast(ResponseCode::INTERNAL_ERROR), id, 0, static_cast(DeviceState::DEL_MENU)); + ClientManager::instance().change_device_state(id, DeviceState::IDLE); } break;