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

BLE peripheral whitelist advertising

Dear all,

Can I achieve ble peripheral whitelist advertising without peer manager? (Assuming central address is already known)

Following are several places that I've modified based on ble_app_uart but it will cause an assert:

First part is whitelist address function.

static void whitelist_set()
{
	ble_gap_addr_t peer_address;
	ble_gap_addr_t const *p_peer_address;
	uint32_t err_code;
	
	/*
	Traget central addr:0x15ca97ce14f4
	*/
	peer_address.addr[5] = 0x15;
	peer_address.addr[4] = 0xca;
	peer_address.addr[3] = 0x97;
	peer_address.addr[2] = 0xce;
	peer_address.addr[1] = 0x14;
	peer_address.addr[0] = 0xf4;
	p_peer_address = &peer_address;
	
	err_code = sd_ble_gap_whitelist_set(&p_peer_address, 0x01);
	APP_ERROR_CHECK(err_code);
}

adding previous function into BLE_ADV_EVT_WHITELIST_REQUEST

static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    uint32_t err_code;

    switch (ble_adv_evt)
    {
        case BLE_ADV_EVT_FAST:
            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
            APP_ERROR_CHECK(err_code);
            break;
        case BLE_ADV_EVT_IDLE:
            sleep_mode_enter();
            break;
		case BLE_ADV_EVT_WHITELIST_REQUEST:
            whitelist_set();
			break; //BLE_ADV_EVT_WHITELIST_REQUEST
        default:
            break;
    }
}

Enabling the whitelist in adv parameters.

static void advertising_init(void)
{
    uint32_t               err_code;
    ble_advertising_init_t init;

    memset(&init, 0, sizeof(init));

    init.advdata.name_type          = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance = false;
    init.advdata.flags              = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;

    init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.srdata.uuids_complete.p_uuids  = m_adv_uuids;

    init.config.ble_adv_fast_enabled  = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout  = APP_ADV_DURATION;
    init.evt_handler = on_adv_evt;

		/* Modified parts */
		init.config.ble_adv_whitelist_enabled          = true;
    init.config.ble_adv_directed_high_duty_enabled = true;
    init.config.ble_adv_directed_enabled           = false;
    init.config.ble_adv_directed_interval          = 0;
    init.config.ble_adv_directed_timeout           = 0;
	
    err_code = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
}

Did I implement anything wrong or did I miss anything?

Thanks,

Ava

Parents Reply Children
  • Hi,

    I did above modifications based on ble_app_uart SDK16 but I received "fatal error".

    To solve this, here are several attempts I've done:

    1. I left      " init.config.ble_adv_whitelist_enabled "      to be false and it runs the same behavior with original ble_app_uart sample
    2. Based on last post, I added address type so the code was like:
      static void whitelist_set()
      {
      	ble_gap_addr_t peer_address;
      	ble_gap_addr_t const *p_peer_address;
      	uint32_t err_code;
      	
      	/*
      	Target addr:0x15ca97ce14f4
      	*/
      	memset(&peer_address, 0x00, sizeof(peer_address));  //New added
      	peer_address.addr_id_peer = 1;  //New added
      	peer_address.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
      	peer_address.addr[5] = 0x15;
      	peer_address.addr[4] = 0xca;
      	peer_address.addr[3] = 0x97;
      	peer_address.addr[2] = 0xce;
      	peer_address.addr[1] = 0x14;
      	peer_address.addr[0] = 0xf4;
      	p_peer_address = &peer_address;
      	
      	err_code = sd_ble_gap_whitelist_set(&p_peer_address, 0x01);
      	APP_ERROR_CHECK(err_code);
      }
      but I'm not quite sure which address type is to be selected so I tried both. The performance is quite different:
      1. when it is BLE_GAP_ADDR_TYPE_PUBLIC, the system runs but without address filtering function
      2. when it is BLE_GAP_ADDR_TYPE_RANDOM_STATIC,the system runs into an assert and I received "fatal error"

    Which setting should I apply? I'm still looking for the causing of the assert.

    Thanks,

    Ava

  • Hi,

    Seems like the assert occurs here:

    err_code = sd_ble_gap_whitelist_set(&p_peer_address, 0x01);
    APP_ERROR_CHECK(err_code);

    When peer_address_type is selected to BLE_GAP_ADDR_TYPE_RANDOM_STATIC, it will assert...

  • Hi,

    When you say assert I assume you means that the error handler has detected an error? If you make a debug build (define "DEBUG") and enable logging I expect you will get more information. Alternatively, place a breakpoint on the line after the call to sd_ble_gap_whitelist_set() and inspect the return value. Looking at the address from your previous post I see it is not a valid static address (the 5th byte does not have the two most significant bits set). Therefor, it is expected that the call returns NRF_ERROR_INVALID_ADDR. The address type you specify must correspond with the address itself.

  • Thanks Einar,

    I'm trying to figure it out.

    BTW, what's the different between those address types?

    Basically I'll connect a peripheral to ble_app_uart_central to check its address. More specifically, the peripheral address will be printed here(in scan_evt_handler):

             case NRF_BLE_SCAN_EVT_CONNECTED:
             {
                  ble_gap_evt_connected_t const * p_connected =
                                   p_scan_evt->params.connected.p_connected;
                 // Scan is automatically stopped by the connection.
    							printf("Connecting to target %02x%02x%02x%02x%02x%02x",
                          p_connected->peer_addr.addr[0],
                          p_connected->peer_addr.addr[1],
                          p_connected->peer_addr.addr[2],
                          p_connected->peer_addr.addr[3],
                          p_connected->peer_addr.addr[4],
                          p_connected->peer_addr.addr[5]
                          );
             } break;

    What address type is this? If I burn new program(central) into the same device, does the address remain the same?

    If so, if I wanna put this address into the whitelist, which address type should I select?

    Thanks,

    Ava

  • Hi Ava,

    Avadacadabara said:
    BTW, what's the different between those address types?

    This page has a good explanation of the different address types.

    Avadacadabara said:
    What address type is this?

    Looking at the code snippet from your post a few days ago, where the most significant byte was 0x15, you can look at the two most significant bits to see that the address type there is private resolvable. This is typically used by modern mobile phones for instance. Note that the upper bits does not have this meaning for a public address so it cannot be ruled out by looking at this. That means that there could also be another issue here instead.

    Avadacadabara said:
    If I burn new program(central) into the same device, does the address remain the same?

    If the central is using private resolvable address, then the address change regularly.

    Avadacadabara said:
    If so, if I wanna put this address into the whitelist, which address type should I select?

    If this is as it seems private resolvable address then you should select BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE. Note that if the central is using a resolvable private address then whitelisting like this will not work. That is because the address will change regularly, and in that case you will need to obtain the Identity Resolution Key (IRK) in order to make whitelisting work even as the address change. And to obtain this the devices need to pair, and then the IRK is exchanged during the pairing process (if you have another method to obtain the IRK that would also work, but the only standard way to exchange it is via pairing).

Related