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

iBeacon format Major/Minor or UUID can not be dynamically updated?

=======

SDK: 15.3

Product all base: ble_app_template

Problem: cannot update iBeacon content dynamically during system run-time.

=======

we try to use ADV with ibeacon after beacon start-up,
and then dynamically change ibeacon's Major/Minor version to iphone/android by using
    //stop advertising
    err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle);
    APP_ERROR_CHECK(err_code);
    
   // enable configure
    err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    APP_ERROR_CHECK(err_code);
    //start advertising
    err_code = sd_ble_gap_adv_start(m_advertising.adv_handle, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);
where changed adv is like
static ble_gap_adv_data_t m_adv_data = // this one is fail at  sd_ble_gap_adv_set_configure  with error 4
{
    .adv_data =
    {
        .p_data = m_beacon_info, // this is a new change run-time.
        .len    = APP_BEACON_INFO_LENGTH;  // 21B)
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0

    }
};
but it seems to fail at run-time dynamically change ibeacon format.
Can u help confirm by ble_app_ibeacon example.
But it this adv pattern change to 
static ble_gap_adv_data_t m_adv_data  =  // this one can be workable and ADV changeable.
{
    .adv_data =
    {
        .p_data = enc_adv_data_buffer,  // customer infomation
        .len    = BLE_GAP_ADV_SET_DATA_SIZE_MAX ;  // 31B which is BLE default ADV pattern 
    },
    .scan_rsp_data =
    {
        .p_data = NULL,
        .len    = 0

    }
};
to sum up, it seems we can not change ibeacon format content dynamically but we can 
change ADV content if we use default BLE beacon (31B format); is that true?
Leo
  • If you start from the 'ble_app_beacon' you would need to

    1. Stop the advertising.
    2. Change the 'm_beacon_info' data to your desired value.
    3. Run the 'advertising_init()' function (or copy paste the function to your desired stream)
    4. Start advertising again using 'advertising_start()'

    As for how you would change the value inside 'm_beacon_info' is a bit different. You would need to make services and inside it characteristics. One would write inside the characteristic and then the written characteristic value would then be loaded inside the 'm_beacon_info' and so on.

    Tutorial to create services: https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/ble-services-a-beginners-tutorial

    Tutorial to create characteristics: https://devzone.nordicsemi.com/nordic/short-range-guides/b/bluetooth-low-energy/posts/ble-characteristics-a-beginners-tutorial

    Feel free to ask any queries you have in mind Slight smile

  • Hi, Ameer,

    It still doesn't work and I list my mechanism and code below, plz help clarify where the problem is...

    1. device advertising init with iBeacon format.

    2. during system run-time, I try to update iBeacon's major/minor field by a function updateAdvertisingData()

        but ADV update at

        err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);

        where error code = 0xC (wrong size) 

    3. i am mixed about using funtion

    err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);

    and 

    err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);

    which API is fit to use to change ADV content in SDK 15.  It seems it has many ways to update ADV pattern

    ADV init: 

    ==

    void advertising_init(void)
    {
    ret_code_t err_code;
    ble_advdata_manuf_data_t manuf_specific_data;

    memset(&init, 0, sizeof(init));

    init.advdata.name_type = BLE_ADVDATA_NO_NAME;
    init.advdata.include_appearance = true;
    init.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; 
    init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
    init.advdata.uuids_complete.p_uuids = m_adv_uuids;

    init.config.ble_adv_whitelist_enabled = true; //BLE_ADV_WHITELIST_ENABLED;
    init.config.ble_adv_fast_enabled = true;
    init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
    init.config.ble_adv_fast_timeout = APP_ADV_DURATION;

    init.evt_handler = on_adv_evt;

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

    m_advertising.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    m_advertising.adv_params.p_peer_addr = NULL; // Undirected advertisement.
    m_advertising.adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    m_advertising.adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL;
    m_advertising.adv_params.duration = 0; // Never time out.
    m_advertising.adv_handle = m_adv_handle;

    manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
    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(&init.advdata, 0, sizeof(init.advdata));

    init.advdata.name_type = BLE_ADVDATA_NO_NAME;
    init.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
    init.advdata.p_manuf_specific_data = &manuf_specific_data;
    err_code = ble_advertising_init(&m_advertising, &init);
    APP_ERROR_CHECK(err_code);

    ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
    APP_ERROR_CHECK(err_code);

    }

    updateAdvertisingData ():

    ==

    static uint32_t uiBuffIndex = 0;
    uint32_t err_code;
    ble_advdata_t advdata;
    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;

    //stop advertising
    err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle);
    APP_ERROR_CHECK(err_code);


    #if 1   // run-time update beacon here.
    m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -4] = (uint8_t)Dev_Info.DevBleMac[2];
    m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -3] = (uint8_t)Dev_Info.DevBleMac[1];
    m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -2] = (uint8_t)Dev_Info.DevBleMac[0];
    m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -1] = ((Dev_Info.VerMajor[0]-0x30<<4)|Dev_Info.VerMinor[1]-0x30);
    #endif

    manuf_specific_data.data.p_data = (uint8_t *) m_updated_beacon_info;
    manuf_specific_data.data.size = APP_BEACON_INFO_LENGTH;   // ibeacon size  = 21B

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


    //
    m_advertising.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
    m_advertising.adv_params.p_peer_addr = NULL; // Undirected advertisement.
    m_advertising.adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
    m_advertising.adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL;
    m_advertising.adv_params.duration = 0; // Never time out.
    m_advertising.adv_handle = m_adv_handle;
    // 


    err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    APP_ERROR_CHECK(err_code);  // fail at err_code = 0xC

    err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
    APP_ERROR_CHECK(err_code);

    }

    where

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

    }
    };

    ===

  • From an initial look I would suggest you start your code from the 'ble_app_beacon' example. Do have a look at the difference of your 'advertising_init()' function and theirs. Doing the advertising_init with the 'ble_app_beacon' example method should allow it you to edit the data.

    P.S. Try to add your code using the Insert ->Insert Code, gives a bit more readability.

  • void advertising_init(void)
    {
      ret_code_t err_code;
      ble_advdata_manuf_data_t manuf_specific_data;
    
      memset(&init, 0, sizeof(init));
    
      init.advdata.name_type = BLE_ADVDATA_NO_NAME;
      init.advdata.include_appearance = true;
      init.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED; 
      init.advdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
      init.advdata.uuids_complete.p_uuids = m_adv_uuids;
    
      init.config.ble_adv_whitelist_enabled = true; //BLE_ADV_WHITELIST_ENABLED;
      init.config.ble_adv_fast_enabled = true;
      init.config.ble_adv_fast_interval = APP_ADV_INTERVAL;
      init.config.ble_adv_fast_timeout = APP_ADV_DURATION;
    
      init.evt_handler = on_adv_evt;
    
      // Initialize advertising parameters (used when starting advertising).
      memset(&m_advertising.adv_params, 0, sizeof(m_advertising.adv_params));
    
      m_advertising.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
      m_advertising.adv_params.p_peer_addr = NULL; // Undirected advertisement.
      m_advertising.adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
      m_advertising.adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL;
      m_advertising.adv_params.duration = 0; // Never time out.
      m_advertising.adv_handle = m_adv_handle;
    
      manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER;
      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(&init.advdata, 0, sizeof(init.advdata));
    
      init.advdata.name_type = BLE_ADVDATA_NO_NAME;
      init.advdata.flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
      init.advdata.p_manuf_specific_data = &manuf_specific_data;
      err_code = ble_advertising_init(&m_advertising, &init);
      APP_ERROR_CHECK(err_code);
    
      ble_advertising_conn_cfg_tag_set(&m_advertising, APP_BLE_CONN_CFG_TAG);
      APP_ERROR_CHECK(err_code);
    
    }
    
    void updateAdvertisingData()
    {
    static uint32_t uiBuffIndex = 0;
    uint32_t err_code;
    ble_advdata_t advdata;
    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;
    
      //stop advertising
      err_code = sd_ble_gap_adv_stop(m_advertising.adv_handle);
      APP_ERROR_CHECK(err_code);
    
    
      #if 1   // run-time update beacon here.
      m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -4] = (uint8_t)Dev_Info.DevBleMac[2];
      m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -3] = (uint8_t)Dev_Info.DevBleMac[1];
      m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -2] = (uint8_t)Dev_Info.DevBleMac[0];
      m_updated_beacon_info[APP_BEACON_INFO_LENGTH-1 -1] = ((Dev_Info.VerMajor[0]-0x30<<4)|Dev_Info.VerMinor[1]-0x30);
      #endif
    
      manuf_specific_data.data.p_data = (uint8_t *) m_updated_beacon_info;
      manuf_specific_data.data.size = APP_BEACON_INFO_LENGTH;   // ibeacon size  = 21B
    
      // Initialize advertising parameters (used when starting advertising).
      memset(&m_advertising.adv_params, 0, sizeof(m_advertising.adv_params));
    
    
      //
      m_advertising.adv_params.properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED;
      m_advertising.adv_params.p_peer_addr = NULL; // Undirected advertisement.
      m_advertising.adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
      m_advertising.adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL;
      m_advertising.adv_params.duration = 0; // Never time out.
      m_advertising.adv_handle = m_adv_handle;
      // 
    
    
      err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
      APP_ERROR_CHECK(err_code);  // fail at err_code = 0xC
    
      err_code = sd_ble_gap_adv_set_configure(&m_advertising.adv_handle, &m_adv_data, &m_advertising.adv_params);
      APP_ERROR_CHECK(err_code);
    }

Related