diff --git a/LFtid1056/PQSMsg.cpp b/LFtid1056/PQSMsg.cpp index c9620d3..412e621 100644 --- a/LFtid1056/PQSMsg.cpp +++ b/LFtid1056/PQSMsg.cpp @@ -681,6 +681,80 @@ std::vector generate_preupgrade_message() return GetMsg(DataBuf, static_cast(MsgRequestType::Request_Read_RunningInformation)); } + /** + * @brief 生成正式升级报文-单帧升级文件传输 + * @param data 当前帧升级数据 + * @param updateCount 当前帧序号 + * @param updateSize 升级文件总大小 + * @param count 总帧数 + * @param crc CRC校验值 + * @return 包含完整报文的字节向量 + */ +std::vector generate_upgrade_start_message(const std::vector& data, + std::uint32_t updateCount, + std::uint32_t updateSize, + std::uint32_t count, + std::uint32_t crc) +{ + // 创建44字节头部 + 数据区缓冲区,初始化为0 + std::vector DataBuf(44 + data.size(), 0x00); + + // 拷贝数据体到44字节头部之后 + std::copy(data.begin(), data.end(), DataBuf.begin() + 44); + + DataBuf[0] = 0x00; // 校验方式 0-crc校验 1-md5校验 + DataBuf[1] = 0x00; // 备用 + DataBuf[2] = 0x00; // 备用 + + // 4字节当前帧序号 + DataBuf[3] = static_cast(((updateCount + 1) >> 24) & 0xFF); + DataBuf[4] = static_cast(((updateCount + 1) >> 16) & 0xFF); + DataBuf[5] = static_cast(((updateCount + 1) >> 8) & 0xFF); + DataBuf[6] = static_cast((updateCount + 1) & 0xFF); + + // 4字节总帧数 + DataBuf[7] = static_cast((count >> 24) & 0xFF); + DataBuf[8] = static_cast((count >> 16) & 0xFF); + DataBuf[9] = static_cast((count >> 8) & 0xFF); + DataBuf[10] = static_cast(count & 0xFF); + + // 4字节总大小 + DataBuf[11] = static_cast((updateSize >> 24) & 0xFF); + DataBuf[12] = static_cast((updateSize >> 16) & 0xFF); + DataBuf[13] = static_cast((updateSize >> 8) & 0xFF); + DataBuf[14] = static_cast(updateSize & 0xFF); + + // 4字节校验码 + DataBuf[15] = static_cast((crc >> 24) & 0xFF); + DataBuf[16] = static_cast((crc >> 16) & 0xFF); + DataBuf[17] = static_cast((crc >> 8) & 0xFF); + DataBuf[18] = static_cast(crc & 0xFF); + + DataBuf[19] = 0x00; // 压缩方式 备用 + + // DataBuf[20]~DataBuf[27] 为0,压前大小/压前校验备用 + // DataBuf[28]~DataBuf[43] 为0,16字节预留备用 + // vector 初始化时已经全部置0,无需重复赋值 + + // 调用通用报文生成函数,功能码38对应升级 + return GetMsg(DataBuf, static_cast(MsgRequestType::Request_Upgrade)); +} + +/** + * @brief 生成正式升级报文-传输完毕开始升级 + * @return 包含完整报文的字节向量 + */ +std::vector generate_upgrade_end_message() +{ + // 创建3字节数据缓冲区,初始化为0 + std::vector DataBuf(3, 0x00); + + DataBuf[0] = 0x55;//开始升级标志 + + // 调用通用报文生成函数,功能码38对应升级 + return GetMsg(DataBuf, static_cast(MsgRequestType::Request_Upgrade)); +} + /** * @brief 生成设置装置对时的报文 * @param time 下发的对时时间 (tm值) diff --git a/LFtid1056/PQSMsg.h b/LFtid1056/PQSMsg.h index 602c7aa..7534e16 100644 --- a/LFtid1056/PQSMsg.h +++ b/LFtid1056/PQSMsg.h @@ -49,7 +49,9 @@ enum class MsgRequestType : unsigned char { //补招事件日志 Request_Read_Event = 0x0D, //执行控制事件 - Request_Ctrl = 0x0A + Request_Ctrl = 0x0A, + //执行装置升级 + Request_Upgrade = 0x26 }; // 接收报文功能码枚举 enum class MsgResponseType : unsigned char { @@ -89,6 +91,8 @@ enum class MsgResponseType : unsigned char { Response_Read_Event = 0x8D, //执行控制事件应答 Response_Ctrl = 0x8a, + //装置升级应答-升级数据传输采用40/41默认应答,升级执行和结束采用专用A6升级应答 + Response_Upgrade = 0xA6, //默认肯定应答 Response_NewACK = 0x40, //默认否定应答 @@ -2416,6 +2420,25 @@ std::vector generate_machineversion_message(); * @return 包含完整报文的字节向量 */ std::vector generate_preupgrade_message(); +/** + * @brief 生成正式升级报文-单帧升级文件传输 + * @param data 当前帧升级数据 + * @param updateCount 当前帧序号 + * @param updateSize 升级文件总大小 + * @param count 总帧数 + * @param crc CRC校验值 + * @return 包含完整报文的字节向量 + */ +std::vector generate_upgrade_start_message(const std::vector& data, + std::uint32_t updateCount, + std::uint32_t updateSize, + std::uint32_t count, + std::uint32_t crc); +/** + * @brief 生成正式升级报文-传输完毕开始升级 + * @return 包含完整报文的字节向量 + */ +std::vector generate_upgrade_end_message(); /** * @brief 生成设置装置对时的报文 * @param time 下发的对时时间 (tm值) diff --git a/LFtid1056/client2.cpp b/LFtid1056/client2.cpp index aadaaa7..3bb111a 100644 --- a/LFtid1056/client2.cpp +++ b/LFtid1056/client2.cpp @@ -23,6 +23,47 @@ static uv_loop_t* global_loop = nullptr; static uv_timer_t monitor_timer; extern SafeMessageQueue message_queue; +// 鐢熸垚涓 C# CreateNormalCrc32Table 瀹屽叏瀵瑰簲鐨勮〃 +static std::array CreateNormalCrc32Table_Char(uint32_t poly) +{ + std::array table{}; + + for (int i = 0; i < 256; ++i) + { + uint32_t data = static_cast(i) << 24; + for (int j = 0; j < 8; ++j) + { + bool flag = (data & 0x80000000u) == 0x80000000u; + if (flag) + { + data = (data << 1) ^ poly; + } + else + { + data <<= 1; + } + } + table[i] = data; + } + + return table; +} + +// 涓 C# CalcNoemalCrc32 瀹屽叏瀵瑰簲 +static uint32_t CalcNormalCrc32_Char(const std::vector& bytes, + uint32_t poly = 0x04C11DB7u) +{ + static const std::array table = CreateNormalCrc32Table_Char(poly); + + uint32_t crc = 0xFFFFFFFFu; + for (size_t i = 0; i < bytes.size(); ++i) + { + crc = (crc << 8) ^ table[((crc >> 24) & 0xFFu) ^ bytes[i]]; + } + + return crc; +} + // ClientContext 瀹炵幇 ClientContext::ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index) : loop(loop), state(ConnectionState::DISCONNECTED), @@ -348,6 +389,140 @@ void ClientContext::clear_float_cache() { std::lock_guard lock(float_cache_mutex_); point_float_cache_.clear(); } + +//鍗囩骇绠$悊鐩稿叧鍑芥暟 +/** + * @brief 绋嬪簭鍒囩墖鍑芥暟 + * @param file 鍗囩骇绋嬪簭鏂囦欢 + * @param frame_index 瑕佸彂閫佺殑甯у簭鍙 + * @param frame_payload_size 鍗曞抚鏁版嵁闀 + * @return 鍒囩墖鏁版嵁 + */ +static std::vector slice_frame_data(const std::vector& file, + uint32_t frame_index, + uint32_t frame_payload_size) +{ + const uint64_t offset = static_cast(frame_index) * frame_payload_size; + if (offset >= file.size()) { + return {}; + } + + const uint64_t remain = file.size() - offset; + const uint64_t copy_len = std::min(remain, frame_payload_size); + + return std::vector( + file.begin() + static_cast(offset), + file.begin() + static_cast(offset + copy_len)); +} +/** + * @brief 瑁呯疆鍗囩骇鍙傛暟鍒濆鍖 + * @param file 鍗囩骇绋嬪簭鏂囦欢 + * @param frame_payload_size 鍗曞抚鏁版嵁闀 + * @return 鏄惁闇瑕佸崌绾 + */ +bool ClientContext::prepare_upgrade_task(const std::vector& file, uint32_t frame_payload_size) +{ + if (file.empty() || frame_payload_size == 0) { + return false; + } + + std::lock_guard lock(upgrade_mutex_); + + upgrade_task_.file_data = file; + upgrade_task_.file_size = static_cast(file.size()); + upgrade_task_.file_crc = CalcNormalCrc32_Char(file, 0x04C11DB7u); + upgrade_task_.frame_payload_size = frame_payload_size; + upgrade_task_.total_frames = + static_cast((file.size() + frame_payload_size - 1) / frame_payload_size); + upgrade_task_.next_frame_index = 0; + upgrade_task_.active = (upgrade_task_.total_frames > 0); + + return upgrade_task_.active; +} + +/** + * @brief 鐢熸垚鍗囩骇浼犺緭鐨勪笅涓甯ф姤鏂 + * @param out_packet 鍗囩骇鎶ユ枃 + * @param finished 鏄惁缁撴潫 + * @return 鏄惁缁х画 + */ +bool ClientContext::build_next_upgrade_packet(std::vector& out_packet, bool& finished) +{ + std::lock_guard lock(upgrade_mutex_); + + finished = false; + out_packet.clear(); + + if (!upgrade_task_.active) { + return false; + } + + if (upgrade_task_.next_frame_index >= upgrade_task_.total_frames) { + finished = true; + upgrade_task_.active = false; + return false; + } + + std::vector frame_data = + slice_frame_data(upgrade_task_.file_data, + upgrade_task_.next_frame_index, + upgrade_task_.frame_payload_size); + + if (frame_data.empty()) { + upgrade_task_.active = false; + return false; + } + + out_packet = generate_upgrade_start_message( + frame_data, + upgrade_task_.next_frame_index, // 0-based锛屽唴閮ㄤ細 +1 + upgrade_task_.file_size, + upgrade_task_.total_frames, + upgrade_task_.file_crc + ); + + ++upgrade_task_.next_frame_index; + + if (upgrade_task_.next_frame_index >= upgrade_task_.total_frames) { + finished = true; + } + + return true; +} + +/** + * @brief 鑾峰彇褰撳墠鍗囩骇鐨勫綋鍓嶅抚鍜屾诲抚鏁 + * @param current_frame_index 褰撳墠甯 + * @param total_frames 鎬诲抚鏁 + * @return 鏄惁姝e父 + */ +bool ClientContext::get_upgrade_progress(uint32_t& current_frame_index, uint32_t& total_frames) const +{ + std::lock_guard lock(upgrade_mutex_); + + if (!upgrade_task_.active) { + current_frame_index = 0; + total_frames = 0; + return false; + } + + current_frame_index = upgrade_task_.next_frame_index; + total_frames = upgrade_task_.total_frames; + return true; +} + +void ClientContext::clear_upgrade_task() +{ + std::lock_guard lock(upgrade_mutex_); + upgrade_task_ = UpgradeTask{}; +} + +bool ClientContext::has_active_upgrade_task() const +{ + std::lock_guard lock(upgrade_mutex_); + return upgrade_task_.active; +} + // 鐗堟湰姣旇緝鍑芥暟鐨勮緟鍔╁嚱鏁帮細鍒嗗壊瀛楃涓插苟杞崲涓烘暣鏁板悜閲 std::vector splitVersionString(const std::string& versionStr) { std::vector segments; @@ -1744,8 +1919,8 @@ bool ClientManager::set_preupgrade_action_to_device(const std::string& identifie if (ctx->device_info.device_id == identifier || ctx->device_info.mac == identifier) { - //璁剧疆鐢ㄤ簬鏍¢獙鐨勯鍗囩骇鏂囦欢 - ctx->set_preupgrade_filepath(path); + //璁剧疆鐢ㄤ簬鏍¢獙鐨勯鍗囩骇鏂囦欢 鏍¢獙閲囩敤榛樿鐢熸垚鐨勬枃浠 鏆傛椂涓嶄娇鐢 + //ctx->set_preupgrade_filepath(path); // 鐢熸垚棰勫崌绾ф姤鏂 auto packet = generate_preupgrade_message(); @@ -1763,6 +1938,111 @@ bool ClientManager::set_preupgrade_action_to_device(const std::string& identifie return false; // 璁惧鏈壘鍒 } +/** + * @brief 瑁呯疆鍗囩骇鍔ㄤ綔 鍙戦佸垵濮嬪抚 + * @param file 鍗囩骇绋嬪簭鏂囦欢 + * @param sin_length 涓婇佸崟甯ч暱搴 + * @return 鍙戦佺粨鏋 + */ +bool ClientManager::send_upgrade_action_to_device(const std::string& identifier, const std::vector& file,int sin_length) { + std::lock_guard lock(mutex_); + + for (auto& pair : clients_) { + auto& ctx = pair.second; + if (ctx->device_info.device_id == identifier || + ctx->device_info.mac == identifier) { + + //姝ゅ璁$畻鏂囦欢鎬诲ぇ灏忥紝灏嗗弬鏁扮▼搴忔枃浠跺垎鍓叉垚渚濈収鍗曞抚闀垮害鐨勫缁勬枃浠讹紝璁$畻鏂囦欢crc锛岃绠椾繚瀛樻诲抚鏁帮紝淇濆瓨褰撳墠甯ц鏁 + + //涔嬪悗閲嶆柊鍐欎竴涓狢lientManager鐨勫嚱鏁帮紝鐢ㄤ簬灏嗕箣鍓嶈绠楀嚭鐨勫弬鏁伴獙璇佹甯稿悗渚濇鑷姩鐢熸垚鎶ユ枃骞舵墽琛岋紝涓嶈鐩存帴鍦ㄨ繖閲屾墽琛岋紝鍥犱负鍚庣画浼氬湪鍒殑鍦版柟璋冪敤锛岄槻姝㈤渶瑕佷竴鐩磋幏鍙栨墍鏈夊弬鏁板啀鐢熸垚鎶ユ枃锛岀洿鎺ユ墦鍖呮柟渚胯皟鐢ㄣ + + // 1. 鍏堝噯澶囧崌绾т换鍔 + if (!ctx->prepare_upgrade_task(file, static_cast(sin_length))) { + return false; + } + + // 2. 鐢熸垚棣栧抚鍗囩骇鎶ユ枃 + std::vector first_packet; + bool finished = false; + if (!ctx->build_next_upgrade_packet(first_packet, finished) || first_packet.empty()) { + ctx->clear_upgrade_task(); + return false; + } + + // 娣诲姞鍔ㄤ綔鍒伴槦鍒 (鐘舵: 璇诲彇鏂囦欢鐩綍) + ctx->add_action(DeviceState::SET_UPGRADE, first_packet); + + // 濡傛灉褰撳墠绌洪棽鍒欑珛鍗虫墽琛 + if (ctx->current_state_ == DeviceState::IDLE) { + ctx->process_next_action(); + } + + return true; // 鎴愬姛娣诲姞 + } + } + return false; +} + +/** + * @brief 瑁呯疆鍗囩骇鍔ㄤ綔 鏌ヨ骞剁敓鎴愪笅涓甯ф姤鏂 + * @param identifier 瑁呯疆鏍囪瘑锛坉evice_id 鎴 mac锛 + * @param current_frame_index 鑾峰彇褰撳墠甯(0-based锛岃〃绀轰笅涓娆¤鍙戦佺殑甯у彿) + * @param total_frames 鑾峰彇鎬诲抚鏁 + * @param all_sent 鏄惁鍏ㄩ儴鍙戦佸畬姣 + * @param packet 杈撳嚭鐨勪笅涓甯ф姤鏂囷紱鑻ュ凡鍙戦佸畬姣曞垯涓虹┖ + * @return 鑾峰彇缁撴灉 + */ +bool ClientManager::try_get_next_upgrade_packet_to_device(const std::string& identifier, + uint32_t& current_frame_index, + uint32_t& total_frames, + bool& all_sent, + std::vector& packet) +{ + current_frame_index = 0; + total_frames = 0; + all_sent = false; + packet.clear(); + + std::lock_guard lock(mutex_); + + for (auto& pair : clients_) { + auto& ctx = pair.second; + if (ctx->device_info.device_id == identifier || + ctx->device_info.mac == identifier) + { + // 鍏堣幏鍙栧綋鍓嶈繘搴 + if (!ctx->get_upgrade_progress(current_frame_index, total_frames)) { + return false; // 娌℃湁娲诲姩鍗囩骇浠诲姟 + } + + // 濡傛灉褰撳墠甯у彿宸茬粡鍒版诲抚鏁帮紝璇存槑鍏ㄩ儴鍙戦佸畬姣 + if (current_frame_index >= total_frames) { + all_sent = true; + return true; + } + + // 杩樻湁甯ф湭鍙戦侊紝鍒欏彧鐢熸垚涓嬩竴甯ф姤鏂囷紝涓嶅湪杩欓噷鐩存帴鍙戦 + bool finished = false; + if (!ctx->build_next_upgrade_packet(packet, finished)) { + packet.clear(); + return false; + } + + // build_next_upgrade_packet 涔嬪悗锛宯ext_frame_index 宸茬粡鑷 + // 杩欓噷鍐嶆洿鏂颁竴娆¤繘搴︾粰澶栭儴 + ctx->get_upgrade_progress(current_frame_index, total_frames); + + if (current_frame_index >= total_frames) { + all_sent = true; + } + + return true; + } + } + + return false; // 鏈壘鍒拌澶 +} + /** * @brief 鐢熸垚瑁呯疆鎺у埗鍛戒护鎶ユ枃 * @param type 鍛戒护绫诲瀷 1-瑁呯疆澶嶄綅锛2-鍚姩褰曟尝锛3-鍚姩200ms鏁版嵁璁板綍锛4-鍚姩3绉掓暟鎹褰 @@ -1814,10 +2094,10 @@ bool ClientManager::read_eventlog_action_to_device(const std::string& identifier ctx->device_info.mac == identifier) { ctx->event_lineNo = monitorPoint; - // 鐢熸垚瀹氬兼弿杩版姤鏂 + // 鐢熸垚琛ユ嫑鎶ユ枃 auto packet = generate_recallevent_message(Time1, Time2, eventType, monitorPoint); - // 娣诲姞鍔ㄤ綔鍒伴槦鍒 (鐘舵: 璇诲彇鏂囦欢鐩綍) + // 娣诲姞鍔ㄤ綔鍒伴槦鍒 (鐘舵: 琛ユ嫑浜嬩欢) ctx->add_action(DeviceState::READING_EVENTLOG, packet); // 濡傛灉褰撳墠绌洪棽鍒欑珛鍗虫墽琛 diff --git a/LFtid1056/client2.h b/LFtid1056/client2.h index 84bcdf7..1f6145a 100644 --- a/LFtid1056/client2.h +++ b/LFtid1056/client2.h @@ -67,6 +67,7 @@ enum class DeviceState { READING_STATSFILE, // 补招稳态数据文件 SET_CTRL, // 设置装置控制命令 SET_PREUPGRADE, // 装置预升级校验 + SET_UPGRADE, // 装置升级 // 可根据需要添加更多状态 CUSTOM_ACTION // 自定义动作 }; @@ -145,6 +146,44 @@ public: bool event_add_stat_packet(const std::vector& packet, int current_packet, int total_packets);//事件日志插入多帧缓存数据 std::vector event_get_and_clear_stat_packets();//事件日志取出所有缓存数据并清空缓存 void event_clear_stat_cache();//事件日志清空缓存 + //升级任务管理-------------------------------------------------- + struct UpgradeTask + { + std::vector file_data; // 完整升级文件 + uint32_t file_size = 0; // 文件总大小 + uint32_t file_crc = 0; // 文件CRC32 + uint32_t frame_payload_size = 0; // 单帧数据长度 + uint32_t total_frames = 0; // 总帧数 + uint32_t next_frame_index = 0; // 下一个要发送的帧序号(0-based) + bool active = false; // 当前是否存在升级任务 + }; + + mutable std::mutex upgrade_mutex_; + UpgradeTask upgrade_task_; + /** + * @brief 装置升级参数初始化 + * @param file 升级程序文件 + * @param frame_payload_size 单帧数据长 + * @return 是否需要升级 + */ + bool prepare_upgrade_task(const std::vector& file, uint32_t frame_payload_size); + /** + * @brief 生成升级传输的下一帧报文 + * @param out_packet 升级报文 + * @param finished 是否结束 + * @return 是否继续 + */ + bool build_next_upgrade_packet(std::vector& out_packet, bool& finished); + void clear_upgrade_task(); + bool has_active_upgrade_task() const; + /** + * @brief 获取当前升级的当前帧和总帧数 + * @param current_frame_index 当前帧 + * @param total_frames 总帧数 + * @return 是否正常 + */ + bool get_upgrade_progress(uint32_t& current_frame_index, uint32_t& total_frames) const; + //升级任务管理-------------------------------------------------- // 统计数据缓存 struct PointFloatCache { @@ -468,9 +507,30 @@ public: /** * @brief 生成预升级校验报文 * @param path 预校验文件路径 - * @return 包含完整报文的字节向量 + * @return 发送结果 */ bool set_preupgrade_action_to_device(const std::string& identifier, const std::string& path); + /** + * @brief 装置升级动作 发送初始帧 + * @param file 升级程序文件 + * @param sin_length 上送单帧长度 + * @return 发送结果 + */ + bool send_upgrade_action_to_device(const std::string& identifier, const std::vector& file, int sin_length); + /** + * @brief 装置升级动作 查询并生成下一帧报文 + * @param identifier 装置标识(device_id 或 mac) + * @param current_frame_index 获取当前帧(0-based,表示下一次要发送的帧号) + * @param total_frames 获取总帧数 + * @param all_sent 是否全部发送完毕 + * @param packet 输出的下一帧报文;若已发送完毕则为空 + * @return 获取结果 + */ + bool try_get_next_upgrade_packet_to_device(const std::string& identifier, + uint32_t& current_frame_index, + uint32_t& total_frames, + bool& all_sent, + std::vector& packet); //设备运行情况判断 bool get_dev_status(const std::string& identifier); diff --git a/LFtid1056/dealMsg.cpp b/LFtid1056/dealMsg.cpp index 607967b..79bab38 100644 --- a/LFtid1056/dealMsg.cpp +++ b/LFtid1056/dealMsg.cpp @@ -132,6 +132,21 @@ std::vector GeneratePreUpgradeFileFromLengthBytes(uint32_t fileLen) return fileData; } +// 璇诲彇鏂囦欢涓轰簩杩涘埗瀛楄妭鏁扮粍 +std::vector read_file_as_bytes(const std::string& file_path) +{ + std::ifstream file(file_path, std::ios::binary); + if (!file.is_open()) { + std::cerr << "鎵撳紑鏂囦欢澶辫触: " << file_path << std::endl; + return {}; + } + + return std::vector( + std::istreambuf_iterator(file), + std::istreambuf_iterator() + ); +} + //娑堟伅澶勭悊閫昏緫 void process_received_message(string mac, string id,const char* data, size_t length) { // 瀹為檯鐨勬秷鎭鐞嗛昏緫 @@ -160,9 +175,11 @@ void process_received_message(string mac, string id,const char* data, size_t len ClientManager::instance().set_cloud_status(id, 1); //璁剧疆浜嗕簯鍓嶇疆鐧诲綍鐘舵佷负宸茬櫥褰 ClientManager::instance().read_devversion_action_to_device(id);//涓诲姩瑙﹀彂锛岃鍙栬缃増鏈厤缃俊鎭紝浠呭湪瑁呯疆鐧诲綍鍚庢墽琛屼竴娆★紝褰撳墠鑾峰彇鐗堟湰淇℃伅纭瀵规椂鎶ユ枃缁撴瀯銆 - ClientManager::instance().set_preupgrade_action_to_device(id, "");//瑁呯疆鍗囩骇棰勬牎楠屾祦绋 鏍¢獙鏂囦欢鑷姩鐢熸垚 褰撳墠濉┖ - //ClientManager::instance().set_ctrl_action_to_device(id,0x01,0x00);//灏濊瘯瑁呯疆閲嶅惎鎸囦护锛佺涓姝ユ牎楠 - //ClientManager::instance().set_ctrl_action_to_device(id, 0x01, 0x01);//灏濊瘯瑁呯疆閲嶅惎鎸囦护锛佹牎楠屽畬姣曞悗灏濊瘯鎵ц閲嶅惎鎸囦护 + //std::vector file_data = read_file_as_bytes("pqs_arm2.bin"); + //ClientManager::instance().send_upgrade_action_to_device(id, file_data,10240);//榛樿鍗曞抚鏈澶10240 + + //ClientManager::instance().set_preupgrade_action_to_device(id, "");//瑁呯疆鍗囩骇棰勬牎楠屾祦绋 鏍¢獙鏂囦欢鑷姩鐢熸垚 褰撳墠濉┖ + //ClientManager::instance().set_ctrl_action_to_device(id,0x01,0x00);//灏濊瘯瑁呯疆閲嶅惎鎸囦护锛 //ClientManager::instance().get_dev_status(id);//璁惧鍦ㄧ嚎鎯呭喌鍒ゆ柇 ture鍦ㄧ嚎 false绂荤嚎 //ClientManager::instance().set_real_state_count("D002", 1,1);//鐧诲綍鍚庢祴璇曞疄鏃 @@ -2310,8 +2327,10 @@ void process_received_message(string mac, string id,const char* data, size_t len if (udata[9] == 0x01) { //褰撳墠浠呮鏌0x01澶嶄綅鎸囦护锛佸叾浣欐帶鍒舵寚浠ゅ叏閮ㄤ緷鐓т笉鍚堟硶澶勭悊锛 std::cout << "***ctrl do next" << mac << std::endl; - //鎺у埗鍛戒护鏍¢獙鍚堟硶锛岃皟鏁翠负绌洪棽锛屽鐞嗗悗缁伐浣溿 - ClientManager::instance().change_device_state(id, DeviceState::IDLE); + + //鏍¢獙瀹屾瘯鍚庣洿鎺ュ噯澶囬噸鍚 + auto packet = generate_control_message(0x01, 0x01); + ClientManager::instance().change_device_state(id, DeviceState::SET_CTRL, packet); } else { std::cout << "***ctrl fail" << mac << std::endl; @@ -2427,6 +2446,95 @@ void process_received_message(string mac, string id,const char* data, size_t len } break; + case DeviceState::SET_UPGRADE: + //瑁呯疆鍗囩骇 + if (udata[8] == static_cast(MsgResponseType::Response_Upgrade)) { + //鎺ユ敹鍒版渶缁堢殑鍗囩骇楠岃瘉鎶ユ枃 + if (udata[9] == 0x01) { + //鎺ユ敹鏂囦欢鎴愬姛锛屼笅鍙戝紑濮嬪崌绾ф寚浠 + //浜嬩欢涓嶆彃鍏ラ槦鍒楋紝鐩存帴淇敼瑁呯疆鏈鏂扮姸鎬侊紝闃叉澶栭儴鍏朵粬鎸囦护鎵撴柇鏇存柊娴佺▼ + std::cout << "*** upgrade 0x01 do next ***!" << mac << std::endl; + auto sendbuff = generate_upgrade_end_message(); + ClientManager::instance().change_device_state(id, DeviceState::SET_UPGRADE, sendbuff); + } + else if (udata[9] == 0x02) { + //鎺ユ敹鏂囦欢閿欒锛 + std::cout << "*** upgrade 0x02 fail ***!" << mac << std::endl; + // 鍗囩骇娴佺▼澶辫触锛岃皟鏁翠负绌洪棽鐘舵侊紝澶勭悊涓嬩竴椤瑰伐浣溿 + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + else if (udata[9] == 0x55) { + //鍗囩骇娴佺▼鎴愬姛锛岀瓑鍊欒缃噸鍚 + std::cout << "*** upgrade 0x55 success ***!" << mac << std::endl; + // 鍗囩骇娴佺▼澶辫触锛岃皟鏁翠负绌洪棽鐘舵侊紝澶勭悊涓嬩竴椤瑰伐浣溿 + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + else if (udata[9] == 0xAA) { + // 鍗囩骇娴佺▼澶辫触锛 + std::cout << "*** upgrade 0xAA fail ***!" << mac << std::endl; + // 鍗囩骇娴佺▼澶辫触锛岃皟鏁翠负绌洪棽鐘舵侊紝澶勭悊涓嬩竴椤瑰伐浣溿 + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + else { + std::cout << "*** upgrade ?? error ***!" << mac << std::endl; + // 鍗囩骇娴佺▼澶辫触锛岃皟鏁翠负绌洪棽鐘舵侊紝澶勭悊涓嬩竴椤瑰伐浣溿 + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + } + else if (udata[8] == static_cast(MsgResponseType::Response_NewACK)) { + uint32_t current_frame_index = 0;//褰撳墠甯 + uint32_t total_frames = 0;//鎬诲抚鏁 + bool all_sent = false; + std::vector packet;//鎶ユ枃娴 + + bool ok = ClientManager::instance().try_get_next_upgrade_packet_to_device( + id, + current_frame_index, + total_frames, + all_sent, + packet + ); + + if (!ok) { + //缁勮鍚庣画鍗囩骇鎶ユ枃鏃跺嚭鐜板紓甯革紝鏃犳硶鍙戦佸悗缁抚鏂囦欢 + std::cout << "鑾峰彇涓嬩竴甯уけ璐n"; + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + else if (!packet.empty()) { + // 鍙鎷垮埌浜嗘姤鏂囷紝灏卞厛鍙戦 + std::cout << "宸茬敓鎴愬苟鍙戦佷笅涓甯э紝褰撳墠杩涘害: " + << current_frame_index << "/" << total_frames << std::endl; + + ClientManager::instance().change_device_state(id, DeviceState::SET_UPGRADE, packet); + + if (all_sent) { + std::cout << "鏈鍚庝竴甯у凡鍙戝嚭锛屽悗缁瓑寰呰缃秷鎭痋n"; + } + } + else if (all_sent) { + // 娌℃湁鏂版姤鏂囧彲鍙戯紝璇存槑涔嬪墠宸茬粡鍏ㄩ儴鍙戝畬 + std::cout << "鎵鏈夊抚閮藉凡鍙戦佸畬姣曪紝绛夊緟瑁呯疆娑堟伅\n"; + return; + } + else { + // 鐞嗚涓婁笉璇ヨ蛋鍒拌繖閲岋紝闃插尽澶勭悊 + std::cout << "鏈幏鍙栧埌鏈夋晥鍗囩骇鎶ユ枃\n"; + 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; + // 鍗囩骇娴佺▼澶辫触锛岃皟鏁翠负绌洪棽鐘舵侊紝澶勭悊涓嬩竴椤瑰伐浣溿 + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + else { + // 瑁呯疆绛旈潪鎵闂紓甯 + std::cout << "*** upgrade ?? fail ***!" << mac << std::endl; + // 鍗囩骇娴佺▼澶辫触锛岃皟鏁翠负绌洪棽鐘舵侊紝澶勭悊涓嬩竴椤瑰伐浣溿 + ClientManager::instance().change_device_state(id, DeviceState::IDLE); + } + break; + case DeviceState::CUSTOM_ACTION: // 鑷畾涔夊姩浣滅姸鎬 std::cout << "CUSTOM_ACTION state: Processing custom response from " << mac << std::endl;