蓝牙设备GATT服务和通讯协议怎么设计

给控制板加蓝牙、要和手机 App 通讯,固件这边的 GATT 服务和特征值怎么规划?讲清自定义 Service / Characteristic、Write 与 Write Without Response、Notify、MTU 与分包、广播包里放什么、配对鉴权,以及 iOS 和 Android 的差异。

多爱普团队8 分钟阅读
蓝牙设备GATT服务和通讯协议怎么设计
本文目录
  1. GATT 的基本概念
  2. 推荐的最小结构
  3. MTU 和分包
  4. Write 还是 Write Without Response
  5. 广播包里放什么
  6. 配对和鉴权
  7. 连接参数
  8. 和 App 联调前,固件这边可以先自测
  9. 常见问题
  10. 用模组默认的透传服务可以吗?
  11. 一台手机能同时连多台设备吗?
  12. 设备要支持多部手机同时连吗?
  13. 能帮我们审 GATT 设计吗?

控制板加蓝牙,最常见的做法是外挂一个蓝牙透传模组,或者直接换成带 BLE 的主控。模组手册里一般有默认的透传服务,能用,但真要做成产品,还有不少地方要和 App 一起定:特征值怎么分、一包能发多少字节、广播里放什么、手机怎么认出是你家的设备。

这篇是写给固件工程师的。App 侧的扫描、连接和重连流程,在 蓝牙APP开发怎么做 里有详细说明,这里只讲设备侧需要和 App 对齐的部分。

GATT 的基本概念

BLE 通讯是 App 读写设备上的"特征值"(Characteristic)。特征值归属于"服务"(Service),每个都有 UUID。一个特征值可以有几种属性:

  • Read:App 主动读
  • Write:App 写,设备在链路层确认
  • Write Without Response:App 写,不等确认,速度快
  • Notify:设备主动推送给 App,不需要 App 确认
  • Indicate:设备推送,App 要确认,更可靠但更慢

推荐的最小结构

对大多数控制器,一个自定义服务、两个特征值就够了:

Service      自定义 128 位 UUID
├── RX 特征值  Write / Write Without Response   App → 设备:指令
└── TX 特征值  Notify                          设备 → App:应答和主动上报

再加上标准的设备信息服务(Device Information,0x180A),放型号、固件版本、硬件版本,方便 App 连接后快速判断设备能力。

不建议给每个参数单独开一个特征值。参数一多,GATT 表会很长,加参数还要改 GATT 结构。用一对读写特征值传上层协议帧,参数的区分交给命令字,扩展起来简单得多。帧格式的设计可以看 控制器与App通讯协议怎么制定。

OTA 如果走自定义流程,可以单独再开一对特征值,和业务指令分开,避免升级时和普通数据互相干扰。

MTU 和分包

BLE 默认 ATT MTU 是 23 字节,扣掉 3 字节头,一次写入或通知最多 20 字节有效数据。连接后可以协商更大的 MTU:

  • Android 由 App 调用接口请求,具体能到多少取决于手机和设备双方
  • iOS 由系统自动协商,App 不能指定
  • 设备侧要声明自己支持的最大 MTU

所以协议设计上不要假设 MTU 一定很大。超过当前 MTU 的帧要分包,接收方按帧里的长度字段重组。我们在 BMS 项目里做蓝牙 OTA,就是按 64 字节分包,一个约 59KB 的固件分成 926 包。

Write 还是 Write Without Response

  • 普通指令(读参数、写参数、控制动作):用 Write 也行,配合上层协议的应答,可靠性足够
  • 大量数据(OTA、批量参数):用 Write Without Response 快很多,但要做流控,否则设备缓冲区会被写爆

流控常见做法是"发 N 包等一次确认",或者设备在 Notify 里告诉 App 当前还能收多少。具体在 蓝牙OTA升级怎么实现 里展开。

广播包里放什么

App 扫描时只能看到广播数据,连接之前要靠它判断"这是不是我家的设备"。建议放:

  • 设备名:带品牌前缀和序列号后几位,比如 XX-MC-3F2A
  • 厂商自定义数据(Manufacturer Specific Data):公司 ID + 产品型号 + 序列号 / MAC + 状态标志(是否已绑定、是否在升级模式)

为什么要在广播里放 MAC 或序列号?因为 iOS 拿不到设备的 MAC 地址,系统给的是一个随机的标识,而且换手机就变。如果你的业务要按 MAC 或序列号绑定设备、扫码匹配设备,必须把它放进广播数据或者连接后可读的特征值里。

我们的航标灯器调试 App 就是按蓝牙名称前缀加序列号规则过滤扫描结果,现场只显示本厂灯器。参考 航标灯器蓝牙调试与升级 App。

配对和鉴权

BLE 系统配对(弹窗输 PIN)在不同手机上体验差别很大,很多产品选择不用系统配对,改在应用层做鉴权:

  1. 连接后设备发一个随机数
  2. App 用约定的密钥算出结果回给设备
  3. 设备校验通过才接受控制指令

这样附近的人用通用蓝牙调试工具连上也改不了参数。密钥怎么分发,可以结合云端的设备绑定一起设计。

连接参数

连接间隔决定通讯速度和功耗。电池供电设备想省电,间隔设大一些;需要快速传数据(OTA、批量读取)时,设备可以主动请求缩短间隔,传完再恢复。iOS 对连接参数有自己的限制,设备请求的值不在允许范围内会被拒绝,具体以苹果的配件设计规范为准。

和 App 联调前,固件这边可以先自测

不用等 App。用通用的 BLE 调试工具就能验证 GATT 结构、读写和通知。我们自己做了一个聊天式的蓝牙调试工具 ChatBLE,可以保存快捷命令、HEX 和文本切换,固件工程师自测和售后排查都能用。

常见问题

用模组默认的透传服务可以吗?

可以,很多产品就是这么做的。只要上层协议帧设计好,透传服务足够用。需要注意模组的 MTU 上限和透传缓冲区大小。

一台手机能同时连多台设备吗?

可以,但同时连接数受手机限制,不同机型差别很大。需要批量操作的场景,最好按"逐台连接、操作、断开"来设计。

设备要支持多部手机同时连吗?

多数 BLE 设备同一时间只接受一个连接。要不要支持多连接,看业务需求和芯片能力,并在协议里定好冲突怎么处理。

能帮我们审 GATT 设计吗?

可以,把 GATT 表和协议文档 发给我们。整体合作方式见 传统设备智能化升级。

项目咨询

把项目情况发过来,先帮你理清下一步

发来设备类型、协议资料、样机状态和计划上线时间,我们会结合对应的服务和案例给出推进建议。

如果你暂时不方便填写完整信息,也可以直接前往 联系页面 获取电话、邮箱与微信方式。

提交项目需求

适用于 蓝牙设备GATT服务和通讯协议怎么设计 场景,提交后默认进入业务咨询通道。

微信、电话、邮箱至少填写一项

点击发送即表示您同意我们的隐私政策和服务条款