fix(nimble): Improve safety, fix bugs, and update docs across NimBLE examples

- Remove unused headers from examples
- Improve periodic adv/sync example functionality and readability
- Use ble_hs_id_infer_auto() instead of hardcoded BLE_OWN_ADDR_PUBLIC/RANDOM
- Add ble_hs_util_ensure_addr() calls in on_sync for proper address setup
- Use correct ext adv instance (0 instead of 1) in phy_prph, l2cap_coc, multi_conn
- Fix struct name: ble_gap_periodic_adv_enable_params -> ble_gap_periodic_adv_start_params
- Add CONFIG_BT_NIMBLE_GAP_SERVICE guards around ble_svc_gap_device_name_set
- Fix unsafe AD data parsing with bounds checks in central examples
- Fix UUID matching bugs (off-by-one loop condition and byte order) in
  phy_cent, htp_cent, and proximity_sensor_cent
- Fix ble_multi_conn_cent address type to use dynamic inference
- Remove contradictory sm_sc=0 after sm_sc=1 in ble_multi_adv
- Add CONFIG_BT_NIMBLE_EXT_ADV=y to ble_multi_adv sdkconfig defaults
- Check return values for ble_gap_set_host_feat, nimble_port_init
- Update tutorials and READMEs to match code changes
This commit is contained in:
Rahul Tank
2026-02-25 13:04:23 +05:30
parent 773cb7c129
commit 24962cc3fe
69 changed files with 1027 additions and 2059 deletions
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
@@ -11,6 +11,7 @@
#include "nimble/nimble_port.h"
#include "nimble/nimble_port_freertos.h"
#include "host/ble_hs.h"
#include "host/ble_ead.h"
#include "host/util/util.h"
#include "console/console.h"
#include "services/gap/ble_svc_gap.h"
@@ -253,37 +254,50 @@ enc_adv_data_cent_decrypt(uint8_t length_data, const uint8_t *data, const uint8_
uint8_t op;
uint8_t len, offset = 0;
uint8_t *enc_data;
uint8_t enc_payload_len;
int rc;
uint8_t dec_data_len;
uint8_t temp[BLE_EAD_DECRYPTED_PAYLOAD_SIZE(UINT8_MAX)];
struct ble_store_key_ead key_ead = {0};
struct ble_store_value_ead value_ead = {0};
while (offset < length_data) {
len = data[offset];
/* Bounds check: ensure we can read the type byte and the full AD field */
if (offset + 1 >= length_data) {
break;
}
op = data[offset + 1];
uint8_t temp[len];
if (len == 0 || offset + 1 + len > length_data) {
break;
}
switch (op) {
case BLE_GAP_ENC_ADV_DATA:
enc_data = (uint8_t *) malloc (sizeof(uint8_t) * len);
/* Encrypted payload is AD value (len - 1 bytes, excluding the type byte) */
enc_payload_len = len - 1;
enc_data = (uint8_t *) malloc (sizeof(uint8_t) * enc_payload_len);
if (enc_data == NULL) {
MODLOG_DFLT(ERROR, "Failed to allocate enc_data");
return 0;
}
memcpy(enc_data, data + offset + 2, len);
memcpy(enc_data, data + offset + 2, enc_payload_len);
memcpy(&key_ead.peer_addr.val, peer_addr, PEER_ADDR_VAL_SIZE);
rc = ble_store_read_ead(&key_ead, &value_ead);
if (rc != 0 || !value_ead.km_present) {
MODLOG_DFLT(INFO, "Reading of session key and iv from NVS failed rc = %d", rc);
free(enc_data);
return 0;
} else {
MODLOG_DFLT(INFO, "Read session key and iv from NVS successfully");
}
rc = ble_ead_decrypt(value_ead.km->session_key, value_ead.km->iv, enc_data, len,
temp);
rc = ble_ead_decrypt(value_ead.km->session_key, value_ead.km->iv, enc_data,
enc_payload_len, temp);
if (rc == 0) {
MODLOG_DFLT(INFO, "Decryption of adv data done successfully");
} else {
@@ -593,6 +607,8 @@ enc_adv_data_cent_gap_event(struct ble_gap_event *event, void *arg)
if (event->passkey.params.action == BLE_SM_IOACT_INPUT) {
pkey.action = event->passkey.params.action;
/* WARNING: Hardcoded passkey for demonstration only.
* In production, generate a random passkey per pairing. */
pkey.passkey = 123456;
ESP_LOGI(tag, "Entering passkey %" PRIu32, pkey.passkey);
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);
@@ -247,6 +247,8 @@ enc_adv_data_prph_gap_event(struct ble_gap_event *event, void *arg)
/** For now only BLE_SM_IOACT_DISP is handled */
if (event->passkey.params.action == BLE_SM_IOACT_DISP) {
pkey.action = event->passkey.params.action;
/* WARNING: Hardcoded passkey for demonstration only.
* In production, generate a random passkey per pairing. */
pkey.passkey = 123456;
ESP_LOGI(tag, "Enter passkey %" PRIu32 " on the peer side", pkey.passkey);
rc = ble_sm_inject_io(event->passkey.conn_handle, &pkey);