2025-07-30 7:00 AM
I'm developing a BLE central application on a NUCLEO-WB55RG board using the P2P_Client example as a base. I'm facing an issue where I can successfully pair with a peripheral, but the bonding information is never saved to non-volatile memory. Keep in mind I'm new to this field so it is very possible one of my steps in the process is wrong. The board being paired is an NRF52832 development board and the logs, which I will share later in the post, clearly state pairing was completed and bonding worked.
ENVIRONMENT
PROBLEM DESCRIPTION
My application flow is as follows:
WHAT I'VE ALREADY TRIED
I've tried:
CONFIGURATION & CODE
Here's my app_conf.h
#define CFG_BONDING_MODE (1)
#define CFG_FIXED_PIN (111111)
#define CFG_USED_FIXED_PIN (0)
#define CFG_ENCRYPTION_KEY_SIZE_MAX (16)
#define CFG_ENCRYPTION_KEY_SIZE_MIN (8)
...
#define CFG_IO_CAPABILITY CFG_IO_CAPABILITY_NO_INPUT_NO_OUTPUT
...
#define CFG_MITM_PROTECTION CFG_MITM_PROTECTION_NOT_REQUIRED
...
#define CFG_SC_SUPPORT CFG_SECURE_OPTIONAL
...
#define CFG_KEYPRESS_NOTIFICATION_SUPPORT CFG_KEYPRESS_NOT_SUPPORTED
And here's the relevant app_ble code blocks (I will also attach the file, forgive the mess I'm just trying to get a prototype working).
static void Ble_Hci_Gap_Gatt_Init(void)
{
...
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode = CFG_MITM_PROTECTION;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin = CFG_ENCRYPTION_KEY_SIZE_MIN;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax = CFG_ENCRYPTION_KEY_SIZE_MAX;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin = CFG_USED_FIXED_PIN;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin = CFG_FIXED_PIN;
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode = CFG_BONDING_MODE;
ret = aci_gap_set_authentication_requirement(BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.bonding_mode,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.mitm_mode,
CFG_SC_SUPPORT,
CFG_KEYPRESS_NOTIFICATION_SUPPORT,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMin,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.encryptionKeySizeMax,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Use_Fixed_Pin,
BleApplicationContext.BleApplicationContext_legacy.bleSecurityParam.Fixed_Pin,
CFG_IDENTITY_ADDRESS);
...
}
static void GetBondedDevices(void) {
tBleStatus ret;
uint8_t num_bonded_devices = 0;
/* Assuming a maximum of CFG_BLE_NUM_LINK bonded devices can be stored.
* Adjust the size of `bonded_device_list` if necessary.
*/
Bonded_Device_Entry_t bonded_device_list[CFG_BLE_NUM_LINK];
/* Get the list of bonded devices from the BLE stack's security database. */
ret = aci_gap_get_bonded_devices(&num_bonded_devices, bonded_device_list);
if (ret == BLE_STATUS_SUCCESS) {
APP_DBG_MSG("\r\n\r** BONDED DEVICE LIST (Total: %d) **\n\r", num_bonded_devices);
if (num_bonded_devices > 0) {
for (int i = 0; i < num_bonded_devices; i++) {
APP_DBG_MSG(" -> Device %d: \n\r", i + 1);
APP_DBG_MSG(" - BD_ADDR: %02X:%02X:%02X:%02X:%02X:%02X\n\r",
bonded_device_list[i].Address[5],
bonded_device_list[i].Address[4],
bonded_device_list[i].Address[3],
bonded_device_list[i].Address[2],
bonded_device_list[i].Address[1],
bonded_device_list[i].Address[0]);
}
} else {
APP_DBG_MSG(" -> No bonded devices found.\n\r");
}
} else {
APP_DBG_MSG(" -> Failed to get bonded devices, result: 0x%x \n\r", ret);
}
}
static void PairTask(void) {
APP_DBG_MSG("PAIRING REQUEST");
tBleStatus ret = aci_gap_send_pairing_req(BleApplicationContext.BleApplicationContext_legacy.connectionHandle, 0); /* Force_Rebond set to 0 (No) */
APP_DBG_MSG("aci_gap_send_pairing_req command, result: 0x%x\n", ret);
}
I'm using tasks so these PairTask and GetBondedDevices are called using the sequencer.
LOGS FROM STM32 SIDE
[app_ble.c][SVCCTL_App_Notification][570]
** CONNECTION COMPLETE EVENT WITH SERVER
[app_ble.c][SVCCTL_App_Notification][575] -> Sending Pairing Request 8010x
[app_ble.c][PairTask][1115] PAIRING REQUEST
[app_ble.c][PairTask][1118] aci_gap_send_pairing_req command, result: 0x0
[app_ble.c][SVCCTL_App_Notification][540] DISCONNECTION EVENT: Reason = 0x3E
[app_ble.c][SVCCTL_App_Notification][541]
** DISCONNECTION EVENT WITH SERVER 00x
[app_ble.c][GetBondedDevices][1139]
** BONDED DEVICE LIST (Total: 0) **
[app_ble.c][GetBondedDevices][1153] -> No bonded devices found.
LOGS FROM NRF SIDE
*** Booting nRF Connect SDK v2.9.2-4ab7b98fc76f ***
*** Using Zephyr OS v3.7.99-aa34a5632971 ***
Starting Bluetooth Peripheral BMS example
I: 2 Sectors of 4096 bytes
I: alloc wra: 0, f28
I: data wra: 0, 1d8
I: SoftDevice Controller build revision:
I: 8c 08 59 97 97 6b e1 de |..Y..k..
I: 80 e5 fd f6 b4 58 ff 37 |.....X.7
I: d9 6d e5 58 |.m.X
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF52x (0x0002)
I: Firmware: Standard Bluetooth controller (0x00) Version 140.22792 Build 3781924759
I: No ID address. App must call settings_load()
Bluetooth initialized
I: Identity: CC:EE:C2:73:D3:31 (random)
I: HCI: version 6.0 (0x0e) revision 0x10fd, manufacturer 0x0059
I: LMP: version 6.0 (0x0e) subver 0x10fd
Advertising successfully started
Connected
Confirming pairing for 00:80:E1:27:57:A7 (public)
Security changed: 00:80:E1:27:57:A7 (public) level 2
Pairing completed: 00:80:E1:27:57:A7 (public), bonded: 1
Disconnected, reason 0x08
MY QUESTION
Am I missing something? Could it be related to the NRF52832 device potentially not being the proper address type for the type of bonding that I'm doing?