## 蓝牙 Mesh 技术初探
>2017年蓝牙 SIG 推出了最新的蓝牙技术,包括蓝牙5和蓝牙 Mesh ,引起业界的广泛兴趣。特别是蓝牙 Mesh 技术,打破了以往蓝牙技术的使用方式和场景,开发者对此也是满怀期待。因为目前关于蓝牙 Mesh 技术的文档相对较少,使得这一新标准带着些许神秘感。本文介绍了蓝牙 Mesh 技术的基本理论以及与蓝牙其他技术的异同点。
### 蓝牙5和蓝牙 Mesh
#### 蓝牙5
蓝牙5是蓝牙 SIG 今年新推出的蓝牙标准,相比之前的蓝牙 4.x,有了以下提升:
- Slot Availability Mask(SAM)
增加了蓝牙设备在连接以后动态调整通信时隙(SLOT)的功能。一个支持蓝牙5的手环在下载固件的时候,可以申请比之前更多的时隙,更快的完成大数据量的传输。
- 新版本 LE 的物理层
之前的蓝牙低功耗标准物理层使用的是 1M/S 的 PHY,现在增加了 2M/S 作为可选项,同时在 1M/S 的 PHY 里新支持1:2和1:8的编码模式,数据率降到 125kbps 和 500kbps。前者的增加使蓝牙5的吞吐率大大提高,达到旧标准的8倍。而后者由于使用了编码方式,提高了灵敏度,视距(LOS)也大大提高,常常认为会有4倍以上的距离增益。
- 广播报文的扩展
蓝牙5把广播信道从之前的38,39,40扩展到了数据信道,可以采用 FEC+Pattern mapper 来提高容错率和增加距离,也可以在任何信道触发连接。Beacon 也有一些新的功能选项。
总的来说,蓝牙5是一个深入到底层的,相对旧版本比较大的改动。图1列出一些主要的性能提升。
图1 蓝牙5的标准相比之前版本的主要提升
#### 蓝牙 Mesh
也许是因为蓝牙 Mesh 的发布晚于蓝牙5,所以很容易让人误解 Mesh 技术是基于蓝牙5技术的,其实它们两者没有前后的关系。蓝牙 Mesh 可以支持蓝牙4和蓝牙5标准,因为目前蓝牙5的解决方案相对较少,反而对蓝牙4的支持更好。
蓝牙 SIG 在阐述蓝牙的工作原理时,一般这样分类:基础率/增强数据率(BR/EDR),低耗能/低功耗(LE)。在低耗能/低功耗(LE)里面又分为点对点(P2P),广播(Broadcast)和网格网络( Mesh )。新推出的蓝牙 Mesh 网络拓扑建立了大型设备网络,是建筑自动化、传感器网络、资产跟踪以及需要多台设备间可靠安全通信的解决方案的理想选择,见图2。
图2 蓝牙技术的分类
下文将分别对蓝牙 Mesh 的架构、基本构成、组网和信息的传递进行说明。
### 架构
蓝牙 Mesh 使用了新的协议架构。在图4中可以看到新的蓝牙 Mesh 的架构与图3中表示的非 Mesh 版本的架构有很大的差别的。SIG 定义了很多新的协议层来实现 Mesh 的功能,这里简单做个说明。
图3 Bluetooth LE 的协议架构(非蓝牙 Mesh )
图4 BLE Mesh 的协议架构
#### Bearer Layer
Bearer Layer 定义了 Mesh 节点怎么传递网络消息。它定义了两种 Bearer,广播 bearer 和 GATT bearer。
广播 Bearer 利用的是 BLE GAP 广播包的 advertising 和 scanning 的功能来传递和接收 Mesh 报文。GAP 在B LE4.x 的规范里定义了四种模式:
1. Broadcaster:发送 advertising events 的设备(有 Transmitter,可能有 Receiver);
2. Observer:接收 advertising events 的设备(可能有 Transmitter,有 Receiver);
3. Peripheral:物理链路上接受连接的设备,在 LL 层 Connection State为Slave(有 Transmitter 和 Receiver);
4. Central:物理链路上发起连接的设备,在 LL 层 Connection State 为 Master(有 Transmitter 和 Receiver)。
GATT Bearer 允许不支持 Advertising Bearer 的设备间接的与 Mesh 节点进行通讯。可以利用封装在 GATT 里面的代理协议(Proxy Protocol),用特别定义的 GATT characteristics,产生代理功能(Proxy Feature)来实现非 Mesh 设备和 Mesh 设备的通信。代理节点(Proxy Node)因为可以同时支持两种 Bearer Layer,所以可以作为 Mesh 节点和非 Mesh 节点的中间桥梁。
#### 网络层(Network Layer)
网络层对下面部分作了定义:
1. 定义了多种网络地址类型;
2. 定义了网络层的帧格;
3. 打通传输层(Transport layer)和承载层(Bearer layer);
4. 定义了一些输入输出过滤器,决定哪些消息需要转发,处理还是拒绝;
5. 定义了网络消息的加密和认证。
#### 底层传输层(Lower Transport Layer)
底层传输层负责把太长的传输层的包拆成若干个分给网络层,把短的网络层的包再组成一个长的传输层的 PDU。
#### 上层传输层(Upper Transport Layer)
上层传输层主要负责加密,解密和应用数据授权。定义一些需要在这一层的节点间会话,比如 Friend 功能,心跳包(Heartbeats)。
#### 访问层(Access Layer)
访问层定义了应用层的数据,怎样控制和使用加密和解密。验证消息的上下文、密码,决定是否应该再交给更上层。
#### 基础 Model 层(Foundation Models Layer)
基础 model 层负责基础模型的实现与 Mesh 网络的配置和管理。
#### Model 层(Models Layer)
Model 层作为最外面的一层,包括上文讲过的行为、消息、状态等等,都定义在这一层。
### 基本构成
蓝牙 Mesh 推出了很多新的概念和名字,这些新的名字和代号组成了整个蓝牙 Mesh 网络的框架。图5展示了一个典型的蓝牙 Mesh 拓扑结构,其中所有的圆圈在蓝牙 Mesh 中被称为节点(Node),只有加入到蓝牙 Mesh 网络中的设备才可以叫做节点。
图5 一个典型的蓝牙 Mesh 的拓扑结构
1. 中继节点(Relay Node)
从典型的拓扑结构中可以看出节点到节点之间的消息(message)传递是网状的。要实现网状的拓扑,就需要引入中继节点(Relay Node)。中继节点可以帮忙转发其他节点发来的消息,也正是因为有了中继节点,蓝牙 Mesh 网络就可以实现多跳(Multi-Hops)。
2. 低能耗节点(Low Power node)
在物联网的应用里,有相当多的设备是对供电敏感的,比如大量电池供电的传感器,开关等等。在蓝牙 Mesh 的规范里,针对这些对电源有要求的节点,定义了一种低能耗节点。这种低能耗节点不需要一直保持工作状态,使用休眠唤醒机制来保证较长的电池使用寿命。
3. 朋友节点(Friend node)
与上述低能耗节点配合使用,在相配对的低功耗节点休眠的时候,负责收取和暂存别的节点发过来的数据,等待醒来的低能耗节点取走。朋友节点的存在使得蓝牙 Mesh 网络可以支持电池供电的设备成为可能。
### 组网过程
如果你之前接触过蓝牙技术,一定知道在传统蓝牙的点对点组网方式下,会有一个承担组网任务的设备,一般是手机。这个设备可以不断的监听发现周围的设备,比如耳机或手环,然后决定要不要启动连接的命令。
在蓝牙 Mesh 的规范里,组网的过程使用了一个和 WiFi
入网一样的单词:配网(Provision)。在配网过程中,会包含配网者(Provisioner)和未配网设备(unprovisioned devices)。设备在没有被配网之前,叫做未配网设备,配网成功以后的设备称做节点。
#### 配网者(Provisioner)
在 Mesh 的规范中,并没有指定到底什么设备可以做配网者,应用场景中的设备都可以指定为配网者。一般认为,手机、平板、机顶盒等一些运算存储能力比较强,有良好的人机界面的设备比较适合做配网者。
#### 配网过程
配网的全过程大概包括5个步骤,分别如下。
广播信标帧(Beaconing)→邀请(Invitation)→交换公钥(Exchanging Public Keys)→认证(Authentication)→分发配网信息(Distribution of the Provisioning Data)。
在配网初始过程,未配网设备会发出信标帧。在 Mesh 里使用的是新定义的 AD 广播包类型,称为 Mesh AD。配网者接收到 Beacon,使用配网邀请 PDU(Protocol Data Unit)发出配网邀请。要入网的设备收到配网邀请以后,会把自己的配网能力(Provisioning capabilities)发给配网者。配网者根据收到的信息内容,来进行公钥的交换。接下来两者就会进行互动随机数的认证流程,这个过程可能是灯闪几下,或者喇叭叫几声。最后一步,认证完成,从公钥和设备的私钥派生出会话密钥(Session Key)。在之后的配网信息交互过程会用这个会话密钥来加密。配网成功以后,就会根据交换的 NetKey 来加密后面的数据交换。跟加密相关的一些参数例如 IV index 和分配给节点的地址,会存在配网者那里。
### 信息传递机理
#### 地址
如上文所述,当配网者把多个节点加入到网络中的时候,都会给它们包含的元素(在节点中可以寻址访问的实体,例如吊灯里的某个灯泡)分别分配一个唯一的地址。在蓝牙 Mesh 网络中的地址分为三种:单播地址,组播地址和虚拟地址。虚拟地址是新概念,它可以看做是组播地址的扩展。虚拟地址可以使用128位的标签 Label UUID 在逻辑上来表示,在传输过程中又用哈希值表示这些 UUID 来减少字节数。在 Mesh 中,总共有16384个哈希值,代表最多有70万亿的虚拟地址可以使用。按照蓝牙SIG的定义,虚拟地址不用集中管理,增加了随意性,更像一个标签,比如厨房,餐厅。
#### 发布和订阅(Publish/Subscribe)
在蓝牙 Mesh 里面发消息的动作叫做发布(Publish)。网络中哪些元素对消息感兴趣就可以订阅(Subscribe)这些内容,好比订阅 CSDN 专栏,所有发布到这个专栏的文章你都会收到。在蓝牙 Mesh 中节点发布消息到单播地址,组播地址或者虚拟地址,订阅这个地址的节点或元素可以接收这些数据。
图6是蓝牙 SIG 在介绍订阅和发布时候的图例。本文中给这些灯和开关加了序号以便于理解。在图中,开关1发布信息给组播地址“厨房”,节点灯1、灯2、灯3都注册到了“厨房”这个地址上,因此他们能收到处理发给厨房的消息。换句话说,灯1,灯2和灯3都能被开关1控制开关。开关2发布消息到“餐厅”,只有灯3订阅了“餐厅”这个地址,所以只有灯3能被开关2控制。在这个例子里同样说明了每个节点可以订阅多个确切的地址。同样的,开关5和开关6同样都可以发布消息到“花园”。
图6 蓝牙 Mesh 使用的消息订阅和发布
使用这种方式的一个很大的好处是当需要有一些节点添加,删除或者替换的时候,其他的节点不用重新配置。比如新买了一个开关,把它配网以后发布到“花园”,那么“花园”里的灯一样可以被这个新的开关和开关6控制。如果你之前接触过其他的一些技术,例如 MQTT,一定对这种发布/订阅的方式不陌生。
### 信息传递中会遇到的问题和解决方法
在绝大部分的无线 Mesh 网络中,都会使用一定的路由算法来实现消息的中继和节点间通讯的高效率。一般来说在带有路由算法的网络中,都要存储类似于路由表的数据结构,来保证消息的上传下达。带有路由的网络一般比较复杂,也需要定期去维护节点间的路由以保证即使网络变化消息也能准确的传递。从上文可知,因为蓝牙 Mesh 网络不存在路由,它使用的是可管理的泛洪(Managed Flooding)。
图7表示的是运行路由算法的 A-F 六个节点经过路由算法确定以后的路由路径。在这种路由的 Mesh 网络中,如果从 A 发消息至 F,参与的节点可能是 A-C-E-F,其他的节点不会转发或者承担中继的任务。整个过程经过三次转发完成,传输效率较高。但是当 C 或 E 节点出现变化的时候,那么 A->F 的路由路径需要重新选择,会出现大量网络封包和延时。
图7 带有路由算法的消息传输路径
图8表示的是利用泛洪进行消息的传递。这种方式不需要事先确定路由,当 A 发消息给 F,所有有机会收到该条消息的中继节点都会进行转发,所以短时间在网络中会出现大量的重复的报文,造成信道拥堵和节点功耗的增加。好处当然也显而易见:网络简单,易维护。中间节点的移动和变化不会对消息传输带来大的影响。
图8 使用泛洪算法的消息传输路径
蓝牙 Mesh 网络使用的是一种优化可管理的泛洪,为了达到网络的稳定和信息的有效送达,引入了包括心跳包(Heartbeats)、最大跳数(TTL)、消息暂存(Message Cache)、朋友节点(Friendship)和子网(Subnets)等等方法。
心跳包:节点会定期的发送心跳包。周围的节点可以根据心跳包得知自己和别的节点大概的远近,需要达到的跳数。
1. TTL(Time to Live):规定了每个消息最多可以经过几次中继。大量的广播中继报文会拥塞整个网络,这个也是泛洪网络最被人诟病的地方。通过心跳包和 TTL 的共同合作,可以最大程度上减少不必要的中继报文造成的网络信道的拥堵。
2. 消息暂存(Message Cache):消息暂存是指当收到一个消息时,节点有能力和暂存的最近收到的消息做比较,来判断是否为新消息,是否需要进行处理。这一方法也同样能够减少网络中无谓的广播封包。
3. 朋友节点(Friendship):典型的一个泛洪的网络不支持休眠的低能耗节点。而蓝牙 Mesh 引入的朋友节点和低能耗节点使得对供电敏感的设备也一样可以适用于这一网络。
4. 子网(Subnets):子网的概念可以把蓝牙 Mesh 网络分成若干个子网。子网最初是为了安全考虑,但同样也能够减少子网间的中继报文。
### 结语
蓝牙 Mesh 是蓝牙技术在物联网领域的一次大胆和坚定的尝试。它打破了长期以来业界和消费者对于蓝牙的固有印象,把蓝牙的应用范围推向更广的领域,引起了开发者和应用者广泛的兴趣。对于蓝牙 Mesh 技术的进一步应用和发展,我们拭目以待!