Page 1 of 1

ESP32-S3 Issue with enabling RPA using NimBLE

Posted: Wed Mar 25, 2026 6:26 pm
by hs1994
Hello,

I am currently running a heavily modified cts_cent example. I am able to connect and bond with the target device and exchange IRK.

Now, I need to enable RPA to perform the connections. So far, I was able to connect using a Random Static address, but never as Resolvable Private address. The documentation seems to point to functions that are only applicable to Host Based Privacy. However, ESP32-S3 uses Controller Based Privacy, which causes several functions at "ble_hs_pvcy.h" to become unavailable.

I have tried calling several function combinations, but to no avail.

Currently, I have the following relevant lines of code:

Code: Select all

ble_hs_cfg.sm_our_key_dist = BLE_SM_PAIR_KEY_DIST_ID | BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_SIGN;  
    ble_hs_cfg.sm_their_key_dist = BLE_SM_PAIR_KEY_DIST_ENC | BLE_SM_PAIR_KEY_DIST_SIGN;

Code: Select all

static void
ble_cts_cent_on_sync(void)
{
    int rc;

    // Enable RPA capability
    rc = ble_hs_pvcy_set_resolve_enabled(true);
    assert(rc == 0);

    // Generate Random Static Address
    ble_addr_t out_addr = {
        .type = BLE_ADDR_PUBLIC,
        .val = {0},
    };
    ble_hs_id_gen_rnd(0, &out_addr);
    ble_hs_id_set_rnd(out_addr.val);

    // Configure the ESP with a Bluetooth MAC Address
    rc = ble_hs_util_ensure_addr(1);
    assert(rc == 0);

    /* Begin scanning for a peripheral to connect to. */
    ble_cts_cent_scan();
}
Then, on the connect function, I have the following:

Code: Select all

static void
ble_cts_cent_connect_if_interesting(void *disc)
{
    uint8_t own_addr_type;
    int rc = 0;
    ble_addr_t *addr;

    /* Scanning must be stopped before a connection can be initiated. */
    rc = ble_gap_disc_cancel();

    /* Figure out address to use while connecting*/
    rc = ble_hs_id_infer_auto(1, &own_addr_type);

    printf("\nAddress type: %d\n", own_addr_type);

    if (rc != 0)
    {
        printf("\n\nError determining address type; rc=%d\n", rc);
        return;
    }

    /* Try to connect the the advertiser.  Allow 30 seconds (30000 ms) for
     * timeout.
     */
    addr = &((struct ble_gap_disc_desc *)disc)->addr;

    // Set connection parameters to T4H default values
    struct ble_gap_conn_params params = {
        .scan_itvl = 0x0010,
        .scan_window = 0x0010,
        .itvl_max = 8,
        .itvl_min = 8,
        .latency = 49,
        .supervision_timeout = 300,
        .min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN,
        .max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN,

    };

    rc = ble_gap_connect(own_addr_type, addr, 30000, &params,
                         ble_cts_cent_gap_event, NULL);
    if (rc != 0)
    {
        printf("\n\nError: Failed to connect to device; addr_type=%d "
               "addr=%s; rc=%d\n",
               addr->type, addr_str(addr->val), rc);
        return;
    }
}
Furthermore, I see ble_gap_connect() being called with own_addr_type = 0x03, which is what I expect it to be (BLE_OWN_ADDR_RPA_RANDOM_DEFAULT), however using a BLE sniffer i see the address as Static instead of Resolvable.

Thanks in advance