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

Adding scan response gives invalid flags

I see this quote in response to a question asking for examples on how to code a scan response

possibly not - but it's trivial - just encode the scan response in the same way you encode the advertising data and then add the encoded data to the p_sr_data and srdlen of the sd_ble_gap_adv_data_set(). Or if you're using the Advertising and Scan Response encoder library, one layer higher, the unencoded data into the last argument of ble_adv_data_set()p_srdata, if if you're using the entire advertising module, ble_advertising_init() with a non-NULL p_srdata second paramter.

Trivial it aint!!! Well at least regardless of what I place in the scan response I get invalid flags unless the scan response is empty.

Its a scannable advertsiement!

adv_properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;

Then there is this very confusing statement in the documentation:

The format of the advertising data will be checked by this call to ensure interoperability.
* 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 assumed what this means is that I duplicate the flags setting done in the advertisement and the friendly name setting in the advertisement. This is all I do and the advertisement alone works but when I add the scan response INVALID FLAGS!  Go figure. It doesn't seem to matter what I pit in there I get the same result

SO PLEASE

Provide an example that WORKS for a connectable peripheral.

Using the advertisement alone I have several Androids whose LeScanner (Lollipop +) do NOT report certain advertisements generated by the Nordic nRF52... dongle. Changing the NAME in the advertisement makes it detectable. I have only seen this behavior with ads generated by the Nordic chip (no market device I have worked with has that problem. I am beginning to think it has something to do with the messed up scan response from the Nordic. Sniffers DO detect the ads. I know Android needs to have a response to a scan request so I am trying desperately to generate one.

Here is the contents of the advertisement and scan response data

Advertisement 02, 01, 06, 0A, 09, 42, 70, 54, 69, 6D, 65, 4F, 6E, 65, 07, 03, 10, 18, 0A, 18, 05, 18
Scan Response 02, 01, 06, 0A, 09, 42, 70, 54, 69, 6D, 65, 4F, 6E, 65
Failed to set advertisement data. Error code: invalid flags

Parents Reply Children
  • The advertisement alone does NOT give the invalid flags. Only when I try to add the scan response. Here is the code. All the flag settings are defined by Nordic. They should be valid. Note that this is the pc-ble-driver and the code is on a PC. I am making direct calls to the sd_* methods via the pc-ble-driver serial interface.

    Note further that the code to populate the scan response is commented out because its addition causes the INVALID FLAGS error. Without it, the code works.

    static ble_gap_adv_params_t     m_adv_params;
    static ble_gap_adv_data_t m_adv_data;
    static uint8_t  data_buffer[BUFFER_SIZE];
    static uint8_t  scan_rsp_buffer[BUFFER_SIZE];
    
    uint32_t advertisement_data_set(adapter_t* adapter, uint8_t* advHandle, 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;
        char printBuf[256];
        memset(printBuf, 0, 256);
        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
    
        // Required Nordic duplicate for the scan response
        scan_rsp_buffer[scan_index++] = 2;        // length of flags data type
        scan_rsp_buffer[scan_index++] = BLE_GAP_AD_TYPE_FLAGS;
        scan_rsp_buffer[scan_index++] = BLE_GAP_ADV_FLAG_LE_GENERAL_DISC_MODE | BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    
        // 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;
        }
    
    
        ble_gap_adv_properties_t adv_properties;
        adv_properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
        adv_properties.anonymous = 0;
        adv_properties.include_tx_power = 0;
    
        m_adv_params.properties = adv_properties;
        m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
        m_adv_params.duration = BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED;
        m_adv_params.p_peer_addr = NULL;
        m_adv_params.interval = ADVERTISING_INTERVAL_40_MS;
        m_adv_params.max_adv_evts = 0;
        m_adv_params.primary_phy = BLE_GAP_PHY_AUTO;
        m_adv_params.secondary_phy = BLE_GAP_PHY_AUTO;
        m_adv_params.channel_mask[0] = 0;
        m_adv_params.channel_mask[1] = 0;
        m_adv_params.channel_mask[2] = 0;
        m_adv_params.channel_mask[3] = 0;
        m_adv_params.channel_mask[4] = 0;
    
        memset (&m_adv_data, 0, sizeof(m_adv_data));
    
        m_adv_data.adv_data.p_data = data_buffer;
        m_adv_data.adv_data.len = index;
     //   m_adv_data.scan_rsp_data.p_data = scan_rsp_buffer;
     //   m_adv_data.scan_rsp_data.len = scan_index;
    
        printf("Advertising data set\n");
        printf("Advertisement %s\n", byteToHex(m_adv_data.adv_data.p_data, &printBuf[0], ", ", m_adv_data.adv_data.len));
      //  if (scan_index > 0)
      //  {
      //      memset(printBuf, 0, 256);
      //      printf("Scan Response %s\n", byteToHex(m_adv_data.scan_rsp_data.p_data, &printBuf[0], ", ", m_adv_data.scan_rsp_data.len));
      //  }
    
        error_code = sd_ble_gap_adv_set_configure(adapter, advHandle, &m_adv_data, &m_adv_params);
    
        if (error_code != NRF_SUCCESS)
        {
            if (error_code == 10)
            {
                printf("Failed to set advertisement data. Error code: invalid flags\n");
            }
            else
            {
                printf("Failed to set advertisement data. Error code: 0x%02X\n", error_code);
            }
            fflush(stdout);
            return error_code;
        }
        fflush(stdout);
        return NRF_SUCCESS;
    }

Related