基础概念

BLE 角色全景:client/server、central/peripheral 与 observer/broadcaster 各管哪一层

发布于 2026-07-21 · 来自「嵌入式江湖」技术专栏

蓝牙低功耗(BLE)里"角色"特别容易把人搞晕:同样是"两端",有人叫 client/server,有人叫 central/peripheral,还有 broadcaster/observer。很多开发者下意识以为"主机就是 client、从机就是 server",结果调试时怎么都对不上。

核心原因:BLE 在不同协议层定义了完全不同的角色对,而且它们彼此独立。本文把这三对角色拆开讲清——它们分别在哪一层、管什么、能不能随便组合。

阅读前提:了解广播/连接基本流程即可。想深入看专栏里的《广播与扫描》《GATT 服务与特征值设计》。

一、三对角色,分属不同层

角色对 所在层 解决的问题 是否建立连接
Broadcaster / Observer GAP(广播/扫描) 单向广播、无需连接
Central / Peripheral GAP(连接) 谁发起并维持连接
GATT Server / Client GATT(数据模型) 谁拥有数据、谁来读写 (建立在连接之上)

一句话:广播层决定"能不能被看见",连接层决定"谁拉起链路",GATT 层决定"数据在谁手里、谁来取"。这三件事是正交的。

二、GAP 层:广播与连接(链路层视角)

GAP(Generic Access Profile)在链路层之上定义设备"怎么被发现、怎么连起来"。它又分两种场景。

角色定义在 Host,动作发生在 Controller(重要澄清):这四个角色的名字和规则,全部由 GAP(Host 层) 规定;而它们对应的空中动作——发广播、扫广播、建连接——都交由 Controller 的链路层(Link Layer) 执行。链路层有五个状态(Standby / Advertising / Scanning / Initiating / Connection),GAP 的四种角色,本质就是把这些 LL 状态按"可连接与否"组合出来:Broadcaster = LL 的 Advertising(不可连接)、Observer = LL 的 Scanning、Peripheral = LL 的 Advertising(可连接)+ Slave、Central = LL 的 Initiating + Master。

所以不要按 controller / host 去切分 Broadcaster/Observer 与 Central/Peripheral:前者是 LL 的 Advertising/Scanning 状态(不连),后者是 LL 的 Initiating + Connection 状态(连),二者都是"GAP 管定义、LL 管执行"。两对角色的区别只在连不连,不在属于哪一层

2.1 无连接场景:Broadcaster / Observer

  • Broadcaster(广播者):只发广播包、不可连接。最典型就是 iBeacon、Eddystone 这类信标——它不停喊"我在这里、我是谁",但不接任何连接。广播类型通常是 ADV_NONCONN_IND
  • Observer(观察者):只扫描、不发起连接。它监听周围广播,拿到广播 payload 就走,从不在空中建立一条连接。对应 LE Set Scan Enable 的扫描者角色。

这对角色用于"单向信息发布":商场信标给手机推位置、温度传感器周期广播读数给网关。两端永不断连,省电到极致。

2.2 可连接场景:Central / Peripheral

  • Peripheral(外围设备):发 可连接 广播(ADV_IND / ADV_DIRECT_IND),等待被连。连接后成为链路的 Slave(从)。心率带、智能锁、BLE 传感器通常扮演这个角色。
  • Central(中心):先扫描可连接广播,再主动发 CONNECT_IND 把链路拉起来,连接后是链路的 Master(主)。手机、网关、主机通常扮演这个角色。

注意:Central/Peripheral 只在"连接建立 + 连接期间"有意义。连接一旦断开,角色随之消失。一个 Central 可以同时连多个 Peripheral(比如手机连手环+耳机+体重秤),而 Peripheral 通常只连一个 Central(虽规范允许多主,工程上少见)。

旧文档常把 Central/Peripheral 叫 Master/Slave,新版规范统一用 Central/Peripheral,建议丢掉主从这套说法。

三、GATT 层:数据归属(属性协议视角)

连接建好之后,数据怎么组织、谁读写,由 GATT(Generic Attribute Profile)定义。这里是另一对角色:

  • GATT Server(服务器):持有属性表(Attribute Table)——也就是 services、characteristics、descriptors。它 响应 对端的 Read/Write,主动发 Notification / Indication。典型:心率带把心率值存在自己的 GATT Server 里。
  • GATT Client(客户端):不持有数据,而是 发现(discover) 对端的服务与特征、发起 Read/Write、接收 Notification。典型:手机 App 去读心率带的值。

关键点:GATT 的 Server/Client 跟"谁发起连接" 完全无关。Server 只是"数据在谁那里",Client 只是"谁来取数据"。

四、最常见误区:把两层角色画等号

这是全文重点。请记住:

GAP 角色(Central/Peripheral)≠ GATT 角色(Client/Server)。

它们可以自由组合。常见四种搭配:

设备 GAP 角色 GATT 角色 例子
手机 App Central Client 连手环读心率
心率带 Peripheral Server 暴露心率特征
手机(同时) Central Server 手机也把自己的时间/设备信息服务暴露给手环
网关 Hub Central Client + Server 连多个传感器取数,同时把汇总数据对外暴露

最反直觉的例子:手机和手表配对时,手机通常是 Central + GATT Client(去读手表的 HR);但手表要同步手机的时间,得反过来读手机的 GATT Server——此时手机在同一连接里又成了 GATT Server。所以"谁是 Server"是按 GATT 事务方向定的,不是按设备定的。

另一个例子:有些 Peripheral 同时是 GATT Client。比如一个 BLE 键盘(Peripheral,被手机连),它想获取手机上的时间服务来校时,就会作为 GATT Client 去读手机的 GATT Server。外围设备照样能当 client。

五、Observer / Broadcaster 与 discover 的区别

新手还常把这几件事混为一谈,这里划清界限:

  • Observer(观察者):是 GAP 扫描角色, 只听广播、不连接。它"发现"的是周围的广播设备。
  • Central(中心):也是扫描角色,但它 会进一步发起连接。它"发现"的是可连接设备。
  • GATT Discovery(服务发现):是 GATT Client 在连接建立后的动作——调用 Discover All Primary Services 等过程,把对端属性表读出来。这跟 Observer 扫广播是两码事,一个在空中(链路层),一个在连接里(GATT 层)。

所以你问题里的 "discover / observer" 其实分属两层:Observer 管"空中发现设备",discover(GATT discovery)管"连上后发现服务"。别因为都带"发现"就当成一回事。

六、角色在协议栈里是怎么落地的

  • 链路层:广播包 ADV_EXT_IND / AUX_ADV_INDAdvMode 字段决定可连接/可扫描/不可连接,从而区分 Broadcaster vs Peripheral、Observer vs Central 的"能不能连"。
  • HCI / GAP 接口:Central 调用"创建连接"类命令(如 LE Create Connection,扩展广播对应 LE Extended Create Connection);Peripheral 在收到连接请求后完成连接。GATT Server 在应用层注册服务表;GATT Client 调用 discovery / read / write API。
  • L2CAP / ATT:GATT 跑在 L2CAP 固定信道 0x0004(ATT)上,所有 Read/Write/Notify 都是 Client↔Server 之间的 ATT 报文。

七、实战坑提醒(8 条)

  1. Peripheral ≠ Server:外围设备不一定持有你想读的数据;它也可能只是个 GATT Client。永远按 GATT 角色找数据,别按 GAP 角色猜。
  2. Central ≠ Client:中心设备既可以是 Client 也可以是 Server,取决于它在某次 GATT 事务里的方向。
  3. Observer 不会连接:用它做信标接收没问题,但别指望 Observer 去读对方数据——它根本没建链。
  4. Broadcaster 不响应:信标类设备收到扫描请求(AUX_SCAN_REQ)可能回扫描响应,但绝不接受连接,别去 CONNECT 它。
  5. 角色是"每连接"的:一个设备在不同连接里可以是不同角色;同一连接里也可双向都是 Server(互有服务)。
  6. 多连接下的 Central:手机连多个 Peripheral 时,每个连接各自一套 GATT Client/Server 关系,别串台。
  7. 调试先看角色:抓包(nRF Sniffer / Wireshark)时,先确认链路层谁发的 CONNECT_IND(定 Central/Peripheral),再看 ATT 层谁发 Read(定 Client/Server),两层分开看。
  8. 命名统一:团队内部统一用 Central/Peripheral/Server/Client,别混用主从、客户端/服务端的中文俗称,避免沟通错位。

八、一句话总结

BLE 的"角色"有三套、分三层:链路层广播用 Broadcaster/Observer(不连接)、连接用 Central/Peripheral(谁拉链路)、GATT 用 Server/Client(数据在谁手里);其中只有后两者常被混淆,但记住"建链的人不一定是拿数据的人"——GAP 角色和 GATT 角色正交,可以任意组合。下次有人拍胸脯说"从机就是 server",你就知道该纠正了。

更多 BLE / 鸿蒙星闪 / 芯片选型 / MCU 实战,持续更新