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.
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
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)
|Step||Description||Related API calls and events|
|1. Initialize provisionier mode||Initialize the Mesh stack in provisioner role. (wait for event||gecko_cmd_mesh_prov_init, gecko_evt_mesh_prov_initialized_id|
|2. Create keys||Application and network keys need to be created (unless they already exist)||gecko_cmd_mesh_prov_create_network, gecko_cmd_mesh_prov_create_appkey|
|3. Scanning||Start scanning for unprovisioned beacons||gecko_cmd_mesh_prov_scan_unprov_beacons, gecko_evt_mesh_prov_unprov_beacon_id|
|4. Start provisioning||Start provisioning, using either PB-ADV or PB-GATT bearer *||gecko_cmd_mesh_prov_provision_device, gecko_cmd_mesh_prov_provision_gatt_device, gecko_evt_mesh_prov_device_provisioned_id|
|5. Read DCD||Read the device composition data (DCD) from the freshly provisioned node||gecko_cmd_mesh_config_client_get_dcd, gecko_evt_mesh_config_client_dcd_data_id, gecko_evt_mesh_config_client_dcd_data_end_id|
|6. Send appkey||Push an application key to the node.||gecko_cmd_mesh_config_client_add_appkey, gecko_evt_mesh_config_client_appkey_status_id|
|7. Bind appkey to model(s)||Bind a model to an application key.||gecko_cmd_mesh_config_client_bind_model, gecko_evt_mesh_config_client_binding_status_id|
|8. Publish settings||Set a model's publication address, key, and parameters.||gecko_cmd_mesh_config_client_set_model_pub, gecko_evt_mesh_config_client_model_pub_status_id|
|9. Subscribe settings||Add an address to a model's subscription list.||gecko_cmd_mesh_config_client_add_model_sub, gecko_evt_mesh_config_client_model_sub_status_id|
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)
|v8||December 20, 2019||update to app.c format|
|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|
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.
Thanks for sharing JaakoV. In case this helps anyone else I found that I always noticed
Failed call to provision node. 180
Where 0x180 is bg_err_invalid_param until/unless I did a factory reset the first time after programming.
Here is a repository I've put together with the code I'm using along with detailed usage instructions: https://github.com/CU-ECEN-5823/ECEN5823-provisioner
I also noticed this behavior described by a previous user
My observation is that this example worked only for provisioning one device.Then for next device ,it gets stuck. Is it already known behaviour ?
I noticed this when provisioning both the switch and light examples. The serial terminal output just frezees with last message
sub add OK
and doesn't respond with information about any new devices which are unprovisioned.
The device firmware examples are already using the 0x3 parameter mentioned as a possible workaround.
I expect you will be able to reproduce this if you use the default soc-btmesh-switch or soc-btmesh-light projects from the latest updated Mesh SDK as of today.
As a workaround I've just power-cycled the provisioner after provisioning completes as described in step 9 ii of the README.
I found the embedded provisioning mechanism to be much more reliable than either the Android or iPhone Bluetooth Mesh applications. For instance, I was never able to get one of the boards I was using to provision successfully with the Andriod application in at least 10 tries. I was able to get it to provision successfully once on iPhone. I noticed messages like the ones below when provisioning with the embedded provisioner on this board, so I'm guessing the reason was some missing error handling in the Android mesh application combined it with something about this particular board which makes it more succeptible to timeouts.
SUB ADD, config 2/2: model 1302 -> address c002
waiting sub ack
setting sub failed with code 0x185 (timeout)
trying again, attempt 1/5
SUB ADD, config 2/2: model 1302 -> address c002
waiting sub ack
sub add OK
Both Android and iPhone applications were crashing or hanging regularly for me when provisioning any board and I didn't ever come up with a guaranteed sequence to complete provisioning with either mobile application when using the latest switch/light firmware. This combined with the fact that the mobile aps don't support vendor models makes me think the embedded provisioner option is the best option available at the current time. If you don't think this is the case I can provide some more information about the problems I've seen with the mobile applications in a new thread.
Referring back to this post:
A question was asked about stopping the scan for unprovisioned device beacons. The response from Sep 2017 was that the API was missing but would be added to a future release. Has this been added? If so, I cannot find appropriate documentation in the mesh sdk 1.4.
A question was asked about stopping the scan for unprovisioned device beacons.
@David, the command is not included in the latest version (1.4.2, released this week). It is still on the todo-list, but there has been multiple other new features and improvements with higher priority.
The unwanted scan responses can be easily filtered in the application. And under the hood, the mesh stack is scanning all the time anyway, so in that sense "stopping the scan" will not result in any power savings.
In any case, we obviously should have a command to stop the scan (i.e. tell the stack to filter those unprovisioned beacon events and not pass them to the application).
I have seen that the mesh profile specification does not need to operate on the Configuration Server model, but I have error 0x0c07 in the publish set 0x1301, 0x1007, 0x1304 Setup Server model. Is there no need to perform operations on these models?
My EVK is EFR32 BLUE Gecko(SLWSTK6020B) and I used the example code of V6 and soc-btmesh-light. I replaced the main.c.
But I have no idea how to add Configuration Client model in DCD via Simplicity studio and What Client model is needed to add. Could you teach me?
And what values I need to use for below parameters in memory configuration.
1 - Max Provisioned Devices
2 - Max Provisioned Device Netkeys
3 - Max Foundation Client Cmds
In Simplicity studio, open the isc file present in your project.
Then in the "Composition Data" pane select the primary element. Then, In "Bluetooth SIG model" hit the green + button and select the "Configuration client" model.
Concerning the memory configuration, make sure the "Max Provisioned Devices" field is set to a value greater that 0. That should be enough for you to be able to provision a node and read its DCD.
Hi Badiss Djafar,
I could provision the light of BLE(soc-btmesh-light) via this example code.
Do you have any example code if I want to turn on or off the light of BLE via the provisioner(example code)?
Update (May 10th):
On BT Mesh SDK 1.4.3 the stack initialization checking was improved. This example was missing the provisioner class initialization (gecko_bgapi_class_mesh_prov_init) which caused the command gecko_cmd_mesh_prov_init to fail. The new attached version fixes this issue.
I see the following lines that define the group addresses:
#define LIGHT_CTRL_GRP_ADDR 0xC001
#define LIGHT_STATUS_GRP_ADDR 0xC002
#define VENDOR_GRP_ADDR 0xC003
My question is are these just arbitrary addresses that you selected? Or did these come from a standard somewhere like the model ID's?
Group addresses are only one type of addresses among others. Addresses are coded on 2 bytes (just like unicast and virtual addresses).
The BT mesh spec, indicates that group addresses shall have the 2 MSB of byte 0 set to 1 (see section 184.108.40.206 of the Mesh profile spec 1.0.1).
so it looks like that:
0b11xxxxxx 0bxxxxxxxx (little endian)
byte 0 byte 1
So to answer your question, the 0xC part of the address is mandatory, the rest is completely arbitrary.