This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Directed advertising with pre-shared IRK

Hello, I'd like to do directed avertising to a central which has a random private resolvable address. My idea: both devices share a pre-defined IRK so the peripheral can compute the central's address and start advertising to this address. According to the core specs v4.2 this should be possible.

p.118: An initiator that receives a directed connectable advertising event that contains a resolvable private address for the initiator’s address, (InitA field) shall resolve the private address using the Local IRK values (see Section 1.3.2.3)

I've modified the central and peripheral examples of the experimental ble_app_blinky so I can work with directed advertising and this setup is working fine when using random static addresses. But as soon as I activate privacy on the central, the central does not react to advertising (i.e. no bluetooth stack event is generated).

On the central I'm using the following code to set privacy:

privacy.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
privacy.private_addr_cycle_s = 15*60;
privacy.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
privacy.p_device_irk = &irk;
sd_ble_gap_privacy_set(&privacy);

On the peripheral I start advertising as follows:

generate_hash(prand,hash,irk);   // generates correct hash, verified
peer_addr.addr_type=BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
peer_addr.addr[0]=hash[0];
peer_addr.addr[1]=hash[1];
peer_addr.addr[2]=hash[2];
peer_addr.addr[3]=prand[0];
peer_addr.addr[4]=prand[1];
peer_addr.addr[5]=prand[2];  // 0b01xxxxxx

memset(&adv_params, 0, sizeof(adv_params));
adv_params.type        = BLE_GAP_ADV_TYPE_ADV_DIRECT_IND; 
adv_params.p_peer_addr = &peer_addr;
adv_params.fp          = BLE_GAP_ADV_FP_ANY;
adv_params.interval    = APP_ADV_INTERVAL;
adv_params.timeout     = APP_ADV_TIMEOUT_IN_SECONDS;
err_code = sd_ble_gap_adv_start(&adv_params);

What am I missing?

nrf52 S132 SoftDevice v3.0.0 API

  • Thanks for the comment Petter Myhre, I found the part I was missing in your link.

    In the scanning device right before starting to scan I've added the advertiser's identity with

    const ble_gap_id_key_t m_peer1 = {
      .id_addr_info = {
        .addr_type = BLE_GAP_ADDR_TYPE_RANDOM_STATIC,
        .addr = {0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xfX},},
      .id_info ={
          .irk = {0x00,0x01,0x02,0x03,...,0x0F},}
    };
    const ble_gap_id_key_t * m_identities[] = {&m_peer1};
    
    sd_ble_gap_device_identities_set(m_identities,NULL,1);
    

    Now the device responds to the advertising, but connection is not possible so far. Interestingly, the address type of the id key must be of type random static in order to make it work, although the advertiser is not using this address type. I'm still confused how I have to set this up correctly.

  • I haven't tested this myself, but I would think it would be something like this:

    const ble_gap_id_key_t m_peer1 = {
      .id_info ={
          .irk = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F},}
    };
    const ble_gap_id_key_t * m_identities[] = {&m_peer1};
    
    err_code = sd_ble_gap_device_identities_set(m_identities,NULL,1);
    APP_ERROR_CHECK(err_code);
    

    I don't think you should set id_addr_info and id_info.

  • I guess you're right, not both should be set. I tested with a private peer + only id_info and static peer + only id_addr_info and it seems to work that way. But still, no connection so far. Initiator replies with a connection request and then seems to stop.

  • Ok. I'll see if I can make a small example. Let me know if you have any news.

Related