diff --git a/src/serial_AT.cpp b/src/serial_AT.cpp index f050341..5a2d02a 100644 --- a/src/serial_AT.cpp +++ b/src/serial_AT.cpp @@ -75,48 +75,61 @@ static std::vector split_csv(const std::string& line) // ---------- 解析入口 ---------- static void parse_qeng_servingcell(const std::string& line) { - auto t = split_csv(line); - if (t.size() < 5) return; + // 1) 必须先确认是 +QENG: + if (line.rfind("+QENG:", 0) != 0) return; - // t[0] = +QENG: - // t[1] = servingcell - if (t[0].find("+QENG") != 0) return; - if (t[1] != "servingcell") return; + // 2) 切掉 "+QENG:" 前缀,留下后面的 CSV + std::string payload = line.substr(std::string("+QENG:").size()); + // trim payload + while (!payload.empty() && isspace(payload.front())) payload.erase(payload.begin()); + while (!payload.empty() && isspace(payload.back())) payload.pop_back(); - // t[2] = CONNECT/NOCONN - // t[3] = RAT: LTE / NR5G-SA / NR5G-NSA - std::string rat = t[3]; + // 3) 对 payload 做 CSV split(此时第一项应当是 servingcell) + auto t = split_csv(payload); + if (t.size() < 4) return; + + // t[0] = servingcell + // t[1] = CONNECT/NOCONN + // t[2] = RAT: LTE / NR5G-SA / NR5G-NSA + // t[3] = TDD/FDD/... + if (t[0] != "servingcell") return; + + std::string rat = t[2]; int pci = -1, rsrp = 0, rsrq = 0, sinr = 0, arfcn = 0; - // ------------------------------------------ - // NR5G SA 模式字段表(你的情况) - // ------------------------------------------ - // +QENG:"servingcell","CONNECT","NR5G-SA","TDD", - // 460,00, , TAC, ARFCN, PCI, - // SSB, Beam, RSRP, RSRQ, SINR, ... - // - // 索引: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 - // if (rat == "NR5G-SA") { + // servingcell, CONNECT, NR5G-SA, TDD, 460,00, NRCellID, TAC, ARFCN, NR_BAND?, PCI, SSB, RSRP, RSRQ, SINR, ... + // 你这条样例切完前缀后的索引: + // 0 servingcell + // 1 CONNECT + // 2 NR5G-SA + // 3 TDD + // 4 460 + // 5 00 + // 6 A053FB01F + // 7 494 + // 8 100186 <- ARFCN + // 9 524910 + // 10 41 <- PCI + // 11 60 + // 12 -90 <- RSRP + // 13 -7 <- RSRQ + // 14 11 <- SINR if (t.size() >= 15) { - safe_stoi(t[9], pci); safe_stoi(t[8], arfcn); + safe_stoi(t[10], pci); safe_stoi(t[12], rsrp); safe_stoi(t[13], rsrq); safe_stoi(t[14], sinr); } } - - // ------------------------------------------ - // LTE 模式字段表(兼容) - // ------------------------------------------ - // LTE 一般字段:...,PCI= t[6], RSRP=t[11], RSRQ=t[12], SINR=t[14] - // else if (rat == "LTE") { + // 注意:LTE 的字段布局各固件/版本差异挺大,你原来的索引不一定总对 + // 这里先保留你原逻辑,但建议你拿一条 LTE 样例再校准索引 if (t.size() >= 15) { safe_stoi(t[6], pci); @@ -125,13 +138,9 @@ static void parse_qeng_servingcell(const std::string& line) safe_stoi(t[14], sinr); } } - - // ------------------------------------------ - // NSA 模式字段表(简单支持) - // ------------------------------------------ else if (rat == "NR5G-NSA") { - // NSA 包含 LTE + NR 两部分字段,先取 LTE anchor + // NSA 也经常是两段信息拼一起,这里先按 LTE anchor 的方式尝试 if (t.size() >= 15) { safe_stoi(t[6], pci); @@ -151,8 +160,8 @@ static void parse_qeng_servingcell(const std::string& line) g_radio_info.raw = line; } - LOG_INFO("[serial_at] QENG parsed: RAT=" + rat + " PCI=" + std::to_string(pci) + " RSRP=" + std::to_string(rsrp) + - " RSRQ=" + std::to_string(rsrq) + " SINR=" + std::to_string(sinr)); + LOG_INFO("[serial_at] QENG parsed: RAT=" + rat + " PCI=" + std::to_string(pci) + " ARFCN=" + std::to_string(arfcn) + + " RSRP=" + std::to_string(rsrp) + " RSRQ=" + std::to_string(rsrq) + " SINR=" + std::to_string(sinr)); } static bool is_imei_ready()