蓝牙mesh的协议栈
这里是关于第三篇蓝牙mesh相关的文章,该写什么?有三个东西可以写:1.蓝牙mesh中的节点 2.蓝牙mesh中的专业术语 3.蓝牙mesh协议栈。经过反复思考,基于对新了解蓝牙mesh网络朋友的角度出发,还是觉得应该写蓝牙mesh协议栈。因为上一篇讲的是蓝牙mesh的网络拓扑,主要是蓝牙mesh 相关的概念,在上一篇的基础上再讲这一篇,下一篇再讲蓝牙mesh中的专业术语,这个学习路径相对简单与轻松。
蓝牙mesh协议栈,准确来讲是由两个部分组成。配网协议和节点消息发送协议(七层网络系统架构)。
如果将蓝牙mesh协议栈,等同于7层网络协议,这是不准确的。为什么这么说?在前一篇中讲到,设备在未加入网络前叫未配网设备,加入网络后叫做节点。这个过程叫做配网流程。而实现这个配网流程的是配网协议,而不是7层网络架构。所以可以这么说,设备配网成功前使用的是配网协议,设备配网成功后,使用的是七层网络协议。我们在接触蓝牙mesh的第一个操作,那绝对是将设备配网,如果你不知道配网协议,那就悲剧了。
配网协议
首先,看一下配网协议,由3个层组成:1、承载层(Bearer) 2、传输层(Transport) 3、配网协议层(Provisioning Protocol)
配网协议的承载层跟7层网络架构的承载层差不多是一样的,都是使用BLE的广播或者GATT连接进行数据交互,但是在服务和特性,以及消息数据报上有细微的区别。
服务特性对比.png
ProxyPDU在代码中通常放在Network Layer里面合并处理,所以有的书籍或者文章中,将配网协议的前两层用七层架构的前两层进行描述。但Provisioning Protocol在蓝牙mesh中是唯一,在代码中要单独处理。配网协议和配网流程的每个步骤,后面的文章中再做详细的解读。
代理功能:为了兼容旧的不支持蓝牙mesh广播包传播的设备(比如手机),具备代理功能的设备可以与旧设备建立低功耗蓝牙GATT连接,在mesh广播数据包和mesh GATT连接数据包之间转换,支持代理功能的节点被称为代理节点(Proxy Node)。(如果暂时对手机不支持蓝牙mesh广播包传输这句话不理解的朋友,我会在后面的文章中给出解释)
在上一篇中,有提到过这个问题。为什么手机不支持蓝牙mesh广播包?如果熟悉BLE的朋友肯定知道,手机既可以做主机搜索附近的设备,也可以做从机,向四周发送广播信号。但是这里说的广播包是指蓝牙mesh协议中的配网广播包,手机在出厂的时候并不会把mesh协议自带到系统里面。我们在把手机当成从机,向外广播时,是我们自己定义的广播内容,手机只是有这个通道。这也是为什么手机APP没法通过广播的形式对设备进行配网的原因,通道里面传什么内容,需要我们自己定义。
手机APP实现配网流程一定是走代理协议建立GATT连接的方式。因为在前一篇中说过,整个蓝牙mesh 是基于广播和GATT连接这两个核心,它只有这两种方式。对应的是广播承载器和GATT承载器,在后面讲到承载层的时候,还会再详细的讲这个部分。
蓝牙mesh协议栈的本质
从蓝牙1.0到蓝牙5.0,每一个版本的出现,只要手机支持,对应的全部功能就可以使用。但是蓝牙mesh不是,蓝牙mesh 是蓝牙4.0后蓝牙Sig发布的一套协议规范,并不是硬件能力相关的东西。所以,蓝牙mesh协议栈的本质是在蓝牙BLE4.0或者BLE5.0版本基础上建立的一个应用程序,应用层是蓝牙mesh,底层是BLE4.0,或者BLE5.0。
节点消息发送协议(七层网络架构)
这里面的每一层,都足够写一篇文章,这里也不详细的讲解。
七层网络架构.png
模型层定义了用于标准化典型用户场景操作的模型,这些模型在蓝牙mesh模型规范或其他更高的层规范中定义。更高层次模型规范的例子包括照明和传感器模型。
通俗点讲,就是协议中的应用层,你可以根据自己的业务需求,按蓝牙模型规范,制定符合自己业务需求的模型。
基础模型层定义配置和管理mesh网络所需的访问层状态、消息和模型。
访问层定义了高层应用程序如何使用上层传输层。它定义应用程序数据的格式;它定义和控制在上层传输层执行的应用程序数据加密和解密;并且在将传入的应用程序数据转发到更高的层之前,它会检查是否在正确的网络和应用程序键的上下文中接收到了传入的应用程序数据。
上层传输层对应用程序数据进行加密、解密和身份验证,并提供访问消息的机密性。它还定义了如何使用传输控制消息来管理节点之间的上层传输层,包括由Friend特性使用时。
底层传输层定义了如何将上层传输层的消息分割并重新组装成多个底层传输层的pdu,以将较大的上层传输层消息传递给其他节点。它还定义了一个单独的控制消息来管理分割和重组。
网络层定义如何向一个或多个元素处理传输消息。它定义了允许传输pdu由承载层传输的网络消息格式。网络层决定是否中继/转发消息,接受它们作进一步处理,或拒绝它们。它还定义了网络消息如何加密和身份验证。
承载层定义网络消息如何在节点之间传输。定义了两种承担者,广告承担者和关贸总协定承担者。将来可能会定义更多的承担者。
蓝牙mesh网络中有一个比较让人头疼的问题:数据大小端编码问题,什么是大小端?
大端编码
当多字节值定义为以“大端”发送时,适用本节中的约定。例如,值0x123456应以0x12、0x34和0x56(最高有效字节优先)的形式传输。
小端编码
当多字节值定义为以“小端”发送时,适用本节中的约定。例如,值0x123456应该以0x56、0x34和0x12的形式传输(最低有效字节优先)。
一个字节的时候,大小端都是一样。
蓝牙mesh 中的大小端规范
对于网络层、下层传输层、上层传输层、mesh beacons和Provisioning,所有多字节的数值都应以大端方式发送。
对于访问层和基础模型,所有的多八位数值应以小端序
大小端只是针对协议中的某个字段内部,当一个数据由多个字段组成时,多个字段的位置不适用大小端的规则。