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 1099:6c54ccecf1e8, committed 2016-01-11
- Comitter:
- vcoubard
- Date:
- Mon Jan 11 08:51:54 2016 +0000
- Parent:
- 1098:5f6b5ea5d5f2
- Child:
- 1100:c3d484a482d8
- Commit message:
- Synchronized with git rev fec4e5ec
Author: Andres Amaya Garcia
Add documentation missing for updateData()
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:54 2016 +0000
@@ -620,8 +620,7 @@
/**
* 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.
+ * matching type).
*
* @param[in] type The ADV type field describing the variable length data.
* @param[in] data Data bytes.
@@ -630,7 +629,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
- * a <type, len> match; otherwise, an appropriate error.
+ * matching AD type; 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:54 2016 +0000
@@ -202,149 +202,70 @@
/**
* Adds advertising data based on the specified AD type (see DataType).
- *
- * @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.
+ * If the supplied AD type is already present in the advertising
+ * payload, then the value is updated.
*
* @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, else
- * BLE_ERROR_NONE.
+ * @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.
+ *
+ * @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 updateData(DataType_t advDataType, const uint8_t *payload, uint8_t len)
{
- 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. */
- };
+ // find field
+ uint8_t* field = findField(advDataType);
- /* 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. */
+ 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;
}
-
- return BLE_ERROR_UNSPECIFIED;
}
/**
@@ -475,6 +396,85 @@
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:54 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,9 +154,5 @@
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
