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

How to switch the functions between beacon advertising to connectable advertising?

Hello, I want to switch the functions between beacon advertising to connectable advertising.

In the code , it can be initial as a beacon advertising or normal advertising ( connectable advertising), then switch to another.

My main code as below:

/**@brief Function for initializing the Advertising functionality.
 *
 * @details Encodes the required advertising data and passes it to the stack.
 *          Also builds a structure to be passed to the stack when starting advertising.
 */
void beacon_advertising_init(void)
{
    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.
    memset(&advdata, 0, sizeof(advdata));

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

    err_code = ble_advdata_set(&advdata, NULL);
    APP_ERROR_CHECK(err_code);

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

    m_adv_params.type        = BLE_GAP_ADV_TYPE_ADV_NONCONN_IND;
    m_adv_params.p_peer_addr = NULL;    // Undirected advertisement.
    m_adv_params.fp          = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval    = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.timeout     = 0;       // Never time out.
}


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

    err_code = sd_ble_gap_adv_start(&m_adv_params, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

    err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
    APP_ERROR_CHECK(err_code);
}

/**@brief Function for initializing the Advertising functionality.
 */
static void advertising_init(void)
{
    ret_code_t             err_code;
    ble_advertising_init_t init;

    memset(&init, 0, sizeof(init));

    init.advdata.name_type               = BLE_ADVDATA_FULL_NAME;
    init.advdata.include_appearance      = true;
    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_TIMEOUT_IN_SECONDS;

    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);
}


/**@brief Function for starting advertising.
 */
static void advertising_start(bool erase_bonds)
{
    if (erase_bonds == true)
    {
        delete_bonds();
        // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED evetnt
    }
    else
    {
        ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);

        APP_ERROR_CHECK(err_code);
    }
}


void app_ble_advertising_init(void)
{
	bool erase_bonds;
	
	buttons_leds_init(&erase_bonds);
    ble_stack_init();
    gap_params_init();
    gatt_init();
    advertising_init();
    services_init();
    conn_params_init();
    peer_manager_init();
	
    // Start execution.
    NRF_LOG_INFO("Template example started.");
    application_timers_start();

    advertising_start(erase_bonds);
}

void app_ble_beacon_init(void)
{
	ble_stack_init();
	
	beacon_advertising_init();
	beacon_advertising_start();
}

int main(void)
{
    bool erase_bonds;
	
    // Initialize.
    log_init();
    timers_init();
	
	app_ble_beacon_init();
	
	while(1)
	{
	    nrf_delay_ms(5000);
		sd_ble_gap_adv_stop();      // Here I want to stop the beacon advertisingadvertising.
		
		nrf_delay_ms(5000);
		app_ble_advertising_init(); // Here I want to start the connectable advertising ,but code error and restart.
		
		while(1);
	}
}

The test board is PCA10040, which main chip is nRF52832.

Now I can start the beacon advertising, then stop it, then restart it , in the main cycle.

I can start the connectable advertising normally.

But I can't switch the two functions to each other.

How can I switch them successfully? 

Thank you!

  • Hey cadillacxlr,

    You need to stop advertisements by calling sd_ble_gap_adv_stop,  change the advertisement data with sd_ble_gap_adv_data_set, and finnaly restart advertisements with sd_ble_gap_adv_start

    Cheers,

    Håkon.

  • Thanks for your reply! And I notice that if the function "ble_stack_init()" is called twice, the chip will restart.

    Now in my code, I can switch the two advertising mode smoothly. Thank you very much!

  • Hello, main code as belows:

    /**@brief Function for starting advertising.
     */
    static void advertising_start(bool erase_bonds)
    {
        if (erase_bonds == true)
        {
            delete_bonds();
            // Advertising is started by PM_EVT_PEERS_DELETED_SUCEEDED evetnt
        }
        else
        {
            ret_code_t err_code = ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    
            APP_ERROR_CHECK(err_code);
        }
    }
    
    
    
    void systick_handler(void * p_context)
    {
    	
    }
    
    void app_ble_advertising_init(void)
    {
    	bool erase_bonds;
    	
    	buttons_leds_init(&erase_bonds);
        ble_stack_init();
        gap_params_init();
        gatt_init();
        advertising_init();
        services_init();
        conn_params_init();
        peer_manager_init();
    	
        // Start execution.
        NRF_LOG_INFO("Template example started.");
        application_timers_start();
    
        advertising_start(erase_bonds);
    }
    
    void change_to_app_ble_advertising_init(void)
    {
    	bool erase_bonds;
    	
    	gap_params_init();
        gatt_init();
        advertising_init();
        services_init();
        conn_params_init();
    	
        advertising_start(erase_bonds);
    }
    
    void app_ble_beacon_init(void)
    {
    	ble_stack_init();
    	
    	beacon_advertising_init();	
    	beacon_advertising_start();
    }
    
    void change_to_app_ble_beacon_init(void)
    {
    	beacon_advertising_init();
    	beacon_advertising_start();
    }
    
    /**@brief Function for application main entry.
     */
    
    uint8_t press_flag_3, press_flag_4;
    int main(void)
    {
        bool erase_bonds;
    	
        // Initialize.
        log_init();
        timers_init();
    
    	ble_stack_init();
    	
    	application_timers_start();
        peer_manager_init();
    	
    	while(1)
    	{
    		change_to_app_ble_advertising_init();
    		nrf_delay_ms(2000);
    		
    		sd_ble_gap_adv_stop();
    		nrf_delay_ms(200);
    		
    		change_to_app_ble_beacon_init();
    		nrf_gpio_pin_write(LED_2,0);
    		nrf_delay_ms(2000);
    		
    		sd_ble_gap_adv_stop();
    		nrf_delay_ms(200);
    	}
    }

Related