文档版本: dev
OpenZilo BLE 协议参考¶
适用设备
本文档适用于 OpenZilo Q。
连接要求
电脑需要支持低功耗蓝牙(BLE)。SDK 使用 NUS 服务与戒指通信,支持协议 v4。
1. 文档范围¶
本文记录 SDK 使用的协议 v4 封包格式、命令和字段。不同固件可能只实现其中一部分命令,可通过功能查询接口确认;设备按键与灯光说明见使用指南。
2. BLE 服务¶
当前协议使用标准 Nordic UART Service(NUS):
| 用途 | UUID | 数据方向 |
|---|---|---|
| Service | 6E400001-B5A3-F393-E0A9-E50E24DCCA9E |
服务标识 |
| TX Characteristic | 6E400003-B5A3-F393-E0A9-E50E24DCCA9E |
戒指通知 SDK |
| RX Characteristic | 6E400002-B5A3-F393-E0A9-E50E24DCCA9E |
SDK 写入戒指 |
SDK 按扫描得到的设备地址连接设备(macOS 使用 UUID),不依赖广播设备名。
SDK 写入 RX Characteristic 时固定按 20 字节分片,最后一片按实际剩余长度发送。该分片是 SDK 的 BLE 发送策略,不是 v4 协议包边界,也不会关闭系统蓝牙栈的 MTU 协商。戒指发送的 TX Characteristic 通知可采用其他分片长度,调用方应交由 OpenZiloClient 或 PacketStream 重组。
3. v4 协议包¶
协议头固定为 11 字节:
| 偏移 | 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|---|
| 0 | magic_number |
u8 |
1 | 固定为 0x3F |
| 1 | version |
u16 |
2 | 当前版本为 4 |
| 3 | command |
u16 |
2 | 命令号 |
| 5 | body_length |
u32 |
4 | 包体字节数 |
| 9 | body_crc |
u16 |
2 | 包体 CRC16;空包体时为 0 |
| 11 | body |
bytes |
可变 | 命令包体 |
协议头及包体中的数值字段均使用网络字节序(大端序),字符串和 data 原始字节不做字节序转换。CRC 只覆盖包体,算法与 SDK 的 crc16_compute() 一致,初始值为 0xFFFF。
BLE 通知可能拆分一个协议包,也可能连续携带多个包。调用方必须先根据固定包头和 body_length 重组完整数据,再解析包体;OpenZiloClient 和 PacketStream 已负责此过程。
4. 命令列表¶
| 功能 | 请求/上报 | 响应 | SDK 接口 |
|---|---|---|---|
| 系统信息 | 0x0101 |
0x0102 |
get_system_info() |
| 查询支持功能 | 0x0105 |
0x0106 |
get_device_capabilities() |
| 命令错误 | 0x01FF 设备响应 |
无 | DeviceError |
| 日志存储信息 | 0x0301 |
0x0302 |
get_log_storage() |
| 日志数据 | 0x0303 |
0x0304 |
read_log_chunk() |
| 校时 | 0x0401 戒指请求 |
0x0402 SDK 应答 |
enable_time_sync()、send_time_response() |
| 录音数量 | 0x0501 |
0x0502 |
get_audio_file_count() |
| 普通录音提取 | 0x0503 |
0x0504 |
get_audio_file_info() |
| 录音数据 | 0x0506 |
0x0505 |
read_audio_frame() |
| 结束普通提取 | 0x0507 |
0x0508 |
end_audio_extract() |
| 快速录音提取 | 0x0509 |
0x0504、连续 0x0505 |
download_audio_file(..., quick=True) |
V2.001.0002.0000 保存后自动上报 |
连续 0x0505 戒指上报 |
主动阶段无 0x0504;恢复时查询元数据 |
receive_auto_audio_file() |
V2.001.0002.0001 保存结果 |
0x050A 戒指上报 |
无 | wait_audio_record_result()、receive_auto_audio_file() |
| 实时录音订阅 | 0x050D |
0x050E |
set_live_audio_subscription() |
| 实时录音数据 | 0x050F、0x0510、0x0511 戒指上报 |
无 | receive_live_audio_file() |
| 清空录音 | 0x050B |
0x050C |
clear_audio_files() |
| 开始录音 | 0x0512 |
0x0513 |
start_audio_recording() |
| 停止录音 | 0x0514 |
0x0515 |
stop_audio_recording() |
| 录音状态 | 0x0516 |
0x0517 |
get_audio_recording_status() |
| 读取录音设置 | 0x0518 |
0x0519 |
get_audio_recording_config() |
| 修改录音设置 | 0x051A |
0x051B |
set_audio_recording_config() |
| 开启实时 IMU | 0x0601 |
0x0602 |
start_sensor_report() |
| 停止实时 IMU | 0x0603 |
0x0604 |
stop_sensor_report() |
| 批量 IMU 数据 | 0x0605 戒指上报 |
无 | wait_sensor_data() |
| 普通双击 | 0x0701 戒指上报 |
无 | wait_sensor_double_tap_event() |
| 按键双击 | 0x0703 戒指上报 |
无 | wait_sensor_key_double_press_event() |
| 按键单击 | 0x0704 戒指上报 |
无 | wait_sensor_key_single_press_event() |
5. 包体定义¶
以下 u16、i16 和 u32 均为大端序。响应中的 error_code 非 0 时,后续字段无效,并且设备可能只返回 error_code。当前固件部分录音错误路径不返回响应,此时 SDK 只能报告超时,不能推断具体错误。
5.1 系统信息¶
0x0101 获取系统信息¶
包体为空。
0x0102 系统信息响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
firmware_version_len |
u16 |
2 | 固件版本字符串长度 |
firmware_version |
UTF-8 | 可变 | 固件版本字符串 |
system_time |
u32 |
4 | Unix 时间戳,单位秒 |
audio_storage_total |
u32 |
4 | 录音存储总字节数 |
audio_storage_available |
u32 |
4 | 录音存储可用字节数 |
battery_percent |
u16 |
2 | 电量百分比 |
battery_charging |
u8 |
1 | 0 未充电,1 充电中 |
sn_len |
u16 |
2 | SN 字符串长度 |
sn |
UTF-8 | 可变 | 设备 SN |
cpuid_len |
u16 |
2 | CPUID 字符串长度 |
cpuid |
UTF-8 | 可变 | 设备 CPUID |
model_len |
u16 |
2 | 型号字符串长度 |
model |
UTF-8 | 可变 | 设备型号 |
5.2 日志¶
0x0301 获取日志存储信息¶
包体为空。
0x0302 日志存储信息响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
page_size |
u32 |
4 | 日志页大小或设备当前返回的分页单位 |
total_len |
u32 |
4 | 日志数据总长度 |
0x0303 读取日志¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
index |
u32 |
4 | 日志索引 |
offset |
u32 |
4 | 读取起始偏移 |
size |
u32 |
4 | 请求字节数 |
0x0304 日志数据响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
data_len |
u32 |
4 | 实际数据长度 |
data |
bytes |
data_len |
日志数据 |
5.3 校时¶
0x0401 戒指请求校时¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
request_time |
u32 |
4 | 请求打包时间戳 T1 |
0x0402 SDK 校时应答¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
request_time |
u32 |
4 | 原请求时间戳 T1 |
response_time |
u32 |
4 | 请求到达时间戳 T2 |
send_time |
u32 |
4 | 应答发送时间戳 T3 |
5.4 录音¶
0x0501 获取录音数量¶
包体为空。
0x0502 录音数量响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
file_count |
u32 |
4 | 录音文件数量 |
0x0503 开始普通提取¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 固定填写 0 |
file_index |
u32 |
4 | 录音文件索引 |
0x0509 开始快速提取¶
包体与 0x0503 相同。设备先返回 0x0504,随后连续上报 0x0505,直至 is_end=1。
0x0504 录音文件信息¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
file_index |
u32 |
4 | 录音文件索引 |
record_time |
u32 |
4 | 录音时间戳,单位秒 |
data_size |
u32 |
4 | 编码数据区总字节数 |
0x0505 录音数据帧¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
file_index |
u32 |
4 | 录音文件索引 |
frame_offset |
u32 |
4 | 本帧在录音数据区中的字节偏移 |
frame_size |
u32 |
4 | 本帧数据字节数,当前最大 4096 |
is_end |
u8 |
1 | 0 非末帧,1 末帧 |
data |
bytes |
frame_size |
录音编码数据 |
data 是原始文件片段:V2.001.0002.0001 为 OP2C 文件;V2.001.0002.0000 为连续“2 字节小端 Speex 长度 + Speex payload”片段。两种布局见录音文件格式。这里的小端长度属于录音文件内部格式,不改变 v4 协议字段使用大端序的规则。
固件 V2.001.0002.0000录音保存成功后,设备会主动连续发送同一格式的 0x0505,但不会预先发送 0x0504。SDK 的 receive_auto_audio_file() 以第一帧的 file_index 确定文件,按 frame_offset 拼接数据,并以 is_end=1 判断连续传输结束。该函数只返回 (file_index, raw_audio),不返回 AudioFileInfo。
自动链路正常连续时 SDK 不发送提取命令。发现偏移缺口、等待后续帧超时或收到损坏帧时,SDK 先通过 0x0503 -> 0x0504 获取并校验文件索引和 data_size,再使用 0x0506 请求当前期望偏移,最多补传 3 次。最终结果以 data_size 为边界;应用必须在录音结束和主动上报期间保持 BLE 连接。如果连接建立过晚而错过数据,应查询录音数量并使用 download_audio_file() 重新下载。
0x0506 请求指定录音偏移¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 固定填写 0 |
file_index |
u32 |
4 | 录音文件索引 |
frame_offset |
u32 |
4 | 需要读取或补传的字节偏移 |
reserved |
u16 |
2 | 当前固件长度检查需要的保留填充,固定填写 0 |
SDK 根据 frame_offset 请求普通链路的下一帧,也使用该命令补取快速下载或自动上报链路中的缺失位置。
0x0507 结束普通提取¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 固定填写 0 |
file_index |
u32 |
4 | 录音文件索引 |
0x0508 结束提取响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
file_index |
u32 |
4 | 录音文件索引 |
0x050A 录音保存结果¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
file_index |
u32 |
4 | 新保存的录音文件索引 |
固件 V2.001.0002.0001 保存录音后发送该包,不再主动上报 0x0505。应用需要用 0x0503 普通提取文件,并以 0x0507 结束。保存失败时包体可能只有 error_code。
0x050B 清空所有录音¶
包体为空。该命令会删除设备中的全部录音,属于破坏性操作。
0x050C 清空录音响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
0x050D 实时录音订阅¶
固件版本
此用法需要固件 V2.001.0002.0001 或更新版本。
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
enabled |
u8 |
1 | 1 开启,0 关闭 |
订阅不会启动录音;V2.001.0002.0001 可由按键长按或远程录音命令启动。仅实时发送时不写入 Flash,也可配置同时保存。断线后清除订阅,关闭订阅会中止实时发送。
0x050E 实时录音订阅响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码;通知未开启或 ATT MTU 小于 128 时返回错误 |
enabled |
u8 |
1 | 设备当前订阅状态 |
0x050F 实时录音开始¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
session_id |
u32 |
4 | 本次录音会话,非 0 |
reserved |
u32 |
4 | 固定为 0 |
record_time |
u32 |
4 | 录音时间戳,单位秒 |
reserved |
u32 |
4 | 固定为 0 |
sample_rate |
u16 |
2 | 固定为 16000 |
channels |
u8 |
1 | 1 或 2,与录音设置一致 |
codec |
u8 |
1 | 固定为 3,表示 Opus |
0x0510 实时录音数据¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
session_id |
u32 |
4 | 与 0x050F 相同 |
sequence |
u32 |
4 | 包序号,从 0 开始 |
byte_offset |
u32 |
4 | 已发送 Opus 数据的字节偏移,从 0 开始 |
length |
u16 |
2 | Opus 包长度,1~100 |
data |
bytes |
length |
一个 20 ms Opus 包,声道数与开始事件一致 |
byte_offset 只累计 Opus 数据本身,不包含 OP2C 文件中的长度前缀。
0x0511 实时录音结束¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
session_id |
u32 |
4 | 与 0x050F 相同 |
reserved |
u32 |
4 | 固定为 0 |
produced_bytes |
u32 |
4 | 设备编码产生的 Opus 字节数 |
sent_bytes |
u32 |
4 | 设备已发送的 Opus 字节数 |
dropped_frames |
u32 |
4 | 设备丢弃的帧数 |
只有 error_code=0、dropped_frames=0,且两个字节计数都等于实际收到的数据量时,录音才完整。实时录音期间请求下载,0x0504 可能返回设备忙碌。
5.5 实时 IMU¶
固件 V2.001.0002.0000 需先进入手势模式;固件 V2.001.0002.0001 取消模式切换,改为由 0x0601 直接启动采集。两版均沿用下列命令号。
0x0601 开启实时上报¶
包体为空。以下直接启动采集的用法需要固件 V2.001.0002.0001 或更新版本;V2.001.0002.0000 需先进入手势模式。从停止状态开启上报时重置 sequence_start;已在上报时重复请求不会重置序号。
实时 IMU 的正常调用顺序必须是:
固件 V2.001.0002.0001:无需切换模式
-> 发送 0x0601
-> 收到 error_code=0 的 0x0602
-> 接收批量 0x0605
在 V2.001.0002.0000 的录音模式下,0x0601 返回设备忙碌;V2.001.0002.0001 没有该模式限制。wait_sensor_data() 只等待数据,不会自动发送 0x0601。
0x0602 开启实时上报响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
sample_rate_hz |
u16 |
2 | 当前采样率,调用方应以该值为准 |
accel_range_g |
u16 |
2 | 加速度计量程 |
gyro_range_dps |
u16 |
2 | 陀螺仪量程 |
0x0603 停止实时上报¶
包体为空。V2.001.0002.0001 同时停止 BLE 上报和 IMU 采集;V2.001.0002.0000 只停止 BLE 上报,手势模式下的本地采集仍可继续。
0x0604 停止实时上报响应¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
0x0605 单点与批量 IMU 数据¶
单点固件成功包体为 error_code:u16 + sequence:u32 + timestamp_ms:u32 + accel_x/y/z:i16 + gyro_x/y/z:i16,固定 22 字节,全大端。SDK 将其转为只有一个样本的 SensorDataBatch。
以下是批量格式(成功包体长度为 10 + 16*N,与单点格式不重叠):
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
error_code |
u16 |
2 | 错误码 |
sequence_start |
u32 |
4 | 本批第一个采样点序号 |
frame_count |
u16 |
2 | 本批采样点数量 |
sample_size |
u16 |
2 | 单个采样点字节数,当前固定为 16 |
samples |
bytes |
frame_count * sample_size |
连续采样点 |
每个 16 字节采样点格式如下:
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
timestamp_ms |
u32 |
4 | 设备采集时间戳,单位毫秒 |
accel_x |
i16 |
2 | X 轴加速度原始值 |
accel_y |
i16 |
2 | Y 轴加速度原始值 |
accel_z |
i16 |
2 | Z 轴加速度原始值 |
gyro_x |
i16 |
2 | X 轴陀螺仪原始值 |
gyro_y |
i16 |
2 | Y 轴陀螺仪原始值 |
gyro_z |
i16 |
2 | Z 轴陀螺仪原始值 |
成功包体长度必须等于:
2 + 4 + 2 + 2 + frame_count * sample_size
每批最多 32 个采样点,实际数量以 frame_count 为准。下一批序号为 sequence_start + frame_count。V2.001.0002.0001 在断线后停止采集,重连后需重新发送 0x0601;V2.001.0002.0000 可在手势模式重连后恢复本地检测,上报仍需重新开启。
5.6 动作事件¶
以下事件消息格式在 V2.001.0002.0000 与 V2.001.0002.0001 中保留,采集条件与单击行为的变化见相应小节。
0x0701 普通双击¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
timestamp_ms |
u32 |
4 | 事件时间戳,单位毫秒 |
V2.001.0002.0001 需要先发送 0x0601 开启 IMU 采集,再检测敲击;V2.001.0002.0000 在手势模式下检测,无需开启 BLE 数据上报。时间戳是开机后毫秒数,与按键事件的秒级设备时间不同。
0x0703 按键双击¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
timestamp_ms |
u32 |
4 | 设备时间戳,单位秒;SDK 字段仍名为 timestamp_ms |
按键双击成立时只上报 0x0703,不再触发对应单击和模式切换。
0x0704 按键单击¶
| 字段 | 类型 | 字节数 | 说明 |
|---|---|---|---|
timestamp_ms |
u32 |
4 | 设备时间戳,单位秒;SDK 字段仍名为 timestamp_ms |
V2.001.0002.0001 确认单击后只上报 0x0704,不切换模式;V2.001.0002.0000 同时尝试切换录音/手势模式。事件需等待双击判定窗口结束,包体不包含模式字段。
按键事件的秒级时间在校时后对应设备的 Unix 时间;未校时时不可当作有效日历时间。不要将其与 IMU/敲击的开机后毫秒数直接比较。
5.7 远程录音与录音设置¶
固件版本
此用法需要固件 V2.001.0002.0001 或更新版本。
以下命令对应录音控制接口第 1 版。开始、查询状态和读取设置的请求包体为空,数值字段均为大端序。应用调用示例见远程录音。
0x0512 / 0x0513 开始录音¶
请求包体为空。成功响应为 error_code:u16, session_id:u32,共 6 字节。录音编号非 0,响应表示设备已接受开始请求;最终状态通过 0x0516 查询。开始请求超时后先查状态,不自动重发。
0x0514 / 0x0515 停止录音¶
请求为 session_id:u32, cancel:u8。cancel=0 结束并按输出设置处理录音,cancel=1 丢弃尚未保存的录音。成功响应为 error_code:u16, session_id:u32。响应中的编号必须与请求一致;收到响应后仍需等待最终状态。
0x0516 / 0x0517 查询录音状态¶
请求包体为空。成功响应共 14 字节:
| 字段 | 类型 | 说明 |
|---|---|---|
error_code |
u16 |
查询操作的错误码 |
session_id |
u32 |
录音编号;空闲时为 0 |
state |
u8 |
0 空闲、1 已排队、2 录音中、3 保存中、4 完成、5 失败、6 已取消 |
saved |
u8 |
1 表示设备已有保存文件,0 表示没有 |
recording_error |
u16 |
该次录音的错误码,与查询错误码分开 |
file_index |
u32 |
已保存文件的索引;未保存时为 0 |
SDK 用 saved 判断文件索引是否有效;没有文件时,返回对象的 file_index 为 None。
0x0518 / 0x0519 读取录音设置¶
请求包体为空,响应以 error_code:u16 开头。成功时后接下表中的 14 字节设置,再接采样率、帧时长和固定编码参数。
| 字段 | 类型 | 说明 |
|---|---|---|
version |
u8 |
设置结构版本,当前为 1 |
output |
u8 |
0 自动、1 保存到设备、2 实时发送、3 同时发送和保存 |
disconnect_policy |
u8 |
0 停止录音、1 继续保存在设备 |
channels |
u8 |
1 或 2 |
bitrate |
u32 |
码率,单位 bit/s |
gain_left_q8、gain_right_q8 |
各 u16 |
左右数字增益,256 表示 1 倍 |
max_duration_ms |
u16 |
最长录音时间,单位毫秒 |
成功响应固定为 34 字节。设置字段后依次为 sample_rate:u16、frame_duration_ms:u16,以及编码参数 codec:u8、complexity:u8、vbr:u8、constrained_vbr:u8、dtx:u8、fec:u8、packet_loss_percent:u8、signal:u16、bit_depth:u8、max_packet_size:u16、application:u16。这些参数由设备返回,不能通过修改设置命令写入。
0x051A / 0x051B 修改录音设置¶
请求仅包含上表的 14 字节设置。响应与读取设置相同,返回设备接受后的完整设置。仅空闲时可修改;断线后继续保存只允许用于设备存储或同时保存模式。
6. 错误码¶
| 值 | 名称 | 说明 |
|---|---|---|
| 0 | SUCCESS |
成功 |
| 1 | UNKNOWN |
未知错误 |
| 2 | DEVICE_BUSY |
设备忙碌 |
| 3 | FILE_NOT_EXIST |
文件不存在 |
| 4 | CMD_GROUP_NOT_EXIST |
命令组不存在 |
| 5 | CMD_NOT_EXIST |
命令不存在 |
| 6 | TIMEOUT |
操作超时 |
| 7 | PARAM_INVALID |
参数异常 |
| 8 | COMMUNICATION |
通信异常 |
| 9 | UNSUPPORTED_SCHEMA |
不支持的消息结构版本 |
用户升级说明见固件升级指南。SDK 提供 update_firmware() 与 ota-update 命令,调用方式见 SDK 固件升级。
功能查询消息格式¶
固件 V2.001.0002.0000 与 V2.001.0002.0001 的发行标签均未实现下列功能查询命令。这里记录 SDK 对功能查询扩展的解析格式,不表示该扩展已随 V2.001.0002.0001 发布。
保留通信协议 v4,现有 GET_INFO、录音配置 v1 等布局不变。所有整数均为大端。
| 命令 | 方向 | 消息体 |
|---|---|---|
0x0105 |
主机 → 设备 | 空 |
0x0106 |
设备 → 主机 | error:u16, 成功时 schema:u8=1,随后 TLV |
0x01FF |
设备 → 主机 | original_command:u16, error:u16,固定 4 字节 |
错误码含义如下:2 忙碌,5 未实现命令,7 参数非法,新增 9 为不支持的结构版本。未知命令返回 5;能力查询非空请求返回 7;14 字节录音配置请求使用未知版本时返回 9。现有命令的已有错误响应继续有效;未将全部旧错误路径迁移到通用回复。收到错误包不再回错误包。
TLV 为 tag:u16, length:u16, value:length bytes,总长受 v4 的 5120 字节上限约束;当前固件使用最多 512 字节的缓冲区生成响应。重复 tag、截断、非法 UTF-8、缺失必要的设备信息字段会报协议错误;未知的可选 tag 跳过,最高位为 1 的未知 tag 要求升级 SDK,不能静默忽略。
| Tag | 内容 |
|---|---|
| 1 | 完整固件版本,UTF-8 |
| 2 | 产品型号,UTF-8 |
| 3 | 固件编译目标,UTF-8 |
| 4 | 本次启动的 8 字节随机 boot_id |
| 5 | 固件构建 ID,UTF-8 |
| 6 | 支持的通信协议列表,连续 u16;当前为 4 |
0x0100 + feature_id |
功能接口版本 major:u8, minor:u8 |
0x0204 |
录音限制,见下表 |
功能 ID:1 system/1,2 time_sync/1,3 audio_files/1,4 recording_control/1,5 live_audio/1,6 imu/2,7 key_events/1,8 double_tap/1,9 ota/1,10 gesture/1。其中斜杠后是本 SDK 支持的主版本。当前固件不声明 gesture。IMU/2 表示订阅直接启动采集;需要额外手势模式的实现不能声明该接口版本。
固件按完整命令组是否注册声明能力;按键及双击事件只在连接了相应生产者的产品构建中声明。声明表示实现支持,不保证当前硬件初始化成功、连接条件满足或设备不忙。
录音限制固定 26 字节:
| 顺序 | 类型 | 含义 |
|---|---|---|
| 1–2 | u16, u16 | 采样率、帧时长 ms |
| 3–6 | u8 × 4 | 声道位图、输出模式位图、允许继续保存的输出模式位图、保留=0 |
| 7–8 | u32 × 2 | 码率下限、上限,闭区间 |
| 9–10 | u16 × 2 | 数字增益 Q8 下限、上限 |
| 11–13 | u16 × 3 | 时长下限、上限、整除步长 ms |
位图按枚举数值设置位;如声道 1/2 对应 0x06,CONTINUE_SAVING 允许 FLASH=1/BOTH=3 对应 0x0A。录音接口 v1 必须同时提供该限制。当前固定 Opus 编码配置仍通过既有配置读回接口获取。
接口变更规则¶
增加字段时可使用可选 TLV,旧客户端可以跳过。不兼容的字段或行为变化应提高接口主版本,并提供新命令或消息结构;需要客户端理解的字段使用必需标记。写入请求包含不支持的字段时,应返回错误。录音文件按内容识别格式,不依赖设备当前固件版本。
请求中没有事务编号,重试录音开始命令前应先查询录音状态。OTA 升级包的适用条件由发行说明提供,SDK 不自动判断所有起始版本组合,也不提供自动回滚。应用固件和引导程序的安全版本独立管理。