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

How to update advertisement packet SDK 15.0.0 ?

Dear all,

I am trying to develop an application that reads data from a sensor (accelerometer) and I want to be able to update the advertisement packet with the measurement I obtain from it.

So far I am able to read the values from the sensor. Using this example as a basis I can transmit a single value, but I am unable to update the content of the package in order to be able to read the right value. Is there any idea, how I can do this update?

I am using SDK 15.0.0.0. From what I have seen in the forum there is no straight forward way to do this, but I wonder, if someone has the same issue and if it is possible to share some sample code with me.

Kind regards

  • HI,

    You can refer to my example at https://github.com/jimmywong2003/nrf5-modify-device-parameter-through-host/blob/modify_non_connectable_advertising/ble_app_change_advertising_example/main.c

    I hardcode the enc_advdata (advertising data) and set the adv data with pointer.

    and then update the battery info (fill up the 1st byte of advdata) in the ADV payload.

            m_adv_data.adv_data.p_data = m_hardcode_enc_advdata;
            m_adv_data.adv_data.len    = 0x1F; // hardcode to 31 bytes
    
            err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
            APP_ERROR_CHECK(err_code);

    void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
    {
            if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
            {
                    nrf_saadc_value_t adc_result;
                    uint16_t batt_lvl_in_milli_volts;
                    // uint8_t percentage_batt_lvl;
                    uint32_t err_code;
    
                    adc_result = p_event->data.done.p_buffer[0];
    
                    err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
                    APP_ERROR_CHECK(err_code);
    
                    batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) +
                                              DIODE_FWD_VOLT_DROP_MILLIVOLTS;
                    m_percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts);
    
    #if defined(USE_THINGY_ADVERTISING_PAYLOAD)
                    m_hardcode_enc_advdata[ADV_PAYLOAD_WITH_BATTERY]    = m_percentage_batt_lvl;
    #endif

  • Hi there Jimmy.

    I am not sure how exactly I can incorporate your code in mine.

    What I have so far is this:

    static void advertising_init(void)
    {
        ret_code_t             err_code;
        memset(&init, 0, sizeof(init));
    
        ble_advdata_manuf_data_t                  manuf_data; //Variable to hold manufacturer specific data
        uint8_t data[]                            = "SomeDa"; //Our data to advertise
        manuf_data.company_identifier             =  0x0059; //Nordics company ID
        manuf_data.data.p_data                    = data;
        manuf_data.data.size                      = sizeof(data);
        init.advdata.p_manuf_specific_data        = &manuf_data;
    
        int8_t tx_power                   = -56;// Set Power Level
        init.advdata.p_tx_power_level = &tx_power;
    
        init.advdata.name_type = BLE_ADVDATA_FULL_NAME; // Use a shortened name
        init.advdata.short_name_len = 6; // Advertise only first 6 letters of name
        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;
    
        // Prepare the scan response manufacturer specific data packet
        ble_advdata_manuf_data_t  manuf_data_response;
        uint8_t                     data_response[] = "Many_bytes_of_data";
        manuf_data_response.company_identifier  = 0x0059;
        manuf_data_response.data.p_data         = data_response;
        manuf_data_response.data.size           = sizeof(data_response);
        init.srdata.name_type = BLE_ADVDATA_NO_NAME;
        init.srdata.p_manuf_specific_data = &manuf_data_response;
    
        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);
    }

    This is how I initialize my advertisement. At the moment I am not using any handler to read the data from the sensor, but I can write one.

    I am not sure I can incorporate your code to what I already have.

  • HI,

    Please try to read the full source code. if you don't know you can try on the board.

    Also, read the blog at https://jimmywongbluetooth.wordpress.com/2019/04/15/how-to-modify-the-device-information-through-ble-connection/.

    You should use the global variable instead of local variable (data).

    for example,

    static uint8_t m_hardcode_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX] =
    {
            0x02, 0x01, 0x04, //flags
            0x1B, 0xFF, 0x59,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
            0x00, 0x00, 0x00, 0x00,
    };


    configure the advertising by using the pointer of this global variable.

    static void non_connectable_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;
            ..
            ..
            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        = 0;   // Never time out.
    
            NRF_LOG_DEBUG("non_connectable_advertising_init");
    
            uint8_t length = m_ble_config->adv_payload.len;
    
            for (uint8_t i=0; i < length ; i++)
            {
                  m_hardcode_enc_advdata[ADV_PAYLOAD_WITH_BATTERY+1+i] = m_ble_config->adv_payload.data[i];
            }
            //memcpy(*m_hardcode_enc_advdata+ADV_PAYLOAD_WITH_BATTERY+1, m_ble_config->adv_payload.data, m_ble_config->adv_payload.len);
    
            // set the p_data to global variable pointer
            m_adv_data.adv_data.p_data = m_hardcode_enc_advdata;

    for example, I use the app_timer to regular read the battery value (through SAADC).

    void saadc_event_handler(nrf_drv_saadc_evt_t const * p_event)
    {
            if (p_event->type == NRF_DRV_SAADC_EVT_DONE)
            {
                    nrf_saadc_value_t adc_result;
                    uint16_t batt_lvl_in_milli_volts;
                    // uint8_t percentage_batt_lvl;
                    uint32_t err_code = NRF_SUCCESS;
    
                    adc_result = p_event->data.done.p_buffer[0];
    
                    err_code = nrf_drv_saadc_buffer_convert(p_event->data.done.p_buffer, 1);
                    APP_ERROR_CHECK(err_code);
    
                    batt_lvl_in_milli_volts = ADC_RESULT_IN_MILLI_VOLTS(adc_result) +
                                              DIODE_FWD_VOLT_DROP_MILLIVOLTS;
                    m_percentage_batt_lvl = battery_level_in_percent(batt_lvl_in_milli_volts);
    
    #if defined(USE_THINGY_ADVERTISING_PAYLOAD)
                    m_hardcode_enc_advdata[ADV_PAYLOAD_WITH_BATTERY]    = m_percentage_batt_lvl;
    #endif
                    NRF_LOG_INFO("Battery service value : %03d %%", m_percentage_batt_lvl);
    

  • I am using SDK 15.0.0. This is the error that I am getting trying to build the project.

  • HI,

    the example of the github is running at the SDK 15.3 (mentioned in the readme).

    You should port such part of code on the SDK 15.0 if you need. it is very straight forward and trivial.

Related