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

Eddystone TLM + iBeacon UUID advertising issue

Hi,

I have an issue with broadcasting Eddystone TLM + iBeacon, my project is based ble_app_eddystone example and nRF5_SDK_17.0.0_9d13099, SOC is nRF52832.

Beacon advertise Eddystone UID +Eddystone TLM +Eddystone URL,  works ok.

The customer need  Eddystone TLM+ iBeacon uuid, so I modified the function es_adv_frame_fill_non_connectable_adv_data() in es_adv_frame.c (line 117), ad custom frame ibeacon. please see the attachement.

It can advertise Eddystone UID +Eddystone URL+ iBeacon, and no problem.  But when I configure to advertising Eddystone UID +Eddystone URL+ Eddystone TLM + iBeacon UUID, it raise an app erro, 

00> <info> beacon_slot_parser: ES_FRAME_TYPE_UID
00>
00> <info> beacon_slot_parser: ES_FRAME_TYPE_TLM
00>
00> <info> beacon_slot_parser: ES_FRAME_TYPE_URL
00>
00> <info> beacon_slot_parser: CFX_BEACON_FRAME_TYPE_IBEACON
00>
00> <info> beacon_main: Enter main loop
00>
00> <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE] at ../../../../../communication/beacon_adv.c:85
00>
00> PC at: 0x0003607F
00>
00> <error> app: End of error report

I attached code of  es_adv_frame.c and beacon_adv.c and sdk_config.h , please help me analyze, why eddystoneTLM + ibeacon  slot failed ?     

Thank you very much.

/**
 * Copyright (c) 2016 - 2020, Nordic Semiconductor ASA
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this
 *    list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form, except as embedded into a Nordic
 *    Semiconductor ASA integrated circuit in a product or a software update for
 *    such product, must reproduce the above copyright notice, this list of
 *    conditions and the following disclaimer in the documentation and/or other
 *    materials provided with the distribution.
 *
 * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * 4. This software, with or without modification, must only be used with a
 *    Nordic Semiconductor ASA integrated circuit.
 *
 * 5. Any software provided in binary form under this license must not be reverse
 *    engineered, decompiled, modified and/or disassembled.
 *
 * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
#include "es_adv_frame.h"
#include "es_slot.h"
#include "beacon_adv.h"

/**@brief Function for setting advertisement data, using 'ble_advdata_encode'.
 *
 * @param[in] p_scrsp_data      Scan response data.
 * @param[in] p_es_data_array   Eddystone service data array.
 */
static void fill_adv_data(ble_advdata_t * p_scrsp_data, uint8_array_t * p_es_data_array, ble_gap_adv_data_t * const p_adv_data)
{
    ble_advdata_t adv_data;
    ret_code_t    err_code;
    ble_uuid_t    adv_uuids[]   = {{ES_UUID, BLE_UUID_TYPE_BLE}};
    uint8_array_t es_data_array = {0};

    ble_advdata_service_data_t service_data; // Structure to hold Service Data.

    service_data.service_uuid = APP_ES_UUID; // Eddystone UUID to allow discoverability on iOS devices.

    service_data.data = (p_es_data_array != NULL) ? *p_es_data_array : es_data_array;

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

    adv_data.name_type               = BLE_ADVDATA_NO_NAME;
    adv_data.flags                   = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    adv_data.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
    adv_data.uuids_complete.p_uuids  = adv_uuids;
    adv_data.p_service_data_array    = &service_data;
    adv_data.service_data_count      = (p_es_data_array != NULL) ? 1 : 0;

    err_code = ble_advdata_encode(&adv_data,
                                  p_adv_data->adv_data.p_data,
                                  &p_adv_data->adv_data.len);
    APP_ERROR_CHECK(err_code);
    if (p_scrsp_data != NULL)
    {
        err_code = ble_advdata_encode(p_scrsp_data,
                                      p_adv_data->scan_rsp_data.p_data,
                                      &p_adv_data->scan_rsp_data.len);
        APP_ERROR_CHECK(err_code);
    }
    else
    {
        p_adv_data->scan_rsp_data.p_data = NULL;
        p_adv_data->scan_rsp_data.len    = 0;
    }
}


void es_adv_frame_fill_connectable_adv_data(ble_advdata_t * p_scrsp_data, ble_gap_adv_data_t * const p_adv_data)
{
    fill_adv_data(p_scrsp_data, NULL, p_adv_data);
}


void es_adv_frame_fill_non_connectable_adv_data(uint8_t slot_no, bool etlm, ble_gap_adv_data_t * const p_adv_data)
{
    uint8_array_t         es_data_array = {0};
    const es_slot_reg_t * p_reg         = es_slot_get_registry();

    if (etlm)
    {
        es_slot_etlm_update(slot_no);

        // If eTLM, the incoming slot_no points to the corresponding EID slot, update to point to TLM slot.
        slot_no = p_reg->tlm_slot;
    }

    // If TLM, update the TLM data.
    else if (p_reg->slots[slot_no].adv_frame.type == ES_FRAME_TYPE_TLM)
    {
        es_slot_tlm_update();
    }


    if(p_reg->slots[slot_no].adv_frame.type > ES_FRAME_TYPE_EID)
    {
        if(!beacon_adv_custom_frame_prepare((es_slot_t*)&p_reg->slots[slot_no], p_adv_data)) {
        	/*  Custom frame returning false means that the actual adv data is
             * handled elsewhere, so just return here*/
            return;
        }

    }

    es_data_array.p_data = (uint8_t *)&p_reg->slots[slot_no].adv_frame.frame;
    es_data_array.size   = p_reg->slots[slot_no].adv_frame.length;

    fill_adv_data(NULL, &es_data_array, p_adv_data);
}

#include "app_error.h"
#include "ble_gap.h"
#include "ble_advdata.h"
#include "es_slot.h"

#include "beacon_communication_typedefs.h"
#include "beacon_adv.h"
#include "beacon_acc_statistics.h"

#include "beacon_ibeacon.h"
#include "beacon_tri_frame.h"


#define NRF_LOG_MODULE_NAME beacon_adv
#include "nrf_log.h"
NRF_LOG_MODULE_REGISTER();


/* Private function declarations */

/**
 * Prepare an rms/minmax frame
 *
 * @param p_es_slot is a pointer to the slot containing the frame
 */
static void m_beacon_adv_populate_acc_stats_frame(es_slot_t* p_es_slot);



/**@brief Function for setting advertisement data, using 'ble_advdata_encode'.
 *
 * @param[in] p_scrsp_data      Scan response data.
 * @param[in] p_es_data_array   Eddystone service data array.
 */
static void m_beacon_adv_fill_proprietary_data(uint8_t type, ble_gap_adv_data_t * const p_adv_data);

/* Private function implementations */

static void m_beacon_adv_populate_acc_stats_frame(es_slot_t* p_es_slot)
{
    beacon_acc_statistics_prepare(p_es_slot);
}



static void m_beacon_adv_fill_proprietary_data(uint8_t type, ble_gap_adv_data_t * const p_adv_data)
{
    ble_advdata_t adv_data;
    ret_code_t    err_code;

    static ble_advdata_manuf_data_t manuf_data;


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

    adv_data.p_manuf_specific_data = &manuf_data;

    switch(type) {
        case BEACON_FRAME_TYPE_IBEACON:
            adv_data.name_type = BLE_ADVDATA_NO_NAME;
            adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
            beacon_ibeacon_get_advertisement_data(&manuf_data);

            break;
        case BEACON_FRAME_TYPE_TRI:
            adv_data.name_type = BLE_ADVDATA_NO_NAME;
         //  adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

            /*add for sdk17*/
            beacon_tri_frame_get_advertisement_data(&manuf_data);

            break;

        default:
            NRF_LOG_INFO("Unidentified proprietary frame 0x%x", type);
            return;
            break;
    }

  //  err_code = ble_advdata_set(&adv_data, NULL);  //special for sdk14

	/*add for sdk17*/
    err_code = ble_advdata_encode(&adv_data, p_adv_data->adv_data.p_data, &p_adv_data->adv_data.len);
    APP_ERROR_CHECK(err_code);
    p_adv_data->scan_rsp_data.p_data = NULL;
    p_adv_data->scan_rsp_data.len    = 0;

}


bool beacon_adv_custom_frame_prepare(es_slot_t* p_es_slot, ble_gap_adv_data_t * const p_adv_data)
{
    uint8_t type = p_es_slot->adv_frame.type;
    switch(type) {
        case BEACON_FRAME_TYPE_ACC_STATISTICS:
            m_beacon_adv_populate_acc_stats_frame(p_es_slot);
            return true;
        break;

        case BEACON_FRAME_TYPE_IBEACON:
            m_beacon_adv_fill_proprietary_data(BEACON_FRAME_TYPE_IBEACON, p_adv_data);
            return false;
        case BEACON_FRAME_TYPE_TRI:
            m_beacon_adv_fill_proprietary_data(BEACON_FRAME_TYPE_TRI, p_adv_data);
            return false;

        default:
            NRF_LOG_INFO("Unknown custom frame 0x%x slot %d", p_es_slot->adv_frame.type, p_es_slot->slot_no);
            return false;
        break;
    }

}
4251.sdk_config.h

Best regards,

Susan

  • Hello Susan,

    00> <info> beacon_main: Enter main loop
    00>
    00> <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE] at ../../../../../communication/beacon_adv.c:85
    00>
    00> PC at: 0x0003607F
    00>
    00> <error> app: End of error report

    I attached code of  es_adv_frame.c and beacon_adv.c and sdk_config.h , please help me analyze, why eddystoneTLM + ibeacon  slot failed ?   

    It seems that you are getting an NRF_ERROR_DATA_SIZE returned from your ble_advdata_encode call.
    The ble_advdata_encode API Reference says the following about the error:

    NRF_ERROR_DATA_SIZE If the operation failed because not all the requested data could fit into the provided buffer or some encoded AD structure is too long and its length cannot be encoded with one octet.

    Could you verify that the contents of your adv_data is in line with the requirements of the ble_advdata_encode function?
    For instance, how long is the total data you are trying to fit into the advertising?
    You may not exceed the 31 byte limit, and you must also remember to account for overhead for each datafield.

    Best regards,
    Karl

  • Hi Karl,

     the total data I try to fit into the advertising is 3bytes (flags) +2(Length +Type)+2bytes (company_identifier) +23byte(m_beacon_ibeacon_payload) , total 30Bytes. I attached the code, please review for me, thank you. 

    /**@file
     *
     * @defgroup   iBeacon handler
     * @{
     * @ingroup 
     * @brief    Module for handling iBeacon operationality.
     *
     * @details  The module handles the storing and forwarding of the
     * components needed for an iBeacon frame.
     *
     */
    
    #include <stdlib.h>
    
    #include "ble_advdata.h"
    #include "sdk_config.h"
    #include "app_error.h"
    
    #include "beacon_flash.h"
    #include "beacon_ibeacon.h"
    #include "beacon_app_typedefs.h"
    
    #define NRF_LOG_MODULE_NAME beacon_ibeacon
    #include "nrf_log.h"
    NRF_LOG_MODULE_REGISTER();
    
    
    /** Private definitions */
    
    #define BEACON_IBEACON_FRAME_LENGTH                0x17                             /**< Total length of information advertised by the Beacon */
    #define BEACON_IBEACON_ADV_DATA_LENGTH             0x15                             /**< Length of manufacturer specific data in the advertisement */
    #define BEACON_IBEACON_DEVICE_TYPE                 0x02                             /**< 0x02 refers to iBeacon */
    #define BEACON_IBEACON_DEFAULT_MEASURED_RSSI       0xd8                             /**< Measured RSSI at 1 meter distance in dBm */
    #define BEACON_IBEACON_DEFAULT_COMPANY_IDENTIFIER  0x0059                           /**< Company identifier for Nordic Semiconductor */
    #define BEACON_IBEACON_DEFAULT_MAJOR_0_VALUE         0x00                           /**< Major value used to identify iBeacons */
    #define BEACON_IBEACON_DEFAULT_MAJOR_1_VALUE         0x00                           /**< Major value used to identify iBeacons */
    #define BEACON_IBEACON_DEFAULT_MINOR_0_VALUE         0x00                           /**< Minor value used to identify iBeacons */
    #define BEACON_IBEACON_DEFAULT_MINOR_1_VALUE         0x00                          /**< Minor value used to identify iBeacons */
    #define BEACON_IBEACON_DEFAULT_UUID                { 0x01, 0x02, 0x03, 0x04, \
                                                    0x05, 0x06, 0x07, 0x08, \
                                                    0x09, 0x0a, 0x0b, 0x0c, \
                                                    0x0d, 0x0e, 0x0f, 0x10 }                /**< Proprietary UUID for iBeacon */
    
    typedef struct {
        uint8_t id;     /**< Packet ID; Equal to 2 for an iBeacon */
        uint8_t len;    /**< Length of the remaining data in the payload */
        uint8_t uid[16];      /**< Beacon UID */
        uint8_t major_0;       /**< Beacon major ID */        
        uint8_t major_1;
        uint8_t minor_0;       /**< Beacon minor ID */
        uint8_t minor_1;
        uint8_t tx;        /**< Tx power received at 1 meter in dBm */
    }__attribute__((packed)) beacon_ibeacon_payload_t;
    
    /** Private variable declarations */
    
    static beacon_ibeacon_params_t m_ibeacon_current_params = {
        .company_id = BEACON_IBEACON_DEFAULT_COMPANY_IDENTIFIER,
        .uid = BEACON_IBEACON_DEFAULT_UUID,
    
        .major_0 = BEACON_IBEACON_DEFAULT_MAJOR_0_VALUE,
        .major_1 = BEACON_IBEACON_DEFAULT_MAJOR_1_VALUE,
        .minor_0 = BEACON_IBEACON_DEFAULT_MINOR_0_VALUE,
        .minor_1 = BEACON_IBEACON_DEFAULT_MINOR_1_VALUE,
    };
    
    /* The advertisement payload */
    static beacon_ibeacon_payload_t m_beacon_ibeacon_payload = {
    
        .id = BEACON_IBEACON_DEVICE_TYPE,
        .len = BEACON_IBEACON_ADV_DATA_LENGTH,
        .uid = BEACON_IBEACON_DEFAULT_UUID,
        .major_0 =BEACON_IBEACON_DEFAULT_MAJOR_0_VALUE,    //if don't comment out this five bytes, will raise NRF_ERROR_DATA_SIZE   
    	.major_1 =BEACON_IBEACON_DEFAULT_MAJOR_1_VALUE,
        .minor_0 = BEACON_IBEACON_DEFAULT_MINOR_0_VALUE,
    	.minor_1 = BEACON_IBEACON_DEFAULT_MINOR_1_VALUE,
        .tx = BEACON_IBEACON_DEFAULT_MEASURED_RSSI,
    };
    
    /* Manufacturer data struct. This is passed on to the advertisement module. */
    static ble_advdata_manuf_data_t m_beacon_ibeacon_manuf_data = {
            .company_identifier = BEACON_IBEACON_DEFAULT_COMPANY_IDENTIFIER,
            .data.p_data = (uint8_t *) &m_beacon_ibeacon_payload,
            .data.size   =  sizeof(beacon_ibeacon_payload_t),
    };
    
    /** Private function declarations */
    
    /** @brief set current advertisement payload
     */
    static void m_beacon_ibeacon_set_payload(void);
    
    /** Private function implementations */
    
    static void m_beacon_ibeacon_set_payload(void)
    {
        m_beacon_ibeacon_manuf_data.company_identifier = m_ibeacon_current_params.company_id;
        memcpy(m_beacon_ibeacon_payload.uid, m_ibeacon_current_params.uid, sizeof(m_beacon_ibeacon_payload.uid));
        m_beacon_ibeacon_payload.major_0 = m_ibeacon_current_params.major_0;
        m_beacon_ibeacon_payload.major_1 = m_ibeacon_current_params.major_1;
        m_beacon_ibeacon_payload.minor_0 = m_ibeacon_current_params.minor_0;
        m_beacon_ibeacon_payload.minor_1 = m_ibeacon_current_params.minor_1;
        m_beacon_ibeacon_payload.tx = m_ibeacon_current_params.ranging_data;
    }
    
    /** Public function implementations  */
    
    ret_code_t beacon_ibeacon_init(void)
    {
        /* See if there is a config saved, and configure the module accoridingly if so */
        if(beacon_flash_access_ibeacon_params(&m_ibeacon_current_params, BEACON_FLASH_ACCESS_READ) == NRF_SUCCESS) {
            beacon_ibeacon_configure(&m_ibeacon_current_params);
        }
    
        return NRF_SUCCESS;
    }
    
    ret_code_t beacon_ibeacon_configure(beacon_ibeacon_params_t* params)
    {
        if(params == NULL) {
            return NRF_ERROR_INVALID_ADDR;
        }
        if(memcmp(params, &m_ibeacon_current_params, sizeof(beacon_ibeacon_params_t)) == 0) {
            /* Current config matches, return success  */
            m_beacon_ibeacon_set_payload();
            return NRF_SUCCESS;
        }
        memcpy(&m_ibeacon_current_params, params, sizeof(beacon_ibeacon_params_t));
        m_beacon_ibeacon_set_payload();
        beacon_flash_access_ibeacon_params(&m_ibeacon_current_params, BEACON_FLASH_ACCESS_WRITE);
    
        return NRF_SUCCESS;
    }
    
    void beacon_ibeacon_get_advertisement_data(ble_advdata_manuf_data_t* p_manuf_data)
    {   
        NRF_LOG_INFO("sizeof_my_maunf: %d", sizeof(m_beacon_ibeacon_manuf_data));
        memcpy(p_manuf_data, &m_beacon_ibeacon_manuf_data, sizeof(ble_advdata_manuf_data_t));
    
    }
    
    #include "app_error.h"
    #include "ble_gap.h"
    #include "ble_advdata.h"
    #include "es_slot.h"
    
    #include "beacon_communication_typedefs.h"
    #include "beacon_adv.h"
    #include "beacon_acc_statistics.h"
    
    #include "beacon_ibeacon.h"
    #include "beacon_tri_frame.h"
    
    
    #define NRF_LOG_MODULE_NAME beacon_adv
    #include "nrf_log.h"
    NRF_LOG_MODULE_REGISTER();
    
    
    /* Private function declarations */
    
    /**
     * Prepare an rms/minmax frame
     *
     * @param p_es_slot is a pointer to the slot containing the frame
     */
    static void m_beacon_adv_populate_acc_stats_frame(es_slot_t* p_es_slot);
    
    
    
    /**@brief Function for setting advertisement data, using 'ble_advdata_encode'.
     *
     * @param[in] p_scrsp_data      Scan response data.
     * @param[in] p_es_data_array   Eddystone service data array.
     */
    static void m_beacon_adv_fill_proprietary_data(uint8_t type, ble_gap_adv_data_t * const p_adv_data);
    
    /* Private function implementations */
    
    static void m_beacon_adv_populate_acc_stats_frame(es_slot_t* p_es_slot)
    {
        beacon_acc_statistics_prepare(p_es_slot);
    }
    
    
    
    static void m_beacon_adv_fill_proprietary_data(uint8_t type, ble_gap_adv_data_t * const p_adv_data)
    {
        ble_advdata_t adv_data;
        ret_code_t    err_code;
    
        static ble_advdata_manuf_data_t manuf_data;
    
        // Build and set advertising data.
        memset(&adv_data, 0, sizeof(ble_advdata_t));
    
    
        switch(type) {
            case BEACON_FRAME_TYPE_IBEACON:
                adv_data.name_type = BLE_ADVDATA_NO_NAME;
                adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
                beacon_ibeacon_get_advertisement_data(&manuf_data);
                adv_data.p_manuf_specific_data = &manuf_data;
    
                NRF_LOG_INFO("sizeof_manuf %d", sizeof(ble_advdata_manuf_data_t));
    
                break;
            case BEACON_FRAME_TYPE_TRI:
                adv_data.name_type = BLE_ADVDATA_NO_NAME;
             //  adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
    
                /*add for sdk17*/
                beacon_tri_frame_get_advertisement_data(&manuf_data);
    
                break;
    
            default:
                NRF_LOG_INFO("Unidentified proprietary frame 0x%x", type);
                return;
                break;
        }
    
      //  err_code = ble_advdata_set(&adv_data, NULL);  //special for sdk14
    
    	/*add for sdk17*/
        err_code = ble_advdata_encode(&adv_data, p_adv_data->adv_data.p_data, &p_adv_data->adv_data.len);
    	NRF_LOG_INFO("encode data length: %d", p_adv_data->adv_data.len);
        APP_ERROR_CHECK(err_code);
        p_adv_data->scan_rsp_data.p_data = NULL;
        p_adv_data->scan_rsp_data.len    = 0;
    
    }
    
    
    bool beacon_adv_custom_frame_prepare(es_slot_t* p_es_slot, ble_gap_adv_data_t * const p_adv_data)
    {
        uint8_t type = p_es_slot->adv_frame.type;
        switch(type) {
            case BEACON_FRAME_TYPE_ACC_STATISTICS:
                m_beacon_adv_populate_acc_stats_frame(p_es_slot);
                return true;
            break;
    
            case BEACON_FRAME_TYPE_IBEACON:
                m_beacon_adv_fill_proprietary_data(BEACON_FRAME_TYPE_IBEACON, p_adv_data);
                return false;
            case BEACON_FRAME_TYPE_TRI:
                m_beacon_adv_fill_proprietary_data(BEACON_FRAME_TYPE_TRI, p_adv_data);
                return false;
    
            default:
                NRF_LOG_INFO("Unknown custom frame 0x%x slot %d", p_es_slot->adv_frame.type, p_es_slot->slot_no);
                return false;
            break;
        }
    
    }
    

    I do more test, if comment out five bytes in the payload, and don't include flags , reduce the total data to 22 Bytes, it can advertising iBeacon + Eddystone UID+ TLM+URL ,  no error.

    00> <info> beacon_slot_parser: ES_FRAME_TYPE_UID
    00>
    00> <info> beacon_slot_parser: ES_FRAME_TYPE_TLM
    00>
    00> <info> beacon_slot_parser: ES_FRAME_TYPE_URL
    00>
    00> <info> beacon_slot_parser: BEACON_FRAME_TYPE_IBEACON
    00>
    00> <info> beacon_main: Enter main loop
    00>
    00> <info> beacon_ibeacon: sizeof_my_maunf: 12
    00>
    00> <info> beacon_adv: sizeof_manuf : 12
    00>
    00> <info> beacon_adv: encode data length: 22

    typedef struct {
    uint8_t id; /**< Packet ID; Equal to 2 for an iBeacon */
    uint8_t len; /**< Length of the remaining data in the payload */
    uint8_t uid[16]; /**< Beacon UID */
     //uint8_t major_0; /**< Beacon major ID */
    // uint8_t major_1;
    // uint8_t minor_0; /**< Beacon minor ID */
    // uint8_t minor_1;
    // uint8_t tx; /**< Tx power received at 1 meter in dBm */
    }__attribute__((packed)) beacon_ibeacon_payload_t;

    /* The advertisement payload */
    static beacon_ibeacon_payload_t m_beacon_ibeacon_payload = {

    .id = BEACON_IBEACON_DEVICE_TYPE,
    .len = BEACON_IBEACON_ADV_DATA_LENGTH,
    .uid = BEACON_IBEACON_DEFAULT_UUID,
    //.major_0 =BEACON_IBEACON_DEFAULT_MAJOR_0_VALUE, 
     //.major_1 =BEACON_IBEACON_DEFAULT_MAJOR_1_VALUE,
    //.minor_0 = BEACON_IBEACON_DEFAULT_MINOR_0_VALUE,
    //.minor_1 = BEACON_IBEACON_DEFAULT_MINOR_1_VALUE,
     //.tx = BEACON_IBEACON_DEFAULT_MEASURED_RSSI,
    };

    /* Manufacturer data struct. This is passed on to the advertisement module. */
    static ble_advdata_manuf_data_t m_beacon_ibeacon_manuf_data = {
    .company_identifier = BEACON_IBEACON_DEFAULT_COMPANY_IDENTIFIER,
    .data.p_data = (uint8_t *) &m_beacon_ibeacon_payload,
    .data.size = sizeof(beacon_ibeacon_payload_t),
    };

    static void m_beacon_adv_fill_proprietary_data(uint8_t type, ble_gap_adv_data_t * const p_adv_data)
    {
    ble_advdata_t adv_data;
    ret_code_t err_code;

    static ble_advdata_manuf_data_t manuf_data;

    // Build and set advertising data.
    memset(&adv_data, 0, sizeof(adv_data));

    switch(type) {
    case CFX_BEACON_FRAME_TYPE_IBEACON:
    adv_data.name_type = BLE_ADVDATA_NO_NAME;
    // adv_data.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;

    cfx_beacon_ibeacon_get_advertisement_data(&manuf_data);
    adv_data.p_manuf_specific_data = &manuf_data;

    NRF_LOG_INFO("sizeof_manuf %d", sizeof(ble_advdata_manuf_data_t));

    break;

    }

    /*add for sdk17*/
    err_code = ble_advdata_encode(&adv_data, p_adv_data->adv_data.p_data, &p_adv_data->adv_data.len);
    NRF_LOG_INFO("encode data length: %d", p_adv_data->adv_data.len);

    APP_ERROR_CHECK(err_code);
    p_adv_data->scan_rsp_data.p_data = NULL;
    p_adv_data->scan_rsp_data.len = 0;

    }

     I print sizeof( m_beacon_ibeacon_manuf_data ) and sizeof( ble_advdata_manuf_data_t ), why it always is 0x12,18Bytes ?  no matter how many beacon_ibeacon_payload_t is set.

    00> <info> cbeacon_slot_parser: ES_FRAME_TYPE_UID
    00>
    00> <info> beacon_slot_parser: ES_FRAME_TYPE_TLM
    00>
    00> <info> beacon_slot_parser: ES_FRAME_TYPE_URL
    00>
    00> <info> beacon_slot_parser: CFX_BEACON_FRAME_TYPE_IBEACON
    00>
    00> <info> beacon_main: Enter main loop
    00>
    00> <info> beacon_ibeacon: sizeof_my_maunf: 12
    00>
    00> <info> beacon_adv: sizeof_manuf : 12
    00>
    00> <info> beacon_adv: encode data length: 0
    00>
    00> <error> app: ERROR 12 [NRF_ERROR_DATA_SIZE] at ../../../../../communication/cfx_beacon_adv.c:191
    00>
    00> PC at: 0x0003656D
    00>
    00> <error> app: End of error report

    ----------------------------------------------------------------------------------------------------------------------

    if I configure the beacon to only advertise iBeacon, the log is as follows, no erro. 

    00> <info> cfx_beacon_slot_parser: CFX_BEACON_FRAME_TYPE_IBEACON
    00>
    00> <info> cfx_beacon_ibeacon: sizeof_my_maunf:  12
    00>
    00> <info> cfx_beacon_adv: sizeof_manuf : 12  , why it still is 12?
    00>
    00> <info> cfx_beacon_adv: encode data length: 27
    00>
    00> <info> cfx_beacon_ibeacon: sizeof_my_maunf: 0x12

    It seems that when broadcasting eddystone UID +TLM+ URL + ibeacon, the length of ble_advdata_manuf_data_t is limited,  can the length of ble_advdata_manuf_data_t be set?

    Thank you in advance.

    Best regards,

    Susan

  • Hello Susan,

    Susan_cfx said:
    the total data I try to fit into the advertising is 3bytes (flags) +2(Length +Type)+2bytes (company_identifier) +23byte(m_beacon_ibeacon_payload) , total 30Bytes.

    Each data field requires two bytes of overhead, one for length and one for type. So in reality, you will need to add 2 bytes to every separate data field you include - in this case, both for company identifier and manufacturer specific data. Adding this to your included length calculation above leaves you at 34 bytes, which exceeds the limit. 
    To remedy this you could either try to remove the company identifier, or shave 3 bytes off the manufacturer specific payload.

    Susan_cfx said:
    I attached the code, please review for me, thank you. 

    Which part in particular would you like me to have a look at?
    It is very hard to read the code you have just copied in between your logs. Your code is also cluttered with comments of non-included code. On a general note I strongly recommend removing scrap code immediately, and saving it elsewhere if necessary, to avoid cluttering up the code and decreasing readability.

    Susan_cfx said:
    if comment out five bytes in the payload, and don't include flags

    Please be advised that the flags may only be omitted in the case that the advertising is non-connectable, otherwise it violates the BLE specification. This is of course not an issue for you now that you are creating a beacon, but I mention it for future reference. Please see the answer by my colleague in this ticket for further details.

    Susan_cfx said:
    It seems that when broadcasting eddystone UID +TLM+ URL + ibeacon, the length of ble_advdata_manuf_data_t is limited,  can the length of ble_advdata_manuf_data_t be set?

    As mentioned you need to add 2 bytes of overhead to each data field of your advertising. Please account for this in your calculations of the manufacturer specific data length limit, and let me know if the limit then is as expected.

    Best regards,
    Karl

  • Hi Karl,  

    As you said both company identifier and manufacturer specific data need to add 2bytes,

    the total data I try to fit into the advertising is 1 Bytes (flags) +2 Bytes (manuf_specific_data.company_identifier) +23 Byte(manuf_specific_data.data.p_data)+ 2 Bytes overhead*3 , total 32Bytes.

    I reference to the example \nRF5_SDK_17.0.0_9d13099\examples\ble_peripheral\ble_app_beacon , 

    It advertise 1 Bytes (flas) + 2 Bytes (manuf_specific_data.company_identifier) + 23Bytes (manuf_specific_data.data.p_data) , add 2 Bytes for each separate data field,   so total  26+2*3 = 32 Bytes,  which also exceeds the limit 31 Bytes. 

    Can "manuf_specific_data.company_identifier"  and "manuf_specific_data.data.p_data " be combined into one fileld,  just add two bytes of overhead ? 

    Best regards,

    Susan 

  • Hello Susan,

    Susan_cfx said:
    Can "manuf_specific_data.company_identifier"  and "manuf_specific_data.data.p_data " be combined into one fileld,  just add two bytes of overhead ? 

    Aha, it seems I misunderstood your question previously.
    Yes, the manufacturing specific data is only 1 data field, so the overhead of this field is only 2 bytes total. You may populate the manufacturer specific data with whatever you would like.

    Susan_cfx said:

    I reference to the example \nRF5_SDK_17.0.0_9d13099\examples\ble_peripheral\ble_app_beacon , 

    It advertise 1 Bytes (flas) + 2 Bytes (manuf_specific_data.company_identifier) + 23Bytes (manuf_specific_data.data.p_data) , add 2 Bytes for each separate data field,   so total  26+2*3 = 32 Bytes,  which also exceeds the limit 31 Bytes. 

    No, this is not correct. The company identifier is part of the manufacturing data, and therefore does not require the 2 bytes overhead - placing the advertising on 30 bytes.
    The following three lines is the entire advertising payload of the ble_app_beacon:

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

    The company identifier is contained within the manufacturer specific data.

    Please do not hesitate to ask if anything still should be unclear!

    Best regards,
    Karl

Related