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

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

Related