3. 网络拓扑与寻址:Mesh网络的骨架与门牌号
聊蓝牙Mesh,绕不开两个东西:拓扑和寻址。
拓扑决定了设备怎么连,寻址决定了消息发给谁。这两个搞不清楚,后面配网、模型交互全得翻车。我刚开始接触Mesh时,就因为在组播地址上栽了个跟头,导致一屋子灯全亮了——嗯,客户差点没把我骂死。
3.1 拓扑结构:不止是Mesh型
很多人以为蓝牙Mesh只有一种拓扑,就是设备之间互相连。其实不然。蓝牙Mesh协议栈支持三种拓扑:星型、树型和Mesh型。它们各有各的适用场景。
3.1.1 星型拓扑
说白了就是一个中心节点,其他节点都连它。中心节点负责转发所有消息。这种结构简单,但中心节点压力大,挂了整个网络就瘫了。
我在做智能家居网关项目时,早期方案就是星型。结果网关一重启,所有子设备全掉线。后来果断切了Mesh型。
3.1.2 树型拓扑
树型是星型的升级版。节点分层,父节点管子节点。好处是消息路径清晰,坏处是上层节点挂了,下层全断。
蓝牙Mesh标准里并没有强制要求树型,但有些私有协议会用它做中继优化。我个人不太推荐纯树型,除非你的网络规模特别大,而且对延迟不敏感。
3.1.3 Mesh型拓扑
这才是蓝牙Mesh的看家本领。每个节点都可以和周围节点通信,消息通过中继一跳一跳传遍全网。没有单点故障,扩展性好。
你想想看,一个Mesh网络里,节点越多,路径越多,可靠性反而越高。这就是Mesh的魅力。
核心结论:实际项目中,绝大多数场景都用Mesh型。星型和树型更多是作为局部优化手段存在。
3.2 寻址:消息的门牌号
拓扑搭好了,消息怎么找到目标设备?这就靠寻址。蓝牙Mesh定义了三种地址类型:单播地址、组播地址和虚拟地址。
3.2.1 单播地址
每个节点在配网时,会分配一个唯一的单播地址。范围是 0x0001 到 0x7FFF。说白了就是设备的身份证,一对一通信时用。
我记得第一次调试时,用单播地址控制一个灯泡,死活没反应。后来发现地址配错了——配网时没保存好。嗯,这种低级错误谁都会犯。
3.2.2 组播地址
组播地址就是群发用的。一个消息发出去,所有加入这个组的设备都能收到。范围是 0xC000 到 0xFFFF。
组播地址分两种:
- 固定组播地址:协议预定义的,比如
0xFFFF是所有节点都收的广播地址。 - 动态组播地址:应用层自己定义的,比如把客厅所有灯加入组播地址
0xC001。
我的经验:组播地址别用太多,每个节点订阅的组播地址数量有限。Nordic nRF5 SDK默认最多支持16个组播地址订阅。超了?消息就丢了。
3.2.3 虚拟地址
虚拟地址是蓝牙Mesh 5.0引入的。它基于128-bit UUID生成,通过哈希映射到一个16-bit的虚拟地址标签。范围是 0x8000 到 0xBFFF。
虚拟地址的好处是:你可以用UUID来标识一个逻辑分组,而不需要手动分配组播地址。适合大规模部署时自动分组。
但注意,虚拟地址的哈希碰撞概率虽然低,但不是零。我在一个项目中用了300多个虚拟地址,结果有两个碰撞了。排查了三天才找到原因。
避坑指南:虚拟地址虽然方便,但不要滥用。每个节点处理虚拟地址需要额外的计算资源。我曾经在一个低功耗传感器节点上用了虚拟地址,结果电池寿命直接砍半。
3.3 地址类型对比
| 地址类型 | 范围 | 用途 | 典型场景 |
|---|---|---|---|
| 单播地址 | 0x0001 - 0x7FFF | 一对一通信 | 配置、固件升级 |
| 组播地址 | 0xC000 - 0xFFFF | 一对多通信 | 场景控制、群组开关 |
| 虚拟地址 | 0x8000 - 0xBFFF | 基于UUID的灵活分组 | 大规模自动分组 |
3.4 寻址实战:一个消息的旅程
假设你有一个Mesh网络,里面有10个灯泡。你想让客厅的3个灯泡同时亮起。你会怎么做?
- 给客厅的3个灯泡分配同一个组播地址,比如
0xC001。 - 发送一条消息,目标地址设为
0xC001,操作码是开灯。 - 网络中的中继节点转发这条消息。
- 只有订阅了
0xC001的3个灯泡会处理这条消息,其他节点直接丢弃。
你看,整个过程就是拓扑+寻址的配合。拓扑保证消息能传到,寻址保证只有目标设备响应。
关键点:消息的TTL(生存时间)决定了它能跳多远。默认TTL是7,最大127。我建议不要设太大,否则网络里全是无效中继,带宽浪费严重。
3.5 寻址与模型的关系
地址最终要绑定到模型上。模型是蓝牙Mesh的功能单元,比如Generic OnOff Server模型控制开关。每个模型可以订阅多个地址,也可以发布到多个地址。
举个例子:
- 灯泡A的OnOff Server模型订阅了组播地址
0xC001。 - 开关B的OnOff Client模型发布到
0xC001。 - 按下开关B,消息发到
0xC001,灯泡A收到并响应。
这就是寻址和模型的协作。没有地址,模型就是孤岛;没有模型,地址就是空壳。
个人习惯:我一般在设计阶段就把地址规划好。单播地址按设备类型分段,组播地址按区域分段。比如0xC000-0xC0FF给客厅,0xC100-0xC1FF给卧室。这样后期维护起来特别省心。
3.6 小结
拓扑和寻址是蓝牙Mesh的骨架。拓扑决定了网络怎么连,寻址决定了消息怎么发。搞懂这两个,你就掌握了Mesh网络的基本盘。