How to send additional data in eddystone protocol?

Is it possible to send additional data in eddystone protocol ?

If yes please do share a snap of code with me.

  • It is not easy to spot the issue with snippets in screenshots. Can you post your full code as text as well as a description on how you have tested and debugged, and what you have found? Please explain if it does advertise at all, but with wrong data? And if not, what happens? Any error checks being hit? Other behavior? Please elaborate.

  • Below written is my code it's not showing any error it simply advertising in the same way as it advertise without adding any scan response and manufacturing data


    #include "sdk_common.h"
    #if NRF_MODULE_ENABLED(BLE_ADVERTISING)
    #include "ble_advdata.h"
    #include "ble_advertising.h"
    #include "nrf_soc.h"
    #include "nrf_log.h"
    #include "sdk_errors.h"
    #include "nrf_sdh_ble.h"

    #define BLE_ADV_MODES (5) /**< Total number of possible advertising modes. */


    /**@brief Function for checking if the whitelist is in use.
    *
    * @param[in] p_advertising Advertising module instance.
    */
    static bool whitelist_has_entries(ble_advertising_t * const p_advertising)
    {
    return p_advertising->whitelist_in_use;
    }


    /**@brief Function for checking if an address is valid.
    *
    * @param[in] p_addr Pointer to a bluetooth address.
    */
    static bool addr_is_valid(uint8_t const * const p_addr)
    {
    for (uint32_t i = 0; i < BLE_GAP_ADDR_LEN; i++)
    {
    if (p_addr[i] != 0)
    {
    return true;
    }
    }
    return false;
    }


    /**@brief Function for checking the next advertising mode.
    *
    * @param[in] adv_mode Current advertising mode.
    */
    static ble_adv_mode_t adv_mode_next_get(ble_adv_mode_t adv_mode)
    {
    return (ble_adv_mode_t)((adv_mode + 1) % BLE_ADV_MODES);
    }


    /**@brief Function for handling the Connected event.
    *
    * @param[in] p_ble_evt Event received from the BLE stack.
    */
    static void on_connected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
    {
    if (p_ble_evt->evt.gap_evt.params.connected.role == BLE_GAP_ROLE_PERIPH)
    {
    p_advertising->current_slave_link_conn_handle = p_ble_evt->evt.gap_evt.conn_handle;
    }
    }


    /**@brief Function for handling the Disconnected event.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[in] p_ble_evt Event received from the BLE stack.
    */
    static void on_disconnected(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
    {
    uint32_t ret;

    p_advertising->whitelist_temporarily_disabled = false;

    if (p_ble_evt->evt.gap_evt.conn_handle == p_advertising->current_slave_link_conn_handle &&
    p_advertising->adv_modes_config.ble_adv_on_disconnect_disabled == false)
    {
    ret = ble_advertising_start(p_advertising, BLE_ADV_MODE_DIRECTED_HIGH_DUTY);
    if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
    {
    p_advertising->error_handler(ret);
    }
    }
    }


    /**@brief Function for handling the Timeout event.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[in] p_ble_evt Event received from the BLE stack.
    */
    static void on_terminated(ble_advertising_t * const p_advertising, ble_evt_t const * p_ble_evt)
    {
    ret_code_t ret;

    if (p_ble_evt->header.evt_id != BLE_GAP_EVT_ADV_SET_TERMINATED)
    {
    // Nothing to do.
    return;
    }

    if ( p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_TIMEOUT
    ||p_ble_evt->evt.gap_evt.params.adv_set_terminated.reason == BLE_GAP_EVT_ADV_SET_TERMINATED_REASON_LIMIT_REACHED)
    {
    // Start advertising in the next mode.
    ret = ble_advertising_start(p_advertising, adv_mode_next_get(p_advertising->adv_mode_current));

    if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
    {
    p_advertising->error_handler(ret);
    }
    }
    }


    /**@brief Get the next available advertising mode.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[in] adv_mode Requested advertising mode.
    *
    * @returns adv_mode if possible, or the best available mode if not.
    */
    static ble_adv_mode_t adv_mode_next_avail_get(ble_advertising_t * const p_advertising,
    ble_adv_mode_t adv_mode)
    {
    bool peer_addr_is_valid = addr_is_valid(p_advertising->peer_address.addr);

    // If a mode is disabled, continue to the next mode.

    switch (adv_mode)
    {
    case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
    if ( (p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled)
    && (!p_advertising->adv_modes_config.ble_adv_extended_enabled)
    && (peer_addr_is_valid))
    {
    return BLE_ADV_MODE_DIRECTED_HIGH_DUTY;
    }
    // Fallthrough.

    case BLE_ADV_MODE_DIRECTED:
    if ((p_advertising->adv_modes_config.ble_adv_directed_enabled) && peer_addr_is_valid)
    {
    return BLE_ADV_MODE_DIRECTED;
    }
    // Fallthrough.

    case BLE_ADV_MODE_FAST:
    if (p_advertising->adv_modes_config.ble_adv_fast_enabled)
    {
    return BLE_ADV_MODE_FAST;
    }
    // Fallthrough.

    case BLE_ADV_MODE_SLOW:
    if (p_advertising->adv_modes_config.ble_adv_slow_enabled)
    {
    return BLE_ADV_MODE_SLOW;
    }
    // Fallthrough.

    default:
    return BLE_ADV_MODE_IDLE;
    }
    }


    /**@brief Function for starting high duty directed advertising.
    *
    * @param[in] p_advertising Advertising instance.
    * @param[out] p_adv_params Advertising parameters.
    *
    * @return NRF_SUCCESS
    */
    static ret_code_t set_adv_mode_directed_high_duty(ble_advertising_t * const p_advertising,
    ble_gap_adv_params_t * p_adv_params)
    {
    p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED_HIGH_DUTY;
    p_advertising->p_adv_data = NULL;

    p_adv_params->p_peer_addr = &(p_advertising->peer_address);
    p_adv_params->interval = 0;
    p_adv_params->properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED_HIGH_DUTY_CYCLE;
    p_adv_params->duration = BLE_GAP_ADV_TIMEOUT_HIGH_DUTY_MAX;

    return NRF_SUCCESS;
    }


    /**@brief Function for starting directed slow advertising.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[out] p_adv_params Advertising parameters.
    *
    * @return NRF_SUCCESS
    */
    static ret_code_t set_adv_mode_directed(ble_advertising_t * const p_advertising,
    ble_gap_adv_params_t * p_adv_params)
    {
    p_advertising->adv_evt = BLE_ADV_EVT_DIRECTED;
    #if !defined (S112) && !defined(S312) && !defined(S113)
    if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
    {
    p_adv_params->properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_DIRECTED;
    }
    else
    {
    #endif // !defined (S112) && !defined(S312)
    p_adv_params->properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_NONSCANNABLE_DIRECTED;
    #if !defined (S112) && !defined(S312) && !defined(S113)
    }
    #endif // !defined (S112) && !defined(S312) && !defined(S113)
    p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_directed_timeout;

    p_advertising->p_adv_data = NULL;

    p_adv_params->p_peer_addr = &p_advertising->peer_address;
    p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_directed_interval;

    return NRF_SUCCESS;
    }


    /**@brief Function for indicating whether to use whitelist for advertising.
    *
    * @param[in] p_advertising Advertising module instance.
    *
    * @return Whether to use whitelist.
    */
    static bool use_whitelist(ble_advertising_t * const p_advertising)
    {
    return((p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
    (!p_advertising->whitelist_temporarily_disabled) &&
    (whitelist_has_entries(p_advertising)));
    }


    /**@brief Function for setting new advertising flags in the advertising parameters.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[in] flags New flags.
    *
    * @return Any error from @ref sd_ble_gap_adv_set_configure.
    */
    static ret_code_t flags_set(ble_advertising_t * const p_advertising, uint8_t flags)
    {
    uint8_t * p_flags = ble_advdata_parse(p_advertising->adv_data.adv_data.p_data,
    p_advertising->adv_data.adv_data.len,
    BLE_GAP_AD_TYPE_FLAGS);

    if (p_flags != NULL)
    {
    *p_flags = flags;
    }

    return sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, &p_advertising->adv_data, &p_advertising->adv_params);
    }


    /**@brief Function for starting fast advertising.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[out] p_adv_params Advertising parameters.
    *
    * @return NRF_SUCCESS or an error from @ref flags_set().
    */
    static ret_code_t set_adv_mode_fast(ble_advertising_t * const p_advertising,
    ble_gap_adv_params_t * p_adv_params)
    {
    ret_code_t ret;

    p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_fast_interval;
    p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_fast_timeout;

    #if !defined (S112) && !defined(S312) && !defined(S113)
    if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
    {
    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
    }
    else
    {
    #endif // !defined (S112) && !defined(S312) && !defined(S113)
    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    #if !defined (S112) && !defined(S312) && !defined(S113)
    }
    #endif // !defined (S112) && !defined(S312) && !defined(S113)

    if (use_whitelist(p_advertising))
    {
    p_adv_params->filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;

    // Set correct flags.
    ret = flags_set(p_advertising, BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED);
    VERIFY_SUCCESS(ret);

    p_advertising->adv_evt = BLE_ADV_EVT_FAST_WHITELIST;
    }
    else
    {
    p_advertising->adv_evt = BLE_ADV_EVT_FAST;
    }
    p_advertising->p_adv_data = &(p_advertising->adv_data);
    return NRF_SUCCESS;
    }


    /**@brief Function for starting slow advertising.
    *
    * @param[in] p_advertising Advertising module instance.
    * @param[out] p_adv_params Advertising parameters.
    *
    * @return NRF_SUCCESS or an error from @ref flags_set().
    */
    static ret_code_t set_adv_mode_slow(ble_advertising_t * const p_advertising,
    ble_gap_adv_params_t * p_adv_params)
    {
    ret_code_t ret;

    p_adv_params->interval = p_advertising->adv_modes_config.ble_adv_slow_interval;
    p_adv_params->duration = p_advertising->adv_modes_config.ble_adv_slow_timeout;

    #if !defined (S112) && !defined(S312) && !defined(S113)
    if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
    {
    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_EXTENDED_CONNECTABLE_NONSCANNABLE_UNDIRECTED;
    }
    else
    {
    #endif // !defined (S112) && !defined(S312) && !defined(S113)
    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    #if !defined (S112) && !defined(S312) && !defined(S113)
    }
    #endif // !defined (S112) && !defined(S312) && !defined(S113)

    if (use_whitelist(p_advertising))
    {
    p_adv_params->filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;

    // Set correct flags.
    ret = flags_set(p_advertising, BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED);
    VERIFY_SUCCESS(ret);

    p_advertising->adv_evt = BLE_ADV_EVT_SLOW_WHITELIST;
    }
    else
    {
    p_advertising->adv_evt = BLE_ADV_EVT_SLOW;
    }
    p_advertising->p_adv_data = &(p_advertising->adv_data);
    return NRF_SUCCESS;
    }


    /**@brief Function for checking if an advertising module configuration is legal.
    *
    * @details Advertising module can not be initialized if high duty directed advertising is used
    * together with extended advertising.
    *
    * @param[in] p_config Pointer to the configuration.
    *
    * @return True If the configuration is valid.
    * @return False If the configuration is invalid.
    */
    static bool config_is_valid(ble_adv_modes_config_t const * const p_config)
    {
    if ((p_config->ble_adv_directed_high_duty_enabled == true) &&
    (p_config->ble_adv_extended_enabled == true))
    {
    return false;
    }
    #if !defined (S140)
    else if ( p_config->ble_adv_primary_phy == BLE_GAP_PHY_CODED ||
    p_config->ble_adv_secondary_phy == BLE_GAP_PHY_CODED)
    {
    return false;
    }
    #endif // !defined (S140)
    else
    {
    return true;
    }
    }


    /**@brief Function for getting the maximum size of the advertising data buffer.
    *
    * @param[in] p_advertising Advertising module instance.
    *
    * @returns The maximum size of the advertising data buffer.
    */
    static uint16_t adv_set_data_size_max_get(ble_advertising_t const * const p_advertising)
    {
    uint16_t adv_set_data_size_max;

    if (p_advertising->adv_modes_config.ble_adv_extended_enabled == true)
    {
    #ifdef BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
    adv_set_data_size_max = BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED;
    #else
    adv_set_data_size_max = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    #endif // BLE_GAP_ADV_SET_DATA_SIZE_EXTENDED_CONNECTABLE_MAX_SUPPORTED
    }
    else
    {
    adv_set_data_size_max = BLE_GAP_ADV_SET_DATA_SIZE_MAX;
    }

    return adv_set_data_size_max;
    }


    void ble_advertising_conn_cfg_tag_set(ble_advertising_t * const p_advertising,
    uint8_t ble_cfg_tag)
    {
    p_advertising->conn_cfg_tag = ble_cfg_tag;
    }


    uint32_t ble_advertising_init(ble_advertising_t * const p_advertising,
    ble_advertising_init_t const * const p_init)
    {
    uint32_t ret;

    ble_advertising_init_t init;


    if ((p_init == NULL) || (p_advertising == NULL))
    {
    return NRF_ERROR_NULL;
    }
    if (!config_is_valid(&p_init->config))
    {
    return NRF_ERROR_INVALID_PARAM;
    }

    // manufacturing data

    p_advertising->d = 's' ; // Extra

    p_advertising->adv_mode_current = BLE_ADV_MODE_IDLE;
    p_advertising->adv_modes_config = p_init->config;
    p_advertising->conn_cfg_tag = BLE_CONN_CFG_TAG_DEFAULT;
    p_advertising->evt_handler = p_init->evt_handler;
    p_advertising->error_handler = p_init->error_handler;
    p_advertising->current_slave_link_conn_handle = BLE_CONN_HANDLE_INVALID;
    p_advertising->p_adv_data = &p_advertising->adv_data;
    memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));

    // Manufacturing Specific data

    ble_advdata_manuf_data_t manuf_data; //Variable to hold manufacturer specific data
    uint8_t data[] = "SomeData!"; //Our data to advertise
    manuf_data.company_identifier = 0x0059; //Nordics company ID
    manuf_data.data.p_data = data;
    manuf_data.data.size = sizeof(data);
    init.advdata.p_manuf_specific_data = &manuf_data;

    // Scan response data

    ble_advdata_manuf_data_t manuf_data_response;
    uint8_t data_response[] = "Many_bytes_of_data";
    manuf_data_response.company_identifier = 0x0059;
    manuf_data_response.data.p_data = data_response;
    manuf_data_response.data.size = sizeof(data_response);
    init.srdata.name_type = BLE_ADVDATA_NO_NAME;
    init.srdata.p_manuf_specific_data = &manuf_data_response;

    // Copy advertising data.
    if (!p_advertising->initialized)
    {
    p_advertising->adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET;
    }
    p_advertising->adv_data.adv_data.p_data = p_advertising->enc_advdata[0];
    p_advertising->adv_data.adv_data.len = adv_set_data_size_max_get(p_advertising);

    ret = ble_advdata_encode(&p_init->advdata, p_advertising->enc_advdata[0], &p_advertising->adv_data.adv_data.len);
    VERIFY_SUCCESS(ret);

    p_advertising->adv_data.scan_rsp_data.p_data = p_advertising->enc_scan_rsp_data[0];
    p_advertising->adv_data.scan_rsp_data.len = adv_set_data_size_max_get(p_advertising);

    ret = ble_advdata_encode(&p_init->srdata,
    p_advertising->adv_data.scan_rsp_data.p_data,
    &p_advertising->adv_data.scan_rsp_data.len);
    VERIFY_SUCCESS(ret);

    // Configure a initial advertising configuration. The advertising data and and advertising
    // parameters will be changed later when we call @ref ble_advertising_start, but must be set
    // to legal values here to define an advertising handle.
    p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
    p_advertising->adv_params.duration = p_advertising->adv_modes_config.ble_adv_fast_timeout;
    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    p_advertising->adv_params.p_peer_addr = NULL;
    p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    p_advertising->adv_params.interval = p_advertising->adv_modes_config.ble_adv_fast_interval;

    ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, NULL, &p_advertising->adv_params);
    VERIFY_SUCCESS(ret);

    p_advertising->initialized = true;
    return ret;
    }


    /**@brief Function for checking that a phy define value matches one of the valid phys from the SD.
    *
    * @param[in] PHY to be validated.
    *
    * @retval true If the PHY value is valid (1mbit, 2mbit, coded).
    * @retval false If the PHY value is invalid.
    */
    static bool phy_is_valid(uint32_t const * const p_phy)
    {
    if ((*p_phy) == BLE_GAP_PHY_1MBPS ||
    (*p_phy) == BLE_GAP_PHY_2MBPS
    #if defined (S140)
    || (*p_phy) == BLE_GAP_PHY_CODED
    #endif // !defined (S140)
    )
    {
    return true;
    }
    else
    {
    return false;
    }
    }


    uint32_t ble_advertising_start(ble_advertising_t * const p_advertising,
    ble_adv_mode_t advertising_mode)
    {
    uint32_t ret;

    if (p_advertising->initialized == false)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    p_advertising->adv_mode_current = advertising_mode;

    memset(&p_advertising->peer_address, 0, sizeof(p_advertising->peer_address));

    if ( ((p_advertising->adv_modes_config.ble_adv_directed_high_duty_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
    ||((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED_HIGH_DUTY))
    ||((p_advertising->adv_modes_config.ble_adv_directed_enabled) && (p_advertising->adv_mode_current == BLE_ADV_MODE_DIRECTED))
    )
    {
    if (p_advertising->evt_handler != NULL)
    {
    p_advertising->peer_addr_reply_expected = true;
    p_advertising->evt_handler(BLE_ADV_EVT_PEER_ADDR_REQUEST);
    }
    else
    {
    p_advertising->peer_addr_reply_expected = false;
    }
    }

    p_advertising->adv_mode_current = adv_mode_next_avail_get(p_advertising, advertising_mode);

    // Fetch the whitelist.
    if ((p_advertising->evt_handler != NULL) &&
    (p_advertising->adv_mode_current == BLE_ADV_MODE_FAST || p_advertising->adv_mode_current == BLE_ADV_MODE_SLOW) &&
    (p_advertising->adv_modes_config.ble_adv_whitelist_enabled) &&
    (!p_advertising->whitelist_temporarily_disabled))
    {
    p_advertising->whitelist_in_use = false;
    p_advertising->whitelist_reply_expected = true;
    p_advertising->evt_handler(BLE_ADV_EVT_WHITELIST_REQUEST);
    }
    else
    {
    p_advertising->whitelist_reply_expected = false;
    }

    // Initialize advertising parameters with default values.
    memset(&p_advertising->adv_params, 0, sizeof(p_advertising->adv_params));

    p_advertising->adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;

    // Use 1MBIT as primary phy if no phy was selected.
    if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_primary_phy))
    {
    p_advertising->adv_params.primary_phy = p_advertising->adv_modes_config.ble_adv_primary_phy;
    }
    else
    {
    p_advertising->adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
    }

    if (p_advertising->adv_modes_config.ble_adv_extended_enabled)
    {
    // Use 1MBIT as secondary phy if no phy was selected.
    if (phy_is_valid(&p_advertising->adv_modes_config.ble_adv_secondary_phy))
    {
    p_advertising->adv_params.secondary_phy = p_advertising->adv_modes_config.ble_adv_secondary_phy;
    }
    else
    {
    p_advertising->adv_params.secondary_phy = BLE_GAP_PHY_1MBPS;
    }
    }
    p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;

    // Set advertising parameters and events according to selected advertising mode.
    switch (p_advertising->adv_mode_current)
    {
    case BLE_ADV_MODE_DIRECTED_HIGH_DUTY:
    ret = set_adv_mode_directed_high_duty(p_advertising, &p_advertising->adv_params);
    break;

    case BLE_ADV_MODE_DIRECTED:
    ret = set_adv_mode_directed(p_advertising, &p_advertising->adv_params);
    break;

    case BLE_ADV_MODE_FAST:
    ret = set_adv_mode_fast(p_advertising, &p_advertising->adv_params);
    break;

    case BLE_ADV_MODE_SLOW:
    ret = set_adv_mode_slow(p_advertising, &p_advertising->adv_params);
    break;

    case BLE_ADV_MODE_IDLE:
    p_advertising->adv_evt = BLE_ADV_EVT_IDLE;
    break;

    default:
    break;
    }

    if (p_advertising->adv_mode_current != BLE_ADV_MODE_IDLE)
    {

    ret = sd_ble_gap_adv_set_configure(&p_advertising->adv_handle, p_advertising->p_adv_data, &p_advertising->adv_params);
    if (ret != NRF_SUCCESS)
    {
    return ret;
    }
    ret = sd_ble_gap_adv_start(p_advertising->adv_handle, p_advertising->conn_cfg_tag);

    if (ret != NRF_SUCCESS)
    {
    return ret;
    }
    }

    if (p_advertising->evt_handler != NULL)
    {
    p_advertising->evt_handler(p_advertising->adv_evt);
    }

    return NRF_SUCCESS;
    }


    void ble_advertising_on_ble_evt(ble_evt_t const * p_ble_evt, void * p_context)
    {
    ble_advertising_t * p_advertising = (ble_advertising_t *)p_context;

    switch (p_ble_evt->header.evt_id)
    {
    case BLE_GAP_EVT_CONNECTED:
    on_connected(p_advertising, p_ble_evt);
    break;

    // Upon disconnection, whitelist will be activated and direct advertising is started.
    case BLE_GAP_EVT_DISCONNECTED:
    on_disconnected(p_advertising, p_ble_evt);
    break;

    // Upon terminated advertising (time-out), the next advertising mode is started.
    case BLE_GAP_EVT_ADV_SET_TERMINATED:
    on_terminated(p_advertising, p_ble_evt);
    break;

    default:
    break;
    }
    }


    uint32_t ble_advertising_peer_addr_reply(ble_advertising_t * const p_advertising,
    ble_gap_addr_t * p_peer_address)
    {
    if (!p_advertising->peer_addr_reply_expected)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    p_advertising->peer_addr_reply_expected = false;

    memcpy(&p_advertising->peer_address, p_peer_address, sizeof(p_advertising->peer_address));

    return NRF_SUCCESS;
    }


    uint32_t ble_advertising_whitelist_reply(ble_advertising_t * const p_advertising,
    ble_gap_addr_t const * p_gap_addrs,
    uint32_t addr_cnt,
    ble_gap_irk_t const * p_gap_irks,
    uint32_t irk_cnt)
    {
    if (!p_advertising->whitelist_reply_expected)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    p_advertising->whitelist_reply_expected = false;
    p_advertising->whitelist_in_use = ((addr_cnt > 0) || (irk_cnt > 0));

    return NRF_SUCCESS;
    }


    uint32_t ble_advertising_restart_without_whitelist(ble_advertising_t * const p_advertising)
    {
    ret_code_t ret;

    (void) sd_ble_gap_adv_stop(p_advertising->adv_handle);

    p_advertising->whitelist_temporarily_disabled = true;
    p_advertising->whitelist_in_use = false;
    p_advertising->adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    // Set correct flags.
    ret = flags_set(p_advertising, BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE);
    VERIFY_SUCCESS(ret);

    ret = ble_advertising_start(p_advertising, p_advertising->adv_mode_current);
    if ((ret != NRF_SUCCESS) && (p_advertising->error_handler != NULL))
    {
    p_advertising->error_handler(ret);
    }

    return NRF_SUCCESS;
    }


    void ble_advertising_modes_config_set(ble_advertising_t * const p_advertising,
    ble_adv_modes_config_t const * const p_adv_modes_config)
    {
    p_advertising->adv_modes_config = *p_adv_modes_config;
    }


    ret_code_t ble_advertising_advdata_update(ble_advertising_t * const p_advertising,
    ble_advdata_t const * const p_advdata,
    ble_advdata_t const * const p_srdata)
    {
    VERIFY_PARAM_NOT_NULL(p_advertising);
    if (p_advertising->initialized == false)
    {
    return NRF_ERROR_INVALID_STATE;
    }

    if ((p_advdata == NULL) && (p_srdata == NULL))
    {
    return NRF_ERROR_NULL;
    }

    ble_gap_adv_data_t new_adv_data;
    memset(&new_adv_data, 0, sizeof(new_adv_data));

    if (p_advdata != NULL)
    {
    new_adv_data.adv_data.p_data =
    (p_advertising->p_adv_data->adv_data.p_data != p_advertising->enc_advdata[0]) ?
    p_advertising->enc_advdata[0] : p_advertising->enc_advdata[1];
    new_adv_data.adv_data.len = adv_set_data_size_max_get(p_advertising);

    ret_code_t ret = ble_advdata_encode(p_advdata,
    new_adv_data.adv_data.p_data,
    &new_adv_data.adv_data.len);
    VERIFY_SUCCESS(ret);
    }

    if (p_srdata != NULL)
    {
    new_adv_data.scan_rsp_data.p_data =
    (p_advertising->p_adv_data->scan_rsp_data.p_data != p_advertising->enc_scan_rsp_data[0]) ?
    p_advertising->enc_scan_rsp_data[0] : p_advertising->enc_scan_rsp_data[1];
    new_adv_data.scan_rsp_data.len = adv_set_data_size_max_get(p_advertising);

    ret_code_t ret = ble_advdata_encode(p_srdata,
    new_adv_data.scan_rsp_data.p_data,
    &new_adv_data.scan_rsp_data.len);
    VERIFY_SUCCESS(ret);
    }

    memcpy(&p_advertising->adv_data, &new_adv_data, sizeof(p_advertising->adv_data));
    p_advertising->p_adv_data = &p_advertising->adv_data;

    return sd_ble_gap_adv_set_configure(&p_advertising->adv_handle,
    p_advertising->p_adv_data,
    NULL);
    }


    #endif // NRF_MODULE_ENABLED(BLE_ADVERTISING)

  • Hi,

    I still do not get the full overview where. You have code for configuring the advertisement packet and scan response packet in ble_advertising_init(), but that function is never called anywhere I can see, so it is expected that this as no effect.

    If that helps I modified the beacon example in SDK 17.1.0 so that it sends manufacturer specific data in the advertising packet and the full name in the scan response packet. You can use that as a reference. To test, drop this file into <SDK 17.1.0>\examples\ble_peripheral\ble_app_beacon\:

    /**
     * Copyright (c) 2014 - 2021, 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.
     *
     */
    /** @file
     *
     * @defgroup ble_sdk_app_beacon_main main.c
     * @{
     * @ingroup ble_sdk_app_beacon
     * @brief Beacon Transmitter Sample Application main file.
     *
     * This file contains the source code for an Beacon transmitter sample application.
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    #include "nordic_common.h"
    #include "bsp.h"
    #include "nrf_soc.h"
    #include "nrf_sdh.h"
    #include "nrf_sdh_ble.h"
    #include "ble_advdata.h"
    #include "app_timer.h"
    #include "nrf_pwr_mgmt.h"
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    
    #define DEVICE_NAME                     "FancyBeacon"                               /**< Name of device. Will be included in the advertising data. */
    
    #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. */
    
    #if defined(USE_UICR_FOR_MAJ_MIN_VALUES)
    #define MAJ_VAL_OFFSET_IN_BEACON_INFO   18                                 /**< Position of the MSB of the Major Value in m_beacon_info array. */
    #define UICR_ADDRESS                    0x10001080                         /**< Address of the UICR register used by this example. The major and minor versions to be encoded into the advertising data will be picked up from this location. */
    #endif
    
    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_MAX];  /**< Buffer for storing an encoded advertising set. */
    static uint8_t              m_enc_srdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];  /**< Buffer for storing an encoded advertising set. */
    
    static uint8_t m_ma_spec_data[] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
    
    /**@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_MAX
        },
        .scan_rsp_data =
        {
            .p_data = m_enc_srdata,
            .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX
    
        }
    };
    
    
    /**@brief Callback function for asserts in the SoftDevice.
     *
     * @details This function will be called in case of an assert in the SoftDevice.
     *
     * @warning This handler is an example only and does not fit a final product. You need to analyze
     *          how your product is supposed to react in case of Assert.
     * @warning On assert from the SoftDevice, the system can only recover on reset.
     *
     * @param[in]   line_num   Line number of the failing ASSERT call.
     * @param[in]   file_name  File name of the failing ASSERT call.
     */
    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
        app_error_handler(DEAD_BEEF, line_num, p_file_name);
    }
    
    /**@brief Function for initializing the Advertising functionality.
     *
     * @details Encodes the required advertising data and passes it to the stack.
     *          Also builds a structure to be passed to the stack when starting advertising.
     */
    static void advertising_init(void)
    {
        uint32_t      err_code;
        ble_advdata_t advdata;
        ble_advdata_t srdata;
        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;
        manuf_specific_data.data.p_data = m_ma_spec_data;
        manuf_specific_data.data.size   = sizeof(m_ma_spec_data);
    
        // Build and set advertising data.
        memset(&advdata, 0, sizeof(advdata));
    
        advdata.name_type             = BLE_ADVDATA_NO_NAME;
        advdata.flags                 = flags;
        advdata.p_manuf_specific_data = &manuf_specific_data;
    
        // build srdata
        memset(&srdata, 0, sizeof(srdata));
    
        srdata.name_type          = BLE_ADVDATA_FULL_NAME;
    
        // 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.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 = ble_advdata_encode(&srdata, 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);
    }
    
    
    /**@brief Function for starting advertising.
     */
    static void advertising_start(void)
    {
        ret_code_t err_code;
    
        err_code = sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
        APP_ERROR_CHECK(err_code);
    
        err_code = bsp_indication_set(BSP_INDICATE_ADVERTISING);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing the BLE stack.
     *
     * @details Initializes the SoftDevice and the BLE event interrupt.
     */
    static void ble_stack_init(void)
    {
        ret_code_t err_code;
        ble_gap_conn_sec_mode_t sec_mode;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
            
        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);
    }
    
    
    /**@brief Function for initializing logging. */
    static void log_init(void)
    {
        ret_code_t err_code = NRF_LOG_INIT(NULL);
        APP_ERROR_CHECK(err_code);
    
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    }
    
    /**@brief Function for initializing LEDs. */
    static void leds_init(void)
    {
        ret_code_t err_code = bsp_init(BSP_INIT_LEDS, NULL);
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing timers. */
    static void timers_init(void)
    {
        ret_code_t err_code = app_timer_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for initializing power management.
     */
    static void power_management_init(void)
    {
        ret_code_t err_code;
        err_code = nrf_pwr_mgmt_init();
        APP_ERROR_CHECK(err_code);
    }
    
    
    /**@brief Function for handling the idle state (main loop).
     *
     * @details If there is no pending log operation, then sleep until next the next event occurs.
     */
    static void idle_state_handle(void)
    {
        if (NRF_LOG_PROCESS() == false)
        {
            nrf_pwr_mgmt_run();
        }
    }
    
    
    /**
     * @brief Function for application main entry.
     */
    int main(void)
    {
        // Initialize.
        log_init();
        timers_init();
        leds_init();
        power_management_init();
        ble_stack_init();
        advertising_init();
    
        // Start execution.
        NRF_LOG_INFO("Beacon example started.");
        advertising_start();
    
        // Enter main loop.
        for (;; )
        {
            idle_state_handle();
        }
    }
    
    
    /**
     * @}
     */
    

    PS: Please post code using Insert -> Code instead of just pasting in the normal text field. That makes readability much better.

  • If i do changes in this function is it going to solve my purpose?

  • Hi,

    I am not able to see that it would. But why are you using a Eddystone implementation as starting point if you just want a generic beacon? Or is that not what you want after all? If it is, then it will be better to use a simple example, for instance the beacon example in the SDK. You can then refer to my previous post to see how to add a scan response. This is easily adaptable.

Related