This article includes a code example that implements a Bluetooth mesh provisioner that can be run on one of our Bluetooth capable development kits.
To understand how the provisioning and configuration of mesh nodes works, it is recommended that you first try out the mesh Android app as explained in the quickstart guide QSG148.
The example presented in this article can perform the same operations as the mobile app but it is more autonomous and requires only minimal input from the user. When the provisioner sees an unprovisioned beacon, it prints the UUID of this device to the debug console and then you can either:
- push button PB1 to provision and configure the device (*
- push button PB0 to ignore this beacon and continue scanning for other beacons (*
*) Alternatively, you can press key 'y' / 'n' on the terminal to provision or ignore the found device (starting from version v6)
The purpose of this example is to show how the Silicon Labs BT mesh stack can be used in provisioning mode. The main steps in provisioning and configuration are summarized below, along with a list of related API calls.
NOTE: This example is intended only for small scale experimental use. It is not meant to be used as a basis for any production use and the code.
Known limitations:
The provisioning data is stored in the EFR32 internal flash and has limited capacity, the maximum number of nodes this example can support is around 10-15
the max number of SIG and vendor models is limited to 16 and 4, respectively (see definition of struct tsDCD)
This example is missing many important features that are needed in a real production quality provisioner, such as:
key refresh, blacklisting of devices
removing nodes from the network
Provisioning and configuration basic steps
The main steps included in provisioning a device into the network and configuring the node are summarized in the following table. This is just a compact list of what operations and API calls are involved in the process. More detailed information about provisioning and configuration in Bluetooth mesh can be found in:
Mesh Profile specification by Bluetooth SIG, rev 1.0 (Chapter 5 Provisioning)
The sample code is attached in a zip file. The zip file includes a readme.md file that explains step-by-step how this code can be installed on top of one of the examples in the Bluetooth mesh SDK.
The Silicon Labs Bluetooth Mesh SDK performs consistency checks on the non-volatile storage areas, that hold information such as keys, at startup. These areas are not erased when flashing a new application. If the application on the EFR32 is changed from embedded provisioner to something else, like a light or switch node, or from such a node to embedded provisioner, the entire contents of flash must be erased to avoid errors during initialization. This can be accomplished with Simplicity Commander
(commander device recover)
Version history:
Revision
Date
Comments
v8
December 20, 2019
update to app.c format
v7
May 10th
Added call to gecko_bgapi_class_mesh_prov_init
v6
February 28, 2019
Example modified to use the new API calls (introduced in SDK 1.4.0) and all deprecated calls removed. Additionally some refactoring of the code + minor improvements.
v5
January 22, 2019
Modified to work with Mesh SDK 1.4.0. Max number of SIG models increased to 16. Some sanity checks added.
v4
September 14, 2018
Modified to work with Mesh SDK 1.3.x.
v3
June 11, 2018
Option to provision using PB-GATT, Option to use fixed application and network keys
v2
May 31, 2018
First draft (based on code package that was earlier posted under a discussion thread
Composition Data and Memory Configuration
In order for the provisioner to configure the nodes there are a few requirements that must be met.
Firstly, the config client must be added to the device composition data (DCD) as shown
The memory configuration tab contains several settings which must be modified as well. These parameters should all be set to non-zero, the default values for each are zero.
max provisioned devices
max provisioned device netkeys
max foundation client commands
For detailed descriptions of these settings please refer to section 3 of UG366.
Update (28th Feb 2019): added package prov_example_v6_SDK-140_new_API.zip . The example code has been modified to use the new config client API introduced in SDK 1.4.0 (deprecated calls removed from the code).
Latest code package attached, small modifications to make this work with Mesh SDK 1.4.0 (+ some sanity checks added).
Updated code package, modified to work with Mesh SDK 1.3.0.
I noticed that you specifically avoid calling gecko_cmd_mesh_prov_model_app_bind() on Model ID 0x0000 (Configuration Server). Attempting to do so results in an error. Should this always be followed? Why do we not need to bind model id 0x0000?
Thanks,
Bobby
0
Hi Bobby,
to be honest, I did not pay any attention to the Configuration Server model. Now that you asked, I checked the BLE mesh profile specification and it says on page 195: (4.4.1 Configuration Server model)
The model shall be supported by a primary element and shall not be supported by any secondary elements. The application-layer security on the Configuration Server model shall use the device key established during provisioning.
So the reason you don't need to bind this model is because it implicitly uses the device key for app.level security.
1
Hello,
I'm having problems while using this code (v4 on MESH SDK v1.3.1). This is the error I get when attempting to provision a node:
Success - initializing unprovisioned beacon scan
gecko_evt_mesh_prov_unprov_beacon_id
53696c6162734465762d1f643a5ecfd0 (64 1f)
confirm?
Sending prov request
Successful call of gecko_cmd_mesh_prov_provision_device
Node successfully provisioned. Address: 0001
provisioning done - uuid 0x53696C6162734465762D1F643A5ECFD0
requesting DCD from the node...
DCD status event. result = 0
DCD: company ID 02ff, Product ID f0b0
Num sig models: 16
model ID: 1008
model ID: 1004
model ID: 1300
model ID: 0002
model ID: 1303
model ID: 1001
model ID: 1006
model ID: 1007
model ID: 1302
Num vendor models: 0
Appkey deployed to 1
mesh_prov_config_status: addr = 0x1, id = 0x0, status = 0x0
APP_BIND, config 1/0:: model 0000 key index 0
success - waiting bind ack
mesh_prov_config_status: addr = 0x1, id = 0x803D, status = 0x2
Not successful, will try again
config retry: try step 7 again
APP_BIND, config 1/0:: model 0000 key index 0
.APP_BIND, config 1/0:: model 0000 key index 0
.APP_BIND, config 1/0:: model 0000 key index 0
success - waiting bind ack
mesh_prov_config_status: addr = 0x1, id = 0x803D, status = 0x2
Not successful, will try again
config retry: try step 7 again
APP_BIND, config 1/0:: model 0000 key index 0
success - waiting bind ack
mesh_prov_config_status: addr = 0x1, id = 0x803D, status = 0x2
Not successful, will try again
config retry: try step 7 again
APP_BIND, config 1/0:: model 0000 key index 0
success - waiting bind ack
mesh_prov_config_status: addr = 0x1, id = 0x803D, status = 0x2
Not successful, will try again
config retry: try step 7 again
APP_BIND, config 1/0:: model 0000 key index 0
success - waiting bind ack
mesh_prov_config_status: addr = 0x1, id = 0x803D, status = 0x2
Not successful, will try again
config retry: try step 7 again
APP_BIND, config 1/0:: model 0000 key index 0
success - waiting bind ack
mesh_prov_config_status: addr = 0x1, id = 0x803D, status = 0x2
ERROR: config failed, retry limit reached. stuck at state 7
Sometimes, it simply gets stuck at:
Successful call of gecko_cmd_mesh_prov_provision_device
Provisioning failed. Reason: 0
Can you tell me what can be wrong?
Thanks,
TC
0
OK, I've managed to figure out what was going on. The array "uint16 SIG_models[8]" defined inside the tsDCD struct was not large enough to accomodate all the models and this caused all kind of weird stuff to happen. Just increased the size of the array and all seems fine now.
1
@Tiago yes, the code is originally written to support up to 8 SIG models and up to 4 vendor models. I thought it would be enough for most basic use cases, but based on your log you had 9 models in your DCD which slightly exceeds the limit.
I will add a note about this in the "known limitations" section, thanks for pointing this out!
0
@JaakkoV Thanks for this provisioner code.
I have merged the switch and light examples into one and everything appears to be working fine after provisioning with this code. However, the nodes "loose" their subscriptions after a reset and stop receiving messages from other nodes which are sending requests . This does not happen when I use the mobile app to provision the nodes, although the app has other limitations (with the app, a node can only be a light or a switch, but not both at the same time). Is this a known issue?
0
@Tiago no, this is not a known issue. I suspect it may have something to do with high number of sub/pub settings you are using.
In the memory configurator, there is an option to control the maximum number of subscriptions, see following screenshot:
Please check that your combined light/switch node is not exceeding this limit and adjust if needed.
Have you monitored the debug prints from the node when you do a reset? Is there any error reported there? After reset, is the node still provisioned or does it lose all configuration data? (I.e.. does it return to unprovisioned mode?)
0
@JaakkoV Yes, but I'm currently only using 2 APP Binds, 2 PUBs and 2 SUBs per node. Nevertheless, increasing the max subscriptions and max app binds in the memory configurator was my first approach. However, I had no luck. The subscriptions are lost when the nodes are reset.
On reset, the node does not print out any error (do I need to enable any special debug flag?).
When I first merged both examples, the nodes would loose all configuration data upon a reset (they would become unprovisioned). But after removing additional stuff from the code now I have this weird behavior of missing subscriptions.
Do I need to adjust any other memory settings, like stack or heap (I've also already increased these) ?
0
I have tried using latest example prov_example_v4_SDK-130.zip. My observation is that this example worked only for provisioning one device.
Then for next device ,it gets stuck. Is it already known behaviour ?
KBA_BT_0501: BT Mesh embedded provisioner example
Introduction
This article includes a code example that implements a Bluetooth mesh provisioner that can be run on one of our Bluetooth capable development kits.
To understand how the provisioning and configuration of mesh nodes works, it is recommended that you first try out the mesh Android app as explained in the quickstart guide QSG148.
The example presented in this article can perform the same operations as the mobile app but it is more autonomous and requires only minimal input from the user. When the provisioner sees an unprovisioned beacon, it prints the UUID of this device to the debug console and then you can either:
- push button PB1 to provision and configure the device (*
- push button PB0 to ignore this beacon and continue scanning for other beacons (*
*) Alternatively, you can press key 'y' / 'n' on the terminal to provision or ignore the found device (starting from version v6)
The purpose of this example is to show how the Silicon Labs BT mesh stack can be used in provisioning mode. The main steps in provisioning and configuration are summarized below, along with a list of related API calls.
NOTE: This example is intended only for small scale experimental use. It is not meant to be used as a basis for any production use and the code.
Known limitations:
The provisioning data is stored in the EFR32 internal flash and has limited capacity, the maximum number of nodes this example can support is around 10-15
the max number of SIG and vendor models is limited to 16 and 4, respectively (see definition of struct tsDCD)
This example is missing many important features that are needed in a real production quality provisioner, such as:
key refresh, blacklisting of devices
removing nodes from the network
Provisioning and configuration basic steps
The main steps included in provisioning a device into the network and configuring the node are summarized in the following table. This is just a compact list of what operations and API calls are involved in the process. More detailed information about provisioning and configuration in Bluetooth mesh can be found in:
Mesh Profile specification by Bluetooth SIG, rev 1.0 (Chapter 5 Provisioning)
https://blog.bluetooth.com/provisioning-a-bluetooth-mesh-network-part-1
https://blog.bluetooth.com/provisioning-a-bluetooth-mesh-network-part-2
Code example
The sample code is attached in a zip file. The zip file includes a readme.md file that explains step-by-step how this code can be installed on top of one of the examples in the Bluetooth mesh SDK.
The Silicon Labs Bluetooth Mesh SDK performs consistency checks on the non-volatile storage areas, that hold information such as keys, at startup. These areas are not erased when flashing a new application. If the application on the EFR32 is changed from embedded provisioner to something else, like a light or switch node, or from such a node to embedded provisioner, the entire contents of flash must be erased to avoid errors during initialization. This can be accomplished with Simplicity Commander
(commander device recover)
Version history:
v7
Composition Data and Memory Configuration
In order for the provisioner to configure the nodes there are a few requirements that must be met.
Firstly, the config client must be added to the device composition data (DCD) as shown
The memory configuration tab contains several settings which must be modified as well. These parameters should all be set to non-zero, the default values for each are zero.
max provisioned devices
max provisioned device netkeys
max foundation client commands
For detailed descriptions of these settings please refer to section 3 of UG366.
Update (28th Feb 2019): added package prov_example_v6_SDK-140_new_API.zip . The example code has been modified to use the new config client API introduced in SDK 1.4.0 (deprecated calls removed from the code).
Latest code package attached, small modifications to make this work with Mesh SDK 1.4.0 (+ some sanity checks added).
Updated code package, modified to work with Mesh SDK 1.3.0.
Hey Jaakko,
I noticed that you specifically avoid calling gecko_cmd_mesh_prov_model_app_bind() on Model ID 0x0000 (Configuration Server). Attempting to do so results in an error. Should this always be followed? Why do we not need to bind model id 0x0000?
Thanks,
Bobby
Hi Bobby,
to be honest, I did not pay any attention to the Configuration Server model. Now that you asked, I checked the BLE mesh profile specification and it says on page 195: (4.4.1 Configuration Server model)
So the reason you don't need to bind this model is because it implicitly uses the device key for app.level security.
Hello,
I'm having problems while using this code (v4 on MESH SDK v1.3.1). This is the error I get when attempting to provision a node:
Sometimes, it simply gets stuck at:
Can you tell me what can be wrong?
Thanks,
TC
@Tiago yes, the code is originally written to support up to 8 SIG models and up to 4 vendor models. I thought it would be enough for most basic use cases, but based on your log you had 9 models in your DCD which slightly exceeds the limit.
I will add a note about this in the "known limitations" section, thanks for pointing this out!
@JaakkoV Thanks for this provisioner code.
I have merged the switch and light examples into one and everything appears to be working fine after provisioning with this code. However, the nodes "loose" their subscriptions after a reset and stop receiving messages from other nodes which are sending requests . This does not happen when I use the mobile app to provision the nodes, although the app has other limitations (with the app, a node can only be a light or a switch, but not both at the same time). Is this a known issue?
@Tiago no, this is not a known issue. I suspect it may have something to do with high number of sub/pub settings you are using.
In the memory configurator, there is an option to control the maximum number of subscriptions, see following screenshot:
Please check that your combined light/switch node is not exceeding this limit and adjust if needed.
Have you monitored the debug prints from the node when you do a reset? Is there any error reported there? After reset, is the node still provisioned or does it lose all configuration data? (I.e.. does it return to unprovisioned mode?)
@JaakkoV Yes, but I'm currently only using 2 APP Binds, 2 PUBs and 2 SUBs per node. Nevertheless, increasing the max subscriptions and max app binds in the memory configurator was my first approach. However, I had no luck. The subscriptions are lost when the nodes are reset.
On reset, the node does not print out any error (do I need to enable any special debug flag?).
When I first merged both examples, the nodes would loose all configuration data upon a reset (they would become unprovisioned). But after removing additional stuff from the code now I have this weird behavior of missing subscriptions.
Do I need to adjust any other memory settings, like stack or heap (I've also already increased these) ?
I have tried using latest example prov_example_v4_SDK-130.zip. My observation is that this example worked only for provisioning one device.
Then for next device ,it gets stuck. Is it already known behaviour ?