From 40d3fb07d98db264dc1f2b0c2b5a3057359a721d Mon Sep 17 00:00:00 2001 From: "Bradford H. Needham" Date: Tue, 8 Mar 2016 20:35:51 -0800 Subject: [PATCH 1/2] Added Eddystone-URL support: added setAdvertisedServiceData() to support BLE Service Data; changed Incomplete to Complete Service UUID list code in Advertising initialization, required by Eddystone-URL protocol; added (for debugging) getAdvertisingLength() and getAdvertising() to enable a Sketch viewing the Advertizing packet. --- libraries/CurieBLE/keywords.txt | 3 ++ libraries/CurieBLE/src/BLEPeripheral.cpp | 53 +++++++++++++++++++++++- libraries/CurieBLE/src/BLEPeripheral.h | 44 ++++++++++++++++++++ 3 files changed, 99 insertions(+), 1 deletion(-) diff --git a/libraries/CurieBLE/keywords.txt b/libraries/CurieBLE/keywords.txt index ad168000..4598ecb2 100644 --- a/libraries/CurieBLE/keywords.txt +++ b/libraries/CurieBLE/keywords.txt @@ -49,7 +49,10 @@ written KEYWORD2 subscribed KEYWORD2 begin KEYWORD2 +getAdvertisingLength KEYWORD2 +getAdvertising KEYWORD2 setAdvertisedServiceUuid KEYWORD2 +setAdvertisedServiceData KEYWORD2 setLocalName KEYWORD2 setAppearance KEYWORD2 setConnectionInterval KEYWORD2 diff --git a/libraries/CurieBLE/src/BLEPeripheral.cpp b/libraries/CurieBLE/src/BLEPeripheral.cpp index 2ac52983..f1218bcd 100644 --- a/libraries/CurieBLE/src/BLEPeripheral.cpp +++ b/libraries/CurieBLE/src/BLEPeripheral.cpp @@ -47,6 +47,9 @@ BLEPeripheral::BLEPeripheral(void) : _state(BLE_PERIPH_STATE_NOT_READY), _advertise_service_uuid(NULL), _local_name(NULL), + _service_data_uuid(NULL), + _service_data(NULL), + _service_data_length(0), _appearance(0), _min_conn_interval(DEFAULT_MIN_CONN_INTERVAL), _max_conn_interval(DEFAULT_MAX_CONN_INTERVAL), @@ -136,6 +139,18 @@ BLEPeripheral::end() _stop(); } +uint8_t +BLEPeripheral::getAdvertisingLength() +{ + return _adv_data_len; +} + +uint8_t* +BLEPeripheral::getAdvertising() +{ + return _adv_data; +} + void BLEPeripheral::setAdvertisedServiceUuid(const char* advertisedServiceUuid) { @@ -148,6 +163,14 @@ BLEPeripheral::setLocalName(const char* localName) _local_name = localName; } +void +BLEPeripheral::setAdvertisedServiceData(const char* serviceDataUuid, uint8_t* serviceData, uint8_t serviceDataLength) +{ + _service_data_uuid = serviceDataUuid; + _service_data = serviceData; + _service_data_length = serviceDataLength; +} + void BLEPeripheral::setDeviceName(const char deviceName[]) { @@ -294,7 +317,7 @@ BLEPeripheral::_advDataInit(void) if (BT_UUID16 == uuid.type) { uint8_t *adv_tmp = &_adv_data[_adv_data_len]; *adv_tmp++ = (1 + sizeof(uint16_t)); /* Segment data length */ - *adv_tmp++ = BLE_ADV_TYPE_INC_16_UUID; + *adv_tmp++ = BLE_ADV_TYPE_COMP_16_UUID; /* Needed for Eddystone */ UINT16_TO_LESTREAM(adv_tmp, uuid.uuid16); _adv_data_len += (2 + sizeof(uint16_t)); } else if (BT_UUID128 == uuid.type) { @@ -324,6 +347,34 @@ BLEPeripheral::_advDataInit(void) memcpy(adv_tmp, _local_name, calculated_len); _adv_data_len += calculated_len + 2; } + + if (_service_data) { + /* Add Service Data (if it will fit) */ + + BLEUuid bleUuid = BLEUuid(_service_data_uuid); + struct bt_uuid uuid = bleUuid.uuid(); + + /* A 128-bit Service Data UUID won't fit in an Advertising packet */ + if (BT_UUID16 != uuid.type) { + return; /* We support service data only for 16-bit service UUID */ + } + + uint8_t block_len = 1 + sizeof(uint16_t) + _service_data_length; + if (_adv_data_len + 1 + block_len > BLE_MAX_ADV_SIZE) { + return; // Service data block is too large. + } + + adv_tmp = &_adv_data[_adv_data_len]; + + *adv_tmp++ = block_len; + _adv_data_len++; + + *adv_tmp++ = BLE_ADV_TYPE_SERVICE_DATA_16_UUID; + UINT16_TO_LESTREAM(adv_tmp, uuid.uuid16); + memcpy(adv_tmp, _service_data, _service_data_length); + + _adv_data_len += block_len; + } } BleStatus diff --git a/libraries/CurieBLE/src/BLEPeripheral.h b/libraries/CurieBLE/src/BLEPeripheral.h index 9a5e9c34..054af330 100644 --- a/libraries/CurieBLE/src/BLEPeripheral.h +++ b/libraries/CurieBLE/src/BLEPeripheral.h @@ -55,6 +55,23 @@ class BLEPeripheral { */ virtual ~BLEPeripheral(void); + /** + * Return the number of bytes in the advertising block. + * Useful for debugging advertising problems. + * + * @note Call only after calling begin(). + */ + uint8_t getAdvertisingLength(); + + /** + * Returns a pointer to the advertising block + * of length getAdvertisingLength(). + * Useful for debugging advertising problems. + * + * @note Call only after calling begin(). + */ + uint8_t* getAdvertising(); + /** * Set the service UUID that the BLE Peripheral Device advertises * @@ -74,6 +91,30 @@ class BLEPeripheral { */ void setLocalName(const char* localName); + /** + * Set the Service Data that the BLE Peripheral Device advertises + * + * @param serviceDataUuid 16-bit Service UUID for this Service Data + * (in string form). Must match the UUID parameter + * of setAdvertisedServiceUuid(). To fit into BLE_MAX_ADV_SIZE, + * the UUID must be a 16-bit UUID. + * + * @param serviceData binary array of Service Data. + * + * @param serviceDataLength length (bytes) of serviceData[] + * + * @note the entire advertising packet must be no more than + * BLE_MAX_ADV_SIZE bytes, which is currently 31. + * This likely means that if you use Service Data + * there will not be room for a Local Name. + * + * @note if serviceDataUuid isn't 16-bits long, or if + * serviceDataLength won't fit in the advertising block, + * the service data will silently not be copied + * into the advertising block. + */ + void setAdvertisedServiceData(const char* serviceDataUuid, uint8_t* serviceData, uint8_t serviceDataLength); + /** * Set the device name for the BLE Peripheral Device * @@ -194,6 +235,9 @@ class BLEPeripheral { const char* _advertise_service_uuid; const char* _local_name; + const char* _service_data_uuid; + uint8_t* _service_data; + uint8_t _service_data_length; char _device_name[BLE_MAX_DEVICE_NAME+1]; uint16_t _appearance; uint16_t _min_conn_interval; From 0ad15b5a46969ddda239cf764caebb32a81e56ae Mon Sep 17 00:00:00 2001 From: "Bradford H. Needham" Date: Sun, 3 Apr 2016 11:07:14 -0700 Subject: [PATCH 2/2] Fixed spaces in keywords.txt; keywords now highlight properly --- libraries/CurieBLE/keywords.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/CurieBLE/keywords.txt b/libraries/CurieBLE/keywords.txt index 4598ecb2..85eccea2 100644 --- a/libraries/CurieBLE/keywords.txt +++ b/libraries/CurieBLE/keywords.txt @@ -49,10 +49,10 @@ written KEYWORD2 subscribed KEYWORD2 begin KEYWORD2 -getAdvertisingLength KEYWORD2 -getAdvertising KEYWORD2 +getAdvertisingLength KEYWORD2 +getAdvertising KEYWORD2 setAdvertisedServiceUuid KEYWORD2 -setAdvertisedServiceData KEYWORD2 +setAdvertisedServiceData KEYWORD2 setLocalName KEYWORD2 setAppearance KEYWORD2 setConnectionInterval KEYWORD2