蓝牙Mesh基础:协议栈架构、节点角色与消息模型
各位同学,咱们今天聊聊蓝牙Mesh的底子。说实话,我刚接触蓝牙Mesh那会儿,也被它那一堆概念搞得有点晕——节点、角色、消息、模型……感觉像进了个新世界。但等你真正用起来就会发现,这些设计其实非常巧妙。
蓝牙Mesh不是传统蓝牙的点对点连接,而是一种多对多的通信网络。每个设备都能转发消息,整个网络就像一张大网,一个节点说话,其他节点都能听到。嗯,咱们先从协议栈开始拆解。
2.1 蓝牙Mesh协议栈架构
蓝牙Mesh的协议栈分好几层,我习惯从下往上理解:
- BLE核心层:负责最底层的射频通信,就是咱们熟悉的蓝牙4.0/5.0那套东西。
- 承载层(Bearer Layer):决定数据怎么传输。最常见的是广播承载(Advertising Bearer)和GATT承载(GATT Bearer)。广播承载是Mesh的主力,GATT承载主要用于手机App连接Mesh网络。
- 网络层(Network Layer):负责消息的转发和路由。这一层决定了消息能不能跳到下一个节点。
- 底层传输层(Lower Transport Layer):处理消息的分片和重组。一条大消息会被切成小块发送,到了接收端再拼回去。
- 上层传输层(Upper Transport Layer):负责加密、解密和消息的可靠性确认。
- 接入层(Access Layer):定义了应用数据怎么封装成消息。
- 基础模型层(Foundation Model Layer):提供一些标准模型,比如配置模型、健康模型等。
- 模型层(Model Layer):这是咱们开发者最常打交道的层。灯控、传感器、开关……都通过模型来实现。
核心要点:蓝牙Mesh协议栈从下到上,层层封装。你不需要每层都精通,但必须知道每层干什么用。我在项目中踩过最大的坑,就是忽略了网络层的TTL设置,导致消息永远跳不出第一个节点。
下面这张图是我自己画的协议栈结构,你一看就明白:
2.2 节点与角色
蓝牙Mesh网络里,每个设备都是一个节点(Node)。但节点不是生而平等的——它们有四种角色。我个人觉得,理解这四种角色是入门Mesh的关键。
| 角色 | 英文名 | 核心功能 | 典型场景 |
|---|---|---|---|
| 中继节点 | Relay | 接收并转发消息,扩大网络覆盖范围 | 智能灯泡、网关 |
| 低功耗节点 | Low Power | 大部分时间休眠,定期唤醒接收消息 | 电池供电的传感器 |
| 朋友节点 | Friend | 为低功耗节点缓存消息,等它唤醒时再发送 | 常供电的插座、网关 |
| 代理节点 | Proxy | 让不支持Mesh的设备(如手机)通过GATT接入网络 | 手机App、调试工具 |
我的经验:一个节点可以同时扮演多个角色。比如一个网关可以既是Relay又是Friend还是Proxy。但要注意,角色越多功耗越大。我曾经在一个项目中把所有节点都设成Relay,结果电池设备两天就没电了……
2.2.1 中继节点(Relay)
Relay是Mesh网络的骨干。它收到消息后,会根据TTL(生存时间)决定是否转发。TTL每经过一跳减1,减到0就不再转发。这样可以防止消息在网络里无限循环。
2.2.2 低功耗节点(Low Power)
Low Power节点平时在睡觉,只有需要时才醒来。它不能直接接收消息,必须依赖一个朋友节点帮它缓存。你想想看,一个温湿度传感器如果一直开着蓝牙接收,电池撑不了几天。所以低功耗节点在物联网里特别实用。
2.2.3 朋友节点(Friend)
Friend节点和Low Power节点是一对一的绑定关系。Friend会定期检查有没有发给Low Power的消息,有的话就存起来。等Low Power醒来时,Friend再一次性发给它。这个机制叫朋友轮询(Friend Poll)。
避坑指南:我曾经在一个项目中,Friend节点和Low Power节点的轮询间隔没配好。Low Power每10秒醒来一次,但Friend每30秒才检查一次缓存。结果消息延迟严重,用户按开关后灯要等20秒才亮。后来我把轮询间隔统一改成5秒,问题才解决。
2.2.4 代理节点(Proxy)
Proxy节点是Mesh网络和外部世界的桥梁。手机没有Mesh协议栈,只能通过GATT连接Proxy节点,然后Proxy把GATT数据转换成Mesh消息。说白了,Proxy就是个翻译官。
2.3 消息与模型
蓝牙Mesh里,节点之间靠消息(Message)沟通。消息分两种:
- 可靠消息(Acknowledged Message):发送方要求接收方回复确认。适合控制类场景,比如开关灯。
- 不可靠消息(Unacknowledged Message):发出去就不管了。适合状态广播,比如温度上报。
消息的格式很简单:操作码(Opcode)+ 参数(Parameters)。操作码告诉节点“你要干什么”,参数告诉节点“具体怎么做”。
那模型(Model)又是什么?模型定义了节点能理解的消息集合。比如一个灯控模型,它知道怎么处理“开灯”、“关灯”、“调亮度”这些消息。
| 模型类型 | 说明 | 例子 |
|---|---|---|
| 服务器模型 | 提供状态,响应客户端请求 | 灯的状态(开/关/亮度) |
| 客户端模型 | 发送请求,控制服务器 | 开关面板 |
| 控制模型 | 既是客户端又是服务器 | 调光器(既能控制别人,也能被控制) |
蓝牙Mesh标准定义了很多基础模型,比如:
- Generic OnOff:开关控制
- Generic Level:亮度/温度等连续值控制
- Sensor:传感器数据上报
- Light Lightness:灯光亮度控制
你还可以自定义模型。我做过一个项目,需要控制窗帘的开合角度,标准模型没有这个功能,我就自己写了个Vendor Model。嗯,自定义模型要注意消息ID不能和标准模型冲突。
核心要点:消息是通信的载体,模型是通信的协议。节点通过模型来理解消息,就像人通过语言来理解对话。你设计产品时,先想清楚需要哪些模型,再决定节点角色。
最后,我用一张图总结一下节点角色和消息的关系: