TWS 耳机 BLE 通信协议文档¶
芯片: 杰理 AC7002 | 蓝牙版本: BT 5.3 | 配对方式: Just Works
文档版本: v1.0 | 最后更新: 2026-05-17
1. 概述¶
本文档定义基于杰理 AC7002 芯片的 TWS 耳机 BLE 通信协议。耳机作为 BLE GATT Server,手机 APP 作为 GATT Client。支持设备信息查询、控制指令下发、事件通知、OTA 固件升级等能力。
1.1 角色定义¶
| 角色 | 说明 |
|---|---|
| GATT Server | TWS 耳机(左/右耳均作为独立的 BLE 设备广播) |
| GATT Client | 手机 APP / 配对主机 |
| TWS 双耳 | 左耳为 Master(主设备),右耳为 Slave(从设备),仅 Master 对外广播 BLE |
1.2 物理层参数¶
| 参数 | 值 |
|---|---|
| 蓝牙版本 | Bluetooth 5.3 |
| 工作频段 | 2.402 GHz ~ 2.480 GHz |
| 调制方式 | GFSK, π/4-DQPSK, 8DPSK |
| 发射功率 | +4 dBm (Max) |
| 接收灵敏度 | -94 dBm (BLE), -89 dBm (BR) |
| 天线类型 | 陶瓷贴片天线 / PCB 板载天线 |
2. 广播与扫描¶
2.1 广播包格式¶
耳机在未连接状态下以 100 ms 间隔广播。广播包采用 ADV_IND 类型。
广播数据结构¶
| AD Type | 内容 | 长度 |
|---|---|---|
| 0x01 (Flags) | LE General Discoverable Mode + BR/EDR Not Supported | 2 bytes |
| 0x08 (Shortened Local Name) | TWS-XXXX (XXXX = MAC 地址后 4 位十六进制,大写) | 9 bytes |
| 0xFF (Manufacturer Specific Data) | 电量及状态信息 (见 2.2) | 6 bytes |
设备名称格式: TWS-XXXX
- 示例:MAC 地址
AA:BB:CC:DD:EE:FF→ 设备名TWS-EEFF - 最大名称长度: 8 字符(
TWS-+ 4 位十六进制)
2.2 Manufacturer Data 格式 (AD Type 0xFF)¶
电量通过广播包的 manufacturer data 携带,便于 iOS/Android 在扫描阶段直接读取,无需建立连接。
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 2 | Company ID | 0x005D (杰理科技) 或 0xFFFF (自定义) |
| 2 | 1 | Battery Level (L) | 左耳电量百分比 0~100, 0xFF = 充电中 |
| 3 | 1 | Battery Level (R) | 右耳电量百分比 0~100, 0xFF = 充电中 |
| 4 | 1 | Battery Level (Case) | 充电仓电量百分比 0~100, 0xFF = 充电中, 0xFE = 仓未连接 |
| 5 | 1 | Status Flags | Bit0: 左耳佩戴(1=已佩戴), Bit1: 右耳佩戴, Bit2: 充电中, Bit3~7: 保留 |
示例: FF FF 64 5A FE 01
- 左耳电量: 100%, 右耳电量: 90%, 充电仓: 未连接, 左耳佩戴中
2.3 扫描响应包 (Scan Response)¶
| AD Type | 内容 | 长度 |
|---|---|---|
| 0x09 (Complete Local Name) | TWS-XXXX | 9 bytes |
| 0x06 (TX Power Level) | +4 dBm | 2 bytes |
3. GATT 服务定义¶
3.1 服务总览¶
| Service UUID | 服务名称 | 类型 | 必选 |
|---|---|---|---|
| 0xFEE0 | 设备信息服务 | Primary | 是 |
| 0xFEE4 | OTA 升级服务 | Primary | 是 |
| 0x1800 | Generic Access | Primary | 是 (标准) |
| 0x1801 | Generic Attribute | Primary | 是 (标准) |
| 0x180F | 电池服务 (可选, 备用电量通道) | Primary | 否 |
3.2 设备信息服务 (UUID: 0xFEE0)¶
特征值总表¶
| UUID | 名称 | 属性 | 权限 | 说明 |
|---|---|---|---|---|
| 0xFEE1 | 设备状态 | Read + Notify | 无加密 | 电量/固件版本/连接状态 |
| 0xFEE2 | 控制指令 | Write (With Response) | 无加密 | 播放/暂停/音量/ANC模式等 |
| 0xFEE3 | 事件通知 | Notify Only | 无加密 | 按键事件/佩戴检测状态 |
3.2.1 特征值 0xFEE1: 设备状态 (Read + Notify)¶
Read 响应格式 (12 bytes):
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Status Code | 0x00 = 正常, 0x01 = 充电中, 0x02 = 低电量 |
| 1 | 1 | Battery L | 左耳电量 0~100 |
| 2 | 1 | Battery R | 右耳电量 0~100 |
| 3 | 1 | Battery Case | 充电仓电量 0~100 |
| 4 | 2 | Firmware Version | BCD 编码, 例: 0x0123 = v1.23 |
| 6 | 2 | Hardware Version | BCD 编码, 例: 0x0100 = v1.0 |
| 8 | 1 | Connection Status | Bit0: 左耳连接, Bit1: 右耳连接, Bit2: Phone连接, Bit3: 充电仓在位 |
| 9 | 1 | ANC Mode | 0x00 = 关闭, 0x01 = 降噪, 0x02 = 通透, 0x03 = 自适应 |
| 10 | 1 | EQ Mode | 0x00 = 默认, 0x01 = 流行, 0x02 = 古典, 0x03 = 摇滚, 0x04 = 自定义 |
| 11 | 1 | Reserved | 保留, 默认 0x00 |
Notify 格式 (4 bytes) — 当任一状态变化时自动推送:
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Changed Mask | 变更掩码, 指示哪个字段变更 |
| 1 | 1 | Old Value | 旧值 |
| 2 | 1 | New Value | 新值 |
| 3 | 1 | Reserved | 保留 |
Changed Mask 定义:
| Bit | 字段 |
|---|---|
| 0 | 电量变化 |
| 1 | 连接状态变化 |
| 2 | ANC 模式变化 |
| 3 | 佩戴状态变化 |
| 4 | EQ 模式变化 |
| 5~7 | 保留 |
3.2.2 特征值 0xFEE2: 控制指令 (Write)¶
请求格式 (3 bytes, 固定长度):
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Command ID | 指令码 |
| 1 | 1 | Parameter | 参数 (根据指令不同含义不同) |
| 2 | 1 | Checksum | Command + Parameter 的 XOR 校验 |
指令定义:
| Command ID | 指令名称 | Parameter | 说明 |
|---|---|---|---|
| 0x01 | 播放/暂停 | 0x00 = 触发切换 | 模拟播放/暂停按键 |
| 0x02 | 下一曲 | 0x00 | — |
| 0x03 | 上一曲 | 0x00 | — |
| 0x04 | 音量增加 | 0x00 = 步进+1, 0x01~0x63 = 直接设置 | — |
| 0x05 | 音量减少 | 0x00 = 步进-1, 0x01~0x63 = 直接设置 | — |
| 0x06 | 设置音量 | 0x00~0x63 (0~99) | 绝对音量值 |
| 0x10 | 设置 ANC 模式 | 0x00=关闭, 0x01=降噪, 0x02=通透, 0x03=自适应 | — |
| 0x11 | ANC 模式循环切换 | 0x00 | 按 关闭→降噪→通透→自适应 循环 |
| 0x12 | 设置 EQ 模式 | 0x00=默认, 0x01=流行, 0x02=古典, 0x03=摇滚, 0x04=自定义 | — |
| 0x13 | EQ 自定义参数 | 10 段均衡器参数 (见扩展格式) | — |
| 0x20 | 接听电话 | 0x00 | — |
| 0x21 | 挂断/拒接电话 | 0x00 | — |
| 0x22 | 唤醒语音助手 | 0x00 | Siri/Google Assistant 等 |
| 0x30 | 查找耳机 | 0x00=左耳响铃, 0x01=右耳响铃, 0x02=双耳响铃 | — |
| 0x40 | 断开 BLE | 0x00 | 通知耳机断开连接 |
| 0x50 | 恢复出厂设置 | 0x00 | 清除配对信息 |
| 0x60 | 读设备日志 | 0x00 | 触发日志上报 |
Write 响应格式 (1 byte):
| 值 | 含义 |
|---|---|
| 0x00 | ACK - 指令接收成功 |
| 0x01 | NACK - 校验失败 |
| 0x02 | NACK - 命令不支持 |
| 0x03 | NACK - 参数无效 |
| 0x04 | NACK - 忙/不可执行 |
3.2.3 特征值 0xFEE3: 事件通知 (Notify Only)¶
格式 (2 bytes):
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Event Code | 事件码 |
| 1 | 1 | Event Data | 事件参数 |
事件定义:
| Event Code | 事件名称 | Event Data | 说明 |
|---|---|---|---|
| 0x01 | 按键 - 单击 | 0x00=左耳, 0x01=右耳 | — |
| 0x02 | 按键 - 双击 | 0x00=左耳, 0x01=右耳 | — |
| 0x03 | 按键 - 三击 | 0x00=左耳, 0x01=右耳 | — |
| 0x04 | 按键 - 长按 (1s) | 0x00=左耳, 0x01=右耳 | — |
| 0x05 | 按键 - 长按 (2s) | 0x00=左耳, 0x01=右耳 | — |
| 0x10 | 佩戴检测 - 戴上 | 0x00=左耳, 0x01=右耳, 0x02=双耳 | 升级版专属 |
| 0x11 | 佩戴检测 - 取下 | 0x00=左耳, 0x01=右耳, 0x02=双耳 | 升级版专属 |
| 0x20 | 入盒检测 - 放入 | 0x00=左耳, 0x01=右耳 | — |
| 0x21 | 入盒检测 - 取出 | 0x00=左耳, 0x01=右耳 | — |
| 0x30 | 低电量告警 | 0x00=左耳, 0x01=右耳, 0x02=充电仓 | 电量 < 10% |
| 0x31 | 充电状态 | 0x00=开始充电, 0x01=充电完成 | — |
| 0x40 | 连接状态 | 0x00=已断开, 0x01=已连接 | — |
3.3 OTA 升级服务 (UUID: 0xFEE4)¶
特征值总表¶
| UUID | 名称 | 属性 | 说明 |
|---|---|---|---|
| 0xFEE5 | OTA 控制 | Write (With Response) | 开始/提交/中止升级 |
| 0xFEE6 | OTA 数据通道 | Write (Without Response) | 固件分块上传 |
| 0xFEE7 | OTA 状态 | Notify | 升级进度/结果通知 |
3.3.1 特征值 0xFEE5: OTA 控制 (Write)¶
请求格式 (4 bytes):
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Command | 操作码 |
| 1 | 2 | Parameter | 参数 (视命令而定) |
| 3 | 1 | Checksum | 前 3 字节的 XOR 校验 |
操作码定义:
| Command | 名称 | Parameter | 说明 |
|---|---|---|---|
| 0x01 | OTA_START | 固件总大小 (bytes, 小端) | 开始 OTA 升级, 初始化存储 |
| 0x02 | OTA_COMMIT | CRC32 (小端) | 提交固件, 带上 CRC32 校验 |
| 0x03 | OTA_ABORT | 0x0000 | 中止升级, 恢复运行旧固件 |
| 0x04 | OTA_GET_INFO | 0x0000 | 查询当前固件信息 (通过 FEE7 回复) |
| 0x05 | OTA_SET_BLOCK_SIZE | 块大小 (bytes) | 设置数据块大小 (默认 128) |
Write 响应格式 (1 byte):
| 值 | 含义 |
|---|---|
| 0x00 | ACK |
| 0x01 | NACK - 格式错误 |
| 0x02 | NACK - 容量不足 |
| 0x03 | NACK - CRC 校验失败 |
| 0x04 | NACK - 升级中不可操作 |
3.3.2 特征值 0xFEE6: OTA 数据通道 (Write Without Response)¶
数据块通过此特征值连续写入,无需等待应答。最大块大小由 OTA_SET_BLOCK_SIZE 设定,默认 128 bytes。
数据块格式:
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 2 | Sequence Number | 序列号 (小端, 从 0 开始) |
| 2 | N | Payload | 固件数据 (N = 块大小) |
写入规则:
- 写入 OTA_START 后进入数据写入模式
- 按序列号递增顺序写入数据块
- 每块携带序列号,耳机检测断点后可请求重传
- 所有块写入完成后发送 OTA_COMMIT
- 耳机在校验完成后回复升级结果 (通过 FEE7)
- 若中途异常断开,重连后需重新 OTA_START
MTU 建议: ≥ 512 bytes (以支持大块写入,提升升级速度)
3.3.3 特征值 0xFEE7: OTA 状态 (Notify)¶
耳机主动推送 OTA 过程中的状态变化。
格式 (4 bytes):
| 偏移 | 长度 | 字段 | 说明 |
|---|---|---|---|
| 0 | 1 | Notification Type | 状态类型 |
| 1 | 2 | Value | 值 (小端) |
| 3 | 1 | Reserved | 保留 |
状态类型定义:
| Type | 名称 | Value | 说明 |
|---|---|---|---|
| 0x00 | OTA_PROGRESS | 0~10000 (0.00%~100.00%) | 升级进度, 精度 0.01% |
| 0x01 | OTA_RESULT_SUCCESS | 设备信息 | 升级成功, Value=固件版本号 |
| 0x02 | OTA_RESULT_FAIL | 错误码 | 升级失败, 见错误码表 |
| 0x03 | OTA_RESULT_REJECT | 0x0000 | 固件不兼容被拒绝 |
| 0x04 | OTA_VERSION_INFO | Major.Minor.Patch | 当前固件版本 (BCD) |
OTA 错误码:
| 值 | 含义 |
|---|---|
| 0x0001 | 存储写入失败 |
| 0x0002 | Flash 擦除失败 |
| 0x0003 | CRC 校验失败 |
| 0x0004 | 固件大小不匹配 |
| 0x0005 | 固件签名无效 |
| 0x0006 | 超时 |
| 0x0007 | 蓝牙断开 |
OTA 完整流程:
4. AT 指令协议¶
除了 GATT 特征值操作外,耳机支持通过 SPP (Serial Port Profile) 或 BLE 数据通道使用 AT 指令进行调试和配置。
注意: AT 指令为工厂调试和生产测试使用,APP 端应优先使用 GATT 特征值。
4.1 AT 指令格式¶
- 前缀:
AT+ - 指令名: 大写字母
- 分隔符:
= - 参数: 逗号分隔, 可选
- 结束符:
\r\n(CR+LF)
4.2 通用响应格式¶
4.3 指令表¶
| 指令 | 参数 | 说明 | 示例 |
|---|---|---|---|
AT+NAME | — | 查询当前设备名 | AT+NAME → +NAME:TWS-A1B2 |
AT+NAME=<name> | name | 设置设备名 (最长 16 字符) | AT+NAME=MyEarbuds |
AT+BATT | — | 查询电量 | AT+BATT → +BATT:80,75,FE |
AT+VERSION | — | 查询固件版本 | AT+VERSION → +VERSION:1.2.3 |
AT+ADDR | — | 查询蓝牙地址 | AT+ADDR → +ADDR:AA:BB:CC:DD:EE:FF |
AT+ANC=<mode> | 0=关,1=降噪,2=通透,3=自适应 | 设置 ANC 模式 | AT+ANC=1 |
AT+ANC? | — | 查询 ANC 模式 | AT+ANC? → +ANC:1 |
AT+EQ=<mode> | 0=默认,1=流行,2=古典,3=摇滚,4=自定义 | 设置 EQ | AT+EQ=2 |
AT+EQ? | — | 查询 EQ 模式 | AT+EQ? → +EQ:2 |
AT+RESET | — | 恢复出厂设置 | AT+RESET |
AT+SLEEP | — | 进入深度睡眠 | AT+SLEEP |
AT+OTA=<action> | start/commit/abort | OTA 操作 (调试用) | AT+OTA=start |
AT+TEST=<mode> | 0=RF测试, 1=音频测试, 2=按键测试, 3=LED测试 | 进入工厂测试模式 | AT+TEST=0 |
AT+LOG=<level> | 0=关闭, 1=错误, 2=警告, 3=信息, 4=调试 | 设置日志级别 | AT+LOG=3 |
4.4 错误码¶
| 码值 | 含义 |
|---|---|
| 1 | 未知指令 |
| 2 | 参数数量错误 |
| 3 | 参数值无效 |
| 4 | 执行失败 |
| 5 | 不支持的硬件功能 (如基础版无佩戴检测) |
| 6 | 忙/系统忙 |
5. 配对与连接¶
5.1 配对方式: Just Works¶
使用 BLE Secure Connections 的 Just Works 配对模型,无需 PIN 码或 Passkey 输入。
| 参数 | 值 |
|---|---|
| IO Capability | NoInputNoOutput |
| Security Mode | Mode 1, Level 1 (无加密) / Level 3 (加密, 推荐) |
| Bonding | 支持, 存储配对信息 |
5.2 连接流程¶
5.3 多连接策略¶
- 耳机 Master (左耳) 同时维护 2 个 BLE 连接:
- 手机 (Phone) - GATT 通信
- 右耳 (TWS Slave) - TWS 内部通信
- TWS 内部通信使用私有协议,不对外暴露
5.4 断线重连¶
| 场景 | 行为 |
|---|---|
| 超出范围断开 | 耳机进入低功耗广播模式 (间隔 500ms), 持续 30 分钟后进入休眠 |
| 手动断开 | 耳机进入可发现模式 5 分钟, 超时后休眠 |
| 入盒关盖 | 立即休眠, 停止广播 |
| 出盒开盖 | 唤醒并恢复广播, 尝试自动回连上次设备 |
6. 安全与加密¶
| 项目 | 说明 |
|---|---|
| 配对加密 | BLE Secure Connections, AES-CCM 加密 |
| OTA 固件签名 | 使用 HMAC-SHA256 签名验证固件包完整性 |
| 控制指令校验 | 每个 Write 包携带 XOR Checksum |
| 防重放攻击 | OTA 数据块使用递增序列号 |
| 私密广播 | 可选: 使用 Resolvable Private Address (RPA) |
7. 低功耗策略¶
| 状态 | BLE 活动 | 平均电流 |
|---|---|---|
| 工作中 (已连接) | 响应 GATT 操作, 维持连接间隔 30ms | ~1.2 mA |
| 工作中 (空闲) | 连接间隔扩展至 100ms | ~0.5 mA |
| 广播中 (未连接) | 广播间隔 100ms, 持续 5 分钟 | ~0.8 mA |
| 低功耗广播 | 广播间隔 500ms | ~0.2 mA |
| 休眠 (入盒关盖) | 停止广播 | ~5 µA |
| OTA 升级中 | 连续数据写入, 连接间隔 7.5ms | ~3 mA |
8. 兼容性¶
| 平台 | BLE 版本要求 | 注意事项 |
|---|---|---|
| iOS | 10.0+ | Core Bluetooth API 支持 Notify 和 Write |
| Android | 6.0+ (API 23) | 需动态请求位置权限用于 BLE 扫描 |
| HarmonyOS | 2.0+ | 兼容 BLE 4.2+ |
| Windows | 10+ (BLE 支持) | 需第三方 BLE 调试工具 |
| macOS | 10.10+ | 使用 Core Bluetooth 框架 |
9. 版本历史¶
| 版本 | 日期 | 变更说明 |
|---|---|---|
| v1.0 | 2026-05-17 | 初稿, 定义基础 BLE 协议、GATT 服务、OTA、AT 指令 |
文档结束