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

How to resolve Initiator's address when direct advertising?

How to push Initiator to resolve its private address (seen at direct_addr of adv_report) when bonded private Advertiser does a direct advertising?

I need the only Initiator's own address to be resolved (based on device IRK) because I use software whitelisting for the reason of more than 8 peers so I don't call sd_ble_gap_whitelist_set() nether sd_ble_gap_device_identities_set(). As a consequence of no calls of these functions BLE_GAP_EVT_ADV_REPORT isn't fired when scan filter is BLE_GAP_SCAN_FP_ACCEPT_ALL. To receive adv reports filter should be changed to BLE_GAP_SCAN_FP_ALL_NOT_RESOLVED_DIRECTED but sd_ble_gap_connect() doesn't accept such setup.

I suppose the solution may be in pp_local_irks of sd_ble_gap_device_identities_set() but I can't get in mind how to use that based on description presented on Infocenter.

My case is most matched to variants #3 and #4 of Scan Private Devices MSC with the only difference: Advertiser's address shall remain unresolved because I'll resolve and whitelist it within BLE_GAP_EVT_ADV_REPORT handler by myself.

  • Hi,

    I am sorry for the late reply. I have been testing a bit and discussing with a SoftDevice developer, but we are not sure what is happening.

    A common problem when you want to advertise to the initiator's resolvable address is that you must make sure that your own address is also resolvable. This does not seem to be the problem in this case since you wrote "both use sd_ble_gap_privacy_set()", though.

    Would it be possible for you to make the small modifications to the example that you described so that we know that we are looking at the same code as you are?

    Edit: Can you verify that the address type in the call to sd_ble_gap_privacy_set() is BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE in both ends?

  • Dear Einar, may I know what you've tested exactly? Have you got a setup/code which meets your expectation or BLE specification? I do still prefer you to take a pair of examples from SDK, enable the privacy on both ends then check how the direct advertising works - this will be a really clear test.

    My central and peripherals use the same code to enable the privacy:

    ble_gap_privacy_params_t privacy_params = {0};
    
    privacy_params.privacy_mode      = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
    privacy_params.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
    APP_ERROR_CHECK(sd_ble_gap_privacy_set(&privacy_params));

  • Hi,

    I have tested with the following central and peripheral modifications from the HRS examples in SDK 15.3 and see similar behavior, but I have not understood what causes this. I am discussing with the SoftDevice team, so hopefully, we should have some results soon.

    diff --git a/examples/ble_peripheral/ble_app_hrs/main.c b/examples/ble_peripheral/ble_app_hrs/main.c
    index 9b0167e..3363c32 100644
    --- a/examples/ble_peripheral/ble_app_hrs/main.c
    +++ b/examples/ble_peripheral/ble_app_hrs/main.c
    @@ -85,7 +85,7 @@
     #define DEVICE_NAME                         "Nordic_HRM"                            /**< Name of device. Will be included in the advertising data. */
     #define MANUFACTURER_NAME                   "NordicSemiconductor"                   /**< Manufacturer. Will be passed to Device Information Service. */
     #define APP_ADV_INTERVAL                    300                                     /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
    -
    +#define APP_ADV_DIRECT_INTERVAL                    300                                     /**< The advertising interval (in units of 0.625 ms. This value corresponds to 187.5 ms). */
     #define APP_ADV_DURATION                    18000                                   /**< The advertising duration (180 seconds) in units of 10 milliseconds. */
     
     #define APP_BLE_CONN_CFG_TAG                1                                       /**< A tag identifying the SoftDevice BLE configuration. */
    @@ -121,7 +121,7 @@
     
     #define SEC_PARAM_BOND                      1                                       /**< Perform bonding. */
     #define SEC_PARAM_MITM                      0                                       /**< Man In The Middle protection not required. */
    -#define SEC_PARAM_LESC                      1                                       /**< LE Secure Connections enabled. */
    +#define SEC_PARAM_LESC                      0                                       /**< LE Secure Connections enabled. */
     #define SEC_PARAM_KEYPRESS                  0                                       /**< Keypress notifications not enabled. */
     #define SEC_PARAM_IO_CAPABILITIES           BLE_GAP_IO_CAPS_NONE                    /**< No I/O capabilities. */
     #define SEC_PARAM_OOB                       0                                       /**< Out Of Band data not available. */
    @@ -129,7 +129,7 @@
     #define SEC_PARAM_MAX_KEY_SIZE              16                                      /**< Maximum encryption key size. */
     
     #define DEAD_BEEF                           0xDEADBEEF                              /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */
    -
    +static uint32_t m_peer_count = 0;
     
     BLE_HRS_DEF(m_hrs);                                                 /**< Heart rate service instance. */
     BLE_BAS_DEF(m_bas);                                                 /**< Structure used to identify the battery service. */
    @@ -158,6 +158,8 @@ static ble_uuid_t m_adv_uuids[] =                                   /**< Univers
         {BLE_UUID_DEVICE_INFORMATION_SERVICE,   BLE_UUID_TYPE_BLE}
     };
     
    +static pm_peer_id_t      m_peer_id = PM_PEER_ID_INVALID;                                 /**< Device reference handle to the current bonded central. */
    +
     
     /**@brief Callback function for asserts in the SoftDevice.
      *
    @@ -201,9 +203,19 @@ void advertising_start(bool erase_bonds)
         else
         {
             ret_code_t err_code;
    -
    -        err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    -        APP_ERROR_CHECK(err_code);
    +    
    +        if (m_peer_count > 0)
    +        {
    +            NRF_LOG_INFO("Start directed advertising");
    +            err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_DIRECTED);
    +            APP_ERROR_CHECK(err_code);
    +        }
    +        else
    +        {
    +            NRF_LOG_INFO("Start fast advertising");
    +            err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    +            APP_ERROR_CHECK(err_code);
    +        }
         }
     }
     
    @@ -662,15 +674,50 @@ static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
     
         switch (ble_adv_evt)
         {
    +        case BLE_ADV_EVT_DIRECTED_HIGH_DUTY:
    +            NRF_LOG_INFO("High Duty Directed advertising.");
    +            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_DIRECTED);
    +            APP_ERROR_CHECK(err_code);
    +            break;
    +
    +        case BLE_ADV_EVT_DIRECTED:
    +            NRF_LOG_INFO("Directed advertising.");
    +            err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING_DIRECTED);
    +            APP_ERROR_CHECK(err_code);
    +            break;
    +
             case BLE_ADV_EVT_FAST:
                 NRF_LOG_INFO("Fast advertising.");
                 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_PEER_ADDR_REQUEST:
    +        {
    +            NRF_LOG_INFO("Peer addr request");
    +            
    +            pm_peer_data_bonding_t peer_bonding_data;
    +
    +            if (m_peer_id == PM_PEER_ID_INVALID)
    +            {
    +                m_peer_id = pm_next_peer_id_get(PM_PEER_ID_INVALID);
    +            }
    +
    +            // Only Give peer address if we have a handle to the bonded peer.
    +            if (m_peer_id != PM_PEER_ID_INVALID)
    +            {
    +                err_code = pm_peer_data_bonding_load(m_peer_id, &peer_bonding_data);
    +                if (err_code != NRF_ERROR_NOT_FOUND)
    +                {
    +                    APP_ERROR_CHECK(err_code);
    +
    +                    ble_gap_addr_t * p_peer_addr = &(peer_bonding_data.peer_ble_id.id_addr_info);
    +                    err_code = ble_advertising_peer_addr_reply(&m_advertising, p_peer_addr);
    +                    APP_ERROR_CHECK(err_code);
    +                }
    +            }
    +            
    +        } break; //BLE_ADV_EVT_PEER_ADDR_REQUEST
     
             default:
                 break;
    @@ -690,7 +737,8 @@ static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
         switch (p_ble_evt->header.evt_id)
         {
             case BLE_GAP_EVT_CONNECTED:
    -            NRF_LOG_INFO("Connected.");
    +            NRF_LOG_INFO("Connected. Type: %u. Addr:", p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr_type);
    +            NRF_LOG_HEXDUMP_INFO(p_ble_evt->evt.gap_evt.params.connected.peer_addr.addr, BLE_GAP_ADDR_LEN);
                 err_code = bsp_indication_set(BSP_INDICATE_CONNECTED);
                 APP_ERROR_CHECK(err_code);
                 m_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    @@ -783,6 +831,12 @@ static void ble_stack_init(void)
     
         // Register a handler for BLE events.
         NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    +
    +    // Configure privacy
    +    pm_privacy_params_t privacy_params = {0};
    +    privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
    +    privacy_params.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
    +    pm_privacy_set(&privacy_params);
     }
     
     
    @@ -875,6 +929,10 @@ static void advertising_init(void)
         init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
         init.advdata.uuids_complete.p_uuids  = m_adv_uuids;
     
    +    init.config.ble_adv_directed_enabled  = true;
    +    init.config.ble_adv_directed_high_duty_enabled = true;
    +    init.config.ble_adv_directed_interval          = APP_ADV_DIRECT_INTERVAL;
    +    init.config.ble_adv_directed_timeout           = 1000;
         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;
    @@ -939,10 +997,7 @@ static void idle_state_handle(void)
         err_code = nrf_ble_lesc_request_handler();
         APP_ERROR_CHECK(err_code);
     
    -    if (NRF_LOG_PROCESS() == false)
    -    {
    -        nrf_pwr_mgmt_run();
    -    }
    +    nrf_pwr_mgmt_run();
     }
     
     
    @@ -966,8 +1021,13 @@ int main(void)
         conn_params_init();
         peer_manager_init();
     
    +
         // Start execution.
         NRF_LOG_INFO("Heart Rate Sensor example started.");
    +
    +    m_peer_count = pm_peer_count();
    +    NRF_LOG_INFO("Peer count: %u", m_peer_count);
    +
         application_timers_start();
         advertising_start(erase_bonds);
     
    

    diff --git a/examples/ble_central/ble_app_hrs_c/main.c b/examples/ble_central/ble_app_hrs_c/main.c
    index 3325cfd..2954d70 100644
    --- a/examples/ble_central/ble_app_hrs_c/main.c
    +++ b/examples/ble_central/ble_app_hrs_c/main.c
    @@ -85,7 +85,7 @@
     
     #define SEC_PARAM_BOND              1                                   /**< Perform bonding. */
     #define SEC_PARAM_MITM              0                                   /**< Man In The Middle protection not required. */
    -#define SEC_PARAM_LESC              1                                   /**< LE Secure Connections enabled. */
    +#define SEC_PARAM_LESC              0                                   /**< LE Secure Connections enabled. */
     #define SEC_PARAM_KEYPRESS          0                                   /**< Keypress notifications not enabled. */
     #define SEC_PARAM_IO_CAPABILITIES   BLE_GAP_IO_CAPS_NONE                /**< No I/O capabilities. */
     #define SEC_PARAM_OOB               0                                   /**< Out Of Band data not available. */
    @@ -904,7 +904,6 @@ static void idle_state_handle(void)
         err_code = nrf_ble_lesc_request_handler();
         APP_ERROR_CHECK(err_code);
         
    -    NRF_LOG_FLUSH();
         nrf_pwr_mgmt_run();
     }
     
    @@ -930,6 +929,28 @@ void scanning_start(bool * p_erase_bonds)
     }
     
     
    +void use_privacy(void)
    +{
    +    ret_code_t err_code;
    +
    +    // Configure privacy
    +    pm_privacy_params_t privacy_params = {0};
    +    privacy_params.privacy_mode = BLE_GAP_PRIVACY_MODE_DEVICE_PRIVACY;
    +    privacy_params.private_addr_type = BLE_GAP_ADDR_TYPE_RANDOM_PRIVATE_RESOLVABLE;
    +    pm_privacy_set(&privacy_params);
    +
    +    // Log IRK in order to use it in peripheral
    +    ble_gap_privacy_params_t current_privacy_params = {0};
    +    ble_gap_irk_t 	         curretn_irk = {0};
    +    current_privacy_params.p_device_irk = &curretn_irk;
    +    err_code = sd_ble_gap_privacy_get(&current_privacy_params);
    +    APP_ERROR_CHECK(err_code);
    +    
    +    NRF_LOG_INFO("Own IRK:");
    +    NRF_LOG_HEXDUMP_INFO(current_privacy_params.p_device_irk, 16);
    +}
    +
    +
     int main(void)
     {
         bool erase_bonds;
    @@ -942,6 +963,9 @@ int main(void)
         ble_stack_init();
         gatt_init();
         peer_manager_init();
    +
    +    use_privacy();
    +
         db_discovery_init();
         hrs_c_init();
         bas_c_init();
    

  • Dear Einar, have you also checked the second issue I pointed here? I suspect both issues share the same deep root in SoftDevice.

  • Hi,

    Yes, I saw that as well. Some of the developers in the SoftDevice team are looking more into this now. I will keep you posted.

Related