NimBLE bonding information removed after second device pairing

azkarate
Posts: 7
Joined: Thu Jun 18, 2020 2:04 pm

NimBLE bonding information removed after second device pairing

Postby azkarate » Wed Aug 25, 2021 2:27 pm

I am working on a BLE project using NimBLE on a ESP32-SOLO-1 and I am encountering a problem with the bonding of multiple devices.

When I connect a new device the bonding process starts and completes correctly. I am able to read and write all the characteristics without any problem. I can even bond another device and also works perfectly, but when I try to connect the first device, which is already bonded, the connection is rejected with a 531 error code (disconnected by user) on the ESP32 side.

The NimBLE configuration structure looks like this:

Code: Select all

ble_hs_cfg.reset_cb = ble_onResetCallback;
ble_hs_cfg.sync_cb = ble_onSyncCallback;
ble_hs_cfg.gatts_register_cb = ble_serviceRegisterCallback;
ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
ble_hs_cfg.sm_io_cap = BLE_HS_IO_DISPLAY_ONLY;
ble_hs_cfg.sm_sc = true;
ble_hs_cfg.sm_bonding = true;
ble_hs_cfg.sm_mitm = true;
ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID;
ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_ID;
On the sync callback I initialize the device addres like this:

Code: Select all

/* Configure RPA and random BLE address */
ble_hs_pvcy_rpa_config(NIMBLE_HOST_ENABLE_RPA);

ownAddrType = BLE_OWN_ADDR_RANDOM;

/* Begin advertising. */
ble_startAdvertising();
I am using ESP-IDF v4.3 on Visual Studio Code.

azkarate
Posts: 7
Joined: Thu Jun 18, 2020 2:04 pm

Re: NimBLE bonding information removed after second device pairing

Postby azkarate » Thu Aug 26, 2021 3:07 pm

I have found that when a device subscribes to all of the characteristics I have (24 in total) the descriptors are saven on the NVS. As I pretend to save bonding information of 4 devices and the stack automatically saves the descriptors of each device I understand tha I need enough space on the NVS for all of this information. I have set the NVS partition to 40K and set the "menuconfig >> Component config >> Bluetooth >> NimBLE options >> Maximum number of CCC descriptors to save across reboots" option to 256 (more than enough to save what I need). Also the "Maximum number of bonds to save across reboots" option is set to 4.

I also changed the BLE synch callback to something closer to the bleprph example

Code: Select all

uint8_t addr_val[6] = {0};

assert(ble_hs_util_ensure_addr(true) == 0);

if (ble_hs_id_infer_auto(true, &ownAddrType)) {
	ESP_LOGE("BLE_Sync", "Error determining address type");
	return;
}

ble_hs_id_copy_addr(ownAddrType, addr_val, NULL);

ESP_LOGI("BLE_Sync", "Device address type %i", ownAddrType);
With this changes I now am able to bond two devices but when I bond a 3rd or sometimes when I bond a 4th device the first devices' bonding is corrupted, because on iOS devices it disconnects instantly and on Android devices a new bonding process is started.

I hope someone can show some light on my problem, thanks in advance.

azkarate
Posts: 7
Joined: Thu Jun 18, 2020 2:04 pm

Re: NimBLE bonding information removed after second device pairing

Postby azkarate » Tue Aug 31, 2021 2:03 pm

I have kind of resolved the issue. I changed the device address type to public using the following sync callback:

Code: Select all

assert(ble_hs_util_ensure_addr(0) == 0);

ble_hs_id_copy_addr(ownAddrType, addr_val, NULL);

ESP_LOGI("BLE_Sync", "Device address %02X:%02X:%02X:%02X:%02X:%02X type %i",
				addr_val[0], addr_val[1], addr_val[2], addr_val[3], addr_val[4],
				addr_val[5], ownAddrType);
I also changed the Maximum number of CCC descriptors to save across reboots to 128 because my application has 24 characteristics that can be notified.

Once this is set up, the ESP32 starts with a BLE MAC address of type 0 (BLE_ADDR_PUBLIC) and the multiple devices are bonded over reboots. Still there is one issue, I set up to 3 the Maximum number of bonds to save across reboots and when a 4th device is bonded, this bond is not saved over reboots. Is there any way to remove the oldest device and add this new bond to the NVS?

Thanks in advance,

Jon

Who is online

Users browsing this forum: Majestic-12 [Bot] and 80 guests