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

best way to retrieve latest used BLE bonding infos using SDK16 peer manager library

To the kind attention of Nordic support team,

I was reading in peer_manager library that when a ble connection is established, using the connection handler as a parameter should be possible to retrieve the index in the peer database
where those connections infos are stored (pm_peer_id_get). I suppose we can manually save that 'last valid connection index'.

After that, when we want to advertise again (and make a decision about the type of advertising) we could call pm_peer_count to see if there are valid peers. In that case we could retrieve that saved 'last valid connection index' and use it as a parameter to call pm_peer_data_bonding_load.

In case latest valid ble connection has got a long term key (LTK) saved, it makes sense to try a directed advertising, I think (could you please confirm?).
What it is not clear to me, if we have to manually save that last valid connection index.
Probably there is a peer_manager routine that is doing that, so that I can retrieve bonding infos of latest used connection by only calling a suitable library routine. 

Also in case of directed advertising, we should be sure that it times out, or at least that we can advertise for other host to scan, in case the directed adv. host is missing.

When doing directed advertising yesterday I noticed that over about 20 tries, the internal prototype  experienced a couple of resets. I don't know if it is a software issue or an energetic one (could you briefly argument something about that please).

So my question: is there a peer manager library routine so to retrieve latest used bonding infos related to latest connection? Should I save 'manually' that index I was talking about?

Thank you very much for your precious help

Best regards

Parents
  • Hello,

    Directed advertising is usually targeted towards the last connected GAP central, so all you really need to keep track of is one peer id. The ble_app_hids_* examples in SDK 17 demonstrates how this adv. mode can be implemented.

    When doing directed advertising yesterday I noticed that over about 20 tries, the internal prototype  experienced a couple of resets. I don't know if it is a software issue or an energetic one (could you briefly argument something about that please).

     The most common reason for sudden resets are code assertions. I suggest you build the project with the "DEBUG" flag to trap all errors instead of letting the Error module reset the device. Do you have debug logging enabled to see if any errors are reported?

    Best regards,

    Vidar

Reply
  • Hello,

    Directed advertising is usually targeted towards the last connected GAP central, so all you really need to keep track of is one peer id. The ble_app_hids_* examples in SDK 17 demonstrates how this adv. mode can be implemented.

    When doing directed advertising yesterday I noticed that over about 20 tries, the internal prototype  experienced a couple of resets. I don't know if it is a software issue or an energetic one (could you briefly argument something about that please).

     The most common reason for sudden resets are code assertions. I suggest you build the project with the "DEBUG" flag to trap all errors instead of letting the Error module reset the device. Do you have debug logging enabled to see if any errors are reported?

    Best regards,

    Vidar

Children
  • Thank you very much Vidar Berg. 

    "Directed advertising is usually targeted towards the last connected GAP central, so all you really need to keep track of is one peer id. "

    At the moment we are using sdk16 and ble_advertising_start(&m_advertising,BLE_ADV_MODE_DIRECTED_HIGH_DUTY) so to successfully start directed adv.

    We want to trigger that routine with BLE_ADV_MODE_DIRECTED_HIGH_DUTY parameter, only if last connection is still a valid bond.

    Otherwise, we want to trigger ble_advertising_start using BLE_ADV_MODE_FAST.

    We are putting to the test something like this:

    /**@brief Function for initializing the Advertising functionality. */
    static void advertising_init(void) 
    {
    	uint32_t err_code;
    	uint8_t adv_flags;
    	ble_advertising_init_t init;
    
    	memset(&init, 0, sizeof(init));
    
    	adv_flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    	init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
    	init.advdata.include_appearance = true;
    	init.advdata.flags = adv_flags;
    	init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    	init.advdata.uuids_complete.p_uuids = m_adv_uuids;
    
            #if SWIFT_PAIR_SUPPORTED == 1
            init.advdata.p_manuf_specific_data = &m_sp_manuf_advdata;
            memcpy(&m_sp_advdata, &init.advdata, sizeof(m_sp_advdata));
            #endif
    
    	init.config.ble_adv_whitelist_enabled = true;
    	init.config.ble_adv_directed_high_duty_enabled = true;
    	init.config.ble_adv_directed_enabled = true;
    	init.config.ble_adv_directed_interval = APP_ADV_FAST_INTERVAL;
    	init.config.ble_adv_directed_timeout = APP_ADV_FAST_DURATION;
    	init.config.ble_adv_fast_enabled = true;
    	init.config.ble_adv_fast_interval = APP_ADV_FAST_INTERVAL;
    	init.config.ble_adv_fast_timeout = APP_ADV_FAST_DURATION;
    	init.config.ble_adv_slow_enabled = true;
    	init.config.ble_adv_slow_interval = APP_ADV_SLOW_INTERVAL;
    	init.config.ble_adv_slow_timeout = APP_ADV_SLOW_DURATION;
    
    	init.evt_handler = on_adv_evt;
    	init.error_handler = ble_advertising_error_handler;
    
    	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);
    }

    Then:

    /**@brief Function for starting advertising. */
    pm_peer_data_bonding_t bonding_data;
    pm_peer_data_bonding_t * p_data = &bonding_data;
    void StartAdvertising(void *p_erase_bonds) 
    {
    	bool erase_bonds = *(bool *)p_erase_bonds;
    
    	if(erase_bonds) 
    	{
    		DeleteBonds();
    		// Advertising is started by PM_EVT_PEERS_DELETE_SUCCEEDED event.
    	}
    	else 
    	{
                //LastConnectionIndexRead(&connIndex);
                if(pm_peer_count() > 0)
                {                  
                    // there are valid peers
                    pm_peer_data_bonding_load((pm_peer_id_t) 0, p_data);
                    //NRF_LOG_INFO("ble retrieved index: %x", connIndex);
    
                    NRF_LOG_INFO("ADV_DIRECTED_IND");
                    NRF_LOG_INFO("PEER BLE ADDRESS: ");
                    NRF_LOG_HEXDUMP_INFO(p_data->peer_ble_id.id_addr_info.addr, 6);
    
                    ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
                    APP_ERROR_CHECK(err_code);
                }
                else
                {
                     NRF_LOG_INFO("ADV_IND");
                     whitelist_set(PM_PEER_ID_LIST_SKIP_NO_ID_ADDR);
    
                     ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
                     APP_ERROR_CHECK(err_code);                     
                }
    	}
    }

    Does it makes sense? Basically here we are doing adv_ind if there are no valid bonding entries, otherwise we start high duty directed advertising. Is it formally correct according to your experience and sdk16? 

    If not, what would be the better way to proceed?

    Thank you

  • Thank you Vidar Berg very much, now it is much more clear to me:

    In sdk16 we had to keep track of latest pm_peer_id (pm_peer_id_get after a new connection) save in flash using fds and use it as a parameter to pm_peer_data_bonding_load when starting a new directed advertisement.

    Please note that when inserting a passkey, pm_peer_id is invalid, but with very little of magic using Nordic pm_peer_count it is very simple to sort everything out.

    Thank you

  • But this is the very best solution: 

    pm_peer_ranks_get(&m_peer_id, NULL, NULL, NULL);
Related