BLE_API_Tiny_BLE
Fork of BLE_API by
Revision 300:d9a39f759a6a, committed 2015-03-02
- Comitter:
- rgrover1
- Date:
- Mon Mar 02 11:50:48 2015 +0000
- Parent:
- 299:c1e4400af825
- Child:
- 301:54c87189e423
- Commit message:
- Synchronized with git rev 91b4b8f8
Author: Rohit Grover
initialize the min/max length values correctly in the constructor for URIDataChar.
Previously, the minLength value was always set to URI_DATA_MAX, whereas maxLen got initialized by the values stored persistently. Except for the case of default initialization, the value of maxLength would always be less than then minLength; causing improper behaviour from the underlying stack while setting up characterisitics.
Changed in this revision
--- a/public/BLEDevice.h Mon Mar 02 11:50:48 2015 +0000 +++ b/public/BLEDevice.h Mon Mar 02 11:50:48 2015 +0000 @@ -71,9 +71,7 @@ * Any central device can connect to this peripheral. * * \par ADV_SCANNABLE_UNDIRECTED - * Any central device can connect to this peripheral, and - * the secondary Scan Response payload will be included or - * available to central devices. + * Include support for Scan Response payloads. * * \par * See Bluetooth Core Specification 4.0 (Vol. 3), Part C, @@ -252,6 +250,27 @@ void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)); template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); + /** + * Setup a callback for when a characteristic is being read by a client. + * + * @Note: this functionality may not be available on all underlying stacks. + * You could use GattCharacteristic::setReadAuthorizationCallback() as an + * alternative. + * + * @Note: it is possible to chain together multiple onDataRead callbacks + * (potentially from different modules of an application) to receive updates + * to characteristics. Services may add their own onDataRead callbacks + * behind the scenes to trap interesting events. + * + * @Note: it is also possible to setup a callback into a member function of + * some object. + * + * @return BLE_ERROR_NOT_IMPLEMENTED if this functionality isn't available; + * else BLE_ERROR_NONE. + */ + ble_error_t onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)); + template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)); + void onUpdatesEnabled(GattServer::EventCallback_t callback); void onUpdatesDisabled(GattServer::EventCallback_t callback); void onConfirmationReceived(GattServer::EventCallback_t callback); @@ -269,13 +288,13 @@ * input: Length in bytes to be read, * output: Total length of attribute value upon successful return. */ - ble_error_t readCharacteristicValue(uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP); + ble_error_t readCharacteristicValue(GattAttribute::Handle_t handle, uint8_t *const buffer, uint16_t *const lengthP); /** * @param localOnly * Only update the characteristic locally regardless of notify/indicate flags in the CCCD. */ - ble_error_t updateCharacteristicValue(uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly = false); + ble_error_t updateCharacteristicValue(GattAttribute::Handle_t handle, const uint8_t *value, uint16_t size, bool localOnly = false); /** * Yield control to the BLE stack or to other tasks waiting for events. This @@ -553,6 +572,16 @@ transport->getGattServer().setOnDataWritten(objPtr, memberPtr); } +inline ble_error_t +BLEDevice::onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { + return transport->getGattServer().setOnDataRead(callback); +} + +template <typename T> inline ble_error_t +BLEDevice::onDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { + return transport->getGattServer().setOnDataRead(objPtr, memberPtr); +} + inline void BLEDevice::onUpdatesEnabled(GattServer::EventCallback_t callback) { @@ -583,13 +612,13 @@ return transport->getGap().getState(); } -inline ble_error_t BLEDevice::readCharacteristicValue(uint16_t handle, uint8_t *const buffer, uint16_t *const lengthP) +inline ble_error_t BLEDevice::readCharacteristicValue(GattAttribute::Handle_t handle, uint8_t *const buffer, uint16_t *const lengthP) { return transport->getGattServer().readValue(handle, buffer, lengthP); } inline ble_error_t -BLEDevice::updateCharacteristicValue(uint16_t handle, const uint8_t *value, uint16_t size, bool localOnly) +BLEDevice::updateCharacteristicValue(GattAttribute::Handle_t handle, const uint8_t *value, uint16_t size, bool localOnly) { return transport->getGattServer().updateValue(handle, const_cast<uint8_t *>(value), size, localOnly); }
--- a/public/GattAttribute.h Mon Mar 02 11:50:48 2015 +0000 +++ b/public/GattAttribute.h Mon Mar 02 11:50:48 2015 +0000 @@ -46,17 +46,15 @@ */ /**************************************************************************/ GattAttribute(const UUID &uuid, uint8_t *valuePtr = NULL, uint16_t initialLen = 0, uint16_t maxLen = 0) : - _uuid(uuid), _valuePtr(valuePtr), _initialLen(initialLen), _lenMax(maxLen), _len(initialLen), _handle() { + _uuid(uuid), _valuePtr(valuePtr), _initialLen(initialLen), _lenMax(maxLen), _handle() { /* empty */ } public: Handle_t getHandle(void) const {return _handle; } const UUID &getUUID(void) const {return _uuid; } - uint16_t getLength(void) const {return _len; } uint16_t getInitialLength(void) const {return _initialLen;} uint16_t getMaxLength(void) const {return _lenMax; } - uint16_t *getLengthPtr(void) {return &_len; } void setHandle(Handle_t id) {_handle = id; } uint8_t *getValuePtr(void) {return _valuePtr; } @@ -65,7 +63,6 @@ uint8_t *_valuePtr; uint16_t _initialLen; /* Initial length of the value */ uint16_t _lenMax; /* Maximum length of the value */ - uint16_t _len; /* Current length of the value */ Handle_t _handle; private:
--- a/public/GattCharacteristicCallbackParams.h Mon Mar 02 11:50:48 2015 +0000 +++ b/public/GattCharacteristicCallbackParams.h Mon Mar 02 11:50:48 2015 +0000 @@ -33,6 +33,17 @@ const uint8_t *data; /**< Incoming data, variable length. */ }; +struct GattCharacteristicReadCBParams { + GattAttribute::Handle_t charHandle; + enum Type { + GATTS_CHAR_OP_INVALID = 0x00, /**< Invalid Operation. */ + GATTS_CHAR_OP_READ_REQ = 0x0A, /**< Read Request. */ + } op; /**< Type of write operation, */ + uint16_t offset; /**< Offset for the read operation. */ + uint16_t *len; /**< Length of the outgoing data. */ + uint8_t *data; /**< Outgoing data, variable length. */ +}; + struct GattCharacteristicWriteAuthCBParams { GattAttribute::Handle_t charHandle; uint16_t offset; /**< Offset for the write operation. */
--- a/public/GattServer.h Mon Mar 02 11:50:48 2015 +0000 +++ b/public/GattServer.h Mon Mar 02 11:50:48 2015 +0000 @@ -34,6 +34,7 @@ characteristicCount(0), onDataSent(), onDataWritten(), + onDataRead(), onUpdatesEnabled(NULL), onUpdatesDisabled(NULL), onConfirmationReceived(NULL) { @@ -43,10 +44,10 @@ friend class BLEDevice; private: /* These functions must be defined in the sub-class */ - virtual ble_error_t addService(GattService &) = 0; - virtual ble_error_t readValue(uint16_t handle, uint8_t buffer[], uint16_t *const lengthP) = 0; - virtual ble_error_t updateValue(uint16_t, uint8_t[], uint16_t, bool localOnly = false) = 0; - virtual ble_error_t initializeGATTDatabase(void) = 0; + virtual ble_error_t addService(GattService &) = 0; + virtual ble_error_t readValue(GattAttribute::Handle_t handle, uint8_t buffer[], uint16_t *const lengthP) = 0; + virtual ble_error_t updateValue(GattAttribute::Handle_t, uint8_t[], uint16_t, bool localOnly = false) = 0; + virtual ble_error_t initializeGATTDatabase(void) = 0; // ToDo: For updateValue, check the CCCD to see if the value we are // updating has the notify or indicate bits sent, and if BOTH are set @@ -63,6 +64,31 @@ void setOnDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { onDataWritten.add(objPtr, memberPtr); } + + /** + * A virtual function to allow underlying stacks to indicate if they support + * onDataRead(). It should be overridden to return true as applicable. + */ + virtual bool isOnDataReadAvaialble() const { + return false; + } + ble_error_t setOnDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { + if (!isOnDataReadAvaialble()) { + return BLE_ERROR_NOT_IMPLEMENTED; + } + + onDataRead.add(callback); + return BLE_ERROR_NONE; + } + template <typename T> + ble_error_t setOnDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { + if (!isOnDataReadAvaialble()) { + return BLE_ERROR_NOT_IMPLEMENTED; + } + + onDataRead.add(objPtr, memberPtr); + return BLE_ERROR_NONE; + } void setOnUpdatesEnabled(EventCallback_t callback) {onUpdatesEnabled = callback;} void setOnUpdatesDisabled(EventCallback_t callback) {onUpdatesDisabled = callback;} void setOnConfirmationReceived(EventCallback_t callback) {onConfirmationReceived = callback;} @@ -74,6 +100,12 @@ } } + void handleDataReadEvent(const GattCharacteristicReadCBParams *params) { + if (onDataRead.hasCallbacksAttached()) { + onDataRead.call(params); + } + } + void handleEvent(GattServerEvents::gattEvent_e type, uint16_t charHandle) { switch (type) { case GattServerEvents::GATT_EVENT_UPDATES_ENABLED: @@ -109,6 +141,7 @@ private: CallChainOfFunctionPointersWithContext<unsigned> onDataSent; CallChainOfFunctionPointersWithContext<const GattCharacteristicWriteCBParams *> onDataWritten; + CallChainOfFunctionPointersWithContext<const GattCharacteristicReadCBParams *> onDataRead; EventCallback_t onUpdatesEnabled; EventCallback_t onUpdatesDisabled; EventCallback_t onConfirmationReceived;
--- a/services/URIBeaconConfigService.h Mon Mar 02 11:50:48 2015 +0000 +++ b/services/URIBeaconConfigService.h Mon Mar 02 11:50:48 2015 +0000 @@ -100,7 +100,7 @@ initSucceeded(false), lockedStateChar(UUID_LOCK_STATE_CHAR, &lockedState), lockChar(UUID_LOCK_CHAR, ¶ms.lock), - uriDataChar(UUID_URI_DATA_CHAR, params.uriData, URI_DATA_MAX, params.uriDataLength, + uriDataChar(UUID_URI_DATA_CHAR, params.uriData, 0, URI_DATA_MAX, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE), unlockChar(UUID_UNLOCK_CHAR, ¶ms.lock), flagsChar(UUID_FLAGS_CHAR, ¶ms.flags),