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

How can I update advertising data without restarting advertising process ?

Currently, if I want to update the advertising data, firstly, I use sd_ble_gap_adv_stop, then update the advertising data with ble_advdata_service_data_t, then advertising_init, at the end, ble_advertising_start.

Is it possible update the advertising data without restarting advertising ?

I found sd_ble_gap_adv_data_set, but ble_advdata_service_data_t is defined as:

/**@brief Service data structure. */
typedef struct
{
    uint16_t                     service_uuid;                        /**< Service UUID. */
    uint8_array_t                data;                                /**< Additional service data. */
} ble_advdata_service_data_t;

And sd_ble_gap_adv_data_set

uint32_t sd_ble_gap_adv_data_set	(	uint8_t const * 	p_data,
                                    uint8_t 	dlen,
                                    uint8_t const * 	p_sr_data,
                                    uint8_t 	srdlen 
                                    )

They are a little different, I don't know how to use.

Any suggestion guys !?

Thanks.

Parents
  • I got it working by calling 

    ret_code_t err_code = sd_ble_gap_adv_data_set(NULL, 0, sr_data, sizeof(sr_data));

    whenever the scan response data needed updating, where I managed the layout of the data within array sr_data.

  • p_sr_data is the scanned data, right ?

    And p_data is the advertising data.

  • Absolutely right. You might want to endure the pain of the tutorials on advertising and setting up a service (the tutorials use SDK11). If you set up a service, as shown in the Service tutorial then the stack will handle adverting it and you only need worry about managing the scan response. So I did 4 things:

    1) Set up up a service as describe in the Service tutorial.

    2) Used that service setting up advertising & noting that setting the contents of the entire 

    ble_adv_modes_config_t to zero

    static void advertising_init(void)
    {
        ret_code_t             err_code;
        ble_advdata_t          advdata;
        ble_adv_modes_config_t options;
    
        // Build advertising data struct to pass into @ref ble_advertising_init.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type               = BLE_ADVDATA_FULL_NAME;
        //advdata.include_appearance      = true;
        advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
        advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
        advdata.uuids_complete.p_uuids  = m_adv_uuids;
    
        memset(&options, 0, sizeof(options));
        err_code = ble_advertising_init(&advdata, NULL, /*NULL*/ &options, on_adv_evt, NULL);
        APP_ERROR_CHECK(err_code);
    }

    Start advertising:

    static void advertising_start(void)
    {
        // Initialize advertising parameters (used when starting advertising).
    	ble_gap_adv_params_t m_adv_params;
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.type			= BLE_GAP_ADV_TYPE_ADV_SCAN_IND; 	//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; 				/**< Allow scan requests and connect requests from any device. */
        m_adv_params.interval		= NON_CONNECTABLE_ADV_INTERVAL; 	// setting the advertising interval to 100ms.
        m_adv_params.timeout		= APP_CFG_NON_CONN_ADV_TIMEOUT; 	// this define is 0, meaning that advertising will never timeout.
    
        ret_code_t err_code = sd_ble_gap_adv_start(&m_adv_params, BLE_CONN_CFG_TAG_DEFAULT);
        APP_ERROR_CHECK(err_code);
    }

    Update the scan response when required

    #define SR_LEN 15
    
    static void scan_resp_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    	static uint8_t sr_data[SR_LEN];
    	sr_data[00] = SR_LEN - 1;		// Ad length- length of the data field not including the length field (to SR_LEN)!
    	sr_data[01] = 0xff;				// Ad type	- Manufacturers specific data
    	sr_data[02] = 0xff;				// Ad 		- Manufacturers ID
    	sr_data[03] = 0xff;				// Ad 		- Manufacturers ID
    
    
    	/*
    		Update the sr_data array with your new data - bytes 4 -> 14
    		But make sure you get the value of the length correct otherwise you’ll get a fatal error!
    		err_code = 9 NRF_ERROR_INVALID_LENGTH
    		Just 15 bytes are used here however you can use up to 31.
    	 */   
    
        ret_code_t err_code = sd_ble_gap_adv_data_set(NULL, 0, sr_data, sizeof(sr_data));
        APP_ERROR_CHECK(err_code);
    }

    hope this helps.

  • Yes, all steps are working. But I cannot update the Advertising Data without these procedure : stopAdv, initAdv & startAdv. 

    I used sd_ble_gap_adv_data_set, but it returns error 7 which represent Invalid_PARAMS.

    When we initAdv, it calls sd_ble_gap_adv_data_set, but the parameter p_data is an p_encoded_advdata. So using directly sd_ble_gap_adv_data_set returns Invalid_DATA, but if I put p_encoded_advdata as parameters it returns Invalid_PARAMS.

    Also the type of Invalid_DATA is ble_advdata_t.

  • My work was based on the ble_app_template example so I inherited the setup process. There could be some effect on the order of setup.

    Anyway this is my setup process, almost identical to the ble_app_template example. However looks like you are also providing the contents of the advertising packet, which I have delegated to the stack. In my case it wasn't necessary to stop advertising, change scan response, start advertising.

    int main(void)
    {
        bool erase_bonds;
    
        // Sets up nrf_log
        log_init();
        // this is where the timer module is initialised & new timers created.
        timers_init();
        // sets up buttons & leds. Note: the value of erase_bonds is determined
        // by the button pressed when the board boots.
        buttons_leds_init(&erase_bonds);
    
        // configure the softdevice
        ble_stack_init();
    
        // set all the gap parameters, timings and the appearance.
        gap_params_init();
    
        //
        gatt_init();
    
        services_init();
        advertising_init();
        conn_params_init();
        peer_manager_init();
    
        // Start execution.
        NRF_LOG_INFO("Template example started.\r\n");
        application_timers_start();
    
        advertising_start();
    
        // set up the uart
        uart_init();
    
        // Enter main loop.
        for (;;)
        {
            if (NRF_LOG_PROCESS() == false)
            {
                power_manage();
            }
        }
    }
     

Reply
  • My work was based on the ble_app_template example so I inherited the setup process. There could be some effect on the order of setup.

    Anyway this is my setup process, almost identical to the ble_app_template example. However looks like you are also providing the contents of the advertising packet, which I have delegated to the stack. In my case it wasn't necessary to stop advertising, change scan response, start advertising.

    int main(void)
    {
        bool erase_bonds;
    
        // Sets up nrf_log
        log_init();
        // this is where the timer module is initialised & new timers created.
        timers_init();
        // sets up buttons & leds. Note: the value of erase_bonds is determined
        // by the button pressed when the board boots.
        buttons_leds_init(&erase_bonds);
    
        // configure the softdevice
        ble_stack_init();
    
        // set all the gap parameters, timings and the appearance.
        gap_params_init();
    
        //
        gatt_init();
    
        services_init();
        advertising_init();
        conn_params_init();
        peer_manager_init();
    
        // Start execution.
        NRF_LOG_INFO("Template example started.\r\n");
        application_timers_start();
    
        advertising_start();
    
        // set up the uart
        uart_init();
    
        // Enter main loop.
        for (;;)
        {
            if (NRF_LOG_PROCESS() == false)
            {
                power_manage();
            }
        }
    }
     

Children
No Data
Related