How can I add scan response data to the SDK example ble_app_beacon?
How can I add scan response data to the SDK example ble_app_beacon?
Not sure what you are trying to acheive here?
Do you want to change the 128-bit UUID that is already added to the BLE stack's table?
You can take a look at the ble_advdata_t struct to see which data can be added to the scan response data.
As an example:
If we want to transmit the TX-power level in the scan response packet (And not the Vendor Specific UUID) of the ble_app_uart example:
static void advertising_init(void)
{
uint32_t err_code;
ble_advertising_init_t init;
int8_t tx_power = -4;
memset(&init, 0, sizeof(init));
init.advdata.name_type = BLE_ADVDATA_FULL_NAME;
init.advdata.include_appearance = false;
init.advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_LIMITED_DISC_MODE;
//init.srdata.uuids_complete.uuid_cnt = sizeof(m_adv_uuids) / sizeof(m_adv_uuids[0]);
//init.srdata.uuids_complete.p_uuids = m_adv_uuids;
init.srdata.p_tx_power_level = &tx_power;
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;
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);
}
Let me know if I misunderstood something or you have further questions.
Best regards,
Joakim.
Wim said:Where can I change the first 14 bytes? Is that a 128 bit UUID? Where is it set?
One of my colleagues has made custom service tutorial available on github.
This tutorial is updated to SDK v15.0.0 and you could take a look at that to a better understanding on how the UUID is added to the BLE stack.
Cheers.
Hi Joakim,
I was looking how to program:
- iBeacon (to be recognized by iOS)
- with scan response data (for additional measurement or other data)
- and connectable (to act as normal BLE peripheral)
I succeeded (after combining your info and single stepping through some code)
Here is my example:
static void advertising_init(void)
{
uint32_t err_code;
uint8_t index;
uint8_t ch_array[10];
uint16_t major_value;
uint16_t minor_value;
ble_advdata_t advdata;
ble_advdata_t srdata;
ble_advdata_manuf_data_t manuf_specific_data;
ble_advdata_service_data_t service_data_array;
//Compose iBeacon data. Put the measurement data as major_value and minor_value
manuf_specific_data.company_identifier = APP_COMPANY_IDENTIFIER; //Apple iBeacon. Others are not recognized by iOS
index = MAJ_VAL_OFFSET_IN_BEACON_INFO;
m_beacon_info[index++] = 0xab;//MSB_16(major_value);
m_beacon_info[index++] = 0xcd;//LSB_16(major_value);
m_beacon_info[index++] = 0xef;//MSB_16(minor_value);
m_beacon_info[index++] = MyTime; //LSB_16(minor_value);
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: flags, manufacturer_specific_data
memset(&advdata, 0, sizeof(advdata));
advdata.name_type = BLE_ADVDATA_NO_NAME; //name will be included in scan response data
advdata.flags = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
advdata.p_manuf_specific_data = &manuf_specific_data;
// Build and set scan response data: name, service_data
memset(&srdata, 0, sizeof(srdata));
srdata.name_type = BLE_ADVDATA_SHORT_NAME;
srdata.short_name_len = 3; // Advertise only first 3 letters of name
ch_array[0] = 0; //eight interesting bytes
ch_array[1] = 1;
ch_array[2] = 2;
ch_array[3] = 3;
ch_array[4] = 4;
ch_array[5] = 5;
ch_array[6] = 6;
ch_array[7] = 7;
service_data_array.service_uuid = 0x5678; //16 bit UUID still TBD
service_data_array.data.size = 8;
service_data_array.data.p_data = ch_array;
srdata.service_data_count = 1;
srdata.p_service_data_array = &service_data_array;
// 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_CONNECTABLE_SCANNABLE_UNDIRECTED;
m_adv_params.p_peer_addr = NULL; // Undirected advertisement.
m_adv_params.filter_policy = BLE_GAP_ADV_FP_ANY;
m_adv_params.interval = NON_CONNECTABLE_ADV_INTERVAL;
m_adv_params.duration = 0; // Never time out.
m_adv_params.primary_phy = BLE_GAP_PHY_1MBPS;
m_adv_params.duration = APP_ADV_DURATION;
m_adv_params.interval = APP_ADV_INTERVAL;
//First encode the advertisement data
err_code = ble_advdata_encode(&advdata, m_adv_data.adv_data.p_data, &m_adv_data.adv_data.len);
APP_ERROR_CHECK(err_code);
//Now encode the scan response data
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);
nrf_gpio_pin_toggle(NRF_GPIO_PIN_MAP(0, 30));
}
Now my advertisement data is:
02:01:06:1A:FF:59:00:02:15:01:12:23:34:45:56:67:78:89:9A:AB:BC:CD:DE:EF:F0:AB:CD:EF:00:C3
And the scna response data is:
0B:16:78:56:00:01:02:03:04:05:06:07:04:08:45:50:50
I hope it can help other programmers.
Best regards,
Wim
I forgot a few lines of code:
#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 MAJ_VAL_OFFSET_IN_BEACON_INFO 18 /**< Position of the MSB of the Major Value in m_beacon_info array. */
static uint8_t m_beacon_info[APP_BEACON_INFO_LENGTH] = /**< Information advertised by the Beacon. */
{
APP_DEVICE_TYPE, // Manufacturer specific information. Specifies the device type in this
// implementation.
APP_ADV_DATA_LENGTH, // Manufacturer specific information. Specifies the length of the
// manufacturer specific data in this implementation.
APP_BEACON_UUID, // 128 bit UUID value.
APP_MAJOR_VALUE, // Major arbitrary value that can be used to distinguish between Beacons.
APP_MINOR_VALUE, // Minor arbitrary value that can be used to distinguish between Beacons.
APP_MEASURED_RSSI // Manufacturer specific information. The Beacon's measured TX power in
// this implementation.
};Hi.
Thanks for sharing your solution, so that others might benefit from it.
Best regards,
Joakim.