添加信号强度查询

This commit is contained in:
cxh 2026-01-22 15:37:26 +08:00
parent dc0fc7047a
commit 53de68b400
2 changed files with 81 additions and 5 deletions

View File

@ -5,6 +5,17 @@
// 全局 IMEI读取成功后写入
extern std::string IMEI;
struct RadioInfo
{
int rsrp = -999; // dBm
int rsrq = -999; // dB
float sinr = -999; // dB
std::string rat; // LTE / NR5G / etc.
std::string band;
};
extern RadioInfo g_radio_info;
// 初始化 AT 串口(启动线程)
void init_serial_at(const std::string& device, int baudrate);

View File

@ -17,6 +17,9 @@
std::string IMEI;
std::mutex imei_mutex;
RadioInfo g_radio_info;
static std::mutex radio_mutex;
// ================== 运行控制 ==================
static std::atomic<bool> serial_at_running{false};
@ -105,8 +108,13 @@ void stop_http_server()
http_server.reset();
}
// 只保留一个任务AT+GSN
static std::vector<AtTask> at_tasks = {{"AT+GSN", 3, 0, {}}};
// IMEI 需要无限重试
// 信号 AT 命令周期查询5 秒一次)
// max_retries = -1 → 永不删除
static std::vector<AtTask> at_tasks = {
{"AT+GSN", -1, 0, {}}, // 直到成功为止
{"AT+QENG=\"servingcell\"", -1, 0, {}} // RSRP/RSRQ/SINR 查询(周期)
};
// ================== 发送线程 ==================
static void serial_at_send_loop()
@ -130,12 +138,16 @@ static void serial_at_send_loop()
{
auto& task = *it;
if (task.sent_count >= task.max_retries)
// ============================
// FIX: max_retries = -1 → 无限发送
// ============================
if (task.max_retries >= 0 && task.sent_count >= task.max_retries)
{
it = at_tasks.erase(it);
continue;
}
// 5 秒一次发送
if (task.last_sent.time_since_epoch().count() == 0 ||
std::chrono::duration_cast<std::chrono::seconds>(now - task.last_sent).count() >= 5)
{
@ -176,10 +188,63 @@ static void handle_serial_at_data(const std::string& data)
LOG_INFO("[serial_at] IMEI = " + line);
std::lock_guard<std::mutex> lock(at_tasks_mutex);
at_tasks.clear();
{
std::lock_guard<std::mutex> lock(at_tasks_mutex);
// 保留非 IMEI 的任务
at_tasks.erase(
std::remove_if(at_tasks.begin(), at_tasks.end(), [](const AtTask& t) { return t.cmd == "AT+GSN"; }),
at_tasks.end());
}
return;
}
// =======================
// QENG="servingcell" 解析
// =======================
if (line.rfind("+QENG:", 0) == 0 || line.find("servingcell") != std::string::npos)
{
std::vector<std::string> tokens;
std::string tmp;
std::stringstream ss(line);
while (std::getline(ss, tmp, ','))
{
// 去除双引号和空白
tmp.erase(std::remove(tmp.begin(), tmp.end(), '"'), tmp.end());
tmp.erase(0, tmp.find_first_not_of(" \t"));
tmp.erase(tmp.find_last_not_of(" \t") + 1);
tokens.push_back(tmp);
}
// LTE 格式固定至少 15~17 字段
if (tokens.size() >= 15)
{
// 对号入座
int pci = std::stoi(tokens[6]); // 物理小区编号
int band = std::stoi(tokens[8]); // LTE band
int rsrp = std::stoi(tokens[11]); // dBm
int rsrq = std::stoi(tokens[12]); // dB
int sinr = std::stoi(tokens[14]); // dB
{
std::lock_guard<std::mutex> lk(radio_mutex);
g_radio_info.pci = pci;
g_radio_info.band = band;
g_radio_info.rsrp = rsrp;
g_radio_info.rsrq = rsrq;
g_radio_info.sinr = sinr;
g_radio_info.raw = line; // 保留原始字符串用于调试
}
LOG_INFO("[serial_at] QENG parsed: RSRP=" + std::to_string(rsrp) + " RSRQ=" + std::to_string(rsrq) +
" SINR=" + std::to_string(sinr) + " PCI=" + std::to_string(pci) +
" BAND=" + std::to_string(band));
continue;
}
}
}
}