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

app_error_fault_handler occurs when starting direct advertisement

Hi.

I'm trying to use direct advertising to connect only with devices that have already been paired.

When I start direct advertising, I get a app_error_fault_handler.

Whitelist is not used.

I initialized the advertisement as follows.

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_LIMITED_DISC_MODE;
    init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
    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;

    init.config.ble_adv_whitelist_enabled          = false;
    init.config.ble_adv_directed_high_duty_enabled = true;
    init.config.ble_adv_directed_enabled           = true;
    init.config.ble_adv_directed_interval          = 40;
    init.config.ble_adv_directed_timeout           = 128;
    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);
}

And after successful pairing, the peer ID is stored in the FDS.

static void pm_evt_handler(pm_evt_t const * p_evt)
{
......

    case PM_EVT_PEER_DATA_UPDATE_SUCCEEDED:
        err_code = pm_peer_id_get(m_conn_handle , &peer_id);

	    APP_ERROR_CHECK(err_code);
	
	    if(peer_id == PM_PEER_ID_INVALID)
	    {
	        StoreBlePeerID(); //Peer ID store to FDS
	    }

.....
}

And when the system is turned off, BLE is disconnected.
If the system is turned on later, Advertise starts using ble_advertising_start(&m_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY).

static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
........

case BLE_ADV_EVT_PEER_ADDR_REQUEST:
		GetBlePeerID(&CurPeerId); //Read stored peer id to FDS
			
		err_code = pm_peer_data_bonding_load(CurPeerId, &peer_bonding_data);
		if (err_code != NRF_ERROR_NOT_FOUND)
		{
			APP_ERROR_CHECK(err_code);
				
			// Manipulate identities to exclude peers with no Central Address Resolution.
			identities_set(PM_PEER_ID_LIST_SKIP_ALL);
				
			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);
		}
		else
		{
			null();
		}
		break; 

........
}

BLE_ADV_EVT_DIRECTED_HIGH_DUTY event occurs after responding to peer address in on_adv_evt, but app_error_fault_handler is occurs immediately.

I can't figure out why. Am I doing anything wrong?

Parents
  • Hi

    What advertising parameters have you set? Error code 7 points towards invalid parameters. What are you updating your advertising parameters to do? I.E. what PHY are you advertising on, and what BLE_GAP_ADV_TYPE are you advertising on for instance?

    Directed advertising only makes sense once bonded, since you then know which device you should advertise to. Also, please note that directed advertising is the only suitable for some special occasions, such as HID mouse and keyboards where you want very fast direct advertisement after a connection loss in order to seamlessly reconnect. You may not see so easily how this is done in the example since it uses the advertising module. Essentially the advertising module starts with the most aggressive and most restrictive advertising mode, and goes down the list, subsequently using each mode until it's timeout as long as it is enabled.

    Bluetooth sniffer devices and the apps like nRFConnect that are designed to pick up any Bluetooth advertisement will see devices that use directed advertisements (before they are bonded to a device). Most other scanning devices filter out these however.

    Best regards,

    Simon

Reply
  • Hi

    What advertising parameters have you set? Error code 7 points towards invalid parameters. What are you updating your advertising parameters to do? I.E. what PHY are you advertising on, and what BLE_GAP_ADV_TYPE are you advertising on for instance?

    Directed advertising only makes sense once bonded, since you then know which device you should advertise to. Also, please note that directed advertising is the only suitable for some special occasions, such as HID mouse and keyboards where you want very fast direct advertisement after a connection loss in order to seamlessly reconnect. You may not see so easily how this is done in the example since it uses the advertising module. Essentially the advertising module starts with the most aggressive and most restrictive advertising mode, and goes down the list, subsequently using each mode until it's timeout as long as it is enabled.

    Bluetooth sniffer devices and the apps like nRFConnect that are designed to pick up any Bluetooth advertisement will see devices that use directed advertisements (before they are bonded to a device). Most other scanning devices filter out these however.

    Best regards,

    Simon

Children
  • Hi,

    I will briefly show you my source code.

    void Update_AdvData( uint8_t ChannelData, bool StartState)
    {
    	uint32_t               err_code;	
    	ble_advdata_t          advdata;	
    	ble_advdata_manuf_data_t manuf_data;
    	
    	memset(&advdata, 0, sizeof(advdata));	
    	memset(&manuf_data, 0, sizeof(manuf_data));
    	
    	advdata.name_type               = BLE_ADVDATA_FULL_NAME;
    	advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
    	advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    	advdata.uuids_complete.p_uuids  = m_adv_uuids;
    			
    	manuf_data.company_identifier        = APP_COMPANY_IDENTIFIER;
    
    	if(StartState == TRUE)
    	{
    		ChannelData |= BIT7;
    	}
    	else
    	{
    		ChannelData &= ~BIT7;
    	}
    	
    	manuf_data.data.p_data               = &ChannelData;
    	manuf_data.data.size                 = sizeof(ChannelData);
    	advdata.p_manuf_specific_data   = &manuf_data;
    	
    	
    	advdata.p_tx_power_level = SC_TX_POWER_LEVEL_0DBM;
    
    	err_code = ble_advertising_advdata_update(&m_advertising, &advdata, NULL);
    	APP_ERROR_CHECK(err_code);
    }

    Things have changed slightly now.

    1. Device starts fast advertise

    2. BLE_ADV_EVT_FAST_WHITELIST event occurs

    3. After a while, stop Advertise using sd_ble_gap_adv_stop(m_advertising.adv_handle).

    4. Update p_manuf_specific_data in Update_AdvData().

    5. BLE_ERROR_GAP_DISCOVERABLE_WITH_WHITELIST is returned from ble_advertising_advdata_update().

    It seems to be caused by sd_ble_gap_adv_set_configure().

    What did I do wrong?

    I want to change p_manuf_specific_data on every Advertise.

Related