Can't connect to device in the whitelist

Hello everyone,

I am using a nRF52840 as a central device to scan and connect to peripherals using the whitelist. I have a peripheral that doesn't support pairing (it's a pulse oximeter), but since I am using the whitelist to scan and filter the other devices I am working with, I decided to manually add the address of this pulse oximeter to the whitelist. For the record, I have done this with another peripheral and checked that the procedure works.

Anyways, I add the peripheral address to the whitelist and print all the addresses stored in the whitelist to make sure I am scanning for the peripherals correctly.

This is where my problem happens: Even thought the address of the pulse oximeter shows up in the whitelist, when I turn on the device, it doesn't get connected to the central. 



This is the code I am using to store the address in the whitelist. manually. It is not mine, I got it from another forum a long time ago but I lost the link .-.

static void onWhitelistRequest(void) {
  
  ret_code_t err_code;
  BondedDeviceInfo_t bonded_devices_info[ADDRESSES_IN_WHITELIST] = {0};
  uint16_t           bonded_devices_count = 0;
  uint8_t            i, j;
  uint64_t aux_konsung_mac = 0;
  uint64_t aux_berry_mac = 0;
  ble_gap_addr_t konsung_mac = {0};
  ble_gap_addr_t berry_mac = {0};

// Extract info from FLASH
  getDevices(bonded_devices_info, &bonded_devices_count);

  for(j = 0; j < bonded_devices_count; j++) {
    if(strcmp(bonded_devices_info[j].tag, "pleth sonosat") == 0) {
      aux_konsung_mac = bonded_devices_info[j].mac_address;
    } else if (strcmp(bonded_devices_info[j].tag, "pleth bm1000") == 0) {
      aux_berry_mac = bonded_devices_info[j].mac_address;
    }
  }

  for (j = 0; j < 6; j++) {
    konsung_mac.addr[j] = (aux_konsung_mac >> (j*8)) & 0xFF;
    berry_mac.addr[j] = (aux_berry_mac >> (j*8)) & 0xFF;
  }

  konsung_mac.addr_type = BLE_UUID_TYPE_UNKNOWN;
  berry_mac.addr_type = BLE_UUID_TYPE_UNKNOWN;

  // Whitelist buffers.
  ble_gap_addr_t whitelist_addrs[ADDRESSES_IN_WHITELIST];
  ble_gap_irk_t  whitelist_irks[ADDRESSES_IN_WHITELIST];

  memset(whitelist_addrs, 0x00, sizeof(whitelist_addrs));
  memset(whitelist_irks, 0x00, sizeof(whitelist_irks));

  uint32_t addr_cnt = (sizeof(whitelist_addrs) / sizeof(ble_gap_addr_t));
  uint32_t irk_cnt = (sizeof(whitelist_irks) / sizeof(ble_gap_irk_t));

  // Reload the whitelist and whitelist all peers.
  whitelistLoad();

  // Get the whitelist previously set using pm_whitelist_set().
  err_code =
      pm_whitelist_get(whitelist_addrs, &addr_cnt, whitelist_irks, &irk_cnt);

  /* Check if the pulse oximeter has been already detected, if so, 
    add to the whitelist if necessary. */
    
    // add Konsung manually to whitelist
  bool bPresent = false;
  if (aux_konsung_mac) {
    
    for(uint8_t i = 0; i < addr_cnt; i++) {
            // Loop through all addresses in the whitelist table.
        if(strcmp(whitelist_addrs[i].addr, konsung_mac.addr) == 0) {
            // Address is present in whitelist.
            PRINT_INFO("Konsung already in whitelist\n");
            bPresent = true;
        }
    }

    if(bPresent == false) {
            whitelist_addrs[addr_cnt] = konsung_mac;
            addr_cnt++;

            ble_gap_addr_t const * p_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];

            for (uint32_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++)
            {
                p_addr[i] = &whitelist_addrs[i];
            }
  
            err_code = sd_ble_gap_whitelist_set(p_addr, addr_cnt);
            APP_ERROR_CHECK(err_code);
    }

  }
  
   // add Berry manually to whitelist **PROBLEM HERE**
  bPresent = false;
  if (aux_berry_mac) {
    for(uint8_t i = 0; i < addr_cnt; i++) {
      // Loop through all addresses in the whitelist table.
      if(strcmp(whitelist_addrs[i].addr, berry_mac.addr) == 0) {
            // Address is present in whitelist.
            PRINT_INFO("Berry already in whitelist\n");
            bPresent = true;
      }
    }

    if(bPresent == false) {
            whitelist_addrs[addr_cnt] = berry_mac;
            addr_cnt++;

            ble_gap_addr_t const * p_addr[BLE_GAP_WHITELIST_ADDR_MAX_COUNT];

            for (uint32_t i = 0; i < BLE_GAP_WHITELIST_ADDR_MAX_COUNT; i++)
            {
                p_addr[i] = &whitelist_addrs[i];
            }
  
            err_code = sd_ble_gap_whitelist_set(p_addr, addr_cnt);
            APP_ERROR_CHECK(err_code);
    }
  }

  PRINT_DEBUG("Address count: %d, IRK count: %d\n", addr_cnt, irk_cnt);

  for (int i = 0; i < addr_cnt; i++) {
    PRINT_DEBUG("Scanning for address: %02X %X %X %X %X %X \n", whitelist_addrs[i].addr[5],
                whitelist_addrs[i].addr[4], whitelist_addrs[i].addr[3], whitelist_addrs[i].addr[2],
                whitelist_addrs[i].addr[1], whitelist_addrs[i].addr[0]);
  }


  if (((addr_cnt == 0) && (irk_cnt == 0)) || (g_whitelist_disabled)) {
    // Don't use whitelist.
    err_code = nrf_ble_scan_params_set(&m_scan, NULL);
    APP_ERROR_CHECK(err_code);
  }
}


NOTE: The strategy to manually add an address to the whitelist works for the Konsung peripheral (already tested in another firmware). However, it doesn't work for the Berry peripheral.

Thank you very much for your help,

PD: I am using SDK v17.1

Parents
  • Hi,

    Does it work / are you able to connect if you don't use whitelisting? If yes, can you double-check that you are whitelisting the right address? A quite common mistake when working manually with BLE addresses is to get the endianness wrong, so it could be worth trying to swap it.

    If that does not work, perhaps you can elaborate a bit on the issue and what you have found from debugging. Does the central attempt to connect at all? What do you see from a sniffer trace? And do you have some logging on the nRF that could tell us something?

  • Hello Einar, thank you for your response! To answer your questions:

    • Yes, I am able to connect without whitelist.
    • I tried swapping the address and it doesn't work either.
    • I will provide some debugging.

    I have a theoretical question: Are the peer address and the device MAC address the same? Because, right now what I am storing in the whitelist is the MAC address of the pulse oximeter.

    Thank you again

  • Hi,

    Yes, this gives a bit more overview. The fact that there is no connection attempt is important.

    I see you specify the address type (addr_type) as BLE_UUID_TYPE_UNKNOWN which does not really make sense, but this is defined to 0, so it is the same as if you used BLE_GAP_ADDR_TYPE_PUBLIC. The address might not be public though, and if so the bits indicating address type are 00 (see this good intro), which point to this being the fairly unusual type Non-Resolvable Random Private Address. That immediately seems a bit strange though, as you should see the address change from time to time in this case, and as it is non-resolvable you would not be able to know that it is the same device after the address changes. So it cold be that the address really is public or that I missed something.

    If you don't make progress, perhaps you can test with an nRF spoofing the same address, and make your central implementation connect to that, to make it easier to tweek things and test? Then I can test on my end as well. (To make a peripheral with a specific address, just take a peripheral example and add a call to sd_ble_gap_addr_set() right after initializing the SoftDevice.see for instance  this thread).

  • Hello, Einar. That was actually very helpful specifically because, sometimes, right after I add the address to the whitelist, a Whitelist advertisement report occurs and this is the debug message I get:

    As you can see, the peer address of the device seems to have changed (?). That might point to the fact that the device does have a Non-Resolvable Random Private Address (also, the fact that the MSB are 00 too). Is there a way I can confirm this?

    Additionally, I will try what you suggested about spoofing the address and let you know what I find out.

    Thank you!

  • Hello Einar, I was debugging my program and I check for the properties of the address in the advertisement report. It is a Non-Resolvable Random Private Address indeed.



     
    That means I can't use the whitelist to scan for it, right? Do you have any idea of how I could scan for this device and using the whitelist simultaneously?

    Thank you so much in advance!

  • Hi,

    When a non-public address has the two most significant bits set to 00, that means that it is using a non-resolvable random address. And as you also see the address changing that sort of confirms it (without if it was not for the fact that the two bits tell us otherwise, it could also have been a resolvable random address if you only consider that the address is changing).

    That means that there is no way to filter on the address of this device. And if you use whitelisting, you will not be able to include this device when scanning with a whitelist. An alternative could be to alternate between scanning with whitelist for all the other devices, and scanning without a whitelist, but filtering on some other parts of the advertising packet if possible. Is there any other data there that you can use to identify this device? If not, it is simply not possible (and that is the whole point of a random private address, in order to prevent tracking).

    PS: For completeness, let me just mention that if the device had been using a resolvable private address, then you would get it's identity resolving key (IRK) when bonding, and could use that to recognize the device even when it changes addresses. That is not relevant here, though, as then the two most significant bits in the address should have been 10.

  • Okay, Einar. Thank you very much for your help! That solves my question. I will try to find a way to filter the data coming from that device.

Reply Children
No Data
Related