kunlang_video/src/serial_AT.cpp
2026-01-04 17:29:49 +08:00

105 lines
2.8 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "serial_AT.hpp"
#include <algorithm>
#include <chrono>
#include <mutex>
#include <sstream>
#include <thread>
// ================== 全局 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<SerialPort> serial_at;
static std::thread serial_at_sender;
static std::mutex at_tasks_mutex;
// 只保留一个任务AT+GSN
static std::vector<AtTask> 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<std::mutex> 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<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;
}
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);
// IMEI14~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<std::mutex> lock(at_tasks_mutex);
at_tasks.clear();
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();
}