Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Set a device name in beacon example SDK 15

Hello,

I'm working with PCA10040 EVB.

I've followed this FAQ that shows how to add a device name.

But function sd_ble_gap_adv_set_configure() (called at the end of advertising_init()) returns NRF_ERROR_INVALID_ADDR (16).

When I increased APP_BEACON_INFO_LENGTH from 0x17 to 0x1B, and APP_ADV_DATA_LENGTH from 0x15 to 0x19 (4 bytes for "Test"), function ble_advdata_encode()  (called at the end of advertising_init()) returns NRF_ERROR_DATA_SIZE (12).

The main file includes the following definitions:

#define APP_BLE_CONN_CFG_TAG            1                                  /**< A tag identifying the SoftDevice BLE configuration. */
#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 DEAD_BEEF                       0xDEADBEEF                         /**< Value used as error code on stack dump, can be used to identify stack location on stack unwind. */

I've included, defined and declared as follows:

#include "ble_advdata.h" // In order to add device name
#define BLE_GAP_ADV_TYPE_ADV_SCAN_IND 0x02 // In order to add device name
#define DEVICE_NAME   "Test"

static uint8_t              m_enc_srdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded scan set. */

I've added these lines between "ble_stack_init()" and "advertising_init()":

    ret_code_t err_code;
    ble_gap_conn_sec_mode_t sec_mode;
    BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
    err_code = sd_ble_gap_device_name_set(&sec_mode,
                                     (const uint8_t *)DEVICE_NAME,
                                      strlen(DEVICE_NAME));
    APP_ERROR_CHECK(err_code);

I've changed m_adv_data.scan_rsp_data field from:

.scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0
    }

to:

.scan_rsp_data =
    {
        .p_data = m_enc_srdata,
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    }

The advertising_init() function is:

static void advertising_init(void)
{
    uint32_t      err_code;
    ble_advdata_t advdata;
    
    ble_advdata_t srdata; // This line was added !!!
    
    uint8_t       flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;

    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; // This line was commented !!!
    
    advdata.flags                 = flags;
    advdata.p_manuf_specific_data = &manuf_specific_data;

/********************** Added code ************************/
    // Build and set scan response data.
    memset(&srdata, 0, sizeof(srdata));
    srdata.name_type             = BLE_ADVDATA_FULL_NAME;

    err_code = ble_advdata_encode(&srdata, m_adv_data.scan_rsp_data.p_data, &m_adv_data.scan_rsp_data.len);
    APP_ERROR_CHECK(err_code);
/**********************************************************/
    // 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_ADV_SCAN_IND;                               // This line was added
    //m_adv_params.properties.type = BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED;   // This line was commented

    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.
    
    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_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);
}

Please help me to understand what I'm doing wrong or missing.

Thanks in advance for your help!

Parents
  • Hi,

    I found the root cause to be BLE_GAP_ADV_TYPE_ADV_SCAN_IND. The value that you have chosen for this define is 0x02, but that corresponds to BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY. Rather it looks like you should have used BLE_GAP_ADV_TYPE_NONCONNECTABLE_SCANNABLE_UNDIRECTED. I suggest using that define directly instead of defining it on your own, just as BLE_GAP_ADV_TYPE_NONCONNECTABLE_NONSCANNABLE_UNDIRECTED was used directly in the original example. You can find all the available advertising type definitions in ble_gap.h.

    Fixing the above, and keeping everything else as you posted it (still keeping APP_BEACON_INFO_LENGTH and APP_ADV_DATA_LENGTH at 0x17 and 0x15 respectively) the example runs without issue, and it advertises as "Test" in the scan response data.

    The reason why increasing APP_BEACON_INFO_LENGTH and APP_ADV_DATA_LENGTH gives an NRF_ERROR_DATA_SIZE error is that those defines control the size of the "manufacturer specific data", which is one of the advertising types that can be part of an advertising packet. This is the advertising data type used for storing the beacon data, and the beacon data itself is formatted into the m_beacon_info uint8_t array. You simply made that array too long to fit within the advertising packet, which made ble_advdata_encode() return with that error. The device name, on the other hand, is stored in another advertising type and has nothing to do with the manufacturer specific data.

    One further comment: Commenting out the line
    advdata.name_type             = BLE_ADVDATA_NO_NAME;
    actually makes no difference, as the BLE_ADVDATA_NO_NAME enum value is 0. It is better to keep it there, so that you are explicitly stating that there is no device name included in advdata.

    Please note that using scannable advertising uses more power (sending advertising data, listening for scan requests, then maybe sending scan response data) than nonscannable advertising (sending advertising data.) Also note that the beacon example is made for easily being modified to conform to the iBeacon specification (obtainable from mfi.apple.com.) Changing to scannable and/or changing the format of the beacon data in the manufacturer specific data may break with that specification. If you are not planning on following the iBeacon specification then you are of course free to do those changes.

    Regards,
    Terje

  • Hello Terje,

    Thank you very much for your quick reply and detailed explanation.

    It works fine. The nRF Connect recognizes the device as "Test".

    Best regards,

    Ratson

  • can you please share complete stack/code you made changes to set beacon device name.it would be really helpful

  • also  #if defined(USE_UICR_FOR_MAJ_MIN_VALUES) is not highlited in beacon stack...so it can not use major minor valuse ...what could be the reason

Reply Children
No Data
Related