基于nordic平台mesh的入网配置流程

一 Provisioning

配置。

配置是向蓝牙mesh网络中的新设备提供它们加入网络所需的信息的过程。要成为节点并参与蓝牙mesh网络通信,必须配置每个设备。

从配置的角度来看,设备可以是以下类型之一:

  • 配置者(Provisioner ) : 充当配置角色。
  • 接受配置者(Provisionee):充当节点角色。

尽管可以使用多个配置者,但在mesh中仅需要一个配置者即可进行配置。

作为配置过程的一部分,配置者和被配置者在配置者的bearer 层上建立通信。该层支持在配置者和未配置的设备之间传输配置PDU。

nRF5 SDK提供了以下两个bearer配置:

  • PB-ADV
  • PB-GATT

要对位于预配置程序的无线电范围之外的设备执行预配置,可以使用远程预配置(PB-remote)功能。

与配置过程相关的API独立于基础bearer。 请参阅 Implementing provisioning ,以获取有关如何在用户应用程序中使用配置API的信息。

nRF5 SDK示例默认情况下使用两个bearer配置之一。更多相关信息查看Examples main page.

1 Information sent during provisioning

配置期间发送的信息。

在配置过程中,新的未配置设备将接收以下元素:

  • a unicast address of the primary element(主元素的单波地址)
  • a network key and the associated key index(网络密钥和关联的密钥索引)
  • IV index,
  • IV Update Flag,
  • Key Refresh Flag.

此外,在配置过程结束时会计算设备密钥。设备密钥是专用密钥,仅用于配置者和被配置者之间的私有通信(例如,在provisioning后configured 设备时)。它源自使用Diffie-Hellman(ECDH)协议在设备之间建立的共享机密。

2 PB-ADV bearer

该bearer用于在广播信道上交换配置PDU。Nordic BLE设备(充当Provisioner或Provisionee)可以本地支持此breaer,而平板电脑或计算机(充当Provisioner)也可以支持此breaer。

建议始终支持此breaer,除非由于特定于应用程序的限制而无法实现。

要启用此承载,请将MESH_FEATURE_PB_ADV_ENABLED设置为1。

如果不需要,可以禁用此bearer。而且,一旦配置了设备,它就独立于用于蓝牙mesh通信的广告载体(ADV)。

在大多数nRF5 SDK Mesh例子中该bearer都是默认打开的。更多相关信息查看Examples main page.

3 PB-GATT bearer

根据Bluetooth Mesh Profile Specification (MshPRFv1.0.1),许多移动设备和计算机对在广播通道上发送蓝牙mesh数据包的支持有限。对于这些情况,定义了GATT-based bearers。

PB-GATT bearer使用蓝牙mesh供应服务交换配置PDU。可以在被配置者的设备上启用此bearer,以使用移动应用程序调配它们。

要启用此bearer,请将以下定义设置为1:

  • MESH_FEATURE_PB_GATT_ENABLED
  • MESH_FEATURE_GATT_PROXY_ENABLED

如果设备支持GATT bearer (Proxy Service),则必须支持此承载。更多信息参看:GATT provisioning and Proxy

二 Implementing provisioning

实现配置过程。

此章节概述了配置过程和可用的API功能,这些功能可用于设置配置者和被配置者。

  • Using provisioner APIs on the provisioner
    • Setting up standalone provisioner
    • Setting up serial provisioner
      • ECDH offloading
  • Using provisioning APIs on the provisionee (unprovisioned device)
  • Handing errors

下图说明了配置过程,以及所有函数调用,消息和事件。

在这里插入图片描述

在使用这个配置规程之前,必须初始化并启用SoftDevice和Bluetooth Mesh协议栈。作为参考,请参阅light-switch \ server示例或任何其他具有Node角色的示例的main.c文件中的mesh_init()

如果设备没有使用其中一个角色的代码,则可以排除该角色的代码。为此,仅链接您设备要支持的角色的代码。调用其角色功能尚未编译到库中的不受支持的函数将返回NRF_ERROR_NOT_SUPPORTED。

1 Using provisioner APIs on the provisioner

在配置者上使用配置API。

配置者是蓝牙mesh的节点,负责配置mesh网络中其他节点。通常,配置者包含配置客户端和客户端节点,用于控制其他节点(如照明或空调)中的特定功能。配置者通常是网关设备的一部分,网关设备是在蓝牙mesh网络和其他网络技术(例如Internet)之间提供桥梁的设备。

设置配置者的主要有两种方法:

  • 作为独立应用程序运行(独立配置程序)
  • 由主机应用程序通过串行接口(串行配置程序)控制它

下图说明了两种设置的流程。
在这里插入图片描述

1.1 Setting up standalone provisioner

设置独立的配置器。

独立配置器提供配置功能,无需依赖外部主机。这样,独立的配置器必须能够存储有关网络中已配置节点的信息,包括其地址和设备密钥,这对于配置器能够配置节点是必不可少的。

由于嵌入式处理器中可用的内存量有限,因此使用独立的配置器程序会限制可以配置的节点数量。此限制对应于蓝牙mesh网络的最大数量。

要使用独立配置器配置设备,请确保在配置器应用程序中实现以下步骤:

  • Step 1: Initialize a standalone provisioner
  • Step 2: Start the provisioning procedure
  • Step 3: Receive Provisioning Capabilities and select public key exchange and authentication method
  • Step 4: Exchange public keys
  • Step 5: Authenticate the provisioning procedure
  • Step 6: Complete the provisioning procedure

Step 1: Initialize a standalone provisioner
初始化独立的配置器。

要使用任何配置API,必须使用nrf_mesh_prov_init()函数初始化配置上下文。

该功能需要带有相关参数的静态分配的配置上下文结构。

配置上下文结构维护配置过程的状态。除其他信息外,它包含以下数据,这些数据是根据用户提供的参数值初始化的:

  • 指向公钥和私钥的指针–用于加密的密钥对。这些密钥可以使用nrf_mesh_prov_generate_keys() 函数进行预编程或生成。

这些数字必须是specific elliptic curve,这意味着常规随机数不能用作密钥对。

应该通过调用nrf_mesh_prov_bearer_add() API来初始化配置bearer。

请参阅静态预配器示例(/examples/light-switch/provisioner/src/provisioner_helper.c)中的prov_helper_provisioner_init(),以了解如何初始化预配器。

Step 2: Starting the provisioning procedure
通过调用nrf_mesh_prov_provision() API开始配置过程。

确保为此API提供了以下参数:

  • 指向配置器上下文的指针。
  • 指向要被配置节点的UUID指针。
  • 注意计时器间隔(以秒为单位)。
  • 指向配置数据的指针。
    • 这些数据是用来配置未配置设备的,包含netkey, netkey index, IV index, target address, IV update flag, and Key Refresh Flag。
  • 使用Bearer
    • 当前,蓝牙mesh协议栈仅支持配置器进行广播Bearer配置(PB-ADV)。

该步骤得到的结果:

  • 用UUID指示的设备打开配置链接。
  • 发送预配置邀请消息,以邀请未预配置的设备参与预配置过程。

Step 3: Receiving Provisioning Capabilities and selecting public key exchange and authentication method

接收被配置端的IO能力,并选择公钥交换和身份验证方法。

未配置的设备通过发送“IO能力”消息来响应“配置邀请”消息。此操作将为配置器应用程序生成NRF_MESH_PROV_EVT_CAPS_RECEIVED事件。

配置者应用程序然后检查事件参数中报告的未配置设备的IO能力。然后,它调用nrf_mesh_prov_oob_use()函数以选择公钥交换机制和身份验证方法。

生成NRF_MESH_PROV_EVT_CAPS_RECEIVED事件后,请确保nrf_mesh_prov_oob_use()函数使用这些变量和参数:

  • 公钥交换机制。
    • 如果未配置设备的公共密钥在带外(OOB)可用,则配置者应用程序必须在供应上下文中将capability.pubkey_type设置为NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB。 否则,应用程序不应设置该值。
  • OOB身份验证方法。
    • 将方法参数设置为以下之一:
      • 对于静态OOB身份验证: NRF_MESH_PROV_OOB_METHOD_STATIC.
      • 对于输出OOB身份验证:: NRF_MESH_PROV_OOB_METHOD_OUTPUT.
      • 用于输入OOB身份验证: NRF_MESH_PROV_OOB_METHOD_INPUT.
      • 不进行身份验证: NRF_MESH_PROV_OOB_METHOD_NONE.
    • 将操作参数设置为nrf_mesh_prov_types.h文件中提到的值之一。
    • 将size参数设置为介于0x01和0x08之间的值(如n Bluetooth mesh profile specification文件规范中所定义)。

Step 4: Exchanging public keys
交换公钥。

交换公钥取决于您是否在步骤3中设置了features.pubkey类型:

  • 如果响应NRF_MESH_PROV_EVT_CAPS_RECEIVED事件时将capabilities.pubkey_type设置为NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB,则配置规程将向配置器应用程序发送NRF_MESH_PROV_EVT_OOB_PUBKEY_REQUEST事件。
    • 收到此事件后,配置器应用程序应获取被配方的公钥(例如,要求用户在控制台中键入UART接口是否可用),然后使用nrf_mesh_prov_pubkey_provide()API将其提供给协议栈。
  • 如果未设置capability.pubkey_type,则公钥将在带内交换,并且不会生成任何事件。

Step 5: Authenticating the provisioning procedure
验证配置规程。

根据步骤3中的身份验证方法的不同,协议栈将生成不同的事件:

  • 静态OOB (NRF_MESH_PROV_OOB_METHOD_STATIC):蓝牙mesh协议栈将生成NRF_MESH_PROV_EVT_STATIC_REQUEST事件。
    • 接收到此事件后,预配器应用程序应通过调用nrf_mesh_prov_auth_data_provide() API提供静态OOB值以继续该规程。
  • 输出OOB (NRF_MESH_PROV_OOB_METHOD_OUTPUT): 蓝牙mesh协议栈将生成NRF_MESH_PROV_EVT_INPUT_REQUEST事件。
    • 接收到此事件后,配置者应用程序应从用户请求输入数据,并通过调用nrf_mesh_prov_auth_data_provide()API来提供该数据以继续该规程。
  • 输入OOB (NRF_MESH_PROV_OOB_METHOD_INPUT):蓝牙网格堆栈将生成NRF_MESH_PROV_EVT_OUTPUT_REQUEST并将数据作为输出提供给应用程序。
    • 接收到此事件后,应用程序应使用提供的数据执行输出操作。
  • 没有验证 (NRF_MESH_PROV_OOB_METHOD_NONE):在配置过程中不会生成任何事件。

Step 6: Completing the provisioning procedure

完成配置程序。

如果认证成功:

  1. 协议栈会将分配数据分发到未配置的设备。
  2. 然后,未配置的设备将发送“配置完成”消息,以表明它已接收到数据。
  3. 收到此消息后,蓝牙mesh协议栈将生成NRF_MESH_PROV_EVT_COMPLETE事件。配置者应用然后可以存储这个新已被配置设备的设备密钥和地址。

完成此步骤后,将关闭预配链接,并将生成NRF_MESH_PROV_EVT_LINK_CLOSED事件。

1.2 Setting up serial provisioner

设置串行配置者。

串行配置者使用串行接口进行配置,从而允许主机控制器使用外部微控制器与蓝牙mesh网络进行交互。

主机控制器存储有关网络上节点的信息,从而将RAM存储在外部微控制器中,以用于其他特定用途。蓝牙mesh网络的大小仅受主机中可用资源的限制。

串行配置器应用程序中包含的步骤如下:

  1. 使用标准规程初始化SoftDevice和Bluetooth Mesh堆栈。
  2. 使用nrf_mesh_serial_init()和nrf_mesh_serial_enable()API函数初始化并启用串行接口。
  3. 启用ECDH。
  4. 用与独立配置器相同的过程来配置设备,但是用串行命令替换独立的API调用,并用串行事件替换独立的事件。

ECDH offloading
ECDH(椭圆曲线Diffie-Hellman)是一种加密算法,用于安全地在两个设备之间创建共享机密。 它用于创建加密密钥,然后将其用于在将预配置数据传输到被配置方时保护其安全。

如果并行运行多个配置程序,请启用ECDH卸载。 ECDH是一种处理器密集型算法,很容易成为瓶颈。 ECDH卸载是一项功能,可让主机处理器计算ECDH共享密钥,从而节省目标处理器中的CPU资源。

要启用ECDH卸载,请确保您的应用程序在初始化设备时调用mesh_opt_prov_ecdh_offloading_set。

2 Using provisioning APIs on the provisionee (unprovisioned device)

在被配置者(未配置的设备)上使用配置规程的API。

被配置方是将由配置方配置的设备。配置成功完成后,此设备将成为蓝牙mesh网络中的节点。

下图显示了使用静态OOB身份验证时配置过程的示例流程图。
在这里插入图片描述
要配置未配置的设备,请确保在被配置方应用程序中实施以下步骤:

  • Step 1: Initializing a provisionee
  • Step 2: Starting the provisioning procedure
  • Step 3: Sending Provisioning Capabilities and receiving Provisioning Start
  • Step 4: Exchanging public keys
  • Step 5: Authenticating the provisioning procedure
  • Step 6: Completing the provisioning procedure

Step 1: Initializing a provisionee
初始化被配置者。

要使用任何配置API,必须使用nrf_mesh_prov_init() 函数初始化配置上下文。

该函数需要静态分配的配置上下文结构和其他相关参数。

配置上下文结构维护配置规程的状态。除其他信息外,它包含以下数据,根据用户提供的参数值进行初始化:

  • 指向公钥和私钥的指针,用于加密的密钥对。这些键可以预先编程,也可以使用nrf_mesh_prov_generate_keys()函数生成。

    这些数字必须是specific elliptic curve,这意味着常规随机数不能用作密钥对。

  • 带外(OOB)身份验证能力–用于确定可以对节点使用哪种身份验证。通过设置与认证相关的字段的一个或多个值来选择认证方法(oob_static_type, oob_output_size, oob_output_actions, oob_input_size, and oob_input_actions):

    • 使用静态OOB进行身份验证:设置oob_static_types 为NRF_MESH_PROV_OOB_STATIC_TYPE_SUPPORTED.
      • 当支持此身份验证方法时,当配置方发送配置邀请时被配置方应用程序应提供静态OOB信息。
      • 如果不使用静态OOB,请将oob_static_types设置为0。
    • 使用输出OOB的身份验证:将oob_output_size设置为0x01到0x08之间的值,并将oob_output_actions设置为所需的输出操作。
      • 当支持此身份验证方法时,被配置方应用程序应执行配置方指定的oob_output_actions。
      • 如果不使用OutPut OOB,请将oob_static_types设置为0。
    • 使用输入OOB的身份验证:将oob_input_size设置为0x01到0x08之间的值,并将oob_input_actions设置为所需的输出操作。
      • 当支持此身份验证方法时,被配置者的应用程序应准备好按照配置者的要求从用户获取输入的OOB数据。
      • 如果未使用输入OOB,则将oob_input_size设置为0x00。
    • 不进行身份验证:仅设置算法字段。

对于常规的蓝牙mesh设备(具有节点角色的设备),带有bearer的配置协议栈的初始化由Mesh_provisionee_prov_start() API中的Mesh栈封装。

通过使用所需值更新prov_caps结构,可以在mesh_provisionee_prov_start() 中自定义身份验证选项。

Step 2: Starting the provisioning procedure

开始配置规程。

配置规程由配置者启动,配置者打开配置链接并发送配置邀请。

在打开配置链接之前,未配置的设备必须初始化配置API和bearer,并且必须准备好接收打开链接的请求。对于蓝牙mesh示例应用程序,此过程封装在mesh_provisionee.c模块的mesh_provisionee_prov_start() API中,并且包括以下操作:

  • 选择公钥交换的默认值,默认是在带内进行。
  • 选择身份验证选项(默认使用静态OOB)。
  • 调用nrf_mesh_prov_init() API。
  • 初始化bearers
  • 通过调用nrf_mesh_prov_listen() API开始广播未配置的节点信标。广播可以选择包括以下两个元素:
    • 指向其他数据位置的URI
    • 一个字段,指定可以在其中找到OOB信息的位置。

要自定义公共密钥交换和身份验证选项,可以在此API中修改prov_caps结构值。

在此处修改prov_caps选项将更改所有示例的这些选项。 或者,您可以使用其他名称复制此模块,更新prov_caps值,然后在项目中使用此新模块。

配置者打开配置链接后,蓝牙mesh协议栈会生成NRF_MESH_PROV_EVT_LINK_ESTABLISHED事件。接收到Provisioning Invite消息后,蓝牙mesh协议栈会生成NRF_MESH_PROV_EVT_INVITE_RECEIVED事件,并提供attention timer duration 值作为事件参数。此事件由mesh_provisionee.c模块处理,并调用用户应用程序回调以使应用程序吸引最终用户的注意。例如,led可以按照给定的时间闪烁一段时间。

Step 3: Sending Provisioning Capabilities and receiving Provisioning Start
发送配置性能和接收配置者发送的配置开始消息。

未配置的设备将通过发送“配置能力”消息(步骤1中指定的能力)来响应“配置邀请”消息。这不会为被配置者应用程序生成任何事件。

配置者从被配置者提供的配置能力中选择公钥交换和身份验证方法,并发送“配置开始”消息。这会在被配置方生成NRF_MESH_PROV_EVT_START_RECEIVED事件。

Step 4: Exchanging public keys

交换公钥。

交换公共密钥取决于被配置者是否将capability.pubkey_type设置为NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB:

  • 如果被配置方将capability.pubkey_type设置为NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB,则供配置者:
    1. 从带外读取被配置者的公钥(例如,如果配置者是平板电脑或计算机,则从文本文件中读取)。
    2. 发送自己的公钥。
  • 如果被配置者没有将capability.pubkey_type设置为NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB:被配置者协议栈将在带内发送其公钥。

在此步骤之后,将执行身份验证。

Step 5: Authenticating the provisioning procedure
身份验证规程。

根据提供被配置者提供的配置能力,配置者选择可用的身份验证方法,蓝牙mesh协议栈将生成不同的事件:

  • 静态OOB验证 (NRF_MESH_PROV_OOB_METHOD_STATIC):蓝牙mesh协议栈将生成NRF_MESH_PROV_EVT_STATIC_REQUEST事件。
    • 收到此事件后,应用程序应通过调用nrf_mesh_prov_auth_data_provide() API提供静态OOB值以继续该过程。
    • 静态OOB值始终为16字节长。

  • 输出OOB验证 (NRF_MESH_PROV_OOB_METHOD_OUTPUT):蓝牙mesh协议栈将生成NRF_MESH_PROV_EVT_OUTPUT_REQUEST并将数据输出作为事件参数提供给应用程序。
    • 然后,应用程序应使用此输出数据来执行输出操作。
  • 输入OOB验证(NRF_MESH_PROV_OOB_METHOD_INPUT):蓝牙mesh协议栈将生成NRF_MESH_PROV_EVT_INPUT_REQUEST事件。
    • 然后,配置者应用程序应请求用户输入数据,并通过调用nrf_mesh_prov_auth_data_provide() API提供数据以继续该过程。
  • 没有身份验证 (NRF_MESH_PROV_OOB_METHOD_NONE):不会产生任何事件。

Step 6: Completing the provisioning procedure
完成配置。

如果验证成功:

  1. 协议栈从配置者接收配置数据。
  2. 协议栈将生成 NRF_MESH_PROV_EVT_COMPLETE事件。
  3. 协议栈发送“ Provisioning Complete”消息,以表明它已收到配置数据。
  4. 如果启用了PERSISTENT_STORAGE,则在收到NRF_MESH_PROV_EVT_COMPLETE事件后,mesh_provisionee模块会将预配置数据保存到闪存中。

完成此步骤后,将关闭预配链接,并将生成NRF_MESH_PROV_EVT_LINK_CLOSED事件。

此时,设备可以通过配置模型从配置者处接收更多详细配置信息。只要配置模型服务器已初始化,配置就会在后台自动进行(有关如何执行此操作的示例,请参阅Light switch example 示例)。

3 Handing errors

处理错误

如果配置过程中发生错误,则配置链接将关闭。NRF_MESH_PROV_EVT_LINK_CLOSED事件被传递到应用程序。此事件包含nrf_mesh_prov_evt_link_closed_t.close_reason参数,该参数可用于确定导致配置失败的原因。

如果在NRF_MESH_PROV_EVT_COMPLETE事件之前收到NRF_MESH_PROV_EVT_LINK_CLOSED事件,则必须认为设置过程已失败。

另外,除了超时错误以外,对端设备可能会发送配置失败的PDU。收到配置失败的PDU后,NRF_MESH_PROV_EVT_FAILED事件将传递给应用程序。此事件包含failure_code参数,可用于确定是什么原因导致Provisioning Failed事件。

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值