This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Scanning cannot find Public MAC

Hello:

I have set the scanning module to search devices by MAC address.  It finds the devices that are using a Static Random address, but it cannot find the ones using a Public Static address.

I can see and connect to both using NRF Connect BLE.  I am using the Rigardo module.

Here is the code I use to start the scanning module:

ret_code_t connect_to_mac(uint8_t mac[]) {
  ret_code_t err_code;
  if (isConnected()) {
    uint8_t mac[6];
    getCurrentMac(mac);
    disconnect_from_mac(mac);
  }
  nrf_ble_scan_stop();
  nrf_ble_scan_all_filter_remove(&m_scan);

  nrf_ble_scan_init_t init_scan;

  ble_gap_addr_t m_mac_filter;
  m_mac_filter.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
  err_code = nrf_ble_scan_copy_addr_to_sd_gap_addr(&m_mac_filter, mac);

  if (err_code == NRF_SUCCESS) {
    memset(&init_scan, 0, sizeof(init_scan));

    init_scan.connect_if_match = true;
    init_scan.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
    m_mac_filter.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
    err_code = nrf_ble_scan_init(&m_scan, &init_scan, scan_evt_handler);
    if (err_code == NRF_SUCCESS) {
      err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, &m_mac_filter.addr);
    }
    if (err_code == NRF_SUCCESS) {
      err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
    }
    if (err_code == NRF_SUCCESS) {
      err_code = scan_start();
      if (err_code == NRF_SUCCESS) {
#ifdef DEBUG
        char *msg = malloc(255);
        sprintf(msg, "SCANNING FOR %x:%x:%x:%x:%x:%x TYPE %d",
            m_mac_filter.addr[0],
            m_mac_filter.addr[1],
            m_mac_filter.addr[2],
            m_mac_filter.addr[3],
            m_mac_filter.addr[4],
            m_mac_filter.addr[5],
            m_mac_filter.addr_type);
        err_code = sendStatusToUART(msg);
        free(msg);
#else
        err_code = sendStatusToUART(STATUS_SCANNING);
#endif
      }
    }
    BLE_ERROR_CHECK(err_code);
  } else {
    sendErrorToUART(ERROR_INVALID_MAC);
  }

  return err_code;
}

Can you please point me to any ideas?  The only difference between the two devices is that one MAC is public (using Rigardo defined hardware address) and the other is Random Static.

Are there any limitations on the softdevice for hardware public address?

Thanks,

Juan

Parents
  • I have followed the comments from Kenneth (https://devzone.nordicsemi.com/f/nordic-q-a/44653/scan-address-filter-not-matching-addr_type-public-vs-random_static)

        case BLE_GAP_EVT_ADV_REPORT: {
          char* msg = malloc(256);
          memset(msg,0,256);
          sprintf(msg, "FOUND ADDRESS %x:%x:%x:%x:%x:%x TYPE %d RESPONSE %d",
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[0],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[1],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[2],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[3],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[4],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[5],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr_type,
              p_ble_evt->evt.gap_evt.params.adv_report.type.scan_response);
          sendStatusToUART(msg);
          free(msg);
          break;
        }
        

    The report shows:

    FOUND ADDRESS 25:9a:5c:93:54:94 TYPE 0 RESPONSE 1

    Which shows me that it should be matched (that's the sought mac)... any ideas?  

    Thanks,

    Juan

Reply
  • I have followed the comments from Kenneth (https://devzone.nordicsemi.com/f/nordic-q-a/44653/scan-address-filter-not-matching-addr_type-public-vs-random_static)

        case BLE_GAP_EVT_ADV_REPORT: {
          char* msg = malloc(256);
          memset(msg,0,256);
          sprintf(msg, "FOUND ADDRESS %x:%x:%x:%x:%x:%x TYPE %d RESPONSE %d",
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[0],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[1],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[2],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[3],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[4],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr[5],
              p_ble_evt->evt.gap_evt.params.adv_report.peer_addr.addr_type,
              p_ble_evt->evt.gap_evt.params.adv_report.type.scan_response);
          sendStatusToUART(msg);
          free(msg);
          break;
        }
        

    The report shows:

    FOUND ADDRESS 25:9a:5c:93:54:94 TYPE 0 RESPONSE 1

    Which shows me that it should be matched (that's the sought mac)... any ideas?  

    Thanks,

    Juan

Children
  • And now I am retrieving the filters after I start scanning, and here is what I see the problem happening.

     [ ... ]
     
        err_code = scan_start();
          if (err_code == NRF_SUCCESS) {
            char *msg = malloc(255);
            memset(msg, 0, 255);
            sprintf(msg, "SCANNING FOR %x:%x:%x:%x:%x:%x TYPE %d",
                m_mac_filter.addr[0],
                m_mac_filter.addr[1],
                m_mac_filter.addr[2],
                m_mac_filter.addr[3],
                m_mac_filter.addr[4],
                m_mac_filter.addr[5],
                m_mac_filter.addr_type);
            err_code = sendStatusToUART(msg);
            nrf_ble_scan_filters_t filters;
            memset(&filters, 0, sizeof(nrf_ble_scan_filters_t));
            memset(msg, 0, 255);
            nrf_ble_scan_filter_get( &m_scan, &filters);
            sprintf(msg, "FILTERS: COUNT=%d ENABLED=%d ADDRESS=%x:%x:%x:%x:%x:%x TYPE=%d",
                filters.addr_filter.addr_cnt,
                filters.addr_filter.addr_filter_enabled,
                filters.addr_filter.target_addr[0].addr[0],
                filters.addr_filter.target_addr[0].addr[1],
                filters.addr_filter.target_addr[0].addr[2],
                filters.addr_filter.target_addr[0].addr[3],
                filters.addr_filter.target_addr[0].addr[4],
                filters.addr_filter.target_addr[0].addr[5],
                filters.addr_filter.target_addr[0].addr_type);
            err_code = sendStatusToUART(msg);
            free(msg);
        }
        

    And I am getting the following:

    SCANNING FOR 25:9a:5c:93:54:94 TYPE 0

    FILTERS: COUNT=1 ENABLED=1 ADDRESS=25:9a:5c:93:54:94 TYPE=2

    For some reason, the scanning module is replacing the address type to

    BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE

    When the address is of type BLE_GAP_ADDR_TYPE_PUBLIC.

    Now, looking at the code on the SDK, the function that determines the type of address is

    nrf_ble_scan_address_type_decode

    And it checks if it is public by the code:

     // See Bluetooth Core Specification Vol 6, Part B, section 1.3.
        addr_type  = addr_type >> 6;
        addr_type &= 0x03;

    In my case, the first byte is 94, which 96 >> 6 is 1, so it resolves as Public.  But once the scanning starts, it gets resolved otherwise.

    Does anyone know how can I fix this?  Is this a bug in the SDK ?  (I am using version 16, softdevice 7.0.1 for s104)

    Thanks,

    Juan

  • So for those who may be under the same fight... I hacked the code by:

     if (err_code == NRF_SUCCESS) {
          err_code = nrf_ble_scan_filter_set(&m_scan, SCAN_ADDR_FILTER, &m_mac_filter.addr);
        }
        if (err_code == NRF_SUCCESS) {
          // hack this:
          m_scan.scan_filters.addr_filter.target_addr[0].addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
          err_code = nrf_ble_scan_filters_enable(&m_scan, NRF_BLE_SCAN_ADDR_FILTER, false);
        }

    And it all works.  Far from ideal, but solves my problem.

    If anyone knows a non-hacked solution, please let me know.

    Juan

  • I am happy you found a solution and thanks for sharing it. I've not had time to figure out a non-hacked solution to your problem, but let's go with your solution temporary. If you encounter any problems with this solution, please tell me and I will look into it.

    Best regards,

    Simon

  • Thanks.  This will work for us for now.  But is not a sustainable solution, as we will have to find out if the address is public or private on our own, instead of using the SDK; or do all sort of IF statements to make sure the filter is set properly.

    Cheers,

    Juan

  • This might be a bug. I will talk to the developers and try to get to the bottom of it.

    Best regards,

    Simon

Related