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

Extended advertising fails configuration

For our application, if the device loses connection, we enter beacon mode for longer range, and advertise using extended advertising to broadcast more data. Beacon mode wit normal advertising works very well. When I attempt to configure the extended advertising,     err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params); err_code = 7, invalid parameter. I have gone through the documentation and examples I could find, and still don't know what the issue is. Please recommend what I need to change, and explain why, if possible.

NRF52832

SDK 16.0.0

softDevice 7.0.1 (S132)

#include <stdbool.h>
#include <stdint.h>
#include <string.h>

#include "nordic_common.h"
#include "nrf_soc.h"
#include "nrf_sdh.h"
#include "nrf_sdh_ble.h"
#include "ble_advdata.h"
#include "bt.h"
//#include "btBeacon.h"

#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"

#define NON_CONNECTABLE_ADV_INTERVAL                                                             \
    MSEC_TO_UNITS(100,                                                                           \
                  UNIT_0_625_MS) /**< The advertising interval for non-connectable advertisement \
                                    (100 ms). This value can vary between 100ms to 10.24s). */
#define APP_BEACON_INFO_LENGTH 0x17 /**< Total length of information advertised by the Beacon. */


#define APP_ADV_DATA_LENGTH    0x15 /**< Length of manufacturer specific data in the advertisement. \
                                     */
#define APP_DEVICE_TYPE        0x02 /**< 0x02 refers to Beacon. */
#define APP_MEASURED_RSSI      0xC3 /**< The Beacon's measured RSSI at 1 meter distance in dBm. */
//#define APP_COMPANY_IDENTIFIER          0x0059                             /**< Company identifier
//for Nordic Semiconductor ASA. as per www.bluetooth.org. */
#define APP_MAJOR_VALUE        0x01, 0x02 /**< Major value used to identify Beacons. */
#define APP_MINOR_VALUE        0x03, 0x04 /**< Minor value used to identify Beacons. */

#define APP_BEACON_UUID                 0x01, 0x12, 0x23, 0x34, \
                                        0x45, 0x56, 0x67, 0x78, \
                                        0x89, 0x9a, 0xab, 0xbc, \
                                        0xcd, 0xde, 0xef, 0xf0            /**< Proprietary UUID for Beacon. */
#define APP_SERIAL_PLACEHOLDER  0x31, 0x31, 0x33, 0x30, 0x30, 0x30, \
                                0x34, 0x38, 0x30, 0x35


static ble_gap_adv_params_t
               m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */
static uint8_t m_adv_handle =
    BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED]; /**< Buffer for storing an encoded
                                                                advertising set. */


/**@brief Struct that contains pointers to the encoded advertising data. */
static ble_gap_adv_data_t m_adv_data = {
    .adv_data      = {.p_data = m_enc_advdata, .len = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED},
    .scan_rsp_data = {.p_data = NULL, .len = 0

    }};


static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] = /**< Information advertised by the Beacon. */
    {
        APP_DEVICE_TYPE,     // Manufacturer specific information. Specifies the device type in this
                             // implementation.
        APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
                             // manufacturer specific data in this implementation.
        APP_BEACON_UUID,     // 128 bit UUID value.
        APP_MAJOR_VALUE,   // Major arbitrary value that can be used to distinguish between Beacons.
        APP_MINOR_VALUE,   // Minor arbitrary value that can be used to distinguish between Beacons.
        APP_MEASURED_RSSI, // Manufacturer specific information. The Beacon's measured TX power in
                           // this implementation.
//        APP_SERIAL_PLACEHOLDER,
};


void btBeacon_advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
#if defined(S112)
        NRF_LOG_INFO("**** SOFTDEVICE s112 ****");
#elif defined(S113)
        NRF_LOG_INFO("**** SOFTDEVICE s113 ****");
#elif defined(S132)
        NRF_LOG_INFO("**** SOFTDEVICE s132 ****");
#elif defined(S140)
        NRF_LOG_INFO("**** SOFTDEVICE s140 ****");
#endif

    ble_advdata_manuf_data_t manuf_specific_data;

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;

    // memcpy(&m_beacon_info[APP_BEACON_INFO_LENGTH],APP_BEACON_MESSAGE,APP_BEACON_MESSAGE_LEN);
    manuf_specific_data.data.p_data = (uint8_t *)m_beacon_info;
    manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;

    // Build and set advertising data.
//    memset(&advdata, 0, sizeof(advdata));
    memset(&advdata, 0, sizeof(ble_advdata_t)); // REM

    advdata.name_type             = BLE_ADVDATA_NO_NAME;
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

    // Initialize advertising parameters (used when starting advertising).
    memset(&m_adv_params, 0, sizeof(m_adv_params));

//    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
    m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED; // REM
    m_adv_params.p_peer_addr     = NULL; // Undirected advertisement.
    m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
    m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
    m_adv_params.duration        = 0; // Never time out.
    m_adv_params.max_adv_evts    = 0;
// REM added
    m_adv_params.set_id         = 7;
    m_adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
    m_adv_params.secondary_phy   = BLE_GAP_PHY_2MBPS;
    m_adv_params.scan_req_notification = 0;

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
    NRF_LOG_INFO("errorcode 1 %d", err_code);
    APP_ERROR_CHECK(err_code);

    err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
    NRF_LOG_INFO("errorcode 2 %d", err_code);
    APP_ERROR_CHECK(err_code);
}


void btBeacon_advertising_start(void)
{
    ret_code_t err_code;

    err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
    NRF_LOG_INFO("BEACON advertising start %d", err_code);
    APP_ERROR_CHECK(err_code);
}


void btBeacon_advertising_stop(void)
{
    sd_ble_gap_adv_stop(m_adv_handle);
}

Parents
  • Hello,

    The 'BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED' type only allows data in the scan response packet, so you will have to place the encoded data in the scan response like this:

    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = NULL,
            .len    = 0
        },
        .scan_rsp_data =
        {
            .p_data = m_enc_advdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED
    
        }
    };
    

    And then update the encode function in advertising_init to use the .scan_rsp_data buffer instead:

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
    
        ble_advdata_manuf_data_t manuf_specific_data;
    
        manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
    #if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
        // If USE_UICR_FOR_MAJ_MIN_VALUES is defined, the major and minor values will be read from the
        // UICR instead of using the default values. The major and minor values obtained from the UICR
        // are encoded into advertising data in big endian order (MSB First).
        // To set the UICR used by this example to a desired value, write to the address 0x10001080
        // using the nrfjprog tool. The command to be used is as follows.
        // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val <your major/minor value>
        // For example, for a major value and minor value of 0xabcd and 0x0102 respectively, the
        // the following command should be used.
        // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val 0xabcd0102
        uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16;
        uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF);
    
        uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO;
    
        m_beacon_info[index++] = MSB_16(major_value);
        m_beacon_info[index++] = LSB_16(major_value);
    
        m_beacon_info[index++] = MSB_16(minor_value);
        m_beacon_info[index++] = LSB_16(minor_value);
    #endif
    
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_NO_NAME;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        m_adv_params.set_id          = 7;
        m_adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
        m_adv_params.secondary_phy   = BLE_GAP_PHY_2MBPS;
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    }
    

    Also, you have to remove the "advdata.flags" line as the BT specification does not permit this field in a scan response packet.

        advdata.flags                 = flags;

    Best regards,

    Vidar

Reply
  • Hello,

    The 'BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED' type only allows data in the scan response packet, so you will have to place the encoded data in the scan response like this:

    static ble_gap_adv_data_t m_adv_data =
    {
        .adv_data =
        {
            .p_data = NULL,
            .len    = 0
        },
        .scan_rsp_data =
        {
            .p_data = m_enc_advdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_MAX_SUPPORTED
    
        }
    };
    

    And then update the encode function in advertising_init to use the .scan_rsp_data buffer instead:

    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
    
        ble_advdata_manuf_data_t manuf_specific_data;
    
        manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    
    #if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
        // If USE_UICR_FOR_MAJ_MIN_VALUES is defined, the major and minor values will be read from the
        // UICR instead of using the default values. The major and minor values obtained from the UICR
        // are encoded into advertising data in big endian order (MSB First).
        // To set the UICR used by this example to a desired value, write to the address 0x10001080
        // using the nrfjprog tool. The command to be used is as follows.
        // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val <your major/minor value>
        // For example, for a major value and minor value of 0xabcd and 0x0102 respectively, the
        // the following command should be used.
        // nrfjprog --snr <Segger-chip-Serial-Number> --memwr 0x10001080 --val 0xabcd0102
        uint16_t major_value = ((*(uint32_t *)UICR_ADDRESS) & 0xFFFF0000) >> 16;
        uint16_t minor_value = ((*(uint32_t *)UICR_ADDRESS) & 0x0000FFFF);
    
        uint8_t index = MAJ_VAL_OFFSET_IN_BEACON_INFO;
    
        m_beacon_info[index++] = MSB_16(major_value);
        m_beacon_info[index++] = LSB_16(major_value);
    
        m_beacon_info[index++] = MSB_16(minor_value);
        m_beacon_info[index++] = LSB_16(minor_value);
    #endif
    
        manuf_specific_data.data.p_data = (uint8_t *) m_beacon_info;
        manuf_specific_data.data.size   = APP_BEACON_INFO_LENGTH;
    
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_NO_NAME;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // Initialize advertising parameters (used when starting advertising).
        memset(&m_adv_params, 0, sizeof(m_adv_params));
    
        m_adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_NONCONNECTABLE_SCANNABLE_UNDIRECTED;
        m_adv_params.p_peer_addr     = NULL;    // Undirected advertisement.
        m_adv_params.filter_policy   = BLE_GAP_ADV_FP_ANY;
        m_adv_params.interval        = NON_CONNECTABLE_ADV_INTERVAL;
        m_adv_params.duration        = 0;       // Never time out.
        m_adv_params.set_id          = 7;
        m_adv_params.primary_phy     = BLE_GAP_PHY_1MBPS;
        m_adv_params.secondary_phy   = BLE_GAP_PHY_2MBPS;
    
        err_code = ble_advdata_encode(&advdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
    
        err_code = sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, &m_adv_params);
        APP_ERROR_CHECK(err_code);
    }
    

    Also, you have to remove the "advdata.flags" line as the BT specification does not permit this field in a scan response packet.

        advdata.flags                 = flags;

    Best regards,

    Vidar

Children
Related