ShimLink 控制指令:设置工作模式
App 在设备详情页把工作模式设为防霜冻。固件打印了三段字节:收到的原始帧、解密后的内容、准备回给 App 的明文。下面逐段拆开。依据是协议仓 05 章 3.3.3。
[09-20 16:05:47.916] [ble] rx pkt: [09-20 16:05:47.916] 08 01 17 00 02 00 00 00 01 eb 94 be d8 75 9b b9 [09-20 16:05:47.927] ac aa 66 bf da 77 f5 60 67 a6 87 [09-20 16:05:47.927] [ble] decrypt control data: [09-20 16:05:47.927] 08 01 17 00 02 00 00 00 04 03 01 [09-20 16:05:47.927] [ble] tx data before encrypt: [09-20 16:05:47.936] ff ff 18 00 02 00 00 00 09 03 00 00
一 · App 发出的原始帧
rx pkt,27 B。帧头和 seq 明文,后面是 CCM 密文和 tag。
08 01
cmd
17 00
data_length
02 00 00 00
seq
01 eb 94
ciphertext
be d8 75 9b b9 ac aa 66 bf da 77 f5 60 67 a6 87
tag
| 字节 | 字段 | 含义 |
|---|---|---|
08 01 | cmd,u16 LE | 0x0108 设置工作模式。App 下发设置模式只用这个命令号 |
17 00 | data_length,u16 LE | 23,后面 Data 的长度:seq 4 + 密文 3 + tag 16,不含这 4 B 帧头 |
02 00 00 00 | seq,u32 LE | App→设备方向第 3 帧(第 0 帧是时间同步)。防重放,同时进 CCM 的 nonce 和 AAD |
01 eb 94 | ciphertext | 3 B 明文经 AES-128-CCM 加密,密文与明文等长 |
| 余下 16 B | tag | CCM 认证标签,校验失败设备丢弃整帧且不应答 |
二 · 解密后的明文
decrypt control data。固件把帧头和 seq 原样带出,真正解出来的是最后 3 B。
08 01 17 00 02 00 00 00
帧头 + seq(原样)
04
controlHeader
03
tsn
01
workMode
| 字节 | 字段 | 含义 |
|---|---|---|
04 | controlHeader | 0000 0100:bit 1..0 = 00 来源 App;bit 2 = 1 需要响应;bit 4..3 = 00 请求;bit 7..5 保留为 0 |
03 | tsn | 传输序号,本连接第 3 条请求。响应必须原样带回,App 靠它把响应关联到请求 |
01 | workMode | 00 手动、01 防霜冻、02 自动、03 boost、04 假期。前三种模式的载荷只有这 1 B |
解出来的内容与 App 意图一致,这条请求在结构和取值上都符合 05 章。
三 · 期待设备返回
05 章 3.2 命令总表规定 0x0108 的应答是专用 0x011D,沿用请求的 tsn,载荷是设备实际进入的模式。
1d 01
cmd
17 00
data_length
xx xx xx xx
seq(设备方向)
09
controlHeader
03
tsn
01
workMode
tag ×16
tag
| 字节 | 字段 | 含义 |
|---|---|---|
1d 01 | cmd | 0x011D 工作模式响应 |
17 00 | data_length | 23,明文 3 B |
xx xx xx xx | seq | 设备→App 方向自己的计数,与 App 方向无关 |
09 | controlHeader | 0000 1001:来源设备、不需要响应、响应。若是设备主动上报,bit 4..3 为 10,整字节 0x11 |
03 | tsn | 沿用请求 |
01 | workMode | 设备实际进入的模式 |
只有载荷非法或不支持时才回通用响应 0xFFFF,明文 09 ‖ tsn ‖ status:u16 LE,status 0001 failure、0003 unsupported。05 章第 2 节明确:有专用响应的命令不得用 0xFFFF 报告成功。
四 · 固件实际返回
tx data before encrypt,12 B。
ff ff
cmd
18 00
data_length
02 00 00 00
seq
09
controlHeader
03
tsn
00 00
status
| 字节 | 字段 | 含义 |
|---|---|---|
ff ff | cmd | 0xFFFF 通用响应 |
18 00 | data_length | 24 = seq 4 + 密文 4 + tag 16 |
02 00 00 00 | seq | 设备方向第 3 帧 |
09 | controlHeader | 来源设备、响应,正确 |
03 | tsn | 沿用请求,正确 |
00 00 | status | 0x0000 success |
差异
应回 0x011D 加 1 B 模式,固件回了 0xFFFF 加 2 B status。controlHeader、tsn、seq 都对,差的只是命令号和载荷。
原因是厂商资料 6.1.4 对 0x0108 只写了"上报(0x011d)",没有像 0x0103("响应,上报")或 0x010A("响应(0xFFFF)")那样写明应答方式。固件按字面读成"0x011D 只是上报",于是回了通用响应。App 现在的 setState 也只等 0xFFFF,两边一致但都不符合 05 章,待协议仓裁定。