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

SoftDevice s110 AND s130 have issues with scanResponse in advertisement?

I know that SoftDevice 110 is old but I am stuck with it as it is on a production device with nRF51822. For some reason when I call sd_ble_gap_adv_data_set() with a non NULL value of the parameter uint8_t const * const p_sr_data which is the scan response, no advertisements are sent. In the sd_ble_gap_adv_start(ble_gap_adv_params_t const * const p_adv_params)) I do try with the type set to BLE_GAP_ADV_TYPE_ADV_SCAN_IND. If I set the scan response to NULL and the type to BLE_GAP_ADV_TYPE_ADV_IND then I do get advertisements.

The application is using the bond manager which may have something to do with it. I do not know what version of the SDK is being used, though I have asked and will hopefully get an answer. Is there a known issue with s110 and scan responses?

Now I have moved to s130 and the same issue is present. I have duplicated the flags and local mane in the scan response data and still it does not work. However, if I set the scan response data to NULL and the length to 0 advertisements DO work. The response to a scan request happens, but it is empty. 

I have tried in the start method using both g_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;  and g_adv_params.type = BLE_GAP_ADV_TYPE_ADV_SCAN_IND; 

Neither work if the set function  sd_ble_gap_adv_data_set(uint8_t const *p_data, uint8_t dlen, uint8_t const *p_sr_data, uint8_t srdlen)

is

sd_ble_gap_adv_data_set(data_buffer, index, scan_rsp_buffer, scan_index);

Both work if the set function is

sd_ble_gap_adv_data_set(data_buffer, index, NULL, 0);

Parents Reply Children
  • I could upload the entire code but it wont do much good - you can't run it without the actual physical device. The Bluetooth does not start until the Pulse Ox sensor has given the nRF51822 module a finished sensor value via the serial port.

    In any case, once that is received, these two methods are called, one to create the advertisement data itself and the other to start the advertising:

    static ble_gap_adv_params_t     g_adv_params;
    static uint8_t                  data_buffer[BUFFER_SIZE];
    static uint8_t                  scan_rsp_buffer[BUFFER_SIZE];
    
    uint32_t advertisement_data_set(short int* serviceUuids,
        int length, uint8_t* service128Uuids, const char* friendlyName)
    {
        uint32_t error_code;
        uint8_t  index = 0;
        uint8_t  scan_index = 0;
        uint8_t  i = 0;
        memset(data_buffer, 0, sizeof(data_buffer));
        memset(scan_rsp_buffer, 0, sizeof(scan_rsp_buffer));
    
        const uint8_t name_length = (uint8_t)strlen(friendlyName);
    
        // Set the flags - important to indicate no EDR/BR support for some Androids
        // Actually by spec one is SUPPOSED to set one of the discoverable flags to be discoverable.
        data_buffer[index++] = 2;        // length of flags data type
        data_buffer[index++] = BLE_GAP_AD_TYPE_FLAGS;
        data_buffer[index++] = BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;    // No EDR/BR support and general discoverable
    
        // Set the device name.
        if (friendlyName != NULL)
        {
            data_buffer[index++] = name_length + 1; // Device name + data type
            data_buffer[index++] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
            memcpy((char*)&data_buffer[index], friendlyName, name_length);
            index += name_length;
        }
    
        // Set the device full name as a copy in the scan response.
        if (friendlyName != NULL)
        {
            scan_rsp_buffer[scan_index++] = name_length + 1; // Device name + data type
            scan_rsp_buffer[scan_index++] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
            memcpy((char*)&scan_rsp_buffer[scan_index], friendlyName, name_length);
            scan_index += name_length;
        }
    
        if (serviceUuids != NULL)
        {
            // Set the device's available services.
            data_buffer[index++] = 1 + 2 * length;
            data_buffer[index++] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_COMPLETE;
            for (i = 0; i < length; i++)
            {
                // Store in little-endian format.
                data_buffer[index++] = serviceUuids[i] & 0xFF;
                data_buffer[index++] = (serviceUuids[i] & 0xFF00) >> 8;
            }
        }
    
        // Scan response:
        if (service128Uuids != NULL)
        {
            scan_rsp_buffer[scan_index++] = 1 + 16; //(only room for one)
            scan_rsp_buffer[scan_index++] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_MORE_AVAILABLE;
            // Store in little-endian format.
            memcpy(&scan_rsp_buffer[scan_index], service128Uuids, 16);
            scan_index = scan_index + 16;
        }
    
    
        error_code = sd_ble_gap_adv_data_set(data_buffer, index, NULL, 0);
       // error_code = sd_ble_gap_adv_data_set(data_buffer, index, scan_rsp_buffer, scan_index); // For some reason scan responses dont work
        APP_ERROR_CHECK(error_code);
        return NRF_SUCCESS;
    }
    
    static uint32_t new_advertising_start()
    {
        // Used in start advertising:
        memset(&g_adv_params, 0, sizeof(ble_gap_adv_params_t));
        g_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND; // BLE_GAP_ADV_TYPE_ADV_SCAN_IND;              // general connectable scannable
        g_adv_params.fp = BLE_GAP_ADV_FP_ANY;                           // Any one can scan and connect
        g_adv_params.interval = ADVERTISING_INTERVAL_40_MS;
        g_adv_params.timeout = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;   // Advertises until connected
        simple_uart_put(BLE_STATUS_ADVER_START);
        return sd_ble_gap_adv_start(&g_adv_params);
    }

    When I call the method option with a non-null value of the scan array, no advertisement is sent when calling the start method. If I do as coded (not the commented-out variant) then an advertisement is generated.

    The UART calls are just for the sensor module which has control of the display. It is not relevant for the Bluetooth behavior.

    I should also add that this is down ported from an nRF52840 pc-ble-driver module that I wrote (which does work with scan responses). Don't know if I missed something in my down-port to this old s110 based module.

  • Turns out I read the documentation backwards. The docs say 

    Limitations imposed by this API call to the data provided include having a flags data type in the scan response data and
    * duplicating the local name in the advertising data and scan response data.

    I read that as the limitation was that you had to do that (something I would not normally do). But when I looked in the SDK code I saw text which was much clearer. It said simply that you "do not allow flags in scan response' next to an 'if' statement. Removing the flags and the name from the scan response solved the problem --- at least for s130.

  • Thanks for sharing the solution.

    I'm glad you figured it out.

    Br,
    Joakim

  • The same text appears in all the 'h' files and SoftDevice API docs that I have read. The funny thing when I use the pc-ble-driver for the nRF52840 dongle I duplicated the flags and local name in the scan response and it worked. Since that was my first experience with Nordic chips I assumed my interpretation of the documentation was correct and I carried that code to this.

    In desperation I started looking at the SDK to try and find out what was wrong and stumbled on that comment. Solved the problem but it seems the 'limitation' no longer applies in s140 v 6. Or at least if one uses the pc-ble-driver.

Related