fix: improve field diagnostics and mirror logs to USB CDC
This commit is contained in:
@@ -5,7 +5,8 @@
|
||||
#include "hal_api.h"
|
||||
#include "ql_nw.h"
|
||||
#include "ql_data_call.h"
|
||||
#include "ql_ping.h"
|
||||
#include "ql_func.h"
|
||||
#include "net_diag_probe.h"
|
||||
#include "net_diag.h"
|
||||
|
||||
extern uint8_t get_sleep_mode(void);
|
||||
@@ -16,10 +17,10 @@ extern u8 power_down_status;
|
||||
|
||||
static volatile int enabled;
|
||||
static ql_task_t sample_task, probe_task;
|
||||
static ql_ping_stat_t ping_result;
|
||||
static int ping_seen, ping_error;
|
||||
static int sinr_unavailable;
|
||||
static const char *targets[] = {"223.5.5.5", "banban.api.talkingq.com"};
|
||||
static const char *labels[] = {"参照节点", "业务域名"};
|
||||
static const char *labels[] = {"参照DNS服务", "业务WSS入口"};
|
||||
static const unsigned short ports[] = {53, 443};
|
||||
static unsigned long attempts[2], received[2], streak[2], errors[2];
|
||||
|
||||
static const char *registration_name(int state)
|
||||
@@ -51,6 +52,9 @@ static int paused(void)
|
||||
return fota_start == 1 || power_down_status != 0 || get_sleep_mode();
|
||||
}
|
||||
|
||||
int net_diag_is_enabled(void) { return enabled; }
|
||||
int net_diag_can_probe(void) { return enabled && !paused(); }
|
||||
|
||||
static void sample_worker(void *arg)
|
||||
{
|
||||
int previous_reg = -1, previous_pdp = -1, previous_pause = -1;
|
||||
@@ -84,10 +88,16 @@ static void sample_worker(void *arg)
|
||||
pdp == 1 ? "已连接" : (pdp == -1 ? "读取失败" : "未连接"),
|
||||
get_mqtt_connect_status() == 1 ? "已连接" : "未连接",
|
||||
get_xiaoice_connected_status() ? "已连接" : "未连接");
|
||||
if (sr == QL_NW_SUCCESS && (registered == 1 || registered == 5)) {
|
||||
printf("[现场诊断][%lu ms][信号原始值] RSSI=%d RSRP=%d RSRQ=%d CQI=%d;单位/无效值以模组为准\r\n",
|
||||
if (sr == QL_NW_SUCCESS && rr == QL_NW_SUCCESS &&
|
||||
(reg.data_reg.rat == QL_NW_ACCESS_TECH_E_UTRAN ||
|
||||
reg.data_reg.rat == QL_NW_ACCESS_TECH_E_UTRAN_CA)) {
|
||||
char cqi[32];
|
||||
if (signal.LTE_SignalStrength.cqi >= 0 && signal.LTE_SignalStrength.cqi <= 15)
|
||||
snprintf(cqi, sizeof(cqi), "%d", signal.LTE_SignalStrength.cqi);
|
||||
else snprintf(cqi, sizeof(cqi), "不可用(raw=%d)", signal.LTE_SignalStrength.cqi);
|
||||
printf("[现场诊断][%lu ms][信号原始值] RSSI=%d RSRP=%d RSRQ=%d CQI=%s;单位/无效值以模组为准\r\n",
|
||||
now_ms(), signal.LTE_SignalStrength.rssi, signal.LTE_SignalStrength.rsrp,
|
||||
signal.LTE_SignalStrength.rsrq, signal.LTE_SignalStrength.cqi);
|
||||
signal.LTE_SignalStrength.rsrq, cqi);
|
||||
} else {
|
||||
printf("[现场诊断][%lu ms][信号] 暂不可判读;接口返回=%d 注册=%d\r\n", now_ms(), sr, registered);
|
||||
}
|
||||
@@ -107,10 +117,20 @@ static void sample_worker(void *arg)
|
||||
if ((unsigned long)(now_ms() - next_cell) >= 10000UL || next_cell == 0) {
|
||||
int sinr, result;
|
||||
next_cell = now_ms();
|
||||
result = ql_nw_get_sinr(&sinr);
|
||||
if (result == QL_NW_SUCCESS)
|
||||
printf("[现场诊断][%lu ms][信噪比原始值] SINR=%d;编码以模组为准\r\n", now_ms(), sinr);
|
||||
else net_diag_event("SINR读取失败", result);
|
||||
if (!sinr_unavailable) {
|
||||
if (!m_get_api_ptr || !m_get_api_ptr("ql_nw_get_sinr")) {
|
||||
sinr_unavailable = 1;
|
||||
net_diag_event("当前内核未导出SINR接口;本次开机跳过该项", 0);
|
||||
} else {
|
||||
result = ql_nw_get_sinr(&sinr);
|
||||
if (result == QL_NW_SUCCESS && sinr != 255)
|
||||
printf("[现场诊断][%lu ms][信噪比原始值] SINR=%d;编码以模组为准\r\n", now_ms(), sinr);
|
||||
else if (result == 255 || (result == QL_NW_SUCCESS && sinr == 255)) {
|
||||
sinr_unavailable = 1;
|
||||
net_diag_event("SINR接口/数值不可用;本次开机跳过该项", result);
|
||||
} else net_diag_event("SINR暂时读取失败", result);
|
||||
}
|
||||
}
|
||||
memset(&cells, 0, sizeof(cells));
|
||||
result = ql_nw_get_cell_info(&cells);
|
||||
if (result == QL_NW_SUCCESS && cells.lte_info_valid) {
|
||||
@@ -118,7 +138,7 @@ static void sample_worker(void *arg)
|
||||
for (i = 0; i < cells.lte_info_num && i < QL_NW_CELL_MAX_NUM; ++i) {
|
||||
QL_MCM_NW_LTE_CELL_INFO_T *c = &cells.lte_info[i];
|
||||
if (c->flag != 0 || c->cid == 0) continue;
|
||||
printf("[现场诊断][%lu ms][驻留小区] CID=%lu PCI=%lu EARFCN=%lu MCC=%lu MNC=%lu%s\r\n",
|
||||
printf("[现场诊断][%lu ms][驻留小区] CID=%lu PCI=%lu EARFCN=%lu MCC原始编码=0x%lX MNC原始编码=0x%lX%s\r\n",
|
||||
now_ms(), (unsigned long)c->cid, (unsigned long)c->pci,
|
||||
(unsigned long)c->earfcn, (unsigned long)c->mcc, (unsigned long)c->mnc,
|
||||
had_cell && (cell_id != c->cid || pci != c->pci) ? ";驻留小区发生变化" : "");
|
||||
@@ -135,46 +155,34 @@ static void sample_worker(void *arg)
|
||||
}
|
||||
}
|
||||
|
||||
static void ping_callback(ql_ping_state_e state, int err, ql_ping_stat_t *stat)
|
||||
{
|
||||
(void)state;
|
||||
if (err) ping_error = err;
|
||||
if (stat) { ping_result = *stat; ping_seen = 1; }
|
||||
}
|
||||
|
||||
static void probe_once(int index)
|
||||
{
|
||||
ql_ping_cfg_t cfg;
|
||||
ql_ping_ctx_t *ctx;
|
||||
int ret;
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
cfg.pdpCid = 1; cfg.host = (char *)targets[index];
|
||||
cfg.timeout = 2000; cfg.dataSize = 32; cfg.pingNum = 1;
|
||||
ctx = ql_ping_init(cfg, ping_callback);
|
||||
if (!ctx) { ++errors[index]; net_diag_event("探测初始化失败,下轮重试", index); return; }
|
||||
memset(&ping_result, 0, sizeof(ping_result));
|
||||
ping_seen = 0; ping_error = 0;
|
||||
/* SDK declares ql_ping synchronous: callbacks complete before return. */
|
||||
ret = ql_ping(ctx);
|
||||
ql_ping_deinit(ctx);
|
||||
if (ping_seen && ping_result.sentNum) {
|
||||
attempts[index] += ping_result.sentNum;
|
||||
received[index] += ping_result.rcvdNum;
|
||||
if (ping_result.rcvdNum) {
|
||||
streak[index] = 0;
|
||||
printf("[现场诊断][%lu ms][探测成功] %s %s;往返=%lu ms\r\n",
|
||||
now_ms(), labels[index], targets[index], (unsigned long)ping_result.rtt);
|
||||
net_probe_result result;
|
||||
printf("[现场诊断][%lu ms][探测开始] %s %s:%u;解析后TCP连接,连接超时3000ms\r\n",
|
||||
now_ms(), labels[index], targets[index], (unsigned int)ports[index]);
|
||||
net_diag_probe(targets[index], ports[index], &result);
|
||||
if (result.outcome == PROBE_CANCELLED) {
|
||||
net_diag_event("状态变化,已取消本轮新连接探测", 0); return;
|
||||
}
|
||||
if (result.outcome == PROBE_OK || result.outcome == PROBE_CONNECT || result.outcome == PROBE_TIMEOUT) {
|
||||
++attempts[index];
|
||||
if (result.outcome == PROBE_OK) {
|
||||
++received[index]; streak[index] = 0;
|
||||
printf("[现场诊断][%lu ms][探测成功] %s;IP=%s 解析=%lu ms TCP建连=%lu ms(非AI响应时间)\r\n",
|
||||
now_ms(), labels[index], result.address, result.dns_ms, result.tcp_ms);
|
||||
} else {
|
||||
++streak[index];
|
||||
printf("[现场诊断][%lu ms][探测未回应] %s;连续=%lu 次;可能超时或节点禁Ping,不能单独判定断网\r\n",
|
||||
now_ms(), labels[index], streak[index]);
|
||||
printf("[现场诊断][%lu ms][探测失败] %s;阶段=%s IP=%s 解析=%lu ms TCP等待=%lu ms 错误=%d 连续失败=%lu\r\n",
|
||||
now_ms(), labels[index], result.outcome == PROBE_TIMEOUT ? "TCP超时" : "TCP拒绝/连接错误",
|
||||
result.address, result.dns_ms, result.tcp_ms, result.error, streak[index]);
|
||||
}
|
||||
} else {
|
||||
++errors[index];
|
||||
printf("[现场诊断][%lu ms][探测执行异常] %s;返回=%d 回调错误=%d;无有效发包统计,不计入未回应率\r\n",
|
||||
now_ms(), labels[index], ret, ping_error);
|
||||
printf("[现场诊断][%lu ms][探测执行异常] 目标=%s 阶段=%s 错误=%d 解析返回=%d 解析=%lu ms;不计入TCP失败率\r\n",
|
||||
now_ms(), labels[index], result.outcome == PROBE_DNS ? "域名解析" : "本地套接字/数据连接",
|
||||
result.error, result.dns_result, result.dns_ms);
|
||||
}
|
||||
printf("[现场诊断][%lu ms][累计统计] %s;已发送=%lu 收到=%lu 未回应=%lu 未回应率=%lu%% 执行异常=%lu(本次开机累计)\r\n",
|
||||
printf("[现场诊断][%lu ms][累计统计] %s;TCP有效尝试=%lu 成功=%lu 失败=%lu 失败率=%lu%% 执行异常=%lu;非业务丢包率\r\n",
|
||||
now_ms(), labels[index], attempts[index], received[index], attempts[index] - received[index],
|
||||
attempts[index] ? (attempts[index] - received[index]) * 100UL / attempts[index] : 0, errors[index]);
|
||||
}
|
||||
@@ -212,10 +220,10 @@ void net_diag_start(void)
|
||||
ret = ql_rtos_task_create(&probe_task, 4096, 120, "net_probe", probe_worker, NULL);
|
||||
if (ret != 0) { probe_task = NULL; printf("[现场诊断][错误] 探测任务创建失败=%d,请短按重试\r\n", ret); return; }
|
||||
}
|
||||
printf("\r\n[现场诊断] ===== 主动模式开启:重启退出 =====\r\n"
|
||||
"[现场诊断] 时间=开机毫秒;串口请选择UTF-8并保存完整日志\r\n"
|
||||
"[现场诊断] 信号/连接约2秒一条;小区约10秒一次;两节点依次探测后间隔10秒\r\n"
|
||||
"[现场诊断] 每节点32字节,ICMP超时2000ms;业务域名探测可能另有解析耗时,不等于WSS/AI处理耗时\r\n"
|
||||
"[现场诊断] 主动流量可能改变空闲态、耗电及故障表现;休眠/升级/关机时暂停新探测\r\n");
|
||||
printf("\r\n[现场诊断] ===== 主动模式开启:重启退出 =====\r\n");
|
||||
printf("[现场诊断] 时间=开机毫秒;UART与USB CDC同步,UTF-8;下一轮录音开始记录分段耗时\r\n");
|
||||
printf("[现场诊断] 信号/连接约2秒一条;小区约10秒一次;两节点依次探测后间隔10秒\r\n");
|
||||
printf("[现场诊断] 主动探测改用DNS/TCP,不依赖可选Ping接口;3000ms连接超时不含DNS解析耗时\r\n");
|
||||
printf("[现场诊断] 主动流量可能改变空闲态、耗电及故障表现;休眠/升级/关机时暂停新探测\r\n");
|
||||
enabled = 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user