Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Switching Between Connectable Advertising and Beacon Advertising On BLE_GAP_EVT_ADV_SET_TERMINATED

Hi, I have the following code in main.c:

static void on_adv_evt(ble_adv_evt_t ble_adv_evt)
{
    ret_code_t err_code;

    switch (ble_adv_evt)
    {
        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:
						  NRF_LOG_INFO("AVD EVT IDLING");
					switch (advertising_mode_state)
					{
						case 1:          //advertising_beacon
						{
//									sd_ble_gap_adv_stop();
							connectable_advertising_init();
							advertising_start(BLE_ADV_MODE_SLOW);
							break;
						}
						case 2:          // advertising_connectable
						{
							beacon_advertising_init();
							advertising_start(BLE_ADV_MODE_SLOW);
							break;
						}
					}

        default:
            break;
    }
}


.
.
.
.


/**@brief Function for initializing the Advertising functionality.
 */
static void connectable_advertising_init(void)
{
	  NRF_LOG_INFO("Connectable ADV INIT");
    ret_code_t             err_code;
    ble_advertising_init_t init;

    memset(&init, 0, sizeof(init));
	
	  ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
    uint8_t data                              = UNIT_SERIAL; //Our data to advertise
    manuf_data.data.p_data                    = &data;
    manuf_data.data.size                      = sizeof(data);
    init.advdata.p_manuf_specific_data = &manuf_data;


    init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance      = false;
    init.advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    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_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;

    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);
		
		advertising_mode_state = 2;
		
}

/**@brief Function for initializing the Advertising functionality.
 */
static void beacon_advertising_init(void)
{
	
		NRF_LOG_INFO("Beacon ADV INIT");
	/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data =
{
    .adv_data =
    {
        .p_data = m_enc_advdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    },
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0

    }
};

	
	static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] =                    /**< Information advertised by the Beacon. */
{
    APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                         // implementation.
    APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                         // manufacturer specific data in this implementation.
    APP_BEACON_UUID,     // 128 bit UUID value.
    APP_MAJOR_VALUE,     // Major arbitrary value that can be used to distinguish between Beacons.
    APP_MINOR_VALUE,     // Minor arbitrary value that can be used to distinguish between Beacons.
    APP_MEASURED_RSSI    // Manufacturer specific information. The Beacon's measured TX power in
                         // this implementation.
};

	  uint32_t      err_code;
    ble_advdata_t advdata;
    uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;

    ble_advdata_manuf_data_t manuf_specific_data;

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;

#if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
    // If USE_UICR_FOR_MAJ_MIN_VALUES is defined, the major and minor values will be read from the
    // UICR instead of using the default values. The major and minor values obtained from the UICR
    // are encoded into advertising data in big endian order (MSB First).
    // To set the UICR used by this example to a desired value, write to the address 0x10001080
    // using the nrfjprog tool. The command to be used is as follows.
    // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val <your major/minor value>
    // For example, for a major value and minor value of 0xabcd and 0x0102 respectively, the
    // the following command should be used.
    // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val 0xabcd0102
    uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16;
    uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF);

    uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO;

    m_beacon_info[index++] = MSB_16(major_value);
    m_beacon_info[index++] = LSB_16(major_value);

    m_beacon_info[index++] = MSB_16(minor_value);
    m_beacon_info[index++] = LSB_16(minor_value);
#endif
	
	    manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
    manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;

    // Build and set advertising data.
		NRF_LOG_INFO("Build and set advertising data");
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type             = BLE_ADVDATA_NO_NAME;
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

    // Initialize advertising parameters (used when starting advertising).
		NRF_LOG_INFO("Initialize advertising parameters");
    memset(&m_adv_params, 0, sizeof(m_adv_params));

    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;
    m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = APP_ADV_DURATION; 

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    APP_ERROR_CHECK(err_code);
		NRF_LOG_INFO("Encode Finished");

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
		NRF_LOG_INFO("Err Code: %d", err_code);
    APP_ERROR_CHECK(err_code);
		NRF_LOG_INFO("Configure Finished");
		
    advertising_mode_state = 1;

}


.
.
.
.

/**@brief Function for starting connectable advertising.
 */
static void advertising_start(bool erase_bonds)
{
	
				NRF_LOG_INFO("Entering Connectable Advertising Start");
	
    if (erase_bonds == true)
    {
        delete_bonds();
        // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED event
    }
    else
    {
        ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
		    NRF_LOG_INFO("Err Code: %d", err_code);
        APP_ERROR_CHECK(err_code);
    }
			  NRF_LOG_INFO("Leaving Connectable Advertising Start");
}

/**@brief Function for starting beacon advertising.
 */
/*static void beacon_advertising_start(void)
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);
	
	  NRF_LOG_INFO("Leaving Beacon Advertising Start");
	
}
*/

/**@brief Function for changing the tx power.
 */
static void tx_power_set(void)
{
    ret_code_t err_code = sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV, m_advertising.adv_handle, TX_POWER_LEVEL);
    APP_ERROR_CHECK(err_code);
}
/**@brief Function for enabling the DC/DC Converter.
 */
static void dcdc_enable_init(void)
{
	sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
}

/**@brief Function for application main entry.
 */
int main(void)
{
    bool erase_bonds = false;

    // Initialize.
    log_init();
    timers_init();
//    buttons_leds_init(&erase_bonds);
    power_management_init();
    ble_stack_init();
//		timeslot_sd_init();
		adc_configure();
    gap_params_init();
    gatt_init();
		services_init();
    beacon_advertising_init();
    conn_params_init();
    peer_manager_init();
		dcdc_enable_init();

    // Start execution.
    NRF_LOG_INFO("Service started.");
    application_timers_start();
    advertising_start(erase_bonds);
		tx_power_set();

    // Enter main loop.
    for (;;)
    {
        idle_state_handle();
    }
}

If I initialize the beacon advertising first, which is the shown configuration, I get fatal error code 8 out of ble_advertising_start.

If I initialize the connectable advertising first, it does time out and as intended and tries to initialize  beacon_advertising_init() in on_adv_event, but fails with err code 4 at sd_ble_gap_adv_set_configure

I think I am really close here -- any thoughts on what I am doing wrong?

Parents
  • In my attempting to solve this problem, I thought the problem may be in my advertising data, so I have restructured the code and for the time being, removed the beacon advertising initialization, just attempting to get the connectable advertising to work with sd_ble_gap_adv_start. The program runs with no errors, but even though it exits the start_advertising with nrf_success, I get no noticeable advertising when scanning with nrf connect. 

    /**@brief Function for initializing the connectable advertisement parameters.
     *
     * @details This function initializes the advertisement parameters to values that will put
     *          the application in connectable mode.
     *
     */
    static void connectable_adv_init(void)
    {
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        m_adv_params.duration        = APP_ADV_DURATION;
    
        m_adv_params.p_peer_addr   = NULL;
        m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval      = APP_ADV_INTERVAL;
        m_adv_params.primary_phy   = BLE_GAP_PHY_1MBPS;
    }
    
    
    /**@brief Function for initializing the Advertising functionality.
     */
    static void advertising_init(void)
    {
        ret_code_t               err_code;
        ble_advdata_t            advdata;
        ble_advdata_manuf_data_t manuf_data;
        uint8_t                  flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        APP_ERROR_CHECK_BOOL(sizeof(flags) == ADV_FLAGS_LEN);  // Assert that these two values of the same.
    
        // Build and set advertising data
        memset(&advdata, 0, sizeof(advdata));
    
        manuf_data.company_identifier = COMPANY_IDENTIFIER;
        manuf_data.data.size          = ADV_ADDL_MANUF_DATA_LEN;
        manuf_data.data.p_data        = m_addl_adv_manuf_data;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_data;
    
        if(m_is_non_connectable_mode)
        {
            err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, NULL, &m_adv_params);
            APP_ERROR_CHECK(err_code);
        }
        else
        {
            err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    /**@brief Function for initializing buttons and leds.
     *
     * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
     */
    /*static void buttons_leds_init(bool * p_erase_bonds)
    {
        ret_code_t err_code;
        bsp_event_t startup_event;
    
        err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    
        *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
    }*/
    
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details If there is no pending log operation, then sleep until next the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
    
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    	  NRF_LOG_INFO("err_code: %d", err_code);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
    
        // Initialize.
        log_init();
        timers_init();
        power_management_init();
        ble_stack_init();
    	  adc_configure();
    	  NRF_LOG_INFO("adc congigured.");
        gap_params_init();
    	  NRF_LOG_INFO("gap params init.");
        gatt_init();
    	  NRF_LOG_INFO("gatt init.");
    		services_init();
    	  NRF_LOG_INFO("services init.");
    	  connectable_adv_init();
    	  NRF_LOG_INFO("connectable adv init.");
        advertising_init();
    	  NRF_LOG_INFO("adv init.");
        conn_params_init();
    	  NRF_LOG_INFO("conn params init.");
        peer_manager_init();
    		NRF_LOG_INFO("peer mngr init.");
    
        // Start execution.
        NRF_LOG_INFO("Template example started.");
        application_timers_start();
    
        advertising_start();
    		NRF_LOG_INFO("Advertising Started");
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }
    
    
    /**
     * @}
     */
    
     

Reply
  • In my attempting to solve this problem, I thought the problem may be in my advertising data, so I have restructured the code and for the time being, removed the beacon advertising initialization, just attempting to get the connectable advertising to work with sd_ble_gap_adv_start. The program runs with no errors, but even though it exits the start_advertising with nrf_success, I get no noticeable advertising when scanning with nrf connect. 

    /**@brief Function for initializing the connectable advertisement parameters.
     *
     * @details This function initializes the advertisement parameters to values that will put
     *          the application in connectable mode.
     *
     */
    static void connectable_adv_init(void)
    {
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        m_adv_params.duration        = APP_ADV_DURATION;
    
        m_adv_params.p_peer_addr   = NULL;
        m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval      = APP_ADV_INTERVAL;
        m_adv_params.primary_phy   = BLE_GAP_PHY_1MBPS;
    }
    
    
    /**@brief Function for initializing the Advertising functionality.
     */
    static void advertising_init(void)
    {
        ret_code_t               err_code;
        ble_advdata_t            advdata;
        ble_advdata_manuf_data_t manuf_data;
        uint8_t                  flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        APP_ERROR_CHECK_BOOL(sizeof(flags) == ADV_FLAGS_LEN);  // Assert that these two values of the same.
    
        // Build and set advertising data
        memset(&advdata, 0, sizeof(advdata));
    
        manuf_data.company_identifier = COMPANY_IDENTIFIER;
        manuf_data.data.size          = ADV_ADDL_MANUF_DATA_LEN;
        manuf_data.data.p_data        = m_addl_adv_manuf_data;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_data;
    
        if(m_is_non_connectable_mode)
        {
            err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, NULL, &m_adv_params);
            APP_ERROR_CHECK(err_code);
        }
        else
        {
            err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    /**@brief Function for initializing buttons and leds.
     *
     * @param[out] p_erase_bonds  Will be true if the clear bonding button was pressed to wake the application up.
     */
    /*static void buttons_leds_init(bool * p_erase_bonds)
    {
        ret_code_t err_code;
        bsp_event_t startup_event;
    
        err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_event_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_btn_ble_init(NULL, &startup_event);
        APP_ERROR_CHECK(err_code);
    
        *p_erase_bonds = (startup_event == BSP_EVENT_CLEAR_BONDING_DATA);
    }*/
    
    
    /**@brief Function for initializing the nrf log module.
     */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details If there is no pending log operation, then sleep until next the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
    
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    	  NRF_LOG_INFO("err_code: %d", err_code);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for application main entry.
     */
    int main(void)
    {
    
        // Initialize.
        log_init();
        timers_init();
        power_management_init();
        ble_stack_init();
    	  adc_configure();
    	  NRF_LOG_INFO("adc congigured.");
        gap_params_init();
    	  NRF_LOG_INFO("gap params init.");
        gatt_init();
    	  NRF_LOG_INFO("gatt init.");
    		services_init();
    	  NRF_LOG_INFO("services init.");
    	  connectable_adv_init();
    	  NRF_LOG_INFO("connectable adv init.");
        advertising_init();
    	  NRF_LOG_INFO("adv init.");
        conn_params_init();
    	  NRF_LOG_INFO("conn params init.");
        peer_manager_init();
    		NRF_LOG_INFO("peer mngr init.");
    
        // Start execution.
        NRF_LOG_INFO("Template example started.");
        application_timers_start();
    
        advertising_start();
    		NRF_LOG_INFO("Advertising Started");
    
        // Enter main loop.
        for (;;)
        {
            idle_state_handle();
        }
    }
    
    
    /**
     * @}
     */
    
     

Children
No Data
Related