蓝牙 Mesh 组网能力

更新时间:2024-02-02 09:37:23下载pdf

本文主要介绍蓝牙 Mesh 的主要组网机制与基本概念。

基本概念

Mesh 通信信道

蓝牙 Mesh 是基于蓝牙 LE 4.x 协议实现的组网协议,并在蓝牙的 37/38/39 广播信道上进行通信。

同时,受限于蓝牙广播的数据长度,Mesh 最底层的数据包长度也很短。但是 Mesh transport 层支持对上层的长数据进行分包,但是分包会增加发包的耗时。

Mesh 数据包

常用的 Mesh 数据包类型为 Access message 与 Control message,目前业务用到的大部分都是 Access message。

Access message 在 Low transport 层分为 Unsegmented Access message 与 Segmented Access message。

  • Unsegmented Access message 即不分包 access 数据,最大长度为 15,减去 MIC(4),最大可以 11 字节。11 字节里包括 opcode,即在用 vendor model 发送数据时,opcode 长度为 3,即 data 最大为 8。

  • Segmented Access message 即分包 access 数据,单包最大长度为 12,即总长度为 12 × n,n 为分包数。12 × n 中包括 MIC 4 字节,即用户数据为 12 × n - 4,再减掉 opcode 长度才为实际的用户数据长度,即:12 × n - 4 - opcode_len。如果对于使用 vendor model,则分包数为 n = (data_len + 7) ÷ 12,对 n 取整。

在使用数据包很短的控制命令时,命令的成功率与到达的一致性都很优秀,例如:开关命令、照明的调光命名、传感器的数据上报等。所以采用数据命令长度较长的控制方式时,建议不要选择 Mesh 方案,否则不仅无法发挥其优势而且有可能会出现数据延迟与丢包等问题。

洪泛式网络

蓝牙 Mesh 属于一种低速率的洪泛式组网技术,网络内的节点如果具备转发能力,在收到同一个网络的消息后,如果消息为可转发的消息,则会将消息继续广播出去,以此达到一条 Mesh 数据能在整个 Mesh 网络内快速传递。

洪泛式的组网有优势也有劣势。

  • 优势:节点能够快速响应、到达成功率高、网络健壮性好等。
  • 劣势:容易产生网络风暴,多条消息并发时网络内碰撞大,消息的到达率与响应速度就会下降。

TTL

存活时间(time to live,TTL)指的是一条广播包可被转发次数,在每条的 Mesh 广播包中都会存在,占用 7 bit。对于 TTL 的值有以下解释:

0:has not been relayed and will not be relayed
1:may have been relayed, but will not be relayed
2126:may have been relayed and can be relayed
127: has not been relayed and can be relayed

节点间通信为广播通信没有特定的路径,relay 节点收到的广播包只要 TTL 值不为 0,这条广播包就可以被继续转发,同时将广播包中的 TTL 减一。

SEQ

SEQ 全称 sequence num,每包的序列号。Mesh 的每一包里都有一个长度为 3 个字节的序列号。对于同一个设备在发送 Mesh 数据时,该序列号必须是累加的。

同时,每个 Mesh 设备内部都有一张 SEQ 缓存表,用来缓存接收到的 Mesh 数据包的源地址(src_addr)和其最新的 SEQ,这张表只存放在 RAM(掉电丢失)中。每收到一个 Mesh 数据包时都要去表里查询,收到的 SEQ 是否大于缓存表同一个源地址的 SEQ。如果小于等于,则认为此数据包为重传包或者不合法数据包,同时丢弃此数据包。

Mesh 角色

  • Mesh provisioner:配网者节点,例如涂鸦智能手机 App、蓝牙网关。
  • Relay node:转发节点,Mesh 网络中的长供电节点,可以转发网络内的消息。
  • Proxy node:代理节点,可以被手机 GATT 连接的节点,手机通过连接代理节点来发送或者接收 Mesh 网络的数据来控制整个网络的节点。
  • LPN node:低功耗节点,会定期的休眠与唤醒,来降低自身的功耗。
  • Friend node:配合 LPN node 工作的朋友节点。当 LPN 节点休眠时,替其缓存数据,LPN 节点唤醒时再将数据发给它。

目前,涂鸦的设备默认都具备 Relay、Proxy 能力,而 LPN 与 Friend 特性未使用。

Mesh 密钥

Mesh profile 规范定义了三种类型密钥:

  • 网络密钥 NetKey:用于网络层的通信加密,只有 NetKey 保持一致,设备所发出的数据才可以被同一个 Mesh 网络内的节点进行传输。

  • 应用程序密钥 AppKey:用于上层传输层的通信加密,只有 AppKey 保持一致,节点间通信发送的数据才可以被解密成应用数据。网络密钥和应用程序密钥这两种类型的密钥在 Mesh 节点之间是统一的,只有两个密钥保持一致才能进行通信。

  • 设备秘钥 DevKey:是每个节点唯一的特殊应用程序密钥,即一机一密。只有节点和配网者知道,用于配网者来配置节点通信加密。

Mesh 网络发送参数

前文提到 Mesh 通信使用的洪泛发包,没有路由,发包后也没有收包的 ACK。只有向单播地址发送 Seg 分包数据时才会有 ACK。

所以没有 ACK 就需要靠增加发包数量来提高成功率,也就是应用层发送一条数据时,在 Network 层中会将同样的数据以固定间隔发送多次。同样设备在 Relay 其他设备的包时也会以固定间隔发送多次。这两个间隔与次数即为 Network 层的网络参数,见下表:

参数 释义 计算值 SDK 默认值
Network Transmit Cnt 网络层主动发送次数 实际发送次数 = cnt + 1 7
Network Transmit Step 网络层主动发送间隔 实际发送间隔 = (step + 1) × 10ms 0
Relay Retransmit Cnt 网络层转发发送次数 实际发送次数 = cnt + 1 4
Relay Retransmit Step 网络层转发发送间隔 实际发送间隔 = (step + 1) × 10ms 0

API 说明

设备角色配置

/**@brief mesh node feature. */
typedef enum {
    MESH_FEATURE_RELAY = 0x00,  /**< Relay. */
    MESH_FEATURE_PROXY,         /**< Proxy. */
    MESH_FEATURE_FRIEND,        /**< Friend. */
    MESH_FEATURE_LPN,           /**< LPN. */
} MESH_FEATURE_T;
OPERATE_RET tkl_mesh_node_features_set(MESH_FEATURE_T featrue, UCHAR_T enable);

您可以调用以上接口来配置 Mesh 设备角色,可以选择关闭 Relay 和 Proxy 能力。另外某些平台 SDK 也可以开启 Friend 能力,根据接口返回结果。目前的通用 SDK 不支持 LPN 节点能力。

关闭部分设备的 Relay 能力后,网络内网络风暴出现的概率会降低,提高网络的稳定性与数据传输的速率。您可以使用此接口来探索和调试网络下不同 Relay 配置的效果。

TTL 配置

OPERATE_RET tkl_mesh_node_default_ttl_set(UCHAR_T ttl);

SDK 中设备默认发送的 TTL 为 8,您可以在 OPERATE_RET tuya_init_last(VOID_T) 初始化函数内调用此接口来修改设备发送的默认 TTL。

App 与网关默认 TTL 也为 8,如果要修改的话需要在 App SDK 或者网关 SDK 内修改。

Mesh 网络参数配置

VOID tkl_mesh_network_transmit_set(UCHAR_T cnt, UCHAR_T step);
VOID tkl_mesh_network_relay_retransmit_set(UCHAR_T cnt, UCHAR_T step);

通过以上接口,配置设备的网络层发送参数与 Relay 节点的转发参数。

使用说明

Mesh 网络参数配置

VOID tal_mesh_state_callback(TAL_MESH_NET_STATE_T state){
    tal_main_debug("mesh_state:%d", state);
    switch(state){
        case TAL_MESH_PROVISION_SUCCESS:
            tkl_mesh_network_transmit_set(7, 0);
            tkl_mesh_network_relay_retransmit_set(4, 0);
        break;
        default:
        break;
    }
}

可以在 Mesh 状态回调内收到配网成功的状态时,更新此参数。不过修改此参数需要对 Mesh 协议有较深的理解,如果不是很熟悉,则使用此默认的参数。