BLE Mesh 应用框架

[English]


被 Provisioner 配网到 ESP-BLE-MESH 网络中的第一个节点的单播地址是不是固定的?

  esp_ble_mesh_prov_tprov_start_address 的值用于设置 Provisioner 配网未配网设备的起始地址,即其首先配网的节点的单播地址。单播地址只能在初始化期间设置一次,此后不能修改。


手机 App 首先配置的节点的单播地址是不是固定的?

  该 App 将确定单播地址,目前大多数单播地址是固定的。


配网过程中,认证设备共有多少种方法?提供的示例 中使用了什么方法?

  共有四种设备认证方法,即 No OOB、Static OOB、Output OOB 和 Input OOB。提供的示例里使用的是 No OOB。


配置入网前,未配网设备的广播包可以携带哪些信息?

  • Device UUID

  • OOB Info

  • URL Hash(可选)


ESP-BLE-MESH 如何打印数据包?

  示例使用函数 ESP_LOG_BUFFER_HEX() 打印信息语境,而 ESP-BLE-MESH 协议栈则使用 bt_hex() 打印。


Device UUID 可以用于设备识别吗?

  可以。每个设备都有独一无二的 Device UUID,用户可以通过 Device UUID 识别设备。


如何知道当前 Provisioner 正在配网哪个未配网设备?

  - esp_ble_mesh_prov_tprov_attention 的值由 Provisioner 在配网过程中设置给未配网设备。
  • 该值只能在初始化期间设置一次,此后不能修改。未配网设备加入 mesh 网络后可以用特定的方式来显示自己正在配网,比如灯光闪烁,以告知 Provisioner 其正在配网。


Provisioner 如何通过获取的 Composition Data 进一步配置节点?

  Provisioner 通过调用 Configuration Client Model API esp_ble_mesh_config_client_set_state() 来进行如下配置。

  • 正确设置参数 esp_ble_mesh_cfg_client_set_state_t 中的 app_key_add,将应用密钥添加到节点中。

  • 正确设置参数 esp_ble_mesh_cfg_client_set_state_t 中的 model_sub_add,将订阅地址添加到节点的模型中。

  • 正确设置参数 esp_ble_mesh_cfg_client_set_state_t 中的 model_pub_set,将发布地址添加到节点的模型中。


节点可以自己添加相应的配置吗?

  本法可用于特殊情况,如测试阶段。

  • 此示例展示了节点如何为自己的模型添加新的组地址。

esp_err_t example_add_fast_prov_group_address(uint16_t model_id, uint16_t group_addr)
{
    const esp_ble_mesh_comp_t *comp = NULL;
    esp_ble_mesh_elem_t *element = NULL;
    esp_ble_mesh_model_t *model = NULL;
    int i, j;

    if (!ESP_BLE_MESH_ADDR_IS_GROUP(group_addr)) {
        return ESP_ERR_INVALID_ARG;
    }

    comp = esp_ble_mesh_get_composition_data();
    if (!comp) {
        return ESP_FAIL;
    }

    for (i = 0; i < comp->element_count; i++) {
        element = &comp->elements[i];
        model = esp_ble_mesh_find_sig_model(element, model_id);
        if (!model) {
            continue;
        }
        for (j = 0; j < ARRAY_SIZE(model->groups); j++) {
            if (model->groups[j] == group_addr) {
                break;
            }
        }
        if (j != ARRAY_SIZE(model->groups)) {
            ESP_LOGW(TAG, "%s: Group address already exists, element index: %d", __func__, i);
            continue;
        }
        for (j = 0; j < ARRAY_SIZE(model->groups); j++) {
            if (model->groups[j] == ESP_BLE_MESH_ADDR_UNASSIGNED) {
                model->groups[j] = group_addr;
                break;
            }
        }
        if (j == ARRAY_SIZE(model->groups)) {
            ESP_LOGE(TAG, "%s: Model is full of group addresses, element index: %d", __func__, i);
        }
    }

    return ESP_OK;
}

注意:使能了节点的 NVS 存储器后,通过该方式添加的组地址以及绑定的应用密钥在设备掉电的情况下不能保存。这些配置信息只有通过 Configuration Client Model 配置时才会保存。


Provisioner 如何通过分组的方式控制节点?

  通常而言,在 ESP-BLE-MESH 网络中实现组控制有两种方法,即组地址方法和虚拟地址方法。假设有 10 个设备,即 5 个带蓝灯的设备和 5 个带红灯的设备。

  • 方案一:5 个蓝灯设备订阅一个组地址,5 个红灯设备订阅另一个组地址。Provisioner 往不同的组地址发送消息,即可实现分组控制设备。

  • 方案二:5 个蓝灯设备订阅一个虚拟地址,5 个红灯设备订阅另一个虚拟地址,Provisioner 往不同的虚拟地址发送消息,即可实现分组控制设备。


Provisioner 如何知道网络中的某个设备是否离线?

  • 节点离线通常定义为:电源故障或其他原因导致的节点无法与 mesh 网络中的其他节点正常通信的情况。

  • ESP-BLE-MESH 网络中的节点间彼此不连接,它们通过广播通道进行通信。

  • 此示例展示了如何通过 Provisioner 检测节点是否离线。

  • 节点定期给 Provisioner 发送心跳包。如果 Provisioner 超过一定的时间未接收到心跳包,则视该节点离线。

  注: 心跳包的设计应该采用单包(字节数小于 11 个字节)的方式,这样收发效率会更高。


Provisioner 如何将节点添加至多个子网?

  节点配置期间,Provisioner 可以为节点添加多个网络密钥,拥有相同网络密钥的节点属于同一子网。Provisioner 可以通过不同的网络密钥与不同子网内的节点进行通信。


为什么 APP 中显示的节点地址的数量比现有的节点地址更多?

  每完成一次快速配网后、开始新一次快速配网前,APP 会存有上次配网的数据,因此 APP 中显示的节点地址的数量比现有的节点地址更多。


在 EspBleMesh App 中输入的 count 值有什么用途?

  count 值为 App 提供配置的代理节点,以决定何时提前开始 Proxy 广播信息。


运行以下示例 fast_prov_server 的节点的 Configuration Client Model 何时开始工作?

  使能了 Temporary Provisioner 功能后,Configuration Client Model 会开始工作。


Temporary Provisioner 功能会一直处于使能的状态吗?

  节点收到打开/关闭电灯的消息后,所有节点会禁用其 Temporary Provisioner 功能并且转化为一般节点。


BLE MESH 打印日志 ran out of retransmit attempts 代表什么?

  节点发送分段消息时,由于某些原因,接收端未收到完整的消息。此时,节点会重传消息。当重传次数达到最大重传数时,会出现该警告。当前最大重传数为 4。


BLE Mesh 打印日志 Duplicate found in Network Message Cache 代表什么?

  当节点收到一条消息时,它会把该消息与网络缓存中存储的消息进行比较。如果在缓存中找到相同的消息,会出现该警告,这意味着之前已接受过该消息,则该消息会被丢弃。


BLE Mesh 打印日志 Incomplete timer expired 代表什么?

  表示 Mesh 网络中的节点接收到了一个不完整的消息,并且在规定时间内没有接收到该消息的剩余部分。这通常是因为消息被分成了多个段 (segment),在传输过程中丢失了其中的一部分,导致节点无法完整地接收该消息。


BLE Mesh 打印日志 No free slots for new incoming segmented messages 代表什么?

  当节点没有空间来接收新的分段消息时,会出现该警告。用户可以通过配置 CONFIG_BLE_MESH_RX_SEG_MSG_COUNT 扩大空间。


BLE Mesh 打印日志 No matching TX context for ack 代表什么?

  发送节点在收到一个分段 ACK 消息且没有匹配到对应的发送上下文(TX context)时,会出现该警告。这可能是因为网络中存在多个 ACK 消息。


BLE Mesh 打印日志 Model not bound to AppKey 0x0000 代表什么?

当节点发送带有模型的消息且该模型尚未绑定到索引为 0x000 的应用密钥时,会出现该警告。


BLE Mesh 打印日志 Busy sending message to DST xxxx 代表什么?

表示节点的客户端模型已将消息发送给目标节点,并且正在等待响应,用户无法将消息发送到单播地址相同的同一节点。接收到相应的响应或计时器到时后,可以发送另一条消息。


为什么会出现 EspBleMesh App 在快速配网期间长时间等待的情况?

  快速配网期间,代理节点在配置完一个节点后会断开与 APP 的连接,待所有节点配网完成后再与 APP 重新建立连接,快速配网期间长时间等待可能是由于:

  • 网络拓扑结构复杂:如果网络中节点数量较多,且拓扑结构比较复杂,Provisioner 可能需要更长的时间来扫描网络和与节点进行通信。

  • 网络信号不稳定:如果网络信号不稳定,通信可能会受到干扰或丢失,从而导致 APP 等待时间变长。

  • 节点响应时间较长:如果节点响应时间较长,可能会导致 Provisioner 等待超时并重新发送消息,从而导致 APP 等待时间变长。

  • App 与 Provisioner 通信故障:如果 APP 与 Provisioner 之间通信故障,可能会导致 App 等待时间变长。


Provisoner 如何控制节点的服务器模型?

  ESP-BLE-MESH 支持所有 SIG 定义的客户端模型。Provisioner 可以使用这些客户端模型控制节点的服务器模型。客户端模型分为 6 类,每类有相应的功能。


设备通信必须要网关吗?

  • 情况 1:节点仅在 mesh 网络内通信。这种情况下,不需要网关。ESP-BLE-MESH 网络是一个泛洪的网络,网络中的消息没有固定的路径,节点与节点之间可以随意通信。

  • 情况 2:如果用户想要远程控制网络,比如在到家之前打开某些节点,则需要网关。


Provisioner 删除网络中的节点时,需要进行哪些操作?

  通常而言,Provisioner 从网络中移除节点主要涉及三个步骤:

  • 首先,Provisioner 将需要移除的节点添加至“黑名单”。

  • 其次,Provisioner 启动 密钥更新程序

  • 最后,节点执行节点重置程序,切换自身身份为未配网设备。


在密钥更新的过程中,Provisioner 如何更新节点的网络密钥?


Provisioner 如何管理 mesh 网络中的节点?

  - ESP-BLE-MESH 在示例中实现了一些基本的节点管理功能,比如 esp_ble_mesh_store_node_info()

Provisioner 想要控制节点的服务器模型时需要什么?

  • Provisioner 在控制节点的服务器模型前,必须包括相应的客户端模型。

  • Provisioner 应当添加本地的网络密钥和应用密钥。

    • Provisioner 调用 API esp_ble_mesh_provisioner_add_local_net_key() 以添加网络密钥。

    • Provisioner 调用 API esp_ble_mesh_provisioner_add_local_app_key() 以添加应用密钥。

  - Provisioner 应当配置自己的客户端模型。


什么时候应该使能节点的 Relay 功能?

  • 如果 mesh 网络中检测到的节点很稀疏,用户可以使能节点的 Relay 功能。

  • 如果 mesh 网络中检测到的节点很密集,用户可以选择仅使能一些节点的 Relay 功能。

  • 如果 mesh 网络大小未知,用户可以默认使能 Relay 功能。


节点包含什么样的模型?

  • ESP-BLE-MESH 中,节点由一系列的模型组成,每个模型实现节点的某些功能。

  • 模型分为两种,客户端模型和服务器模型。客户端模型可以获取并设置服务器模型的状态。

  • 模型也可以分为 SIG 模型和自定义模型。 SIG 模型的所有行为都由官方定义,而自定义模型的行为均由用户定义。


每个模型对应的消息格式是不是固定的?

  • 消息由 opcode 和 payload 组成,通过 opcode 进行区分。

  • 与模型对应的消息的类型和格式都是固定的,这意味着模型之间传输的消息是固定的。


节点的模型可以使用哪些函数发送消息?


如何实现消息传输不丢包?

  如果用户要实现消息传输不丢包,则需有应答的消息。等待应答的默认时间在 CONFIG_BLE_MESH_CLIENT_MSG_TIMEOUT 中设置。如果发送端等待应答超时,就会触发对应的超时事件。

  注: API esp_ble_mesh_client_model_send_msg() 中可以设置应答的超时时间。如果参数 msg_timeout 设为 0, 那么超时时间便会采用默认值(4 秒)。


如何发送无应答的消息?

  • 对于客户端模型,用户可以调用 API esp_ble_mesh_client_model_send_msg() with the parameter need_rsp set to false 发送无应答消息。

  • 对于服务器模型,调用 API esp_ble_mesh_server_model_send_msg() 发送的消息总是无应答的消息。


发送不分包消息时,最多可携带多少有效字节?

  不分包消息的总有效载荷长度(可由用户设置)为 11 个八位位组,因此,如果消息的 opcode 为 2 个八位位组,则该消息可以携带 9 个八位位组的有效信息。 对于 vendor 消息,由于 opcode 是 3 个八位位组,剩余的有效负载长度为 8 个八位位组。


什么时候应该使能节点的 Proxy 功能?

  如果未配网设备将由电话配网,则未配网设备应该使能 Proxy 功能,因为当前几乎所有电话都不支持通过广播承载层发送 ESP-BLE-MESH 数据包。并且,未配网设备成功配网成为 Proxy 节点后,其会通过 GATT 承载层和广播承载层与 mesh 网络中的其他节点通信。


如何使用代理过滤器?

  代理过滤器用于减少 Proxy Client(如手机)和 Proxy Server(如节点)之间交换的 Network PDU 的数量。另外,通过代理过滤器,Proxy Client 可以明确请求仅接收来自 Proxy Server 的某些目标地址的 mesh 消息。


如何实现将节点自检的信息发送出来?

  推荐节点通过 Health Server Model 定期发布其自检结果。


Relay 节点什么时候可以中继消息?

  如果要中继消息,消息需满足以下要求。

  • 消息存在于 mesh 网络中。

  • 消息的目的地址不是节点的单播地址。

  • 消息的 TTL 值需大于 1。


如果一条消息分成几段,那么其他 Relay 节点是接收到一段消息就中继还是等接收到完整的数据包才中继?

  Relay 节点收到其中一段消息时就中继,而非一直等到接收所有的消息。


设备断电后上电,如何能继续在网络中进行通讯?

  在 menuconfig 中启用配置 Store BLE Mesh Node configuration persistently


使用 Low Power 功能降低功耗的原理是什么?

  • 开启无线电进行收听时,设备消耗能量。使能节点的低功耗功能后,它将在大多数时间内关闭无线电功能。

  • 低功耗节点和好友节点需要合作,因此低功耗节点可以以适当或较低的频率接收消息,而无需一直收听。

  • 当低功耗节点有一些新消息时,好友节点将为其存储消息。低功耗节点可以间隔固定时间轮询好友节点,以查看是否有新的消息。


节点间如何传输消息?

节点间传输信息的可能应用场景是,一旦烟雾警报检测到高浓度的烟雾,就会触发喷淋设备。有两种实现方法。

  • 方法 1:喷淋设备订阅组地址。当烟雾警报器检测到高浓度的烟雾时,它会发布一条消息,该消息的目标地址是喷淋设备已订阅的组地址。

  • 方法 2:Provisioner 可以配置喷淋设备的单播地址为烟雾报警器的地址。当检测到高浓度的烟雾时,烟雾警报器以喷淋设备的单播地址为目标地址,将消息发送到喷淋设备。


何时使用 IV Update 更新程序?

IV(Initialization Vector)是 BLE Mesh 网络中的一个重要参数,它用于在节点之间传递和解密消息,同时还用于识别网络中的重放攻击。当 IV 更新时,网络密钥的计算也会被更新,从而增强了网络的安全性。因此,当 IV 达到阈值时,需要更新 IV。 在 BLE Mesh 网络中,IV 阈值是一个在 0 到 0xFFFF 之间的数字,它在网络初始化时被分配,通常为 0。当网络中传输的消息数量超过 IV 阈值时,就需要进行 IV 更新,IV Update 更新程序便会启用。此时,Provisioner 会向网络中的所有节点广播 IV 更新消息,然后节点会更新其 IV 和网络密钥。


为什么需要快速配网?

  通常而言,存在少量未配网设备时,用户可以逐个配置。但是如果有大量未配网设备(比如 100 个)时,逐个配置会耗费大量时间。通过快速配网,用户可以在约 50 秒内配网 100 个未配网设备。


如何启用 IV Update 更新程序?

节点可以使用带有 Secure Network Beacon 的 IV Update 更新程序。


ESP-BLE-MESH 回调函数如何分类?


未配网设备加入 ESP-BLE-MESH 网络的流程是什么?

  设备通过 Provisioner 加入 ESP-BLE-MESH 网络分为两个阶段,配网阶段和配置阶段。

  • 配网阶段:为设备分配单播地址、添加网络密钥 (NetKey) 等。通过配网,设备加入 ESP-BLE-MESH 网络,身份从未配网设备变为节点。

  • 配置阶段:为节点添加应用密钥 (AppKey), 并将应用密钥绑定到相应模型。配置期间,有些选项是可选的,比如为节点添加订阅地址、设置发布地址等。通过配置,该节点实际上可以向 Provisioner 发送消息,也可以接收来自 Provisioner 的消息。


Provisioner 的地址是否可以作为节点上报状态消息的目的地址?

  Provisioner 的单播地址只能在初始化期间设置一次,此后不能更改。理论而言,只要节点知道 Provisioner 的单播地址,此地址便可用作节点上报状态消息的目的地址。节点在网络配置的过程中可以知道 Provisioner 的单播地址,因为 Provisioner 往节点发送消息时,消息的源地址就是 Provisioner 的单播地址。

  订阅地址也可使用。Provisioner 订阅组地址或者虚拟地址,节点向该订阅地址发送消息。


如果 Provisioner 想要改变节点状态,其需满足什么条件?

  • 需要有和节点的服务器模型相对应的客户端模型。

  • 需要和节点有相同的、可用于加密消息的网络密钥和应用密钥。

  • 需要知道节点的地址,可以是单播地址,也可以是订阅地址。


如何使用网络密钥和应用密钥?

  • 网络密钥用于加密网络层的消息。具有相同网络密钥的节点视作在同一网络中,具有不同网络密钥的节点相互之间不能进行通信。

  • 应用密钥用于加密上层传输层中的消息。如果服务器模型和客户端模型绑定的应用密钥不同,则无法实现相互通信。


是否可以采用固定的网络密钥或应用密钥?

  • API esp_ble_mesh_provisioner_add_local_net_key() <https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp-ble-mesh.html?highlight=esp_ble_mesh_provisioner_delete_node_with_uuid#_CPPv442esp_ble_mesh_provisioner_add_local_net_keyAL16E_K7uint8_t8uint16_t> 可以用来添加包含固定值或随机值的网络密钥。

  • API esp_ble_mesh_provisioner_add_local_app_key() 可以用来添加包含固定值或随机值的应用密钥。


如何清除 ESP32 BLE 节点的组网信息?

清除节点的组网信息可以调用 esp_ble_mesh_node_local_reset()


如何删除某个节点的组网信息?


如果节点断电了,下次上电是否还要用手机 APP 重新组网?

可以前往 menuconfig,通过 Component config -> Bluetooth Mesh support -> Store Bluetooth Mesh key and configuration persistently 的选项保存配置信息,就不需要重新组网了。


1 号板子做 Provisioner,2、3、4 号板子做节点。组网成功后,如果 1 号板子掉电了,重新上电后还能否加入到这个 mesh 网络中?

1 号板子重新上电后,如果 net key 和 app key 没有变化,即可直接访问该网络。但是如果没有保存 mesh 网络中节点的地址,则地址将会丢失。


BLE_MESH 中,如果某个节点掉线了,要如何知道?

节点可以周期发布消息,你可以通过 Health model 周期发送 Heartbeat 消息,或者可以通过 vender model 周期发送自定义消息。


BLE_MESH 节点间如何实现以字符串的形式通信?

使用 vendor model,发送端将字符串放入 vendor message 发送,接收端接收消息后按 字符串 解析即可。


配置ble mesh保存节点信息时初始化partition失败: BLE_MESH: Failed to init mesh partition, name ble_mesh, err 261

如果选择 Use a specific NVS partition for BLE Meshh 选项,请确保 partition.csv 文件包含一个名为 ble_mesh 的特定分区。


请问如何在 provisioner 的 demo 中 添加 health_mode?

进入 menuconfig,在 Component config -> ESP BLE Mesh Support -> Support for BLE Mesh Client Models 中勾选上 Health Client Model


ble_mesh_fast_prov_client 当设备 provisioner 和手机当 provisioner 有什么不一样?

  • ble_mesh_fast_prov_server demo 在收到 ESP_BLE_MESH_MODEL_OP_APP_KEY_ADD opcode 时,一并把 model 配置好了,而手机 Provisioner 则需要发送 ESP_BLE_MESH_MODEL_OP_MODEL_APP_BIND opcode 绑定 model APPkey,再发送 ESP_BLE_MESH_MODEL_OP_MODEL_PUB_SET 配置 publication。

  • ble_mesh_fast_prov_client demoble_mesh_fast_prov_server demo 是我们提供的快速配网方案,实现了 100 个节点配置设备入网时间在 60 s 以内。为了实现这个功能,我们添加了一些自定义消息,用于设备间自定义信息的传递。


有什么工具和办法可以查看 ble_mesh 节点之间的加密消息吗?

  • 数据包解密必须配置 netkey、appkey、devkey、iv index,用户可以尝试查看配置接口。

  • 广播包需要 37、38、39 三通道同时抓,一般需要使用到专门的仪器。


app key 是否是厂家可以自己设置? Unicast address 和 app key 是否有某种关联?

app key 可以厂家自己设置,它和 Model 是绑定在一起的,和 Unicast address 没有关系。


如果一个节点突然掉线,那么通过 Health model 监测消息的机制,是整个 mesh 网络都要轮询的发送 Heartbeat 消息吗?

BLE MESH 网络没有建立任何连接,直接通过广播通道发送消息。用户可以向同一个节点发送心跳包进行检查。


主节点(代理节点)与从节点互相发送消息,可以用 client-server 模型吗?是否有提供示例?

请参见 V6.0 版本中 ble_mesh_fast_provision/ble_mesh_fast_prov_server 中提供的示例。


在 NRF 的手机 app 里,右下角 “Setting” 里有个 “Network Key”,可以自由更改,这个修改的是指哪个 network key 呢?

  • 在 NRF 的手机 app 里,右下角 “Setting” 里有个 “Network Key”,修改它就意味着修改了 provisioner 的 Netkey,provisioner 配置其它设备入网时会把这个 netkey 分配给入网的节点。

  • 如果 provisioner 拥有多个 Netkey,provisioner 在配置设备时,可以选择使用哪个 NetKey 分配给设备。provisioner 可以使用不同的 Netkey 和网络中的节点进行通讯。每个节点的 Netkey 都是 provisioner 分配的。


设备如何加入 BLE-Mesh 网络?


Bluetooth® LE (BLE) Mesh 数据传送最大的包是多少 Bytes?

  • 应用层单包最大 384 字节,底层不分包最大 11 字节。


能否提供通过 ESP32 BLE-Mesh 组网的例程?配置组网的 APP 可以使用什么软件?


在 BLE-MESH 中,未配网设备默认的名称是 ESP-BLE-MESH,这个名称在哪里可以修改?


ESP32 的 BLE-MESH 应用可以连接多少个节点设备?

  • 理论上,ESP32 的 BLE-MESH 应用最大支持接入设备为 32767 个,实际应用中的接入设备数取决于内存占用情况。


ESP32 如何手动重置 BLE mesh 设备(不通过手机配网应用程序或配网设备)?

  • 可以调用 esp_ble_mesh_node_local_reset 接口,重置 BLE Mesh 节点,擦除所有的配网信息,还需要等到重置事件到达,确认重置成功,调用后,设备需要重新配网。


ESP32 长时间运行 BLE MESH 程序后,发现客户端向服务器发送消息时出现分段错误,BLE MESH 打印日志 NO multi-segment messsage contexts available。如何解决?

  • 用户可以前往 Component config -> ESP BLE Mesh Support -> Maximum number of simultaneous outgoing segmented messages,通过配置 BLE_MESH_TX_SEG_MSG_COUNT 来扩展空间。


使用 ESP32 BLE Mesh 应用,是否可以关闭网络密钥和 IV 更新?

  • 不可以。网络密钥和 IV 更新必须保持开启。