#include "serial_AT.hpp" #include #include #include #include #include // ================== 全局 IMEI ================== std::string IMEI; // 一般 15 位 // ================== AT 任务结构 ================== struct AtTask { std::string cmd; int max_retries; int sent_count; std::chrono::steady_clock::time_point last_sent; }; static std::unique_ptr serial_at; static std::thread serial_at_sender; static std::mutex at_tasks_mutex; // 只保留一个任务:AT+GSN static std::vector at_tasks = {{"AT+GSN", 3, 0, {}}}; // ================== 发送线程 ================== static void serial_at_send_loop() { while (true) { if (!serial_at || !serial_at->is_open()) { std::this_thread::sleep_for(std::chrono::seconds(1)); continue; } auto now = std::chrono::steady_clock::now(); std::lock_guard lock(at_tasks_mutex); for (auto it = at_tasks.begin(); it != at_tasks.end();) { auto& task = *it; if (task.sent_count >= task.max_retries) { // 达到最大重试次数,直接移除 it = at_tasks.erase(it); continue; } if (task.last_sent.time_since_epoch().count() == 0 || std::chrono::duration_cast(now - task.last_sent).count() >= 5) { serial_at->send_data(task.cmd + "\r\n"); task.sent_count++; task.last_sent = now; } ++it; } std::this_thread::sleep_for(std::chrono::seconds(1)); } } // ================== 接收处理 ================== static void handle_serial_at_data(const std::string& data) { std::istringstream iss(data); std::string line; while (std::getline(iss, line)) { // trim line.erase(0, line.find_first_not_of(" \t\r\n")); line.erase(line.find_last_not_of(" \t\r\n") + 1); // IMEI:14~17 位纯数字(不同模组略有差异) if (line.size() >= 14 && line.size() <= 17 && std::all_of(line.begin(), line.end(), ::isdigit)) { IMEI = line; LOG_INFO("[serial_at] IMEI = " + IMEI); // 成功后清空任务,不再发送 AT std::lock_guard lock(at_tasks_mutex); at_tasks.clear(); return; } } } // ================== 初始化接口 ================== void init_serial_at(const std::string& device, int baudrate) { serial_at = std::make_unique("serial_at", device, baudrate, 5); serial_at->set_receive_callback(handle_serial_at_data); serial_at->start(); serial_at_sender = std::thread(serial_at_send_loop); serial_at_sender.detach(); }