Bluetooth LE (BLE)

BleAdvertisingData

The BleAdvertisingData is used in two ways:

  • In the peripheral role, to define what you want to send when central devices do a scan.
  • In the central role, as a container to hold what the other side has sent during a scan.

For more information about advertising, see the BLE tutorial.

BleAdvertisingData()

Construct a BleAdvertisingData object. You typically do this in a peripheral role before adding new data.

In the central role, you get a filled in object in the BleScanResult object.

// PROTOTYPE
BleAdvertisingData();

append()

Appends advertising data of a specific type to the advertising data object.

// PROTOTYPE
size_t append(BleAdvertisingDataType type, const uint8_t* buf, size_t len, bool force = false);

// EXAMPLE
BleAdvertisingData advData;

uint8_t flagsValue = BLE_SIG_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
advData.append(BleAdvertisingDataType::FLAGS, &flagsValue, sizeof(flagsValue));
  • type The type of data to append. The valid types are listed in the BleAdvertisingDataType section, below.
  • buf Pointer to the buffer containing the data
  • len The length of the data in bytes
  • force If true, then multiple blocks of the same type can be appended. The default is false, which replaces an existing block and is the normal behavior.

Note that advertising data is limited to 31 bytes (BLE_MAX_ADV_DATA_LEN), and each block includes a type and a length byte, so you are quite limited in what you can add.

You normally don't need to include BleAdvertisingDataType::FLAGS, however. If you do not include it, one will be inserted automatically.

appendCustomData

Appends custom advertising data to the advertising data object.

// PROTOTYPE
size_t appendCustomData(const uint8_t* buf, size_t len, bool force = false);
  • buf Pointer to the buffer containing the data
  • len The length of the data in bytes
  • force If true, then multiple blocks of the same type can be appended. The default is false, which replaces an existing block and is the normal behavior.

Note that advertising data is limited to 31 bytes (BLE_MAX_ADV_DATA_LEN), and each block includes a type and a length byte, so you are quite limited in what you can add.

Since 3.2.0:

If BlePhy::BLE_PHYS_CODED advertising PHY is set, it's possible to provide up to 255 (BLE_MAX_ADV_DATA_LEN_EXT_CONNECTABLE) of advertising data.

The first two bytes of the company data are typically the unique company identifier assigned by the Bluetooth SIG. You need to be a member of the Bluetooth SIG to get a company ID, and the field is only 16 bits wide, so there can only be 65534 companies.

The special value of 0xffff is reserved for internal use and testing.

If you are using private custom data it's recommended to begin it with two 0xff bytes, that way your data won't confuse apps that are scanning for company-specific custom data.

The maximum custom data size is 26 bytes, including the company ID. Adding data that is too large will cause it to be omitted (not truncated).

appendLocalName()

An optional field in the advertising data is the local name. This can be useful if the user needs to select from multiple devices.

The name takes up the length of the name plus two bytes (type and length). The total advertising data is limited to 31 bytes (BLE_MAX_ADV_DATA_LEN), and if you include service identifiers there isn't much left space for the name.

// PROTOTYPE
size_t appendLocalName(const char* name);
size_t appendLocalName(const String& name);

appendServiceUUID()

Appends a service UUID to the advertisement (short or long). You typically only advertise the primary service.

For example, the health thermometer advertises the health thermometer service. Upon connecting, the central device can discover that it also supports the battery service. Put another way, a user or app would most likely only want to discover a nearby thermometer, not any battery powered device nearby.

// PROTOTYPE
// Type T is any type that can be passed to the BleUuid constructor
template<typename T>
size_t appendServiceUUID(T uuid, bool force = false) 

// EXAMPLE
advData.appendServiceUUID(healthThermometerService);
  • uuid The UUID to add. This can be a BleUuid object, a uint16_t (short UUID), or a const char * or string literal specifying a long UUID.
  • force If true, then multiple blocks of the same type can be appended. The default is false, which replaces an existing block and is the normal behavior.

Since long UUIDs are long (16 bytes plus 2 bytes of overhead) they will use a lot of the 31 byte payload, leaving little room for other things like short name.

clear()

Remove all existing data from the BleAdvertisingData object.

// PROTOTYPE
void clear();

remove()

Remove a specific data type from the BleAdvertisingData object.

// PROTOTYPE
void remove(BleAdvertisingDataType type);

set()

In a peripheral role, you sometimes will want to build your advertising data complete by hand. You can then copy your pre-build structure into the BleAdvertisingData object using set().

// PROTOTYPE
size_t set(const uint8_t* buf, size_t len);

get(type, buffer)

In the central role, if you want to get a specific block of advertising data by type, you can use this method.

// PROTOTYPE
size_t get(BleAdvertisingDataType type, uint8_t* buf, size_t len) const;
  • type The BleAdvertisingDataType to get.
  • buf A pointer to the buffer to hold the data.
  • len The length of the buffer in bytes.

Returns the number of bytes copied, which will be <= len. Returns 0 if the type does not exist in the advertising data.

get(buffer)

In the central role, if you want to get the advertising data as a complete block of data, you can use the get method with a buffer and length.

Advertising data is limited to 31 bytes (BLE_MAX_ADV_DATA_LEN) and you should make your buffer at least that large to be able to receive the largest possible data.

// PROTOTYPE
size_t get(uint8_t* buf, size_t len) const;
  • buf A pointer to the buffer to hold the data.
  • len The length of the buffer in bytes.

Returns the number of bytes copied, which will be <= len.

length()

Return the length of the data in bytes.

// PROTOTYPE
size_t length() const;

operator[]

uint8_t operator[](uint8_t i) const;

Since 3.0.0:

In Device OS 3.0.0 and later, you can retrieve a byte from the advertising data using the [] operator. This uses get() internally.

deviceName()

Gets the deviceName (SHORT_LOCAL_NAME or COMPLETE_LOCAL_NAME). Returns a String object or an empty string if the advertising data does not contain a name.

// PROTOTYPE
String deviceName() const;

deviceName(buf)

Gets the deviceName (SHORT_LOCAL_NAME or COMPLETE_LOCAL_NAME).

// PROTOTYPE
size_t deviceName(char* buf, size_t len) const;
  • buf Buffer to hold the name. A buffer that is BLE_MAX_ADV_DATA_LEN bytes long will always be large enough.
  • len Length of the buffer in bytes.

Returns the size of the name in bytes. Returns 0 if there is no name.

Note that the buf will not be null-terminated (not a c-string).

serviceUUID()

Returns an array of service UUIDs in the advertising data.

// PROTOTYPE
size_t serviceUUID(BleUuid* uuids, size_t count) const;
  • uuids Pointer to an array of BleUuid objects to fill in
  • len The number of array entries (not bytes)

Returns the number of UUIDs in the advertisement.

This includes all UUIDs in the following advertising data types:

  • SERVICE_UUID_16BIT_MORE_AVAILABLE
  • SERVICE_UUID_16BIT_COMPLETE
  • SERVICE_UUID_128BIT_MORE_AVAILABLE
  • SERVICE_UUID_128BIT_COMPLETE

There is often a single UUID advertised, even for devices that have multiple services. For example, a heart rate monitor might only advertise that it's a heart rate monitor even though it also supports the battery service. The additional services can be discovered after connecting.

Since the advertisement data is limited to 31 bytes, the maximum number of services that could be advertised is 14 16-bit UUIDs.

customData()

Returns the MANUFACTURER_SPECIFIC_DATA data in an advertisement.

// PROTOTYPE
size_t customData(uint8_t* buf, size_t len) const;
  • buf Buffer to hold the data. A buffer that is BLE_MAX_ADV_DATA_LEN bytes long will always be large enough.
  • len Length of the buffer in bytes.

Returns the size of the data in bytes. Returns 0 if there is no MANUFACTURER_SPECIFIC_DATA.

contains()

Return true if the advertising data contains the specified type.

// PROTOTYPE
bool contains(BleAdvertisingDataType type) const;
  • type The data type to look for. For example: BleAdvertisingDataType::SHORT_LOCAL_NAME. See BleAdvertisingDataType.