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?
Parents
  • PS: if I try to call bt_id_create later after some time, to manually create a new ID, it returns error -12. Is this ENOMEM? Sounds strange, since there is still lots of memory free.

  • Hello,

    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().

    The static address value must be specified if you are calling this function before bt_enable(). From the API documentation:

    "Generating random static address or random IRK is not supported when calling this function before bt_enable()."

    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?

    Are you looking at the address included in the advertisment packet? This should include the private resolvable address generated from the IRK you made. It is not the same as the random static address generated by bt_id_create() 

    frankbuss said:
    if I try to call bt_id_create later after some time, to manually create a new ID, it returns error -12. Is this ENOMEM? Sounds strange, since there is still lots of memory free.

    It will try to create a new ID when you call it after bt_enable() and settings load, which means you need to allocate buffer for additional IDs through the CONFIG_BT_ID_MAX symbol.

    Best regards,

    Vidar

  • It should be sufficient to build with CONFIG_BT_PRIVACY=y and CONFIG_BT_SMP=y to enable address rotation as far as I know. The advertisement address should then be updated after every CONFIG_BT_RPA_TIMEOUT seconds.

    Please double check that both of the symbols above are enabled in your build.

  • Yes, both symbols are set to Y, and for testing I tried CONFIG_BT_RPA_TIMEOUT=5. I added a few BT_INFO messages in bt_id_set_private_addr in id.c and can see that it is called in 5 s intervals, but looks like BT_DEV_RPA_VALID is only after reset 0, so the message BT_INFO("RPA: %s", bt_addr_str(&rpa)); at the end is only printed once. Tested with sd-nrf v2.1.0. But I guess this didn't change much, the current master version of the function looks the same:
    https://github.com/intel/zephyr/blob/main/subsys/bluetooth/host/id.c#L213

    I can try to verify it with one of the sample apps, if you like. I have a nRF5340 DK. Which sample app would be useful for testing the Bluetooth address rotation?

  • 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.

Reply Children
Related