背景: MQTT 快照流实测 MQTTSerialize_publish failed — JSON 化快照记录 ~810B/条 超 800B 发送缓冲
方案(用户拍板): 对齐 BLE 通道, 原始字节 hex 上报
固件 (V4.3):
- offlog.c/h: 新增 offlog_evt_to_hex() (32B→64 hex)
- snapshot.c/h: 新增 snap_rec_to_hex() (64B→128 hex); 删 SNAP_MAX_QUERY_JSON, 恢复 count=2
- tcp_json_srv.c / iot_mqtt_srv.c: log_query 改 {"seq":N,"hex":"..."}; SEND_BUF 保持 800
- 2 条快照 hex 响应 406B < 800B
文档: TCP JSON V1.03 / MQTT V1.07 §4.17 records 改 hex + 解析表引用 BLE §6.4/§7
工具: parse_offlog_hex/parse_snap_hex/offlog_payload_desc + hex 展示; 验证: gcc 9 断言 + 工具解析全过 + offscreen UI
22 KiB
DLD960 TCP 接口协议(JSON)
基于《DLD960 串口通信协议》V1.01,提供以太网 TCP 通道的 JSON 交互协议。 适用于上位机、调试工具等直接 TCP 连接场景。
1 通信说明
1.1 连接参数
| 项目 | 说明 |
|---|---|
| 传输层 | TCP |
| 默认端口 | 5960 |
| 编码 | UTF-8 |
| 序列化 | JSON |
| 帧分隔 | 换行符 \n(每个 JSON 对象占一行) |
| 最大帧长 | 4096 字节 |
1.2 通信模式
- 请求-响应:客户端发送命令,设备返回响应(同步或异步)
- 主动推送:设备可主动推送数据(线圈数据、事件)
- 连接保持:支持长连接,60 秒无数据心跳超时断开
1.3 连接流程
Client Device (DLD960)
| |
|--- TCP Connect ------------------>|
| |
|--- pwd_verify (鉴权) ------------>|
|<-- 鉴权成功 / 失败 ---------------|
| |
|--- 命令 1 ----------------------->|
|<-- 响应 1 ------------------------|
| |
|--- 命令 2 ----------------------->|
|<-- 响应 2 ------------------------|
| |
|<-- 主动推送 (loop_data/event) ----|
| |
|--- TCP Close / 超时 ------------->|
2 JSON 消息格式
2.1 请求帧
{"msg_id":1,"cmd":"dev_info_query","ts":1719000000,"data":{...}}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
msg_id |
uint32 | 是 | 消息序列号,递增,用于请求-响应匹配 |
cmd |
string | 是 | 命令标识符 |
ts |
uint32 | 否 | Unix 时间戳(秒) |
data |
object | 否 | 命令参数 |
2.2 响应帧
{"msg_id":1,"cmd":"dev_info_query","ts":1719000001,"code":0,"msg":"success","data":{...}}
| 字段 | 类型 | 必填 | 说明 |
|---|---|---|---|
msg_id |
uint32 | 是 | 对应请求的 msg_id |
cmd |
string | 是 | 命令标识符(与请求一致) |
ts |
uint32 | 否 | 响应时间戳 |
code |
int | 是 | 0=成功,非0=错误码 |
msg |
string | 是 | 结果描述 |
data |
object | 否 | 响应数据 |
2.3 主动推送帧
{"msg_id":100,"cmd":"loop_data","ts":1719000100,"data":{...}}
设备主动推送无
code/msg字段,由cmd区分类型。
2.4 错误码
| code | 说明 |
|---|---|
| 0 | 成功 |
| 1 | 参数错误(格式/范围不正确) |
| 2 | 密码验证失败 / 未鉴权 |
| 3 | 设备忙 |
| 4 | 不支持的命令 |
| 5 | 内部错误 |
| 6 | 数据超长 |
| 7 | 连接未鉴权(需先执行 pwd_verify) |
3 命令详表
| cmd | 说明 | 需鉴权 | 对应串口 |
|---|---|---|---|
pwd_verify |
验证设备密码(连接鉴权) | 否 | 0x1C |
dev_serial_set |
更改设备序列码 | 是 | 0x09 |
dev_info_query |
查询设备信息 | 是 | 0x10 |
ssc_net_set |
设置 SSC 网络配置 | 是 | 0x11 |
ssc_net_query |
查询 SSC 网络配置 | 是 | 0x12 |
iot_net_set |
设置 IoT 网络配置 | 是 | 0x13 |
iot_net_query |
查询 IoT 网络配置 | 是 | 0x14 |
iot_topic_set |
设置设备 Topic | 是 | 0x15 |
iot_topic_query |
查询设备 Topic | 是 | 0x16 |
pwd_set |
设置设备密码 | 是 | 0x1D |
factory_reset |
设备出厂初始化 | 是 | 0x1E |
device_reset |
设备复位 | 是 | 0x1F |
loop_param_set |
设置车检器多路参数 | 是 | 0x63 |
loop_param_query |
读取车检器多路参数 | 是 | 0x64 |
report_config |
设置主动上报 | 是 | 0xC5 |
log_stat |
查询脱机日志统计(事件/快照流) | 是 | — |
log_query |
分页拉取脱机日志(事件/快照流) | 是 | — |
log_clear |
清除脱机日志(事件/快照流,审计留痕) | 是 | — |
| 主动推送 | |||
loop_data |
线圈传感数据(设备→客户端) | — | 0xC0 |
event_report |
事件上报(设备→客户端,客户端须应答,见 §5.2) | — | — |
4 命令详情
4.1 验证设备密码 pwd_verify
连接后首个命令,鉴权通过后才能执行其他命令。 60 秒内未鉴权则断开连接。
请求:
{"msg_id":1,"cmd":"pwd_verify","ts":1719000000,"data":{"password":"123456"}}
| data 字段 | 类型 | 说明 |
|---|---|---|
password |
string | 6 位数字密码 |
响应(成功):
{"msg_id":1,"cmd":"pwd_verify","ts":1719000001,"code":0,"msg":"success"}
响应(失败):
{"msg_id":1,"cmd":"pwd_verify","ts":1719000001,"code":2,"msg":"password incorrect"}
连续 3 次密码错误,设备断开连接并锁定 60 秒。
4.2 更改设备序列码 dev_serial_set
请求:
{"msg_id":2,"cmd":"dev_serial_set","ts":1719000002,"data":{"dev_serial":"A1B2C3D4E5F6"}}
响应:
{"msg_id":2,"cmd":"dev_serial_set","ts":1719000003,"code":0,"msg":"success"}
4.3 查询设备信息 dev_info_query
请求:
{"msg_id":3,"cmd":"dev_info_query","ts":1719000004}
响应:
{"msg_id":3,"cmd":"dev_info_query","ts":1719000005,"code":0,"msg":"success","data":{"dev_serial":"A1B2C3D4E5F6","hard_ver":"1.1","soft_ver":"1.1","model":"DLD960","product_code":"960001","sub_code":{"net":true,"iot":true},"bus":{"bus1":0,"bus2":0,"bus3":0,"bus4":0}}}
4.4 设置 SSC 网络配置 ssc_net_set
请求:
{"msg_id":4,"cmd":"ssc_net_set","ts":1719000006,"data":{"dev_ip":"192.168.1.100","subnet_mask":"255.255.255.0","route_ip":"192.168.1.1","lssc_ip":"192.168.1.200","dns":"8.8.8.8","port":502}}
响应: 标准成功/失败。
4.5 查询 SSC 网络配置 ssc_net_query
请求:
{"msg_id":5,"cmd":"ssc_net_query","ts":1719000008}
响应: data 字段同 4.4。
4.6 设置 IoT 网络配置 iot_net_set
请求:
{"msg_id":6,"cmd":"iot_net_set","ts":1719000010,"data":{"host":"mqtt.example.com","port":1883,"client_id":"dld960_A1B2C3D4E5F6","username":"admin","password":"secret"}}
4.7 查询 IoT 网络配置 iot_net_query
请求:
{"msg_id":7,"cmd":"iot_net_query","ts":1719000012}
4.8 设置设备 Topic iot_topic_set
请求:
{"msg_id":8,"cmd":"iot_topic_set","ts":1719000014,"data":{"client_id_enable":true,"topic_pub":"dld960/data/A1B2C3D4E5F6","topic_sub":"dld960/cmd/A1B2C3D4E5F6"}}
4.9 查询设备 Topic iot_topic_query
请求:
{"msg_id":9,"cmd":"iot_topic_query","ts":1719000016}
4.10 设置设备密码 pwd_set
请求:
{"msg_id":10,"cmd":"pwd_set","ts":1719000018,"data":{"old_password":"123456","new_password":"654321"}}
4.11 设备出厂初始化 factory_reset
请求:
{"msg_id":11,"cmd":"factory_reset","ts":1719000020}
执行后所有配置恢复出厂值,连接可能断开。
4.12 设备复位 device_reset
请求:
{"msg_id":12,"cmd":"device_reset","ts":1719000022}
无响应,设备立即复位。
4.13 设置车检器多路参数 loop_param_set
请求:
{"msg_id":13,"cmd":"loop_param_set","ts":1719000024,"data":{"auto_mode":false,"channels":[{"ch":1,"sensitivity":7,"freq_level":"high","loop_delay":0,"output_mode":"exist","exist_mode":0,"direction_mode":0,"safe_mode":0,"function_mode":0},{"ch":2,"sensitivity":7,"freq_level":"mid_high","loop_delay":5,"output_mode":"enter_pulse","exist_mode":10,"direction_mode":0,"safe_mode":0,"function_mode":0},{"ch":3,"sensitivity":5,"freq_level":"mid_low","loop_delay":0,"output_mode":"exist","exist_mode":0,"direction_mode":1,"safe_mode":5,"function_mode":0},{"ch":4,"sensitivity":8,"freq_level":"low","loop_delay":10,"output_mode":"leave_pulse","exist_mode":15,"direction_mode":0,"safe_mode":0,"function_mode":0}]}}
channels[] 字段 |
类型 | 范围 | 说明 |
|---|---|---|---|
ch |
uint8 | 1~4 | 通道号 |
sensitivity |
uint8 | 0~9 | 灵敏度,默认 7 |
freq_level |
string | 见下 | 线圈高低频档位 |
loop_delay |
uint8 | 0~200 | 延时 ×0.1s,最大 20s |
output_mode |
string | 见下 | 输出方式 |
exist_mode |
uint8 | 0~255 | 0=永久,非0=分钟 |
direction_mode |
uint8 | 0~6 | 0=触发,1~6=方向输出 |
safe_mode |
uint8 | 0~255 | 0=关闭,非0=分钟 |
function_mode |
uint8 | 0~15 | 功能模式 |
freq_level 枚举:
| 值 | 说明 |
|---|---|
"high" |
高频 (33nF) |
"mid_high" |
中高频 (43nF) |
"mid_low" |
中低频 (66nF) |
"low" |
低频 (76nF) |
output_mode 枚举:
| 值 | 说明 |
|---|---|
"exist" |
存在输出 |
"enter_pulse" |
进入脉冲 |
"leave_pulse" |
离开脉冲 |
"direction" |
方向判别 |
4.14 读取车检器多路参数 loop_param_query
请求:
{"msg_id":14,"cmd":"loop_param_query","ts":1719000026}
响应:
{"msg_id":14,"cmd":"loop_param_query","ts":1719000027,"code":0,"msg":"success","data":{"auto_mode":false,"channels":[{"ch":1,"sensitivity":7,"freq_level":"high","loop_delay":0,"output_mode":"exist","exist_mode":0,"direction_mode":0,"safe_mode":0,"function_mode":0,"freq_initial":105300,"freq_current":105280,"freq_diff":20},{"ch":2,"sensitivity":7,"freq_level":"mid_high","loop_delay":5,"output_mode":"enter_pulse","exist_mode":10,"direction_mode":0,"safe_mode":0,"function_mode":0,"freq_initial":100200,"freq_current":98700,"freq_diff":1500},{"ch":3,"sensitivity":5,"freq_level":"mid_low","loop_delay":0,"output_mode":"exist","exist_mode":0,"direction_mode":1,"safe_mode":5,"function_mode":0,"freq_initial":78100,"freq_current":0,"freq_diff":0},{"ch":4,"sensitivity":8,"freq_level":"low","loop_delay":10,"output_mode":"leave_pulse","exist_mode":15,"direction_mode":0,"safe_mode":0,"function_mode":0,"freq_initial":62100,"freq_current":62095,"freq_diff":5}]}}
| 额外字段 | 类型 | 单位 | 说明 |
|---|---|---|---|
freq_initial |
uint32 | Hz | 初始频率 |
freq_current |
uint32 | Hz | 当前实时频率(线圈断开时为 0) |
freq_diff |
uint32 | Hz | 频率变化量 |
4.15 设置主动上报 report_config
请求:
{"msg_id":15,"cmd":"report_config","ts":1719000028,"data":{"sensor_type":12,"enable":true,"once":false,"env_eval":false,"interval":5,"ack_required":false,"timeout":0}}
| data 字段 | 类型 | 说明 |
|---|---|---|
sensor_type |
uint8 | 传感器类型,12=多路线圈(0x0C) |
enable |
bool | 使能主动上报 |
once |
bool | 仅上报一次 |
env_eval |
bool | 环境评估模式 |
interval |
uint8 | 上报间隔(秒),0=实时 |
ack_required |
bool | 上报是否需要客户端确认 |
timeout |
uint8 | 超时(分钟),0=无限制 |
4.16 查询脱机日志统计 log_stat
设备本地 W25Qxx 环形日志(事件区/快照区容量随存储芯片动态,掉电不丢)。用于日志拉取前的分页定位。 通过
data.stream区分日志流:event(事件日志,缺省)/snapshot(传感快照)。
请求:
{"msg_id":16,"cmd":"log_stat","ts":1719000000,"data":{"stream":"event"}}
| data 字段 | 类型 | 说明 |
|---|---|---|
stream |
string | 日志流:event(缺省,可省略)或 snapshot |
响应 data(stream=event):
{"stream":"event","enabled":true,"boot_seq":2,"count":1234,"capacity":16256,"seq_first":100,"seq_last":1333}
响应 data(stream=snapshot):
{"stream":"snapshot","enabled":true,"boot_seq":2,"count":1234,"capacity":48064,"seq_first":100,"seq_last":1333}
| data 字段 | 类型 | 说明 |
|---|---|---|
stream |
string | 日志流:event / snapshot |
enabled |
bool | 日志功能是否启用(Flash 初始化成功) |
boot_seq |
uint16 | 当前启动序号(每次上电 +1,区分复位段) |
count |
uint32 | 有效记录条数(0~capacity,环形覆盖后 < capacity) |
capacity |
uint32 | 容量上限(随存储芯片与流动态):事件流 W25Q32=16256 / Q64=32640 / Q128=65408 / Q256=130944;快照流 W25Q32=48064 / Q64=105408 / Q128=220096 / Q256=449472 |
seq_first |
uint32 | 逻辑首条记录全局序号(seq_last - count + 1,count=0 时为 0) |
seq_last |
uint32 | 最新一条记录全局序号(跨 boot 单调递增) |
4.17 分页拉取脱机日志 log_query
分页按全局序号,不按时间(未同步段时间不可靠)。
count上限按流区分:事件流 4 / 快照流 2(hex 原始字节上报,体积可控)。 通过data.stream区分日志流:event(缺省)/snapshot。 记录格式为存储原始字节的小写 hex 字符串(与 BLE 通道直传的二进制同源同语义),上位机按《DLD960 BLE 协议》字段表解析。
请求:
{"msg_id":17,"cmd":"log_query","ts":1719000000,"data":{"stream":"event","start_seq":1330,"count":4}}
| data 字段 | 类型 | 说明 |
|---|---|---|
stream |
string | 日志流:event(缺省,可省略)或 snapshot |
start_seq |
uint32 | 起始全局序号(含);越界(< seq_first 或 > seq_last)返回空 records |
count |
uint8 | 拉取条数;事件流上限 4、快照流上限 2,超限按各自上限处理;0 按上限处理 |
响应 data:
{"start_seq":1330,"records":[{"seq":1330,"hex":"a53200000200000001000000..."}]}
| 字段 | 类型 | 说明 |
|---|---|---|
seq |
uint32 | 全局序号(与 hex 内 offset 4 字段一致,便于快速定位/排序) |
hex |
string | 记录原始字节的小写 hex:事件流 OfflogEvt 32B → 64 字符;快照流 SnapRec 64B → 128 字符(flash 存储字节原样,小端) |
解析字段表(与 BLE 通道完全一致):
| 流 | 结构 | 字段表 |
|---|---|---|
event |
OfflogEvt 32B | 《DLD960 BLE 协议》§7:magic(0xA5)/type/len/flags/seq/ts_ms/unix_ts/boot_seq/payload(12B),事件类型与 payload 定义同表 |
snapshot |
SnapRec 64B | 《DLD960 BLE 协议》§6.4:magic(0xA6)/len/flags/seq/ts_ms/boot_seq/coils(4×12B,与 0xC0 线上格式一致) |
时间戳语义同事件流:
unix_ts为已同步 Unix 秒(0=未同步),绝对时间用事件流time_anchor锚点回算。
4.18 清除脱机日志 log_clear
⚠ 高风险操作:清除动作本身写入事件流(
log_clear审计——谁在何时清了日志,留痕不可清除)。客户端应做权限控制。
请求:
{"msg_id":18,"cmd":"log_clear","ts":1719000000,"data":{"stream":"event"}}
| data 字段 | 类型 | 说明 |
|---|---|---|
stream |
string | 日志流:event(缺省,可省略)或 snapshot |
响应: 标准成功/失败。
stream=event:成功后log_stat的count归 1(仅剩审计记录),seq_last继续递增(序号不复位)。阻塞 ~2.8s(63 个数据扇区 SPI 擦除),请勿高频调用。stream=snapshot:成功后log_stat的count归 0,seq_last继续递增;清除动作写入事件流审计(log_clear,payload 标记快照流)。阻塞 ~45ms(逻辑清除 + 当前写扇区擦除,其余扇区由环形写覆盖时自动擦)。
5 设备主动推送
主动推送帧与请求-响应共用同一条 TCP 连接,由设备在任意时刻发出。
5.1 线圈传感数据 loop_data
{"msg_id":100,"cmd":"loop_data","ts":1719000100,"data":{"channels":[{"ch":1,"freq_level":"high","has_car":false,"loop_ok":true,"freq_current":105280,"freq_diff":20,"sensitivity":7,"condition":0,"misc":{"type":"time","value":0}},{"ch":2,"freq_level":"mid_high","has_car":true,"loop_ok":true,"freq_current":98700,"freq_diff":1500,"sensitivity":7,"condition":2,"misc":{"type":"time","value":350}},{"ch":3,"freq_level":"mid_low","has_car":false,"loop_ok":false,"freq_current":0,"freq_diff":0,"sensitivity":5,"condition":0,"misc":{"type":"cut_count","value":3}},{"ch":4,"freq_level":"low","has_car":false,"loop_ok":true,"freq_current":62095,"freq_diff":5,"sensitivity":8,"condition":0,"misc":{"type":"flow_count","value":128}}]}}
| 通道字段 | 类型 | 说明 |
|---|---|---|
ch |
uint8 | 通道号 1~4 |
freq_level |
string | 高低频档位 |
has_car |
bool | 有车/无车 |
loop_ok |
bool | 线圈正常/断开 |
freq_current |
uint32 | 当前频率 (Hz) |
freq_diff |
uint32 | 频率变化量 (Hz) |
sensitivity |
uint8 | 灵敏度等级 |
condition |
uint8 | 环境评估值 |
misc.type |
string | "time" / "cut_count" / "flow_count" |
misc.value |
uint32 | 对应数值 |
5.2 事件上报 event_report
方向:设备 → 客户端;⚠️ 客户端必须应答(区别于
loop_data的单向推送)
设备检测到事件时主动推送,非周期性。事件(进车/出车/线圈断开等)是不可再生的关键数据,TCP 送达仅保证客户端进程收到,不代表业务层已处理入库,因此引入应用层应答 + 设备重发机制闭环确认(与 IoT MQTT 协议 V1.04 §5.3 机制对称)。
注:
event_report不受report_config.enable门控——设备上电即检测并推送事件。report_config的enable/interval仅控制loop_data周期推送,与事件上报解耦。
设备推送:
{"msg_id":101,"cmd":"event_report","ts":1719000200,"data":{"events":[{"type":"car_enter","ch":2,"value":0},{"type":"car_leave","ch":2,"value":350}]}}
事件类型 type |
说明 | value |
|---|---|---|
car_enter |
车辆进入 | 0 |
car_leave |
车辆离开 | 通过时间 (×50ms) |
loop_cut |
线圈断开 | 0 |
loop_restore |
线圈恢复 | 断开持续时长 (×50ms) |
客户端应答(收到后必须立即回复):
{"msg_id":101,"cmd":"event_report","ts":1719000201,"code":0,"msg":"success"}
| 字段 | 说明 |
|---|---|
msg_id |
必须回显设备推送的 msg_id,设备以此匹配确认 |
cmd |
固定 "event_report" |
code |
0 = 已接收并处理;非 0 = 处理失败(设备视同未确认,进入重发) |
设备端确认与重发机制:
- 推送
event_report后启动确认定时器,5s 内未收到msg_id匹配且code=0的应答 → 重发; - 重发使用相同的
msg_id与原始ts(首次事件发生时间,不随重发刷新),客户端以此去重; - 最多重发 3 次(含首发共 4 次)。仍未确认 → 事件保留在待发队列,待连接恢复(重新鉴权通过)或下一次事件触发时合并上报;
- 连接断开期间产生的事件同样进入待发队列;等待确认期间新产生的事件合并进下一包
events数组(使用新msg_id),单帧不超过帧长限制(4096 字节); - 待发队列建议深度 ≥16 条事件,溢出时丢弃最旧事件(先保新鲜数据)。
客户端要求:
- 收到
event_report先落库、后应答,应答即承诺数据已持久化; - 按
msg_id在近期窗口(建议 10 分钟)内去重——重复帧为设备未收到应答所致,直接应答code=0,不重复入库(设备重启后msg_id从头递增,去重必须限定时间窗口;TCP 为点对点连接,无需dev_serial维度); - 应答帧保持最小集(不带
data),且与请求同为单行紧凑 JSON +\n结尾。
6 交互示例
6.1 完整会话
>>> {"msg_id":1,"cmd":"pwd_verify","ts":1719000000,"data":{"password":"123456"}}
<<< {"msg_id":1,"cmd":"pwd_verify","ts":1719000001,"code":0,"msg":"success"}
>>> {"msg_id":2,"cmd":"dev_info_query","ts":1719000002}
<<< {"msg_id":2,"cmd":"dev_info_query","ts":1719000003,"code":0,"msg":"success","data":{...}}
>>> {"msg_id":3,"cmd":"loop_param_query","ts":1719000004}
<<< {"msg_id":3,"cmd":"loop_param_query","ts":1719000005,"code":0,"msg":"success","data":{...}}
>>> {"msg_id":4,"cmd":"report_config","ts":1719000006,"data":{"sensor_type":12,"enable":true,"interval":5}}
<<< {"msg_id":4,"cmd":"report_config","ts":1719000007,"code":0,"msg":"success"}
... (5 秒后设备主动推送) ...
<<< {"msg_id":100,"cmd":"loop_data","ts":1719000012,"data":{...}}
<<< {"msg_id":101,"cmd":"loop_data","ts":1719000017,"data":{...}}
<<< {"msg_id":102,"cmd":"event_report","ts":1719000020,"data":{"events":[{"type":"car_enter","ch":1,"value":0}]}}
>>> {"msg_id":102,"cmd":"event_report","ts":1719000021,"code":0,"msg":"success"}
7 帧解析说明
- 每个 JSON 对象为一行,以
\n(0x0A) 结尾 - 解析时按行读取,提取完整 JSON 后解析
- JSON 内部不含换行符(紧凑格式)
- 收到非 JSON 行则丢弃并返回错误
- 帧长超过 4096 字节则断开连接
修订记录
| 版本 | 修订时间 | 修订说明 | 修订人 |
|---|---|---|---|
| V1.00 | 2026-06-22 | 初始版本,基于串口协议 V1.01 | wangfq |
| V1.01 | 2026-07-15 | event_report 增加客户端必答机制:应答格式(回显 msg_id)、设备 5s 超时重发(同 msg_id/ts,最多 3 次)、待发队列合并上报、客户端去重与先落库后应答要求(与 MQTT 协议 V1.04 对称) |
wangfq |
| V1.02 | 2026-08-04 | 增加脱机事件日志命令:log_stat(统计/分页定位)、log_query(按全局序号分页,count≤4)、log_clear(清除+审计留痕);事件类型表与 MQTT 协议 V1.06 对齐 |
wangfq |
| V1.03 | 2026-08-18 | log_stat / log_query / log_clear 增加快照流支持(stream=snapshot,与 BLE 0x28/0x29/0x2A 同语义):快照统计 capacity 随芯片动态(48064~449472)、快照分页 count≤1(4 通道记录 JSON ~810B 超发送缓冲,实测修正;BLE 原始通道仍 ≤2)、快照清除审计留痕;capacity/count 类型修正为 uint32(W25Q256 事件流 130944 超 16bit) |
wangfq |