1. 蓝牙Mesh低功耗设计导论

各位同学好,我是老周。做蓝牙开发十几年了,从经典的BR/EDR到BLE,再到Mesh,一路踩坑过来。今天咱们开始聊蓝牙Mesh,这门课的核心是休眠唤醒与低功耗设计,但开篇得先把地基打牢——协议栈长什么样、节点分几种、角色怎么定。这些东西搞不清楚,后面讲休眠策略你肯定听得云里雾里。

1.1 蓝牙Mesh协议栈架构

蓝牙Mesh的协议栈,说白了就是分层的。每一层只管自己的事,上层调下层,下层给上层服务。我刚开始看规范时也觉得层数多,但实际做项目后发现,这种分层设计特别适合低功耗场景——你想让哪层休眠、哪层唤醒,边界很清楚。

来看这张图,我手绘的,别嫌丑:

蓝牙Mesh协议栈架构 Model Layer(模型层) Foundation Model Layer(基础模型层) Access Layer(接入层) Upper Transport Layer(上层传输层) Lower Transport Layer(下层传输层) Network Layer(网络层) 底层依赖 BLE 5.x 的 Advertising/Scanning 扩展,Mesh 不直接使用 GATT

从上往下看,一共七层。我挑几个重点说说:

  • Model Layer:你写业务逻辑的地方。比如灯的开/关、调色温,都在这一层定义。说白了,这是离你最近的一层。
  • Foundation Model Layer:Mesh网络的基础服务,比如配置、健康检查。你想想看,一个新设备入网,谁来给它分配地址?就是这层干的。
  • Access Layer:把应用数据打包成消息,加上操作码。嗯,这里要注意,消息大小有限制,后面讲分段传输时会细说。
  • Upper/Lower Transport Layer:负责消息的分段与重组、加密与认证。我在项目中遇到过,消息太长被截断,接收端拼不回来——就是下层传输层没处理好。
  • Network Layer:最核心的一层。消息转发、中继、地址过滤全在这。低功耗节点的休眠唤醒,主要就是跟这一层打交道。
个人经验: 很多初学者只关注Model层怎么写代码,忽略了Network层的转发机制。结果节点一多,消息就丢了。我建议你先把Network层的转发逻辑吃透,再写应用层代码。

1.2 节点类型与角色定义

蓝牙Mesh里,节点不是千篇一律的。根据功能不同,分了好几种角色。你想想看,一个智能灯泡和一个墙壁开关,它们需要的功能能一样吗?灯泡可能一直在线,开关可能用电池供电,得省电。

规范里定义了四种节点角色,我整理了一张表:

角色 功能描述 典型功耗 是否支持休眠
Relay Node 中继消息,转发给其他节点 较高(常开) 否
Proxy Node 桥接Mesh网络与GATT设备(如手机) 较高(常开) 否
Friend Node 为低功耗节点缓存消息 中等 否
Low Power Node (LPN) 大部分时间休眠,定期唤醒收消息 极低 是

这里有个关键点:一个节点可以同时扮演多个角色。比如一个设备既可以是Relay,也可以是Friend。但LPN不能同时做Relay——你想想看,一个天天睡觉的节点,怎么帮别人转发消息?

避坑指南: 我曾经在一个项目中,把LPN节点也配成了Relay角色,结果节点频繁唤醒转发消息,电池三天就耗光了。后来才意识到,LPN和Relay是互斥的。这个坑我替你们踩过了。

1.3 节点状态与地址类型

每个Mesh节点都有自己的状态。比如灯的开关状态、亮度值。这些状态通过消息来读写。地址嘛,就是节点的门牌号。

蓝牙Mesh定义了三种地址类型:

  • 单播地址(Unicast):每个节点唯一。配置时由Provisioner分配。我习惯把单播地址比作身份证号。
  • 组播地址(Group):一组节点共享。比如“客厅所有灯”就是一个组。发一条消息,全组都收到。
  • 虚拟地址(Virtual):基于UUID的标签,用于更灵活的订阅。实际项目中用得不多,但做复杂场景时很有用。

你想想看,一个灯泡节点,它可能订阅了“客厅灯”这个组播地址,同时也拥有自己的单播地址。这样既能单独控制,也能批量控制。

1.4 消息发布/订阅机制

Mesh网络的消息传递,核心就是发布/订阅模型。节点可以发布消息到某个地址,也可以订阅某个地址的消息。说白了,就是“谁说话,谁听”。

举个例子:

// 伪代码示例:配置一个灯节点
灯节点.订阅地址 = 0xC001;  // 订阅"客厅灯"组
灯节点.发布地址 = 0xC001;  // 状态变化时发布到同一组

// 开关节点按下
开关节点.发布(地址=0xC001, 消息="开灯");
// 灯节点收到消息,执行开灯动作

这种机制的好处是解耦。开关不用知道灯的具体地址,灯也不用管是谁发的消息。我做过一个项目,客户要求加一个场景面板,只需要配置它发布到对应的组地址就行,其他节点完全不用改代码。

注意: 发布/订阅地址的配置是在Provisioning阶段完成的。如果配错了,节点入网后收不到消息,排查起来很麻烦。我建议你在配置工具里先做地址规划,别上来就写代码。

1.5 本章小结

这一章我们聊了蓝牙Mesh的协议栈架构——七层结构,每层各司其职。节点类型分四种,其中LPN是低功耗设计的核心角色。地址类型和发布/订阅机制是Mesh网络通信的基础。

嗯,这些概念看起来有点多,但别急。后面几章我们会一步步深入,尤其是LPN的休眠唤醒机制,我会把我在实际项目中踩过的坑、总结的经验,全都抖出来。你先把这张图记在脑子里,后面用得上。