Change advertisement data dynamically while using freeRTOS

My situation:
I am using the freertos_ble_peripheral_server_bond example. The aim is to be able to maintain one ble connection while advertising three different advertisement data sets. To achive this, I would like to change the advertisement data dynamically, on the fly. I used struct gapm_update_advertise_data_cmd updateAdvCmd and set the new data with GAPM_AddAdvData() , the same way it is done in the example with struct gapm_start_advertise_cmd advertiseCmd and GAPM_AddAdvData() . But the advertisement data is not updated, I am using a BLE sniffer to check the advertisement data.

Do I need to set any flag or call a function to notify the BLE stack that new advertisement data is available?
Is it even possible to change the advertisement data on the fly with this example, if not why?

I am new to FreeRTOS, is it possible to have more than one BLE_thread?

Any helpful comment would be highly appreciated!

Hi stzi,

You need to send the GAPM_UPDATE_ADVERTISE_DATA_CMD command to the BLE stack to update the advertising data without interrupting the advertising operation.
Looking at the ble_gap.h header there seems to be no wrapper function for this specific command.
You can create one, something like this:

void GAPM_UpdateAdvertiseDataCmd(const struct gapm_update_advertise_data_cmd *updated_adv_data)
    // REQUIRE(device_is_advertising);

    struct gapm_update_advertise_data_cmd *cmd;


    memcpy(cmd, updated_adv_data, sizeof(struct gapm_update_advertise_data_cmd));


See the Gap Interface Specification document in the CMSIS-Pack for details of the command.

I am not exactly sure if the BLE stack and the functions that are used to interact with it are thread safe.
So when I used FreeRTOS I just assumed that they are not and did all interactions with BLE from single thread and set up queues to pass and process data from other threads.

Best regards,

Hi Lukas
Thank you very much! I missed that! I can now change the advertisement data dynamically.

Best regards

My advice would be to let the BLE stack handle the standard flags and let you add your own manufacturer specific flags. To do this, you need to call (after BLE initialization):

    /* First 3 bytes are under the BLE stack control and the rest is under application control */

Then, suppose you want to add 0xA5 as manufacturer specific data, you then need to encode manually your data type and indicate to the BLE stack to update it:

        if (ble_env.state == APPM_ADVERTISING)
        	/* Update the advertising state within the BLE stack */
        	struct gapm_update_advertise_data_cmd *cmd = KE_MSG_ALLOC(GAPM_UPDATE_ADVERTISE_DATA_CMD, TASK_GAPM, TASK_APP, gapm_update_advertise_data_cmd);
        	cmd->operation = GAPM_UPDATE_ADVERTISE_DATA;
        	cmd->adv_data_len = 3;		// Total length
        	cmd->adv_data[0] = 2;		// Length of this AD Type 0xFF
        	cmd->adv_data[1] = 0xFF;	// AD Type 0xFF means manufacturer specific
        	cmd->adv_data[2] = 0xA5;	// Manufacturer specific content
        	ke_msg_send(cmd);			// Send the message to GAPM

Then you will see your 0xA5 manufacturer specific data (see the nRF connect snapshot below) while still relying on the BLE stack to manage the standard flags:

1 Like