This blog is to describe more details on the advertising payload.
The Packet data unit for the advertising channel (called the Advertising Channel PDU) includes a 2-byte header and a variable payload from 6 to 37 bytes. The actual length of the payload is defined by the 6-bit Length field in the header of the Advertising Channel PDU.
https://www.argenox.com/library/bluetooth-low-energy/ble-advertising-primer/
Flags Advertising Data Type
This packet has data type 0x01 indicating various flags. The length is 2 because there are two bytes, the data type and the actual flag value. The flag value has several bits indicating the capabilities of the iBeacon:
- Bit 0 – Indicates LE Limited Discoverable Mode
- Bit 1 – Indicates LE General Discoverable Mode
- Bit 2 – Indicates whether BR/EDR is supported. This is used if your iBeacon is Dual Mode device
- Bit 3 – Indicates whether LE and BR/EDR Controller operates simultaneously
- Bit 4 – Indicates whether LE and BR/EDR Host operates simultaneously
Most iBeacons are single mode devices BR/EDR is not used. For iBeacons, General discoverability mode is used.
After Channel Selection Algorithm 2 (introduced at BT 5.0), the RFU would split into RFU and ChSel.
Scan Response
The advertisement packet has 31 data bytes available for you to use. Due to the limited payload of the Advertising particular on the 128-bit UUID, you can choose to use scan responses. Scan response would have extra 31 data bytes available.
The Scan Response packet has the same packet format as the advertisement, with the exception of the type on the higher layer indicating it’s a scan response instead of an advertisement. So your scan response can provide the device name or other services you didn’t mention in the advertising packet.
Core Specification Supplement
This part defines the basic data types used for Extended Inquiry Response (EIR), Advertising Data (AD), Scan Response Data (SRD), Additional Controller Advertising Data (ACAD), and OOB data blocks. Additional data types may be defined in profile specifications.
Corresponding GAP Advertising and Scan Response Data format in ble_gap.h
EXAMPLES on some common used GAP advertising data format
This example is to fill up advertising payload with Manufacturer specific data (maximum length = 0x25). All the others such as device name, 128 uuid , TX power can be filled up at the scan response payload.
Advertising Data (Flags)
Length | Data Type | Advertising Mode |
0x02 | 0x01 | 0x06 (00000110B) |
Manufacturer Specify Data
Length | Data Type | Company ID | Manufacturer Specific Data |
0x1B (27) | 0xFF | 0x0059 | 0x0001C0111111CC64F00A0B0C0D0E0F101112131415161718 |
Manufacturer Specific Data (offset) | Type | Value / Data |
0 | Header of Manufacturer Payload | 0x01 |
1-7 | MAC Address | 0xCC, 0x11, 0x11, 0x11, 0x11, 0xC0 |
8 | Battery Value in % | 0x64 (100%) |
9 | Measured RSSI Value | 0xF0 |
10 – 24 | Other Value | 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18 |
TX Power
Length | Data Type | TX Power Level |
02 | 0x0A | 0xFC (-4 dBm) |
Slave Connection Interval Range
Length | Data Type | Minimum | Maximum |
0x05 | 0x12 | 0x0006 (7.5ms) | 0x0014 (25ms) |
Service UUIDs (Complete UUID 128 bit)
Length | Data Type | UUID |
0x11 (17) | 0x07 | 0x6E400001-B5A3-F393-E0A9-E50E24DCCA9E |
Device Name
Length | Data Type | Complete Local Name |
0x0C (12) | 0x09 | Nordic_UART (0x4E6F726469635F55415254) |
Without using the ble_advertising module (reduce the RAM / FLASH size usage), we can directly call the softdevice device API to set up the advertising payload.
static void advertising_init(void)
{
uint32_t err_code;
uint16_t len_advdata = BLE_GAP_ADV_MAX_SIZE;
uint16_t len_scandata = BLE_GAP_ADV_MAX_SIZE;
ble_gap_addr_t device_mac_addr;
uint16_t actual_device_name_length = MAXIMUM_DEVICE_NAME_LENGTH;
m_hardcode_enc_advdata[0] = 0x02;
m_hardcode_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
m_hardcode_enc_advdata[2] = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
m_hardcode_enc_advdata[3] = 0x1B; // Maximum payload of the manufacturer specific data
m_hardcode_enc_advdata[4] = BLE_GAP_AD_TYPE_MANUFACTURER_SPECIFIC_DATA;
m_hardcode_enc_advdata[5] = 0x59; // Company Identier
m_hardcode_enc_advdata[6] = 0x00;
m_hardcode_enc_advdata[7] = APP_MANU_HEADER;
err_code = sd_ble_gap_addr_get(&device_mac_addr);
APP_ERROR_CHECK(err_code);
memcpy(&m_hardcode_enc_advdata[8], device_mac_addr.addr, BLE_GAP_ADDR_LEN);
if (strlen(DEVICE_NAME) > MAXIMUM_DEVICE_NAME_LENGTH)
{
NRF_LOG_ERROR("Length of device name %s is exceeded the limit %d", (char *)DEVICE_NAME, MAXIMUM_DEVICE_NAME_LENGTH);
APP_ERROR_CHECK(NRF_ERROR_INVALID_PARAM);
}
/* Get GAP device name and length. */
m_hardcode_enc_scandata[0] = 0x11; /* length = 17 , UUID 128 */
m_hardcode_enc_scandata[1] = BLE_GAP_AD_TYPE_128BIT_SERVICE_UUID_COMPLETE;
memcpy(&m_hardcode_enc_scandata[2], nus_base_uuid, sizeof(nus_base_uuid));
len_scandata = 2 + sizeof(nus_base_uuid);
err_code = sd_ble_gap_device_name_get(&m_hardcode_enc_scandata[20], &actual_device_name_length);
APP_ERROR_CHECK(err_code);
m_hardcode_enc_scandata[18] = actual_device_name_length+1;
m_hardcode_enc_scandata[19] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
len_scandata += 2 + actual_device_name_length;
//err_code = sd_ble_gap_adv_data_set(m_enc_advdata, len_advdata, NULL, 0);
err_code = sd_ble_gap_adv_data_set(m_hardcode_enc_advdata, len_advdata, m_hardcode_enc_scandata, len_scandata);
APP_ERROR_CHECK(err_code);
}
static uint32_t advertising_start(void)
{
uint32_t err_code;
ble_gap_adv_params_t adv_params =
{
.type = BLE_GAP_ADV_TYPE_ADV_IND,
.p_peer_addr = NULL,
.fp = BLE_GAP_ADV_FP_ANY,
.interval = APP_ADV_INTERVAL,
.timeout = APP_ADV_TIMEOUT_IN_SECONDS,
};
err_code = sd_ble_gap_adv_start(&adv_params, APP_BLE_CONN_CFG_TAG);
APP_ERROR_CHECK(err_code);
return err_code;
}
Thanks for your interests on my blog. Since 2019, I have created this blog and shared the idea how to do some funny stuffs. I am very pleasure that I get quite a lot of positive feedback. I really hope that this blog helps your own embedded solution development. May I get support from you to keep it in order to maintain the wordpress host service? Your appreciation would be very helpful.
Usually I don’t learn post on blogs, but I would
like to say that this write-up very pressured me to check
out and do so! Your writing taste has been amazed me. Thanks, quite nice post.
LikeLike
Thanks for sharing! It helped me a lot
LikeLike
Great post. I was checking continuously this weblog and I
am impressed! Extremely useful information specially the ultimate phase 🙂 I deal with such
info much. I was looking for this particular info for a very long time.
Thanks and good luck.
LikeLike