Ble mesh: autoprovisioning and address selection

After a lot of efforts I managed to autoprovision and autoconfigure my nrf52840 board and a series of nrf52840dongles (provisioning and configuring inside the software and not through external app).

In particular, I have configured a switch and a led like a client and his server in an element of my node.

I write the address of the nodes in a particular location of memory (as you can see from the code below)

All is OK: when I toggle the switch on nrf52840 board, the corresponding leds on dongles go on/off.

But if I make an erase/flash operation on the board and then I rewrite the same address in the same memory location, the board stops communicating with the other nodes.

I have to make another erase/flash operation and then write in memory another adderss.

How is this possible?

The code that I use for autoprovisioning is this:

#include "provision.h"
#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(main);

static const uint8_t net_key[16] = {
	0x6f, 0xea, 0x5b, 0x86, 0x38, 0x45, 0x26, 0xb9,
	0x0e, 0x7b, 0x73, 0x0c, 0x69, 0x94, 0x75, 0x0a,
};

static const uint8_t dev_key[16] = {
	0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
	0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0x01,
};

static const uint8_t first_app_key[16] = {
    // First AppKey
	0x8c, 0x32, 0x9f, 0x41, 0xd1, 0xd2, 0xc2, 0x9f,
	0x5a, 0xb7, 0x09, 0x0c, 0x0b, 0x31, 0x4d, 0x1d,
};

static const uint8_t second_app_key[16] = {
    0x88, 0xed, 0x35, 0xc4, 0x95, 0x01, 0xaf, 0x8a,
	0xce, 0x47, 0xd3, 0x11, 0xbf, 0x77, 0xb4, 0xc1,
};

static const uint8_t third_app_key[16] = {
	0x6a, 0x1a, 0xf1, 0xdb, 0xe8, 0x38, 0xdc, 0xf5,
	0x5c, 0x83, 0xa5, 0x33, 0x35, 0xd2, 0xe9, 0xde,
};

static uint16_t net_idx = 0;
static uint32_t iv_index = 0;
static uint8_t flags;
static bool needs_configuration = false;

uint16_t addr = 0x8000;

void configure()
{
	int res;
	uint8_t status = 0;

	if (needs_configuration)
	{
		if (addr == 0x8000)
		{
			LOG_ERR("Device hasn't been provisioned yet.");
			return;
		}

		LOG_INF("Configuring addr %d...", addr);

		res = bt_mesh_cfg_cli_net_key_add(net_idx, addr, net_idx, net_key, NULL);
		LOG_INF("NetKey %d: res %d, status = %d", net_idx, res, status);

		res = bt_mesh_cfg_cli_app_key_add(net_idx, addr, net_idx, 0, first_app_key, NULL);
		LOG_INF("AppKey 0: res %d, status = %d", res, status);

		res = bt_mesh_cfg_cli_app_key_add(net_idx, addr, net_idx, 1, second_app_key, NULL);
		LOG_INF("AppKey 1: res %d, status = %d", res, status);

		res = bt_mesh_cfg_cli_app_key_add(net_idx, addr, net_idx, 2, third_app_key, NULL);
		LOG_INF("AppKey 2: res %d, status = %d", res, status);

		LOG_INF("Configuration completed");
	}
}

void provision()
{

	int err;
	volatile uint32_t *node_addr  = (volatile uint32_t *) 0x10001080; // address node in UICR
	addr = *node_addr;
	/*err = sys_csrand_get(&addr, 2);
	if (err != 0)
	{
		LOG_ERR("Could not get a random address");
		return;
	}
	else
	{
		addr %= 0x7fff;
	}*/
	
	err = bt_mesh_provision(net_key, net_idx, flags, iv_index, addr, dev_key);
	if (err == -EALREADY)
	{
		LOG_INF("Using stored settings");
	}
	else if (err)
	{
		LOG_ERR("Provisioning failed (err %d)", err);
		return;
	}
	else
	{
		LOG_INF("Provisioning completed");
		// configure(addr);
	}
	needs_configuration = true;
}

I'm ready to add other information about my software if this can facilitate you to resolve my problem.

Thanks in advance for your answer

Parents
  • Hi Stefano,

    But if I make an erase/flash operation on the board and then I rewrite the same address in the same memory location, the board stops communicating with the other nodes.

    And by this, do you mean an erase-all and reflashing of the entire SW? Or how exactly are you erasing and flashing?

    Regards,

    Elfving

  • I make erase all and then reflash the entire SW.

  • I see. And you only reflash one device, ie. the DK and not the dongles? I guess one issue could be that the sequence number of the DK is now restarted, while the others are much higher.

    To avoid replay attacks, the nodes store the sequence number of the latest message, and disregard all older ones. Sending a few more (given that a few messages are what has been sent in the past) of these messages should make the sequence number go up high enough. What is recommended is to use new addresses for a new unit instead of using the old ones. If addressing is what is stopping you from doing that, then I would recommend group addresses. Is there any reason why you can not use this approach?

    I am not sure if we have an API for setting and getting the RPL (replay protection list), potentially for safety reasons. But if you are interested in going this route, I can check.

    Regards,

    Elfving

Reply
  • I see. And you only reflash one device, ie. the DK and not the dongles? I guess one issue could be that the sequence number of the DK is now restarted, while the others are much higher.

    To avoid replay attacks, the nodes store the sequence number of the latest message, and disregard all older ones. Sending a few more (given that a few messages are what has been sent in the past) of these messages should make the sequence number go up high enough. What is recommended is to use new addresses for a new unit instead of using the old ones. If addressing is what is stopping you from doing that, then I would recommend group addresses. Is there any reason why you can not use this approach?

    I am not sure if we have an API for setting and getting the RPL (replay protection list), potentially for safety reasons. But if you are interested in going this route, I can check.

    Regards,

    Elfving

Children
  • Hi,

    I understand that:

    1. if I want to use an older address for DK, I have to reflash and readdress also all dongles in the network. Correct?
    2. If I use a new address after reflashing DK, it is not necessary reflash all dongles. Correct?

    About group addresses: actually, I'm using them. For example: 0xC001 is the group address for light client/server of DK and of all dongles, but anyway when reflashing DK (and group address does not change) I have to change its main address for communicating with dongles (and you have just explained me why). What I have not understood?

    Thanks and regards

Related