8.6 KiB
对话无回复诊断日志
设备端新增四类日志,按 round、session、单调运行时间关联。诊断不调整对话协议、VAD 阈值或回复等待时限。
| 标记 | 内容 | 可以缩小的范围 |
|---|---|---|
MIC-DIAG |
录音打开结果及句柄、读取返回值/字节数、全零帧、峰值/平均绝对幅值、录音事件、PCM 缓冲写入丢失 | 区分未取得 PCM、全零输入、已有音频但没有通过 VAD、音频交给编码器前丢失 |
VOICE-TX |
认证消息入队结果;START/END 的序号、类型、字节数、返回值和入队耗时;音频入队失败 | 区分请求未入队、内存分配失败、正常提交发送队列 |
WSS-IO |
实际 TLS 写入结果、累计写入次数和字节;TLS 错误码、部分写入进度和重试;实际接收字节;关闭时的累计收发及未消费接收字节 | 区分入队后未完成写入、对端关闭、收到字节但应用层未获得完整消息 |
VOICE-RX |
接收文本长度、前 192 字节、当前会话、是否通过会话准入检查;二进制消息计数 | 显示 START_ACK/END_ACK、未知回复、被准入检查丢弃的消息。二进制消息仍沿用原有忽略行为 |
VOICE-DIAG |
START/END 入队后的摘要、超时断开前和断开回调时的摘要 | 汇总入队成功/失败数、音频载荷字节、文本/二进制消息数、ACK 次数、末次收包距今时长和回复等待时长 |
拾音统计按一次录音累计,每秒及停止时输出。peak/mean_abs 是 16 位有符号 PCM 的绝对幅值,不是分贝;zero 统计有效读取长度内全部为零的帧。short 包括零长度以及所有非 640 字节的读取。PCM 写入不足或失败计入 ring_drops,同时记录丢失字节数。录音 tick 回调不打印,其他重复事件限频。
VOICE-TX ret=0 只代表入队成功。queue_bytes 只计成功入队的音频载荷,不含自定义包头、WebSocket 帧头、认证和控制消息。WSS-IO tx_bytes 是传给传输层并成功返回的明文字节数,含握手/帧头,不能与 queue_bytes 直接比较;TLS 失败时已写出的部分字节由 tls_write_failed/tls_write_timeout 的 sent 单独报告。正常写入首条和每 50 次打印一次,实际接收前 20 次及每 50 次打印,断开时输出累计值。tick/elapsed_ticks 使用 RTOS tick,其他带 ms 的字段使用单调毫秒。
start_ack/end_ack 按收到的文本子串统计,包含被准入检查拒绝的消息;它们不是对当前 session 的服务端确认保证。应结合 VOICE-RX 原文中的会话标识判断归属。若服务端协议不发送 ACK,ACK 为零本身不代表失败。accepted=1 表示通过外层会话准入检查,后续仍可能因 OTA、打断状态、URL 或 session 校验而未播放。文本仅保留前 192 字节,原有错误消息完整分块日志继续保留。
复现时保留开机到失败后第二次对话结束的完整串口日志。推荐按以下顺序判断:
MIC-DIAG检查读取长度、返回值和电平,结合既有 FVAD 语音确认日志判断拾音与 VAD。VOICE-TX检查 START、音频、END 入队;queue_fail和ring_drops应为零。WSS-IO检查实际写入是否失败,关闭时是否有接收字节和残留未消费数据。VOICE-RX检查 ACK、未知错误文本、被拒绝的回复或二进制数据。timeout-before-disconnect检查wait_ms。wait=2是等待回复,wait=1是无语音,wait=3是 END 入队失败。response表示现有业务逻辑已接收可用音频 URL,不等同于收到任意文本或 TTS_START。
即使 TLS 写入成功,也不能证明服务器应用收到完整录音。若已经看到归属正确的 END_ACK,却没有后续 TTS,优先按 session 查服务端识别和生成链路;若没有 ACK,也需要结合服务端接收记录判断。设备单侧日志不能完全区分服务端未处理、网络中断和回复延迟。
本机验证:python3 tools/test_voice_diag.py、python3 tools/test_conversation_timeout.py、python3 tools/test_wss_io.py、python3 tools/test_wss_receive.py。诊断测试直接编译实际函数并注入录音、缓冲区、队列及收包结果;不替代目标固件构建及设备实测。
GNSS 日志开关
inc/app_gnss_log.h 中的 APP_GNSS_LOG_ENABLED 默认是 0,关闭应用侧全部 GNSS/NMEA 原始输出、解析失败、模式切换、卫星搜索、坐标打印和 GPS 查询提示。需要恢复时可在编译参数中设置 -DAPP_GNSS_LOG_ENABLED=1。语音与 NITZ 时间校准诊断继续输出。
GNSS 数据解析、定位上报和硬件开关流程继续运行。原先放在打印参数内的四处 ql_gnss_close() 已分离为独立操作,避免禁用日志时跳过关闭定位。python3 tools/test_gnss_logging.py 在日志开启和关闭两种配置下验证真实解析代码、无卫星退出、卫星不足退出、搜索超时退出及 FAST 切换 SLOW 的关闭路径。
连接失败与提示音诊断
WSS-DIAG 使用 stage 区分 TLS 握手、TLS 读取、WebSocket 升级。日志记录阶段、实际耗时、超时配置、错误码和收包情况,不输出原始响应头、Cookie 或音频内容。TLS 握手仍是 20 秒总窗口,WebSocket 升级仍是 10 秒窗口,HTTP select 等待仍是 2 秒。
| 日志字段 | 含义和排查方向 |
|---|---|
stage=tls_handshake result=timeout phase=server hello |
TLS 等待服务器 Hello 超时,不能据此判断证书错误。结合 last_step、want_read/want_write、phase_ms、calls_ms 判断等待和本地计算耗时 |
stage=tls_connect failed_at=… verify_flags=… |
记录 TLS 初始化/建连的失败步骤和证书校验标志;校验标志仅在已进行证书校验时有解释意义 |
stage=tls_read reason=peer_close_notify |
对端发送 TLS 关闭通知;仅证明关闭由对端通知,不证明为何关闭 |
stage=tls_read reason=tls_eof/tls_read_timeout/tls_read_error |
分别表示读取返回 0、TLS 读取超时、其他读取错误;保留原始十进制和十六进制返回值 |
stage=ws_upgrade reason=no_response_timeout |
升级等待超时,缓冲中没有响应数据;对照 rx_bytes=0,服务端需核查请求是否到达及是否返回 101 |
stage=ws_upgrade reason=incomplete_headers_timeout |
收到部分数据,但在窗口内未收到完整 HTTP 响应头 |
stage=ws_upgrade reason=http_rejected http=… |
收到了完整响应头及非 101 状态;按实际 HTTP 状态检查代理或后端 |
stage=ws_upgrade reason=invalid_upgrade_response |
收到非法或不符合 WebSocket 校验的响应;例如 101 响应的 Accept/Upgrade/Connection 不符合要求,或响应格式错误;当前不进一步细分具体头字段 |
stage=ws_upgrade reason=transport_error |
等待升级期间底层连接出错,结合紧邻的 tls_read 日志及断开回调的具体错误描述 |
HTTP-DIAG stage=tcp_connect/response_header/response_body |
HTTP 在建连、响应头或响应体等待期间失败;timeout 表示 select 返回 0,select_error 表示负值,并记录立即保存的 errno;超时的 errno 字段为 0,不能用历史 errno 推断原因 |
NET-GATE leave recording=… pending=… mqtt=… action=… |
记录留言键为什么被拦截,区分正在录音、等待留言请求回复和 MQTT 离线。忙碌分支当前仍播放原有网络提示并清除 pending,此次仅增加诊断 |
NET-GATE tip=network_ok reason=mqtt_connected voice_service=not_checked |
“已连上网络”仅由 MQTT 连通触发,不表示 TLS/WebSocket/语音业务已验证 |
例如此次无响应升级会输出类似以下摘要(示例,并非当前固件已有的历史日志):
[WSS-DIAG] stage=ws_upgrade result=failed reason=no_response_timeout http=0 elapsed_ms=10000 timeout_ms=10000 rx_bytes=0 buffered=0 header_bytes=0 parser=0 polls=...
http=0 表示尚未解析到有效状态码,不是服务器返回的 HTTP 状态码。成功 TLS 写入只证明本地传输层接受了数据,设备端仍不能独自证明请求到达服务器或定位中间链路丢包。诊断不会改变现有提示音、重试或业务状态机。
验证:python3 tools/test_wss_receive.py 覆盖完整/分段 101、零响应超时、部分响应头超时、503 拒绝、非法 Accept、对端关闭、TLS 读取超时等分支;python3 tools/test_wss_handshake.py 验证真实握手函数的超时/失败摘要及原有时限、重试和 tick 回绕。以上为主机侧函数测试,需重新构建并烧录目标固件后采集新日志。