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

FULLY Custom Advertisement Data

hi everyone. we are migrating to nordic nrf51 series (before we used ble modules from another vendor blugiga which depends on cc2541 chip) so I m pretty new at nordic nrf51 series.

we had a working solution with that modules based on fully custom advertisement data and scan response data (31 of 31 byte for both of data types) because BGScript allows this ,and now we want to apply same solution model but with nrf51822 chip. in forum there are some question about with this topic but they are not same at exactly my situation.

can anyone share example code for this?. if there needs to make configuration on the api, how can i configure ? my best regards.

  • Hi. I'm not really sure what you mean by fully custom, but here is a tutorial on how to initialize advertising and scan response with various information like UUIDs, manufacturer specific data, tx power, etc.

    EDIT:

    You can use sd_ble_gap_adv_data_set() to make your own custom advertising and scan response packet. See this and this semi relevant discussions or search devzone for the function.

    I tried it very quickly with the following code and it seems to work, but I don't have time to test it thoroughly and there might very well be a more elegant way to do it.

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
    
        // Build advertising data struct to pass into @ref ble_advertising_init.
        memset(&advdata, 0, sizeof(advdata));
        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;
    
        err_code = ble_advertising_init(&advdata, NULL, &options, on_adv_evt, NULL);
        APP_ERROR_CHECK(err_code);
    
        uint8_t adv_data[13] = {0};
        uint8_t sr_data[20] = {0};
    
        // flags for discoverable/connectable
        adv_data[0] = 0x02; // ad field length = 2 bytes
        adv_data[1] = 0x01;   // ad field type = 0x01 [Flags)
        adv_data[2] = 0x06; // flags = 0x06, connectable/undirected
    
        // tx power field advertisement, iOS apps may need this
        adv_data[3] = 0x02; // ad field length = 2 bytes
        adv_data[4] = 0x0a;    // ad field type = 0x0A [TX Power)
        adv_data[5] = 0x03; // TX power in dBm
        // NOTE: TX power is a signed 8-bit value, and is not changed automatically
        // when using "hardware_set_txpower[<power>)". This may be anywhere from -23
        // to +3 based on your settings. Negative values may be converted to two's
        // complement form by adding 256, so for example -23 dBm would be 233 or 0xE9.
        
        // custom manufacturer
        adv_data[6] = 0x06; // ad field length = 5 bytes [arbitrary, maybe more or less but minimum 3)
        adv_data[7] = 0xff; // ad field type = 0xFF [Manufacturer Specific Data)
        adv_data[8] = 0xff; // unknown/prototype Company Identifier Code - octet 2 
        adv_data[9] = 0xff; // unknown/prototype Company Identifier Code - octet 1 
        adv_data[10] = 0xb1; // custom data byte //1 [can be anything)
        adv_data[11] = 0xb2; // custom data byte //2 [can be anything)
        adv_data[12] = 0xb3; // custom data byte //3 (can be anything)
        // NOTE: manufacturer data fields should contain the Company Identifier Code
        // in order to stay within BT 4.0 spec. You should also ideally obtain an
        // an official Company Identifier Code, but 0xFFFF is suitable for development.
        // (this is why the minimum ad field length for this is 3, so the CIC fits)
    
        // More bytes are possible here, but not necessary for this demo.
        // Compare with automatically generated ad packets from other
        // demo projects to see what else you might put here, or read
        // the relevant portions of the Bluetooth 4.0 Core Spec document
        // for greater detail.
        
        // -------------------------------
        // build custom scan response data
        // -------------------------------
    
        // get Bluetooth MAC address of this device (NOTE: this is little-endian!)
    
        sr_data[0] = 0x13;  // ad field length = 19 bytes (0x13)
        sr_data[1] = 0x09;   // ad field type = 0x09 (Complete local name)
        sr_data[2] = 0x06;  // 'M'
        sr_data[3] = 0x79;  // 'y'
        sr_data[4] = 0x20;  // ' '
        sr_data[5] = 0x57;  // 'W'
        sr_data[6] = 0x69;  // 'i'
        sr_data[7] = 0x64;  // 'd'
        sr_data[8] = 0x67;  // 'g'
        sr_data[9] = 0x65;  // 'e'
        sr_data[10] = 0x74; // 't'
        sr_data[11] = 0x20; // ' '
        sr_data[12] = 0x01;
        sr_data[13] = 0x02;
        sr_data[14] = 0x03;
        sr_data[15] = 0x04;
        sr_data[16] = 0x05;
        sr_data[17] = 0x06;
        sr_data[18] = 0x07;
        sr_data[19] = 0x08;
        
        uint32_t err_code;
        err_code = sd_ble_gap_adv_data_set(adv_data, 13, sr_data, 20);
        APP_ERROR_CHECK(err_code);
    }
    
  • hi martin. thank you for fast reply. fully custom advertisement means that , users can create their own advertisement data up to 31 bytes freely. in their forum there is an example named as "custom_advertisement" . link textyou can reach example .( in zip file open .bgs with notepad++ ).regards.

  • Hi Martin, I've understood there is no way to avoid setting AD_FLAGS element on nRF51 when using S110/S120/S130 stacks. Is it correct? Thanks Jan

  • The sd_ble_gap_adv_data_set() function will check if your advertising packet conforms to the Bluetooth standard and will run some checks on it. If you want to build an advertising packet that is compatible with the BLE specification, that works, but non-compatible packets will fail.

    I am not too sure about whether the flags need to be included. The latest BLE addendum allows to leave the flags field empty if it is a non-connectable advertising message, but I guess that they have not yet implemented this.

  • Hi Martin, many thanks for the update. Sorry for being picky but I see that your example contains AD_FLAGS element at the beginning:

    // flags for discoverable/connectable
        adv_data[0] = 0x02; // ad field length = 2 bytes
        adv_data[1] = 0x01;   // ad field type = 0x01 [Flags)
        adv_data[2] = 0x06; // flags = 0x06, connectable/undirected
    

    This is compliant to BT SIG specification but what if we want to do non-compliant advertisement (= or just avoiding GAP/GATT compliancy but rely on L2CAP and other parts of BT Smart stack)? Could you check if you can realy put any 31-byte "rubbish" string to the adv data?

    Thanks Jan

Related