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

How to get manufacturer's data from a received advertising message?

In my application, I'm setting a message as manufacturer's data to be sent with the advertising message. To do that is simple, since I have a data type ble_advdata_t, and I can set a pointer to an object of type ble_advdata_manuf_data_t.

But when I receive a advertising event, the type I get is ble_gap_evt_adv_report_t. This type has a field data[31], where the manufacturer's data is included, but also a bunch of other data sent with the advertising.

I'm looking for a way to get just the manufacture's data. Maybe a "parser" to a variable of type ble_advdata_t.

I have tried to use the function ble_advdata_set, passing the first argument as NULL and the second as a pointer to a variable of type ble_advdata_t, like this:

ble_advdata_set(NULL, &advdata)

since in the documentation it says that it is a function for encoding and setting the advertising data and/or scan response data. Setting the first argument to NULL would just scan response data. But this doesn't seem to work.

Do anybody know what can I do?

Thanks in advance.

Parents
  • See the scanning part of the BLE central tutorial

    Use this function:

    static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata)
    
    {
        uint32_t index = 0;
        uint8_t * p_data;
    
        p_data = p_advdata->p_data;
    
        while (index < p_advdata->data_len)
        {
            uint8_t field_length = p_data[index];
            uint8_t field_type = p_data[index+1];
    
            if (field_type == type)
            {
                p_typedata->p_data = &p_data[index+2];
                p_typedata->data_len = field_length-1;
                return NRF_SUCCESS;
            }
            index += field_length+1;
        }
        return NRF_ERROR_NOT_FOUND;
    }
    

    Call it with type = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF)

Reply
  • See the scanning part of the BLE central tutorial

    Use this function:

    static uint32_t adv_report_parse(uint8_t type, data_t * p_advdata, data_t * p_typedata)
    
    {
        uint32_t index = 0;
        uint8_t * p_data;
    
        p_data = p_advdata->p_data;
    
        while (index < p_advdata->data_len)
        {
            uint8_t field_length = p_data[index];
            uint8_t field_type = p_data[index+1];
    
            if (field_type == type)
            {
                p_typedata->p_data = &p_data[index+2];
                p_typedata->data_len = field_length-1;
                return NRF_SUCCESS;
            }
            index += field_length+1;
        }
        return NRF_ERROR_NOT_FOUND;
    }
    

    Call it with type = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA (0xFF)

Children
  • Thank you, very much. I was going to implement a parser for the advertising myself but this was really handy for me.

  • In NRF SDK 15.2 there is a method 

    uint8_t * ble_advdata_parse(uint8_t  * p_encoded_data, uint16_t data_len, uint8_t ad_type);

    It returns pointer to the specified ad_type.

    Example:

    static void ble_evt_handler(ble_evt_t const *p_ble_evt, void *p_context) {
        if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_REPORT) // is this GAP advertisement?
            return;
        const ble_gap_evt_adv_report_t *p_adv_report = &p_ble_evt->evt.gap_evt.params.adv_report;
        const ble_data_t *data = &p_adv_report->data;
        uint8_t *mfd_data = ble_advdata_parse(data->p_data, data->len, BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA);
        // *mfd_data is a pointer to BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA data
    }

Related