1. BLE基础回顾:协议栈架构、GAP与GATT角色、广播与扫描机制、连接建立流程

各位同学,咱们今天正式开课。在进入蓝牙Mesh之前,我强烈建议先把BLE基础夯实。你想想看,Mesh本质上是BLE的扩展,底层还是那套广播、扫描、连接机制。如果这些基础概念模糊,后面学Mesh会非常痛苦。

我个人习惯,每接手一个新项目,第一件事就是翻芯片的BLE协议栈手册。不是看API怎么调,而是看它支持哪些角色、广播包怎么配、MTU多大。这些底层参数决定了上层应用的天花板。

1.1 BLE协议栈架构:从物理层到应用层

BLE协议栈分三层:Controller、Host、Application。我画了一张图,帮你把层次关系理清楚。

核心要点:Controller负责射频收发,Host负责协议逻辑,Application负责业务实现。这三层通过HCI(Host Controller Interface)通信。

BLE协议栈架构 Application Layer(应用层) 用户业务逻辑、Profile实现、数据解析 Host Layer(主机层) GAP(通用访问规范) GATT(通用属性规范) SM(安全管理) L2CAP(逻辑链路控制) ATT(属性协议) HCI(主机控制器接口) Controller Layer(控制器层) LL(链路层) PHY(物理层) 数据流向:自上而下

这张图你得记住。我当年调试一个连接失败的问题,查了三天,最后发现是HCI层的流控没配好。协议栈每一层都有坑,但只要你心里有这张层次图,定位问题就快得多。

1.2 GAP与GATT角色:谁在干什么?

GAP和GATT是BLE里最容易混淆的两个概念。我简单说:GAP管“谁是谁”,GATT管“怎么传数据”。

GAP角色

GAP定义了四种角色,设备可以同时扮演多个角色。我在做智能门锁项目时,门锁就是Peripheral,手机就是Central。但有些场景下,比如室内定位基站,它既是Central又是Peripheral,这叫“双角色”。

GAP角色 职责 典型设备
Broadcaster 只发广播,不连接 信标、温度传感器
Observer 只扫描广播,不连接 扫描仪、网关
Peripheral 可被连接,通常作为从机 手环、传感器节点
Central 发起连接,通常作为主机 手机、平板

避坑指南:我曾经在项目中把Peripheral和Central的角色搞反了,结果手机连不上设备。后来发现是广播包里的Flags字段没配对。记住:Peripheral发广播,Central扫描并连接。

GATT角色

GATT在连接建立后才生效。它定义了Client和Server两种角色:

  • GATT Server:存储数据(属性表),响应读写请求。传感器设备通常是Server。
  • GATT Client:发起读写请求,接收通知。手机App通常是Client。

你想想看,一个设备可以同时是GATT Server和GATT Client。比如智能手表,它作为Server提供心率数据,同时作为Client读取手机的通知消息。这在BLE协议里完全合法。

1.3 广播与扫描机制:设备怎么“打招呼”?

广播是BLE设备互相发现的基础。我把它比作“在走廊里喊一声,看谁在听”。

广播通道与事件

BLE在2.4GHz频段有40个通道(0-39),其中37/38/39是广播通道。为什么选这三个?因为它们均匀分布在频段内,抗干扰能力强。

广播事件由若干个广播包组成。设备在三个通道上轮流发送,每次发送间隔称为广播间隔(advInterval),范围20ms到10.24s。

注意:广播间隔不是越小越好。我见过有人把广播间隔设成20ms,结果功耗飙升,纽扣电池三天就没电了。一般场景下100ms-500ms是比较合理的范围。

广播包结构

一个广播包最多31字节。结构如下:

广播包格式:
| Preamble(1B) | Access Address(4B) | PDU(2-39B) | CRC(3B) |

PDU结构(广播通道):
| Header(2B) | AdvA(6B) | AdvData(0-31B) |

AdvData内部:
| AD Structure 1 | AD Structure 2 | ... |
  | Length(1B) | AD Type(1B) | AD Data(NB) |

这里有个关键点:AD Type决定了广播数据的含义。比如0x01表示Flags,0x09表示Complete Local Name。我在项目中经常用0xFF(Manufacturer Specific Data)来传自定义数据,这样手机端解析起来也方便。

扫描机制

扫描分两种模式:

  • 被动扫描:只收广播,不发任何包。省电,但无法获取扫描响应。
  • 主动扫描:收到广播后,发送扫描请求(SCAN_REQ),设备回复扫描响应(SCAN_RSP)。可以多拿31字节数据。

我个人习惯,在需要获取设备完整信息时用主动扫描。比如做蓝牙网关,扫描到设备后立即发SCAN_REQ,拿到设备名称和服务UUID,这样后续连接决策更准确。

1.4 连接建立流程:从广播到数据通道

连接建立是BLE协议里最精妙的部分。我拆成几个步骤来讲。

步骤一:广播与扫描

Peripheral在37/38/39通道上发广播包。Central在三个通道上轮流扫描。两者在时间上必须“碰得上”。

步骤二:连接请求

Central收到广播后,发送CONNECT_REQ。这个包包含:

  • Access Address:连接专用的访问地址,后续数据包都用它
  • Connection Interval:连接间隔,1.25ms的整数倍
  • Slave Latency:从机延迟,允许跳过的连接事件数
  • Supervision Timeout:超时时间,超过这个时间没收到包就断开

关键参数:连接间隔(Connection Interval)直接影响吞吐量和功耗。间隔越小,吞吐量越高,但功耗也越大。我一般推荐7.5ms-30ms,具体看应用场景。

步骤三:数据通道跳频

连接建立后,双方切换到数据通道(0-36)。BLE使用自适应跳频,每次连接事件都跳到不同的通道上。这样做的好处是抗干扰——WiFi在某个通道上打架了,BLE自动跳到干净通道。

步骤四:连接参数更新

连接建立后,Central或Peripheral可以发起连接参数更新请求。比如刚连接时用15ms间隔快速交互数据,之后改成100ms间隔省电。

我曾经遇到一个坑:某款芯片在连接参数更新时,如果Central不响应,Peripheral会一直重试,导致功耗异常。后来我加了超时处理,三次重试无响应就断开连接重新广播。

1.5 本章小结

好了,这一章的内容就到这里。我们回顾一下:

  • BLE协议栈分Controller、Host、Application三层,HCI是桥梁
  • GAP管角色和发现,GATT管数据传输
  • 广播在37/38/39通道上发,扫描分主动和被动
  • 连接建立经过广播→扫描→CONNECT_REQ→跳频→参数更新

这些基础概念,后面讲Mesh时会反复用到。尤其是广播机制和连接参数,Mesh的节点间通信就是基于这些底层能力扩展出来的。你把这些吃透了,学Mesh会轻松很多。