NRF52840 BLE address can't be resolved

Hi,

I've designed a product based on nrf52840 soc as a central Bluetooth device. I want to pair and connect to a Bluetooth device (as a slave) that implements a whitelist. 

when the slave is in the pairing mode, nrf52840 can successfully connect and pair with it in the lesc numeric comparison mode ( you can see the pairing process in the lesc_dynamic_pairing(clear).pcapng sniffer trace which I've attached). but after that, when the slave is in the connection mode, the slave device doesn't respond to the SCAN_REQ and CONNECT_IND request of the nrf52840 (you can see this problem in the lesc_dynamic_connection(clear).pcapng sniffer trace in the packet no.192 and no.199). 

After submitting an engineering issue with the company which has produced the slave device, they said that this problem occurred when the address of the central(in our case nrf52840) can't be resolved.

now my question is, are anything is missed in the pairing process according to the sniffer trace which can cause this problem? I've settled up the random resolvable address with the below code snippet.

ble_gap_privacy_params_t privacy_params = {
	.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY,
	.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE,
	.private_addr_cycle_s = BLE_GAP_DEFAULT_PRIVATE_ADDR_CYCLE_INTERVAL_S,
	.p_device_irk = 0
  };
  APP_ERROR_CHECK(sd_ble_gap_privacy_set(&privacy_params));

I want to point out that the slave device works without a problem with the windows and android phones.

lesc_dynamic_pairing(clear).pcapng

lesc_dynamic_connection(clear).pcapng

  • Hi,

    Please try to call pm_privacy_set() with the same parameters right after pm_init() instead of calling sd_ble_gap_privacy_set() directly. Also make sure you are *not* calling pm_privacy_set() sd_ble_gap_addr_set() anywhere in your code as noted in the pm_privacy_set() documentation.

    Best regards,

    Vidar

    Edit: Sorry, I meant to say sd_ble_gap_addr_set() not pm_privacy_set(). See edit above.

  • thanks for your reply, 

    I applied it but I've got the same result. I've attached the sniffer trace for it (for simplicity the IRK is =0x0102030405060708090a0b0c0d0e0f10)

    pair.pcapng

    conection.pcapng

  • To @Notdic_Developers,

    This case may cause the failure of my project and is very crucial,

    Is there any way to be sure that the address is resolvable with the indicated IRK?

    Is there any central example with the random resolvable address which help me to solve the problem?

  • Hi,

    I modified the ble_hrs_c example to connect to our ble_app_hid_keyboard example in nRF5 SDK 17.1.0 which has whitelist advertising enabled by default to see if I could replicate the problem on my end, but haven't had any luck with that thus far.

    Here is my modified project:

    ble_app_hrs_c_privacy.zip

    I also tried to validate the address from you sniffer trace with the IRK exchanged during bonding. Seems like it's not matching, but I need to double check that I got the endianess right.

    /* Initiator address used on reconnect - packet # 199 in lesc_dynamic_connection(clear).pcapng */
        uint8_t local_addr [] = {0x39, 0x62, 0xe8, 0xe9, 0xa3, 0x73};
        ble_gap_addr_t addr;
        addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
        memcpy(addr.addr, local_addr, sizeof(addr.addr));
        ble_gap_irk_t irk; 
        /* Local IRK exchanged during bonding - packet #302 in lesc_dynamic_pairing */
        uint8_t local_irk [] = {0x6c, 0x7a, 0x96, 0x9c, 0x63, 0xac, 0x3a, 0xe7, 0x3d, 0xf2, 0x29, 0x5f, 0xab, 0xd6, 0xe4, 0x28};
        mempcpy(&irk, local_irk, sizeof(irk));
        bool match = pm_address_resolve(&addr, &irk);
        NRF_LOG_INFO("IRK match address: %s", (match) ? "True" : "False");

    Update: I was able to confirm that the address used on re-connect matches the IRK exchanged during bonding. The reason I didn't get a match earlier is that I used the wrong byte order for the IRK (the sniffer is already displaying it as little-endian, and not in big-endian like the address).

        uint8_t local_addr [] = {0x39, 0x62, 0xe8, 0xe9, 0xa3, 0x73};
        ble_gap_addr_t addr;
        addr.addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
        memcpy(addr.addr, local_addr, sizeof(addr.addr));
        ble_gap_irk_t irk; 
        uint8_t local_irk [] = {0x28, 0xe4, 0xd6, 0xab, 0x5f, 0x29, 0xf2, 0x3d, 0xe7, 0x3a, 0xac, 0x63, 0x9c, 0x96, 0x7a, 0x6c};
        mempcpy(&irk, local_irk, sizeof(irk));
    
        bool match = pm_address_resolve(&addr, &irk);
    
        NRF_LOG_INFO("IRK match address: %s", (match) ? "True" : "False"); 

    Did you get a chance to try my example to see if it had the same connection issue?

Related