sweeper_video/src/serial_AT.cpp

105 lines
2.8 KiB
C++
Raw Normal View History

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