problems with bt_id_create

The documentation here:

https://docs.zephyrproject.org/apidoc/latest/group__bt__gap.html#gae11eb8ad254418c38a0e8689df25a159

says, I can call bt_id_create() before bt_enable(). I tried it like this:

uint8_t irk[16] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };

int err = bt_id_create(BT_ADDR_LE_ANY, irk);
if (err < 0) {
  LOG_ERROR("bt_id_create failed (err %d)", err);
}

and I get a -22 as the error code. Do I call the function with the right arguments, and what does error -22 mean? I guess it is EINVAL, but I don't see any invalid argument.
So I tried to call it after bt_enable(). This resulted in a log message like this:
[00:00:11.336,578] <inf> bt_hci_core: Identity: 00:00:00:00:00:00 (public)    
and obviously any call to other functions, like start advertise, doesn't work anymore, because it is an invalid BLE address.
So finally I called bt_id_create() in the ble_ready callback, before the settings_load() call. This seems to work, I get a random BLE address.
But "bt show-id" shows always the same address (after reset). I set CONFIG_BT_RPA_TIMEOUT to 60, looks like it is ignored. But after reset, I get a new BLE address, so seems to work in general, just the automatic change doesn't work. How can I fix this?
  • Yes, it would be nice if you could try run this slightly modified version of the peripheral_hr_coded sample on your DK:

    peripheral_hr_rpa_test.zip

    Here is the UART log I get with CONFIG_BT_LOG_SNIFFER_INFO enabled:

    *** Booting Zephyr OS build v3.1.99-ncs1-1  ***
    Starting Bluetooth Peripheral HR coded example
    I: HW Platform: Nordic Semiconductor (0x0002)
    I: HW Variant: nRF53x (0x0003)
    I: Firmware: Standard Bluetooth controller (0x00) Version 41.37468 Build 2457941745
    I: Identity: F8:D7:8F:38:73:2B (random)
    I: IRK: 0xae859352e2d8b16650a43e62abf82b48
    I: HCI: version 5.3 (0x0c) revision 0x21d8, manufacturer 0x0059
    I: LMP: version 5.3 (0x0c) subver 0x21d8
    Bluetooth initialized
    I: RPA: 5F:43:AA:1A:09:63
    Created adv: 0x20000e08
    Advertiser 0x20000e08 set started
    I: RPA: 70:51:05:05:51:3D
    I: RPA: 58:6A:70:8D:D8:47
    I: RPA: 6E:8A:4F:C3:8B:E2
    I: RPA: 54:27:38:CB:43:F0
    I: RPA: 67:10:20:F7:72:FA
    

  • Thanks, your sample project works. But it doesn't work in my application. I've reduced it to a minimal app to demonstrate the problem (built with "west build -p always --board=nrf5340dk_nrf5340_cpuapp") :
    https://frank-buss.de/tmp/nrf-test.zip
    It advertises only the Bluetooth name, and provides OTA update (the private key in the sample app is the developer test key, in our app we have our own key), same as in our production app.

    I found a workaround by stopping and starting the advertisement regularly. You can see this in line 81 and following in main.c. If this code block is included, then a new Bluetooth address is created every 5 seconds.

    But I think this is a hack and a bug in the nRF framework. As I understand it, if the Bluetooth address is visible from outside, then it should be always recycled as specified in CONFIG_BT_RPA_TIMEOUT, if the BT_PRIVACY setting is enabled and an identity is available. No matter what other settings etc. are used.

  • Looks like manually calling "le_rpa_invalidate()" works as well to force a new RPA, but of course, not a good solution.

  • It looks like the reason my sample worked, and yours didn't, is that I was using the advertising extension APIs rather than the legacy APIs. Like you said, the RPA is not being invalidated when it is supposed to. This causes the address rotation to be skipped on every RPA timeout. 

    I cherry picked the last three commits in the PR below, and that seems to have fixed the problem (note that this PR has not been merged yet).

    https://github.com/zephyrproject-rtos/zephyr/pull/51258 

    Log from your test sample after applying the fix:

  • Thanks. So I'll use the workaround, and will remove it, once we update to the latest Zephyr, when the PR is merged, and a new Zephyr version is released.

Related