extend
Fork of BLE_API by
Diff: ble/GapAdvertisingData.h
- Revision:
- 765:4cd91998cd48
- Parent:
- 763:36c3e2b1f1ae
- Child:
- 769:2d236d9afa9e
diff -r 1e560f0d45e1 -r 4cd91998cd48 ble/GapAdvertisingData.h --- a/ble/GapAdvertisingData.h Fri Aug 07 15:53:50 2015 +0100 +++ b/ble/GapAdvertisingData.h Fri Aug 07 15:53:50 2015 +0100 @@ -209,7 +209,7 @@ * advertising buffer to overflow, else BLE_ERROR_NONE. */ ble_error_t addData(DataType advDataType, const uint8_t *payload, uint8_t len) - { + { /* ToDo: Check if an AD type already exists and if the existing */ /* value is exclusive or not (flags, etc.) */ @@ -234,27 +234,41 @@ } /** - * update one advertising data field with the same AD type (see DataType) + * 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 advDataType The Advertising 'DataType' to add - * @param payload Pointer to the payload contents - * @param len Size of the payload in bytes + * @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. */ - ble_error_t updateData(DataType advDataType, const uint8_t *payload, uint8_t len) - { + 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. */ + }; + + /* Iterate over the adv fields looking for the first match. */ uint8_t byteIndex = 0; - while (byteIndex < _payloadLen) { - if (_payload[byteIndex + 1] == advDataType) { /* Check adv type */ - if (_payload[byteIndex] == (len + 1)) { /* Check adv field length */ - memcpy(&_payload[byteIndex + 2], payload, len); - } + 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 += (_payload[byteIndex] + 1); + + byteIndex += (currentADV->len + 1); /* advance by len+1; '+1' is needed to span the len field itself. */ } return BLE_ERROR_UNSPECIFIED;