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

Fully customize advertising data on SDKv15

Hello everyone,

I want to fully customize the advertising and scan response data of my application because the current SDKv15 does not support all of the Advertising Data Types defined by SIG (https://www.bluetooth.com/specifications/assigned-numbers/generic-access-profile/)

So basically I want to do the same thing as this thread:

https://devzone.nordicsemi.com/f/nordic-q-a/8854/fully-custom-advertisement-data

but with the SDKv15 in which the function "sd_ble_gap_adv_data_set() has been removed from the SoftDevice API" (infocenter.nordicsemi.com/index.jsp

Has anybody achieved something similar?

Best Regards,

Parents
  • Hi, 

    You can just refer to the bootloader with BLE advertising as the reference code.

    /**@brief     Function for the Advertising functionality initialization.
     *
     * @details   Encodes the required advertising data and passes it to the stack.
     *            The advertising data encoded here is specific for DFU.
     */
    static uint32_t advertising_init(uint8_t adv_flags, ble_gap_adv_params_t const * const p_adv_params)
    {
        uint32_t err_code;
        uint16_t actual_device_name_length = BLE_GAP_ADV_SET_DATA_SIZE_MAX - APP_ADV_DATA_HEADER_SIZE;
    
        /* This needs to be static because of SoftDevice API requirements. */
        static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
    
        ble_gap_adv_data_t m_adv_data =
        {
            .adv_data =
            {
                .p_data = m_enc_advdata,
                .len    = APP_ADV_DATA_HEADER_SIZE,
            }
        };
    
        /* Encode flags. */
        m_enc_advdata[0] = 0x2;
        m_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
        m_enc_advdata[2] = adv_flags;
    
        /* Encode 'more available' UUID list. */
        m_enc_advdata[3] = 0x3;
        m_enc_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
        m_enc_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID);
        m_enc_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID);
    
        /* Get GAP device name and length. */
        err_code = sd_ble_gap_device_name_get(&m_enc_advdata[9], &actual_device_name_length);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        // Set GAP device in advertising data.
        m_enc_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1))
        m_enc_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
    
        m_adv_data.adv_data.len += actual_device_name_length;
    
        return sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, p_adv_params);
    }

Reply
  • Hi, 

    You can just refer to the bootloader with BLE advertising as the reference code.

    /**@brief     Function for the Advertising functionality initialization.
     *
     * @details   Encodes the required advertising data and passes it to the stack.
     *            The advertising data encoded here is specific for DFU.
     */
    static uint32_t advertising_init(uint8_t adv_flags, ble_gap_adv_params_t const * const p_adv_params)
    {
        uint32_t err_code;
        uint16_t actual_device_name_length = BLE_GAP_ADV_SET_DATA_SIZE_MAX - APP_ADV_DATA_HEADER_SIZE;
    
        /* This needs to be static because of SoftDevice API requirements. */
        static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
    
        ble_gap_adv_data_t m_adv_data =
        {
            .adv_data =
            {
                .p_data = m_enc_advdata,
                .len    = APP_ADV_DATA_HEADER_SIZE,
            }
        };
    
        /* Encode flags. */
        m_enc_advdata[0] = 0x2;
        m_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
        m_enc_advdata[2] = adv_flags;
    
        /* Encode 'more available' UUID list. */
        m_enc_advdata[3] = 0x3;
        m_enc_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
        m_enc_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID);
        m_enc_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID);
    
        /* Get GAP device name and length. */
        err_code = sd_ble_gap_device_name_get(&m_enc_advdata[9], &actual_device_name_length);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    
        // Set GAP device in advertising data.
        m_enc_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1))
        m_enc_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
    
        m_adv_data.adv_data.len += actual_device_name_length;
    
        return sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, p_adv_params);
    }

Children
  • Hi Jimmy,

    first of all thanks for the rapid response.

    Unfortunately this code snipet is not working for me.

    I have an advanced project based on the HRMS (with FreeRTOS)  in which the functions to initialize and start the advertisment are different than the ones used in the project of the Bootloader with BLE.

    I tried to just call the function sd_ble_gap_adv_set_configure() with the corresponding handle, but it has no effect (the data remains unchanged).

    //create the handle with macro
    BLE_ADVERTISING_DEF(m_advertising);
    
    //initialize advertising
    sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    
    //start advertiser
    ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    
    

    I also tried to initialize my advertiser normally and then just update its data using the sd_ble_gap_adv_set_configure() function but it also has no effect:

    //create the handle with macro
    BLE_ADVERTISING_DEF(m_advertising);
    
    //initialize advertising
    ble_advertising_init(&m_advertising, &init);
    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    
    //start advertiser
    ble_advertising_start(&m_advertising, BLE_ADV_MODE_FAST);
    
    //Update advertising data
    sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    

    Aren't the handles for the advertiser the same? or maybe I'm just missing something?

    Best Regards,

  • Hi,

    You need to follow the standard rule of the advertising payload.  for example, the header of the UUID, flag, device name header.

    You can find all the header of advertising from the bluetooth spec.

  • Hi Jimmy,

    I think that my data follows the standard rules. Here is my advertising data update function:

    void advertising_update_data(void)
    {
        ret_code_t             err_code;
    
        /* This needs to be static because of SoftDevice API requirements. */
        static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
    
        ble_gap_adv_data_t m_adv_data =
        {
            .adv_data =
            {
                .p_data = m_enc_advdata,
                .len    = 3,
            }
        };
    
        /* Encode flags. */
        m_enc_advdata[0] = 0x2;
        m_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
        m_enc_advdata[2] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    	APP_ERROR_CHECK(err_code);
    }
    

  • Hi,

    Do you get any error code after calling set_configure?

    May I know why you need to do full control ?

    why type of advertising do you plan to use?

  • Hi,

    answering your questions:

    1. I was getting error 0x07 (NRF_ERROR_INVALID_PARAM)

    2. I'm migrating an old project to a nordic chip. And I need to replicate exactly the behaviour of the old product. Unfortunately the struct ble_advdata_t doesn't include the AD Types that I need.

    3. I'm using fast advertising

    But I have good news I got the advertising working as follows:

    //create the handle with macro
    BLE_ADVERTISING_DEF(m_advertising);
    
    //initialize advertising
    ble_advertising_init(&m_advertising, &init);
    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    
    //Update advertising data & start advertiser
    sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    sd_ble_gap_adv_stop(m_advertising.adv_handle);
    sd_ble_gap_adv_start(m_advertising.adv_handle, APP_BLE_CONN_CFG_TAG);
    
    

    For me it looks like the function "ble_advertising_start" from "ble_advertising.c" cannot be used to start the advertiser if the function sd_ble_gap_adv_set_configure() is also used

    Thanks a lot for the great support!

Related