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型。星型和树型更多是作为局部优化手段存在。

三种拓扑结构对比 星型拓扑 中心 节点 节点 节点 树型拓扑 根 分支 分支 叶 叶 叶 叶 Mesh型拓扑 A B C D E F 说明:实际蓝牙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个灯泡同时亮起。你会怎么做?

  1. 给客厅的3个灯泡分配同一个组播地址,比如 0xC001。
  2. 发送一条消息,目标地址设为 0xC001,操作码是开灯。
  3. 网络中的中继节点转发这条消息。
  4. 只有订阅了 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网络的基本盘。