This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

manufacturer specific data

Hi,

I want to use the whole payload of the advertising packet. I decided to use the manufacturer specific data. BUt I cant´use the whole payload by myself. I get this payload: 11 00 is "my" test company identifier 1-5 is my payload. I can´t find the row to change the first bytes 1-5. (02 01 06 08 ff)

image description

this is my init function:

static void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
		ble_advdata_manuf_data_t   manuf_data;
		uint8_t m_addl_adv_manuf_data[5] = {1,2,3,4,5};
		
    // Build and set advertising data
    memset(&advdata, 0, sizeof(advdata));

    advdata.name_type               = BLE_ADVDATA_NO_NAME;
    advdata.include_appearance      = false;
    advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    ble_adv_modes_config_t options = {0};
    options.ble_adv_fast_enabled  = BLE_ADV_FAST_ENABLED;
    options.ble_adv_fast_interval = APP_ADV_INTERVAL;
    options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
		
		manuf_data.company_identifier = 0x11;
    manuf_data.data.size          = 5;
    manuf_data.data.p_data        = m_addl_adv_manuf_data;
		advdata.p_manuf_specific_data = &manuf_data;

    err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);
    APP_ERROR_CHECK(err_code);
}

Perhaps anyone give me a hint for using the whole paylaod of an advertising packet?

Parents
  • Hi.

    As Carles describes here, you can put whatever data you want in the advertising packet, but you will have to comply with the triplet format [size, type, data] format that is described in the spec. Here is a list of types and here is more info on the triplet format. Comparing the data in your packet with the list you can see that the three first bytes of your advdata packet is a flag field, 02 = size (1 byte), 01 = type (flags, 1 byte), 06 = data (flags, 06 = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE).

    However, getting rid of the flag field is easier said than done, but there is a workaround. In SDK 9 advertising is initiated with ble_advertising_init() which takes your advpacket, some options, etc as arguments. ble_advertising_init() is checking the validity of your advdata and will return an error if the packet doesn't include a flag field. The function also passes some important options and an eventhandler to be used in various functions in ble_advertising.c. In the end of ble_advertising_init() you will find sd_ble_gap_adv_data_set() defined in ble_gap.h. This is the function that sets your advdata and it won't complain as long as you follow the triplet scheme. So det simplest workaround I found (without tinkering with ble_advertising.c or ble_advdata.c) was this:

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        
        // Build an advertising packet as usual containing flags
        memset(&advdata, 0, sizeof(advdata));
        advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        // Sett all relevant options
        ble_adv_modes_config_t options = {0};
        options.ble_adv_fast_enabled  = BLE_ADV_FAST_ENABLED;
        options.ble_adv_fast_interval = APP_ADV_INTERVAL;
        options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
    
        // Call ble_advertising_init() to pass the options and the event handler to ble_advertising.c 
        err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);
        APP_ERROR_CHECK(err_code);
        
        // Build your advertising packet. 
        uint8_t m_addl_adv_manuf_data[] = {0x08, 0xFF, 0x11, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05};   
        
        // Cheat the softdevice by overwriting the advertising packet data
        err_code = sd_ble_gap_adv_data_set(m_addl_adv_manuf_data, sizeof(m_addl_adv_manuf_data), NULL, 0);
        APP_ERROR_CHECK(err_code);
    }
    

    The packet m_addl_adv_manuf_data is a 9 byte long array.

    1. Length field, 1 byte
    2. Data type value indicating manufacturer specific data, 1 byte
    3. Manuf data, 7 bytes. (Company identifier 0x0011, payload 0x01, 0x02, 0x03, 0x04, 0x05)

    If you are fine with some tinkering, possibly causing ripple effects in all examples and code your SDK folders, there is a very simple workaround:

    Comment out the following in ble_advdata_set() found in ble_advdata.c:

        err_code = advdata_check(p_advdata);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    

    Then you will skip the flag validation entirely. By doing this the code you posted worked "out of the box" on my system.

    Finally note that because of the triplet system you will not be able to have more than 29 bytes of useful payload.

Reply
  • Hi.

    As Carles describes here, you can put whatever data you want in the advertising packet, but you will have to comply with the triplet format [size, type, data] format that is described in the spec. Here is a list of types and here is more info on the triplet format. Comparing the data in your packet with the list you can see that the three first bytes of your advdata packet is a flag field, 02 = size (1 byte), 01 = type (flags, 1 byte), 06 = data (flags, 06 = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE).

    However, getting rid of the flag field is easier said than done, but there is a workaround. In SDK 9 advertising is initiated with ble_advertising_init() which takes your advpacket, some options, etc as arguments. ble_advertising_init() is checking the validity of your advdata and will return an error if the packet doesn't include a flag field. The function also passes some important options and an eventhandler to be used in various functions in ble_advertising.c. In the end of ble_advertising_init() you will find sd_ble_gap_adv_data_set() defined in ble_gap.h. This is the function that sets your advdata and it won't complain as long as you follow the triplet scheme. So det simplest workaround I found (without tinkering with ble_advertising.c or ble_advdata.c) was this:

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        
        // Build an advertising packet as usual containing flags
        memset(&advdata, 0, sizeof(advdata));
        advdata.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
        // Sett all relevant options
        ble_adv_modes_config_t options = {0};
        options.ble_adv_fast_enabled  = BLE_ADV_FAST_ENABLED;
        options.ble_adv_fast_interval = APP_ADV_INTERVAL;
        options.ble_adv_fast_timeout  = APP_ADV_TIMEOUT_IN_SECONDS;
    
        // Call ble_advertising_init() to pass the options and the event handler to ble_advertising.c 
        err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);
        APP_ERROR_CHECK(err_code);
        
        // Build your advertising packet. 
        uint8_t m_addl_adv_manuf_data[] = {0x08, 0xFF, 0x11, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05};   
        
        // Cheat the softdevice by overwriting the advertising packet data
        err_code = sd_ble_gap_adv_data_set(m_addl_adv_manuf_data, sizeof(m_addl_adv_manuf_data), NULL, 0);
        APP_ERROR_CHECK(err_code);
    }
    

    The packet m_addl_adv_manuf_data is a 9 byte long array.

    1. Length field, 1 byte
    2. Data type value indicating manufacturer specific data, 1 byte
    3. Manuf data, 7 bytes. (Company identifier 0x0011, payload 0x01, 0x02, 0x03, 0x04, 0x05)

    If you are fine with some tinkering, possibly causing ripple effects in all examples and code your SDK folders, there is a very simple workaround:

    Comment out the following in ble_advdata_set() found in ble_advdata.c:

        err_code = advdata_check(p_advdata);
        if (err_code != NRF_SUCCESS)
        {
            return err_code;
        }
    

    Then you will skip the flag validation entirely. By doing this the code you posted worked "out of the box" on my system.

    Finally note that because of the triplet system you will not be able to have more than 29 bytes of useful payload.

Children
Related