Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: microbit-dal microbit-dal microbit-ble-open microbit-dal ... more
Fork of BLE_API by
Revision 1098:5f6b5ea5d5f2, committed 2016-01-11
- Comitter:
- vcoubard
- Date:
- Mon Jan 11 08:51:53 2016 +0000
- Parent:
- 1097:4d22814faf46
- Child:
- 1099:6c54ccecf1e8
- Commit message:
- Synchronized with git rev ae516d1a
Author: Andres Amaya Garcia
Clean up code in DiscoveredCharacteristic.cpp
Clean up the code by removing white spaces and adding statements to supress
unused-parameter compiler warnings.
Changed in this revision
--- a/ble/Gap.h Mon Jan 11 08:51:53 2016 +0000
+++ b/ble/Gap.h Mon Jan 11 08:51:53 2016 +0000
@@ -620,7 +620,8 @@
/**
* Update a particular ADV field in the advertising payload (based on
- * matching type).
+ * matching type and length). Note: the length of the new data must be the
+ * same as the old one.
*
* @param[in] type The ADV type field describing the variable length data.
* @param[in] data Data bytes.
@@ -629,7 +630,7 @@
* @note: If advertisements are enabled, then the update will take effect immediately.
*
* @return BLE_ERROR_NONE if the advertisement payload was updated based on
- * matching AD type; otherwise, an appropriate error.
+ * a <type, len> match; otherwise, an appropriate error.
*/
ble_error_t updateAdvertisingPayload(GapAdvertisingData::DataType type, const uint8_t *data, uint8_t len) {
if (type == GapAdvertisingData::COMPLETE_LOCAL_NAME) {
--- a/ble/GapAdvertisingData.h Mon Jan 11 08:51:53 2016 +0000
+++ b/ble/GapAdvertisingData.h Mon Jan 11 08:51:53 2016 +0000
@@ -202,63 +202,149 @@
/**
* Adds advertising data based on the specified AD type (see DataType).
- * If the supplied AD type is already present in the advertising
- * payload, then the value is updated.
+ *
+ * @param advDataType The Advertising 'DataType' to add.
+ * @param payload Pointer to the payload contents.
+ * @param len Size of the payload in bytes.
+ *
+ * @return BLE_ERROR_BUFFER_OVERFLOW if the specified data would cause the
+ * advertising buffer to overflow, else BLE_ERROR_NONE.
+ */
+ ble_error_t addData(DataType advDataType, const uint8_t *payload, uint8_t len)
+ {
+ ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
+
+ // find field
+ uint8_t* field = findField(advDataType);
+
+ // Field type already exist, either add to field or replace
+ if (field) {
+ switch(advDataType) {
+ // These fields will be overwritten with the new value
+ case FLAGS:
+ case SHORTENED_LOCAL_NAME:
+ case COMPLETE_LOCAL_NAME:
+ case TX_POWER_LEVEL:
+ case DEVICE_ID:
+ case SLAVE_CONNECTION_INTERVAL_RANGE:
+ case SERVICE_DATA:
+ case APPEARANCE:
+ case ADVERTISING_INTERVAL:
+ case MANUFACTURER_SPECIFIC_DATA: {
+ // current field length, with the type subtracted
+ uint8_t dataLength = field[0] - 1;
+
+ // new data has same length, do in-order replacement
+ if (len == dataLength) {
+ for (uint8_t idx = 0; idx < dataLength; idx++) {
+ field[2 + idx] = payload[idx];
+ }
+ } else {
+ // check if data fits
+ if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+
+ // remove old field
+ while ((field + dataLength + 2) < &_payload[_payloadLen]) {
+ *field = field[dataLength + 2];
+ field++;
+ }
+
+ // reduce length
+ _payloadLen -= dataLength + 2;
+
+ // add new field
+ result = appendField(advDataType, payload, len);
+ }
+ }
+
+ break;
+ }
+ // These fields will have the new data appended if there is sufficient space
+ case INCOMPLETE_LIST_16BIT_SERVICE_IDS:
+ case COMPLETE_LIST_16BIT_SERVICE_IDS:
+ case INCOMPLETE_LIST_32BIT_SERVICE_IDS:
+ case COMPLETE_LIST_32BIT_SERVICE_IDS:
+ case INCOMPLETE_LIST_128BIT_SERVICE_IDS:
+ case COMPLETE_LIST_128BIT_SERVICE_IDS:
+ case LIST_128BIT_SOLICITATION_IDS: {
+ // check if data fits
+ if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+ // make room for new field by moving the remainder of the
+ // advertisement payload "to the right" starting after the
+ // TYPE field.
+ uint8_t* end = &_payload[_payloadLen];
+
+ while (&field[1] < end) {
+ end[len] = *end;
+ end--;
+ }
+
+ // insert new data
+ for (uint8_t idx = 0; idx < len; idx++) {
+ field[2 + idx] = payload[idx];
+ }
+
+ // increment lengths
+ field[0] += len;
+ _payloadLen += len;
+
+ result = BLE_ERROR_NONE;
+ }
+
+ break;
+ }
+ // Field exists but updating it is not supported. Abort operation.
+ default:
+ result = BLE_ERROR_NOT_IMPLEMENTED;
+ break;
+ }
+ } else {
+ // field doesn't exists, insert new
+ result = appendField(advDataType, payload, len);
+ }
+
+ return result;
+ }
+
+ /**
+ * Update a particular ADV field in the advertising payload (based on
+ * matching type and length). Note: the length of the new data must be the
+ * same as the old one.
*
* @param[in] advDataType The Advertising 'DataType' to add.
* @param[in] payload Pointer to the payload contents.
* @param[in] len Size of the payload in bytes.
*
- * @return BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
- * advertising buffer to overflow. BLE_ERROR_NONE is returned
- * on success.
- *
- * @note When the specified AD type is INCOMPLETE_LIST_16BIT_SERVICE_IDS,
- * COMPLETE_LIST_16BIT_SERVICE_IDS, INCOMPLETE_LIST_32BIT_SERVICE_IDS,
- * COMPLETE_LIST_32BIT_SERVICE_IDS, INCOMPLETE_LIST_128BIT_SERVICE_IDS,
- * COMPLETE_LIST_128BIT_SERVICE_IDS or LIST_128BIT_SOLICITATION_IDS the
- * supplied value is appended to the values previously added to the
- * payload.
- */
- ble_error_t addData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
- {
- // find field
- uint8_t* field = findField(advDataType);
-
- if (field) {
- // Field type already exist, either add to field or replace
- return updateField(advDataType, payload, len, field);
- } else {
- // field doesn't exists, insert new
- return appendField(advDataType, payload, len);
- }
- }
-
- /**
- * Update a particular ADV field in the advertising payload (based on
- * matching type).
- *
- * @param[in] advDataType The Advertising 'DataType' to add.
- * @param[in] payload Pointer to the payload contents.
- * @param[in] len Size of the payload in bytes.
- *
- * @return BLE_ERROR_UNSPECIFIED if the specified field is not found,
- * BLE_ERROR_BUFFER_OVERFLOW if the new value causes the
- * advertising buffer to overflow. BLE_ERROR_NONE is returned
- * on success.
+ * @return BLE_ERROR_UNSPECIFIED if the specified field is not found, else
+ * BLE_ERROR_NONE.
*/
ble_error_t updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
{
- // find field
- uint8_t* field = findField(advDataType);
+ if ((payload == NULL) || (len == 0)) {
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ /* A local struct to describe an ADV field. This definition comes from the Bluetooth Core Spec. (v4.2) Part C, Section 11. */
+ struct ADVField_t {
+ uint8_t len; /* Describes the length (in bytes) of the following type and bytes. */
+ uint8_t type; /* Should have the same representation of DataType_t (above). */
+ uint8_t bytes[0]; /* A placeholder for variable length data. */
+ };
- if (field) {
- // Field type already exist, either add to field or replace
- return updateField(advDataType, payload, len, field);
- } else {
- // field doesn't exists, return an error
- return BLE_ERROR_UNSPECIFIED;
+ /* Iterate over the adv fields looking for the first match. */
+ uint8_t byteIndex = 0;
+ while (byteIndex < _payloadLen) {
+ ADVField_t *currentADV = (ADVField_t *)&_payload[byteIndex];
+ if ((currentADV->len == (len + 1)) && /* Incoming len only describes the payload, whereas ADV->len describes [type + payload]. */
+ (currentADV->type == advDataType)) {
+ memcpy(currentADV->bytes, payload, len);
+ return BLE_ERROR_NONE;
+ }
+
+ byteIndex += (currentADV->len + 1); /* Advance by len+1; '+1' is needed to span the len field itself. */
}
+
+ return BLE_ERROR_UNSPECIFIED;
}
/**
@@ -389,85 +475,6 @@
return NULL;
}
- /**
- * Given the a pointer to a field in the advertising payload it replaces
- * the existing data in the field with the supplied data.
- * Returns BLE_ERROR_NONE on success.
- */
- ble_error_t updateField(DataType_t advDataType, const uint8_t *payload, uint8_t len, uint8_t* field)
- {
- ble_error_t result = BLE_ERROR_BUFFER_OVERFLOW;
-
- switch(advDataType) {
- // These fields will have the new data appended if there is sufficient space
- case INCOMPLETE_LIST_16BIT_SERVICE_IDS:
- case COMPLETE_LIST_16BIT_SERVICE_IDS:
- case INCOMPLETE_LIST_32BIT_SERVICE_IDS:
- case COMPLETE_LIST_32BIT_SERVICE_IDS:
- case INCOMPLETE_LIST_128BIT_SERVICE_IDS:
- case COMPLETE_LIST_128BIT_SERVICE_IDS:
- case LIST_128BIT_SOLICITATION_IDS: {
- // check if data fits
- if ((_payloadLen + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
- // make room for new field by moving the remainder of the
- // advertisement payload "to the right" starting after the
- // TYPE field.
- uint8_t* end = &_payload[_payloadLen];
-
- while (&field[1] < end) {
- end[len] = *end;
- end--;
- }
-
- // insert new data
- for (uint8_t idx = 0; idx < len; idx++) {
- field[2 + idx] = payload[idx];
- }
-
- // increment lengths
- field[0] += len;
- _payloadLen += len;
-
- result = BLE_ERROR_NONE;
- }
-
- break;
- }
- // These fields will be overwritten with the new value
- default: {
- // current field length, with the type subtracted
- uint8_t dataLength = field[0] - 1;
-
- // new data has same length, do in-order replacement
- if (len == dataLength) {
- for (uint8_t idx = 0; idx < dataLength; idx++) {
- field[2 + idx] = payload[idx];
- }
- } else {
- // check if data fits
- if ((_payloadLen - dataLength + len) <= GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
-
- // remove old field
- while ((field + dataLength + 2) < &_payload[_payloadLen]) {
- *field = field[dataLength + 2];
- field++;
- }
-
- // reduce length
- _payloadLen -= dataLength + 2;
-
- // add new field
- result = appendField(advDataType, payload, len);
- }
- }
-
- break;
- }
- }
-
- return result;
- }
-
uint8_t _payload[GAP_ADVERTISING_DATA_MAX_PAYLOAD];
uint8_t _payloadLen;
uint16_t _appearance;
--- a/source/DiscoveredCharacteristic.cpp Mon Jan 11 08:51:53 2016 +0000
+++ b/source/DiscoveredCharacteristic.cpp Mon Jan 11 08:51:53 2016 +0000
@@ -31,29 +31,29 @@
return gattc->read(connHandle, valueHandle, offset);
}
-struct OneShotReadCallback {
- static void launch(GattClient* client, Gap::Handle_t connHandle,
- GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) {
+struct OneShotReadCallback {
+ static void launch(GattClient* client, Gap::Handle_t connHandle,
+ GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) {
OneShotReadCallback* oneShot = new OneShotReadCallback(client, connHandle, handle, cb);
oneShot->attach();
// delete will be made when this callback is called
}
private:
- OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle,
- GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) :
+ OneShotReadCallback(GattClient* client, Gap::Handle_t connHandle,
+ GattAttribute::Handle_t handle, const GattClient::ReadCallback_t& cb) :
_client(client),
_connHandle(connHandle),
- _handle(handle),
- _callback(cb) { }
+ _handle(handle),
+ _callback(cb) { }
- void attach() {
+ void attach() {
_client->onDataRead(makeFunctionPointer(this, &OneShotReadCallback::call));
}
void call(const GattReadCallbackParams* params) {
// verifiy that it is the right characteristic on the right connection
- if (params->connHandle == _connHandle && params->handle == _handle) {
+ if (params->connHandle == _connHandle && params->handle == _handle) {
_callback(params);
_client->onDataRead().detach(makeFunctionPointer(this, &OneShotReadCallback::call));
delete this;
@@ -68,7 +68,7 @@
ble_error_t DiscoveredCharacteristic::read(uint16_t offset, const GattClient::ReadCallback_t& onRead) const {
ble_error_t error = read(offset);
- if (error) {
+ if (error) {
return error;
}
@@ -105,29 +105,29 @@
return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value);
}
-struct OneShotWriteCallback {
- static void launch(GattClient* client, Gap::Handle_t connHandle,
- GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) {
+struct OneShotWriteCallback {
+ static void launch(GattClient* client, Gap::Handle_t connHandle,
+ GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) {
OneShotWriteCallback* oneShot = new OneShotWriteCallback(client, connHandle, handle, cb);
oneShot->attach();
// delete will be made when this callback is called
}
private:
- OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle,
- GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) :
+ OneShotWriteCallback(GattClient* client, Gap::Handle_t connHandle,
+ GattAttribute::Handle_t handle, const GattClient::WriteCallback_t& cb) :
_client(client),
_connHandle(connHandle),
- _handle(handle),
- _callback(cb) { }
+ _handle(handle),
+ _callback(cb) { }
- void attach() {
+ void attach() {
_client->onDataWritten(makeFunctionPointer(this, &OneShotWriteCallback::call));
}
void call(const GattWriteCallbackParams* params) {
// verifiy that it is the right characteristic on the right connection
- if (params->connHandle == _connHandle && params->handle == _handle) {
+ if (params->connHandle == _connHandle && params->handle == _handle) {
_callback(params);
_client->onDataWritten().detach(makeFunctionPointer(this, &OneShotWriteCallback::call));
delete this;
@@ -142,7 +142,7 @@
ble_error_t DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value, const GattClient::WriteCallback_t& onRead) const {
ble_error_t error = write(length, value);
- if (error) {
+ if (error) {
return error;
}
@@ -154,5 +154,9 @@
ble_error_t
DiscoveredCharacteristic::discoverDescriptors(DescriptorCallback_t callback, const UUID &matchingUUID) const
{
+ /* Avoid compiler warnings */
+ (void) callback;
+ (void) matchingUUID;
+
return BLE_ERROR_NOT_IMPLEMENTED; /* TODO: this needs to be filled in. */
}
\ No newline at end of file
