High level Bluetooth Low Energy API and radio abstraction layer
Fork of BLE_API by
Revision 667:875aecb84719, committed 2015-06-19
- Comitter:
- rgrover1
- Date:
- Fri Jun 19 15:53:01 2015 +0100
- Parent:
- 666:b4a737539c2c
- Child:
- 668:222cc9525163
- Commit message:
- Synchronized with git rev 43177a02
Author: Rohit Grover
remove un-necessary comments in GattClient.h
Changed in this revision
--- a/common/BLEDeviceInstanceBase.h Fri Jun 19 15:53:01 2015 +0100 +++ b/common/BLEDeviceInstanceBase.h Fri Jun 19 15:53:01 2015 +0100 @@ -17,6 +17,12 @@ #ifndef __BLE_DEVICE_INSTANCE_BASE__ #define __BLE_DEVICE_INSTANCE_BASE__ +#include "Gap.h" + +/* forward declarations */ +class GattServer; +class GattClient; + /** * The interface for the transport object to be created by the target library's * createBLEDeviceInstance(). @@ -24,16 +30,20 @@ class BLEDeviceInstanceBase { public: + virtual const char *getVersion(void) = 0; + virtual Gap& getGap() = 0; + virtual GattServer& getGattServer() = 0; + virtual GattClient& getGattClient() = 0; + virtual ble_error_t init(void) = 0; virtual ble_error_t shutdown(void) = 0; virtual ble_error_t reset(void) = 0; - virtual const char *getVersion(void) = 0; - virtual Gap& getGap() = 0; - virtual GattServer& getGattServer() = 0; virtual ble_error_t initializeSecurity(bool enableBonding = true, bool requireMITM = true, Gap::SecurityIOCapabilities_t iocaps = Gap::IO_CAPS_NONE, const Gap::Passkey_t passkey = NULL) = 0; + virtual ble_error_t setTxPower(int8_t txPower) = 0; + virtual void getPermittedTxPowerValues(const int8_t **, size_t *) = 0; virtual void waitForEvent(void) = 0; };
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/DiscoveredCharacteristic.cpp Fri Jun 19 15:53:01 2015 +0100 @@ -0,0 +1,63 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "DiscoveredCharacteristic.h" +#include "GattClient.h" + +GattClient::ReadCallback_t DiscoveredCharacteristic::onDataReadCallback; +GattClient::WriteCallback_t DiscoveredCharacteristic::onDataWriteCallback; + +ble_error_t +DiscoveredCharacteristic::read(uint16_t offset) const +{ + if (!props.read()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if (!gattc) { + return BLE_ERROR_INVALID_STATE; + } + + return gattc->read(connHandle, valueHandle, offset); +} + +ble_error_t +DiscoveredCharacteristic::write(uint16_t length, const uint8_t *value) const +{ + if (!props.write()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if (!gattc) { + return BLE_ERROR_INVALID_STATE; + } + + return gattc->write(GattClient::GATT_OP_WRITE_REQ, connHandle, valueHandle, length, value); +} + +ble_error_t +DiscoveredCharacteristic::writeWoResponse(uint16_t length, const uint8_t *value) const +{ + if (!props.writeWoResp()) { + return BLE_ERROR_OPERATION_NOT_PERMITTED; + } + + if (!gattc) { + return BLE_ERROR_INVALID_STATE; + } + + return gattc->write(GattClient::GATT_OP_WRITE_CMD, connHandle, valueHandle, length, value); +} \ No newline at end of file
--- a/common/blecommon.h Fri Jun 19 15:53:01 2015 +0100 +++ b/common/blecommon.h Fri Jun 19 15:53:01 2015 +0100 @@ -21,8 +21,6 @@ extern "C" { #endif -#include <stdint.h> -#include <stddef.h> /** @defgroup BLE_UUID_VALUES Assigned Values for BLE UUIDs * @{ */ @@ -115,18 +113,18 @@ \brief Error codes for the BLE API */ /**************************************************************************/ -typedef enum ble_error_e -{ - BLE_ERROR_NONE = 0, /**< No error */ - BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ - BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ - BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ - BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ - BLE_STACK_BUSY = 5, /**< The stack is busy */ - BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ - BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ - BLE_ERROR_UNSPECIFIED = 8, /**< Unknown error. */ -} ble_error_t; +enum ble_error_t { + BLE_ERROR_NONE = 0, /**< No error */ + BLE_ERROR_BUFFER_OVERFLOW = 1, /**< The requested action would cause a buffer overflow and has been aborted */ + BLE_ERROR_NOT_IMPLEMENTED = 2, /**< Requested a feature that isn't yet implement or isn't supported by the target HW */ + BLE_ERROR_PARAM_OUT_OF_RANGE = 3, /**< One of the supplied parameters is outside the valid range */ + BLE_ERROR_INVALID_PARAM = 4, /**< One of the supplied parameters is invalid */ + BLE_STACK_BUSY = 5, /**< The stack is busy */ + BLE_ERROR_INVALID_STATE = 6, /**< Invalid state. */ + BLE_ERROR_NO_MEM = 7, /**< Out of Memory */ + BLE_ERROR_OPERATION_NOT_PERMITTED = 8, + BLE_ERROR_UNSPECIFIED = 9, /**< Unknown error. */ +}; #ifdef __cplusplus }
--- a/public/BLEDevice.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/BLEDevice.h Fri Jun 19 15:53:01 2015 +0100 @@ -20,8 +20,13 @@ #include "blecommon.h" #include "Gap.h" #include "GattServer.h" +#include "GattClient.h" +#include "BLEDeviceInstanceBase.h" + +#include "GapAdvertisingData.h" +#include "GapAdvertisingParams.h" #include "GapScanningParams.h" -#include "BLEDeviceInstanceBase.h" + /** * The base class used to abstract away BLE capable radio transceivers or SOCs, @@ -316,6 +321,25 @@ ble_error_t stopScan(void); /** + * Create a connection (GAP Link Establishment). + * @param peerAddr + * 48-bit address, LSB format. + * @param peerAddrType + * Address type of the peer. + * @param connectionParams + * Connection parameters. + * @param scanParams + * Paramters to be used while scanning for the peer. + * @return BLE_ERROR_NONE if connection establishment procedure is started + * successfully. The onConnection callback (if set) will be invoked upon + * a connection event. + */ + ble_error_t connect(const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType = Gap::ADDR_TYPE_RANDOM_STATIC, + const Gap::ConnectionParams_t *connectionParams = NULL, + const GapScanningParams *scanParams = NULL); + + /** * This call initiates the disconnection procedure, and its completion will * be communicated to the application with an invocation of the * onDisconnection callback. @@ -368,8 +392,8 @@ * @Note: it is also possible to setup a callback into a member function of * some object. */ - void onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)); - template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)); + void onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)); + template <typename T> void onDataWritten(T * objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)); /** * Setup a callback for when a characteristic is being read by a client. @@ -389,8 +413,8 @@ * @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)); + ble_error_t onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)); + template <typename T> ble_error_t onDataRead(T * objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)); void onUpdatesEnabled(GattServer::EventCallback_t callback); void onUpdatesDisabled(GattServer::EventCallback_t callback); @@ -445,7 +469,11 @@ /** * A version of the same as above with connection handle parameter to allow updates for connection-specific multivalued attribtues (such as the CCCDs). */ - ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly = false); + ble_error_t updateCharacteristicValue(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + const uint8_t *value, + uint16_t size, + bool localOnly = false); /** * Yield control to the BLE stack or to other tasks waiting for events. This @@ -611,6 +639,78 @@ */ ble_error_t purgeAllBondingState(void); + /** + * Launch service discovery. Once launched, service discovery will remain + * active with callbacks being issued back into the application for matching + * services/characteristics. isServiceDiscoveryActive() can be used to + * determine status; and a termination callback (if setup) will be invoked + * at the end. Service discovery can be terminated prematurely if needed + * using terminateServiceDiscovery(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Taken as + * NULL by default. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param cc + * This is the application callback for matching characteristic. + * Taken as NULL by default. Note: service discovery may still be + * active when this callback is issued; calling asynchronous + * BLE-stack APIs from within this application callback might cause + * the stack to abort service discovery. If this becomes an issue, + * it may be better to make local copy of the discoveredCharacteristic + * and wait for service discovery to terminate before operating on the + * characteristic. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. By default it is set as the wildcard UUID_UNKNOWN, + * in which case it matches all services. If characteristic-UUID + * filter (below) is set to the wildcard value, then a service + * callback will be invoked for the matching service (or for every + * service if the service filter is a wildcard). + * @param matchingCharacteristicUUIDIn + * UUID based filter for specifying characteristic in which the application + * is interested. By default it is set as the wildcard UUID_UKNOWN + * to match against any characteristic. If both service-UUID + * filter and characteristic-UUID filter are used with non- wildcard + * values, then only a single characteristic callback is + * invoked for the matching characteristic. + * + * @Note Using wildcard values for both service-UUID and characteristic- + * UUID will result in complete service discovery--callbacks being + * called for every service and characteristic. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); + + /** + * Setup callback for when serviceDiscovery terminates. + */ + void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback); + + /** + * Is service-discovery currently active? + */ + bool isServiceDiscoveryActive(void); + + /** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ + void terminateServiceDiscovery(void); + public: BLEDevice() : transport(createBLEDeviceInstance()), advParams(), advPayload(), scanResponse(), needToSetAdvPayload(true), scanningParams() { advPayload.clear(); @@ -854,6 +954,14 @@ } inline ble_error_t +BLEDevice::connect(const Gap::Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const Gap::ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) { + return transport->getGap().connect(peerAddr, peerAddrType, connectionParams, scanParams); +} + +inline ble_error_t BLEDevice::disconnect(Gap::DisconnectionReason_t reason) { return transport->getGap().disconnect(reason); @@ -894,22 +1002,22 @@ } inline void -BLEDevice::onDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) { +BLEDevice::onDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) { transport->getGattServer().setOnDataWritten(callback); } template <typename T> inline void -BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { +BLEDevice::onDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { transport->getGattServer().setOnDataWritten(objPtr, memberPtr); } inline ble_error_t -BLEDevice::onDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { +BLEDevice::onDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { return transport->getGattServer().setOnDataRead(callback); } template <typename T> inline ble_error_t -BLEDevice::onDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { +BLEDevice::onDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { return transport->getGattServer().setOnDataRead(objPtr, memberPtr); } @@ -954,7 +1062,10 @@ return transport->getGattServer().readValue(attributeHandle, buffer, lengthP); } -inline ble_error_t BLEDevice::readCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t *buffer, uint16_t *lengthP) +inline ble_error_t BLEDevice::readCharacteristicValue(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + uint8_t *buffer, + uint16_t *lengthP) { return transport->getGattServer().readValue(connectionHandle, attributeHandle, buffer, lengthP); } @@ -966,7 +1077,11 @@ } inline ble_error_t -BLEDevice::updateCharacteristicValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t *value, uint16_t size, bool localOnly) +BLEDevice::updateCharacteristicValue(Gap::Handle_t connectionHandle, + GattAttribute::Handle_t attributeHandle, + const uint8_t *value, + uint16_t size, + bool localOnly) { return transport->getGattServer().updateValue(connectionHandle, attributeHandle, const_cast<uint8_t *>(value), size, localOnly); } @@ -1027,13 +1142,13 @@ inline ble_error_t BLEDevice::setTxPower(int8_t txPower) { - return transport->getGap().setTxPower(txPower); + return transport->setTxPower(txPower); } inline void BLEDevice::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP) { - transport->getGap().getPermittedTxPowerValues(valueArrayPP, countP); + transport->getPermittedTxPowerValues(valueArrayPP, countP); } inline ble_error_t @@ -1087,4 +1202,40 @@ return transport->getGap().purgeAllBondingState(); } +inline ble_error_t +BLEDevice::launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc, + ServiceDiscovery::CharacteristicCallback_t cc, + const UUID &matchingServiceUUID, + const UUID &matchingCharacteristicUUID) +{ + return transport->getGattClient().launchServiceDiscovery(connectionHandle, sc, cc, matchingServiceUUID, matchingCharacteristicUUID); +} + +inline void +BLEDevice::onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) +{ + transport->getGattClient().onServiceDiscoveryTermination(callback); +} + +/** + * Is service-discovery currently active? + */ +inline bool +BLEDevice::isServiceDiscoveryActive(void) +{ + return transport->getGattClient().isServiceDiscoveryActive(); +} + +/** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ +inline void +BLEDevice::terminateServiceDiscovery(void) +{ + transport->getGattClient().terminateServiceDiscovery(); +} + + #endif // ifndef __BLE_DEVICE__ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/DiscoveredCharacteristic.h Fri Jun 19 15:53:01 2015 +0100 @@ -0,0 +1,161 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DISCOVERED_CHARACTERISTIC_H__ +#define __DISCOVERED_CHARACTERISTIC_H__ + +#include "UUID.h" +#include "Gap.h" +#include "GattAttribute.h" +#include "GattClient.h" + +/** + * Structure for holding information about the service and the characteristics + * found during the discovery process. + */ +class DiscoveredCharacteristic { +public: + struct Properties_t { + uint8_t _broadcast :1; /**< Broadcasting of the value permitted. */ + uint8_t _read :1; /**< Reading the value permitted. */ + uint8_t _writeWoResp :1; /**< Writing the value with Write Command permitted. */ + uint8_t _write :1; /**< Writing the value with Write Request permitted. */ + uint8_t _notify :1; /**< Notications of the value permitted. */ + uint8_t _indicate :1; /**< Indications of the value permitted. */ + uint8_t _authSignedWrite :1; /**< Writing the value with Signed Write Command permitted. */ + + public: + bool broadcast(void) const {return _broadcast; } + bool read(void) const {return _read; } + bool writeWoResp(void) const {return _writeWoResp; } + bool write(void) const {return _write; } + bool notify(void) const {return _notify; } + bool indicate(void) const {return _indicate; } + bool authSignedWrite(void) const {return _authSignedWrite;} + + private: + operator uint8_t() const; /* disallow implicit conversion into an integer */ + operator unsigned() const; /* disallow implicit conversion into an integer */ + }; + + /** + * Initiate (or continue) a read for the value attribute, optionally at a + * given offset. If the Characteristic or Descriptor to be read is longer + * than ATT_MTU - 1, this function must be called multiple times with + * appropriate offset to read the complete value. + * + * @return BLE_ERROR_NONE if a read has been initiated, else + * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or + * BLE_STACK_BUSY if some client procedure already in progress, or + * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. + */ + ble_error_t read(uint16_t offset = 0) const; + + /** + * Perform a write without response procedure. + * + * @param length + * The amount of data being written. + * @param value + * The bytes being written. + * + * @note It is important to note that a write without response will generate + * an onDataSent() callback when the packet has been transmitted. There + * will be a BLE-stack specific limit to the number of pending + * writeWoResponse operations; the user may want to use the onDataSent() + * callback for flow-control. + * + * @retval BLE_ERROR_NONE Successfully started the Write procedure, else + * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or + * BLE_STACK_BUSY if some client procedure already in progress, or + * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or + * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. + */ + ble_error_t writeWoResponse(uint16_t length, const uint8_t *value) const; + + /** + * Perform a write procedure. + * + * @param length + * The amount of data being written. + * @param value + * The bytes being written. + * + * @note It is important to note that a write will generate + * an onDataWritten() callback when the peer acknowledges the request. + * + * @retval BLE_ERROR_NONE Successfully started the Write procedure, else + * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or + * BLE_STACK_BUSY if some client procedure already in progress, or + * BLE_ERROR_NO_MEM if there are no available buffers left to process the request, or + * BLE_ERROR_OPERATION_NOT_PERMITTED due to the characteristic's properties. + */ + ble_error_t write(uint16_t length, const uint8_t *value) const; + + static void setupOnDataRead(GattClient::ReadCallback_t callback) { + onDataReadCallback = callback; + } + + static void setupOnDataWrite(GattClient::WriteCallback_t callback) { + onDataWriteCallback = callback; + } + + void setupLongUUID(UUID::LongUUIDBytes_t longUUID) { + uuid.setupLong(longUUID); + } + +public: + UUID::ShortUUIDBytes_t getShortUUID(void) const { + return uuid.getShortUUID(); + } + + const Properties_t& getProperties(void) const { + return props; + } + + const GattAttribute::Handle_t& getDeclHandle(void) const { + return declHandle; + } + const GattAttribute::Handle_t& getValueHandle(void) const { + return valueHandle; + } + +public: + DiscoveredCharacteristic() : gattc(NULL), + uuid(UUID::ShortUUIDBytes_t(0)), + props(), + declHandle(GattAttribute::INVALID_HANDLE), + valueHandle(GattAttribute::INVALID_HANDLE) { + /* empty */ + } + +protected: + GattClient *gattc; + +protected: + UUID uuid; + Properties_t props; + GattAttribute::Handle_t declHandle; + GattAttribute::Handle_t valueHandle; + + Gap::Handle_t connHandle; + +public: + static GattClient::ReadCallback_t onDataReadCallback; + static GattClient::WriteCallback_t onDataWriteCallback; +}; + +#endif /*__DISCOVERED_CHARACTERISTIC_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/DiscoveredService.h Fri Jun 19 15:53:01 2015 +0100 @@ -0,0 +1,71 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __DISCOVERED_SERVICE_H__ +#define __DISCOVERED_SERVICE_H__ + +#include "UUID.h" +#include "GattAttribute.h" + +/**@brief Type for holding information about the service and the characteristics found during + * the discovery process. + */ +class DiscoveredService { +public: + void setup(UUID uuidIn, GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { + uuid = uuidIn; + startHandle = startHandleIn; + endHandle = endHandleIn; + } + + void setup(GattAttribute::Handle_t startHandleIn, GattAttribute::Handle_t endHandleIn) { + startHandle = startHandleIn; + endHandle = endHandleIn; + } + + void setupLongUUID(UUID::LongUUIDBytes_t longUUID) { + uuid.setupLong(longUUID); + } + +public: + const UUID &getUUID(void) const { + return uuid; + } + + const GattAttribute::Handle_t& getStartHandle(void) const { + return startHandle; + } + const GattAttribute::Handle_t& getEndHandle(void) const { + return endHandle; + } + +public: + DiscoveredService() : uuid(UUID::ShortUUIDBytes_t(0)), + startHandle(GattAttribute::INVALID_HANDLE), + endHandle(GattAttribute::INVALID_HANDLE) { + /* empty */ + } + +private: + DiscoveredService(const DiscoveredService &); + +private: + UUID uuid; /**< UUID of the service. */ + GattAttribute::Handle_t startHandle; /**< Service Handle Range. */ + GattAttribute::Handle_t endHandle; /**< Service Handle Range. */ +}; + +#endif /*__DISCOVERED_SERVICE_H__*/ \ No newline at end of file
--- a/public/Gap.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/Gap.h Fri Jun 19 15:53:01 2015 +0100 @@ -17,15 +17,16 @@ #ifndef __GAP_H__ #define __GAP_H__ -#include "GapAdvertisingData.h" -#include "GapAdvertisingParams.h" #include "GapEvents.h" #include "CallChain.h" #include "FunctionPointerWithContext.h" using namespace mbed; -class GapScanningParams; /* forward declaration */ +/* Forward declarations for classes which will only be used for pointers or references in the following. */ +class GapAdvertisingParams; +class GapScanningParams; +class GapAdvertisingData; class Gap { public: @@ -56,12 +57,9 @@ * transport library. */ enum DisconnectionReason_t { - CONNECTION_TIMEOUT = 0x08, - REMOTE_USER_TERMINATED_CONNECTION = 0x13, - REMOTE_DEV_TERMINATION_DUE_TO_LOW_RESOURCES = 0x14, /**< Remote Device Terminated Connection due to low resources.*/ - REMOTE_DEV_TERMINATION_DUE_TO_POWER_OFF = 0x15, /**< Remote Device Terminated Connection due to power off. */ - LOCAL_HOST_TERMINATED_CONNECTION = 0x16, - CONN_INTERVAL_UNACCEPTABLE = 0x3B, + REMOTE_USER_TERMINATED_CONNECTION = 0x13, + LOCAL_HOST_TERMINATED_CONNECTION = 0x16, + CONN_INTERVAL_UNACCEPTABLE = 0x3B, }; /* Describes the current state of the device (more than one bit can be set) */ @@ -79,6 +77,49 @@ uint16_t connectionSupervisionTimeout; /**< Connection Supervision Timeout in 10 ms units, see @ref BLE_GAP_CP_LIMITS.*/ } ConnectionParams_t; + enum Role_t { + PERIPHERAL = 0x1, /**< Peripheral Role. */ + CENTRAL = 0x2, /**< Central Role. */ + }; + + struct AdvertisementCallbackParams_t { + Address_t peerAddr; + int8_t rssi; + bool isScanResponse; + AdvertisementType_t type; + uint8_t advertisingDataLen; + const uint8_t *advertisingData; + }; + typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; + + struct ConnectionCallbackParams_t { + Handle_t handle; + Role_t role; + AddressType_t peerAddrType; + Address_t peerAddr; + AddressType_t ownAddrType; + Address_t ownAddr; + const ConnectionParams_t *connectionParams; + + ConnectionCallbackParams_t(Handle_t handleIn, + Role_t roleIn, + AddressType_t peerAddrTypeIn, + const uint8_t *peerAddrIn, + AddressType_t ownAddrTypeIn, + const uint8_t *ownAddrIn, + const ConnectionParams_t *connectionParamsIn) : + handle(handleIn), + role(roleIn), + peerAddrType(peerAddrTypeIn), + peerAddr(), + ownAddrType(ownAddrTypeIn), + ownAddr(), + connectionParams(connectionParamsIn) { + memcpy(peerAddr, peerAddrIn, ADDR_LEN); + memcpy(ownAddr, ownAddrIn, ADDR_LEN); + } + }; + enum SecurityMode_t { SECURITY_MODE_NO_ACCESS, SECURITY_MODE_ENCRYPTION_OPEN_LINK, /**< require no protection, open link. */ @@ -144,10 +185,7 @@ } typedef void (*EventCallback_t)(void); - typedef void (*ConnectionEventCallback_t)(Handle_t, - AddressType_t peerAddrType, const Address_t peerAddr, - AddressType_t ownAddrType, const Address_t ownAddr, - const ConnectionParams_t *); + typedef void (*ConnectionEventCallback_t)(const ConnectionCallbackParams_t *params); typedef void (*HandleSpecificEvent_t)(Handle_t handle); typedef void (*DisconnectionEventCallback_t)(Handle_t, DisconnectionReason_t); typedef void (*RadioNotificationEventCallback_t) (bool radio_active); /* gets passed true for ACTIVE; false for INACTIVE. */ @@ -156,20 +194,12 @@ typedef void (*LinkSecuredCallback_t)(Handle_t handle, SecurityMode_t securityMode); typedef void (*PasskeyDisplayCallback_t)(Handle_t handle, const Passkey_t passkey); - struct AdvertisementCallbackParams_t { - Address_t peerAddr; - int8_t rssi; - bool isScanResponse; - AdvertisementType_t type; - uint8_t advertisingDataLen; - const uint8_t *advertisingData; - }; - typedef FunctionPointerWithContext<const AdvertisementCallbackParams_t *> AdvertisementReportCallback_t; + friend class BLEDevice; -public: +private: /* These functions must be defined in the sub-class */ - virtual ble_error_t setAddress(AddressType_t type, const Address_t address) = 0; - virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) = 0; + virtual ble_error_t setAddress(AddressType_t type, const Address_t address) = 0; + virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address) = 0; virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &) = 0; virtual ble_error_t startAdvertising(const GapAdvertisingParams &) = 0; virtual ble_error_t stopAdvertising(void) = 0; @@ -177,6 +207,10 @@ virtual uint16_t getMinAdvertisingInterval(void) const = 0; virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const = 0; virtual uint16_t getMaxAdvertisingInterval(void) const = 0; + virtual ble_error_t connect(const Address_t peerAddr, + Gap::AddressType_t peerAddrType, + const ConnectionParams_t *connectionParams, + const GapScanningParams *scanParams) = 0; virtual ble_error_t disconnect(DisconnectionReason_t reason) = 0; virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params) = 0; virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params) = 0; @@ -190,9 +224,6 @@ virtual ble_error_t setAppearance(uint16_t appearance) = 0; virtual ble_error_t getAppearance(uint16_t *appearanceP) = 0; - virtual ble_error_t setTxPower(int8_t txPower) = 0; - virtual void getPermittedTxPowerValues(const int8_t **, size_t *) = 0; - ble_error_t startScan(const GapScanningParams &scanningParams, void (*callback)(const AdvertisementCallbackParams_t *params)) { ble_error_t err = BLE_ERROR_NONE; if (callback) { @@ -216,7 +247,7 @@ return err; } -public: +protected: virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) = 0; /* Event callback handlers */ @@ -280,7 +311,7 @@ template<typename T> void addToDisconnectionCallChain(T *tptr, void (T::*mptr)(void)) {disconnectionCallChain.add(tptr, mptr);} -public: +private: GapState_t getState(void) const { return state; } @@ -303,10 +334,17 @@ } public: - void processConnectionEvent(Handle_t handle, AddressType_t peerAddrType, const Address_t peerAddr, AddressType_t ownAddrType, const Address_t ownAddr, const ConnectionParams_t *params) { + void processConnectionEvent(Handle_t handle, + Role_t role, + AddressType_t peerAddrType, + const Address_t peerAddr, + AddressType_t ownAddrType, + const Address_t ownAddr, + const ConnectionParams_t *connectionParams) { state.connected = 1; if (onConnection) { - onConnection(handle, peerAddrType, peerAddr, ownAddrType, ownAddr, params); + ConnectionCallbackParams_t callbackParams(handle, role, peerAddrType, peerAddr, ownAddrType, ownAddr, connectionParams); + onConnection(&callbackParams); } }
--- a/public/GapScanningParams.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/GapScanningParams.h Fri Jun 19 15:53:01 2015 +0100 @@ -80,7 +80,7 @@ _activeScanning = activeScanning; } - +public: /* @Note: The following return durations in units of 0.625 ms */ uint16_t getInterval(void) const {return _interval;} uint16_t getWindow(void) const {return _window; }
--- a/public/GattAttribute.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/GattAttribute.h Fri Jun 19 15:53:01 2015 +0100 @@ -17,6 +17,8 @@ #ifndef __GATT_ATTRIBUTE_H__ #define __GATT_ATTRIBUTE_H__ +#include "UUID.h" + class GattAttribute { public: typedef uint16_t Handle_t;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/GattCallbackParamTypes.h Fri Jun 19 15:53:01 2015 +0100 @@ -0,0 +1,78 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_CALLBACK_PARAM_TYPES_H__ +#define __GATT_CALLBACK_PARAM_TYPES_H__ + +struct GattWriteCallbackParams { + enum WriteOp_t { + OP_INVALID = 0x00, /**< Invalid Operation. */ + OP_WRITE_REQ = 0x01, /**< Write Request. */ + OP_WRITE_CMD = 0x02, /**< Write Command. */ + OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */ + OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */ + OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute Write Request: Cancel all prepared writes. */ + OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute Write Request: Immediately execute all prepared writes. */ + }; + + GattAttribute::Handle_t handle; + WriteOp_t writeOp; /**< Type of write operation, */ + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; + const uint8_t *data; /* @note: data might not persist beyond the callback; make a local copy if needed. */ +}; + +struct GattReadCallbackParams { + GattAttribute::Handle_t handle; + uint16_t offset; /**< Offset for the read operation. */ + uint16_t len; + const uint8_t *data; /* @note: data might not persist beyond the callback; make a local copy if needed. */ +}; + +enum GattAuthCallbackReply_t { + AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid Attribute Handle. */ + AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ + AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: Offset specified was past the end of the attribute. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as Insufficient Authorisation. */ + AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as Prepare Queue Full. */ + AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as Attribute not found. */ + AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ + AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ + AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ +}; + +struct GattWriteAuthCallbackParams { + GattAttribute::Handle_t handle; + uint16_t offset; /**< Offset for the write operation. */ + uint16_t len; /**< Length of the incoming data. */ + const uint8_t *data; /**< Incoming data, variable length. */ + GattAuthCallbackReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the + * request is to proceed; false otherwise. */ +}; + +struct GattReadAuthCallbackParams { + GattAttribute::Handle_t handle; + uint16_t offset; /**< Offset for the read operation. */ + uint16_t len; /**< Optional: new length of the outgoing data. */ + uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ + GattAuthCallbackReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the + * request is to proceed; false otherwise. */ +}; + +#endif /*__GATT_CALLBACK_PARAM_TYPES_H__*/ \ No newline at end of file
--- a/public/GattCharacteristic.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/GattCharacteristic.h Fri Jun 19 15:53:01 2015 +0100 @@ -19,7 +19,7 @@ #include "Gap.h" #include "GattAttribute.h" -#include "GattCharacteristicCallbackParams.h" +#include "GattCallbackParamTypes.h" #include "FunctionPointerWithContext.h" class GattCharacteristic { @@ -355,21 +355,21 @@ /** * Authorization. */ - void setWriteAuthorizationCallback(void (*callback)(GattCharacteristicWriteAuthCBParams *)) { + void setWriteAuthorizationCallback(void (*callback)(GattWriteAuthCallbackParams *)) { writeAuthorizationCallback.attach(callback); enabledWriteAuthorization = true; } template <typename T> - void setWriteAuthorizationCallback(T *object, void (T::*member)(GattCharacteristicWriteAuthCBParams *)) { + void setWriteAuthorizationCallback(T *object, void (T::*member)(GattWriteAuthCallbackParams *)) { writeAuthorizationCallback.attach(object, member); enabledWriteAuthorization = true; } - void setReadAuthorizationCallback(void (*callback)(GattCharacteristicReadAuthCBParams *)) { + void setReadAuthorizationCallback(void (*callback)(GattReadAuthCallbackParams *)) { readAuthorizationCallback.attach(callback); enabledReadAuthorization = true; } template <typename T> - void setReadAuthorizationCallback(T *object, void (T::*member)(GattCharacteristicReadAuthCBParams *)) { + void setReadAuthorizationCallback(T *object, void (T::*member)(GattReadAuthCallbackParams *)) { readAuthorizationCallback.attach(object, member); enabledReadAuthorization = true; } @@ -380,7 +380,7 @@ * @param params to capture the context of the write-auth request; and also contains an out-parameter for reply. * @return true if the write is authorized to proceed. */ - GattCharacteristicAuthCBReply_t authorizeWrite(GattCharacteristicWriteAuthCBParams *params) { + GattAuthCallbackReply_t authorizeWrite(GattWriteAuthCallbackParams *params) { if (!isWriteAuthorizationEnabled()) { return AUTH_CALLBACK_REPLY_SUCCESS; } @@ -406,7 +406,7 @@ * * @return true if the read is authorized to proceed. */ - GattCharacteristicAuthCBReply_t authorizeRead(GattCharacteristicReadAuthCBParams *params) { + GattAuthCallbackReply_t authorizeRead(GattReadAuthCallbackParams *params) { if (!isReadAuthorizationEnabled()) { return AUTH_CALLBACK_REPLY_SUCCESS; } @@ -444,8 +444,8 @@ bool enabledReadAuthorization; bool enabledWriteAuthorization; - FunctionPointerWithContext<GattCharacteristicReadAuthCBParams *> readAuthorizationCallback; - FunctionPointerWithContext<GattCharacteristicWriteAuthCBParams *> writeAuthorizationCallback; + FunctionPointerWithContext<GattReadAuthCallbackParams *> readAuthorizationCallback; + FunctionPointerWithContext<GattWriteAuthCallbackParams *> writeAuthorizationCallback; private: /* disallow copy and assignment */
--- a/public/GattCharacteristicCallbackParams.h Fri Jun 19 15:53:01 2015 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,80 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef __GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__ -#define __GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__ - -struct GattCharacteristicWriteCBParams { - GattAttribute::Handle_t charHandle; - enum Type { - GATTS_CHAR_OP_INVALID = 0x00, /**< Invalid Operation. */ - GATTS_CHAR_OP_WRITE_REQ = 0x01, /**< Write Request. */ - GATTS_CHAR_OP_WRITE_CMD = 0x02, /**< Write Command. */ - GATTS_CHAR_OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */ - GATTS_CHAR_OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */ - GATTS_CHAR_OP_EXEC_WRITE_REQ_CANCEL = 0x05, /**< Execute Write Request: Cancel all prepared writes. */ - GATTS_CHAR_OP_EXEC_WRITE_REQ_NOW = 0x06, /**< Execute Write Request: Immediately execute all prepared writes. */ - } op; /**< Type of write operation, */ - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the incoming data. */ - 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. */ -}; - -enum GattCharacteristicAuthCBReply_t { - AUTH_CALLBACK_REPLY_SUCCESS = 0x00, /**< Success. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_HANDLE = 0x0101, /**< ATT Error: Invalid Attribute Handle. */ - AUTH_CALLBACK_REPLY_ATTERR_READ_NOT_PERMITTED = 0x0102, /**< ATT Error: Read not permitted. */ - AUTH_CALLBACK_REPLY_ATTERR_WRITE_NOT_PERMITTED = 0x0103, /**< ATT Error: Write not permitted. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHENTICATION = 0x0105, /**< ATT Error: Authenticated link required. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_OFFSET = 0x0107, /**< ATT Error: Offset specified was past the end of the attribute. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION = 0x0108, /**< ATT Error: Used in ATT as Insufficient Authorisation. */ - AUTH_CALLBACK_REPLY_ATTERR_PREPARE_QUEUE_FULL = 0x0109, /**< ATT Error: Used in ATT as Prepare Queue Full. */ - AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_FOUND = 0x010A, /**< ATT Error: Used in ATT as Attribute not found. */ - AUTH_CALLBACK_REPLY_ATTERR_ATTRIBUTE_NOT_LONG = 0x010B, /**< ATT Error: Attribute cannot be read or written using read/write blob requests. */ - AUTH_CALLBACK_REPLY_ATTERR_INVALID_ATT_VAL_LENGTH = 0x010D, /**< ATT Error: Invalid value size. */ - AUTH_CALLBACK_REPLY_ATTERR_INSUF_RESOURCES = 0x0111, /**< ATT Error: Encrypted link required. */ -}; - -struct GattCharacteristicWriteAuthCBParams { - GattAttribute::Handle_t charHandle; - uint16_t offset; /**< Offset for the write operation. */ - uint16_t len; /**< Length of the incoming data. */ - const uint8_t *data; /**< Incoming data, variable length. */ - GattCharacteristicAuthCBReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the - * request is to proceed; false otherwise. */ -}; - -struct GattCharacteristicReadAuthCBParams { - GattAttribute::Handle_t charHandle; - uint16_t offset; /**< Offset for the read operation. */ - uint16_t len; /**< Optional: new length of the outgoing data. */ - uint8_t *data; /**< Optional: new outgoing data. Leave at NULL if data is unchanged. */ - GattCharacteristicAuthCBReply_t authorizationReply; /* This is the out parameter which needs to be set to true by the callback if the - * request is to proceed; false otherwise. */ -}; - -#endif /*__GATT_CHARACTERISTIC_CALLBACK_PARAMS_H__*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/GattClient.h Fri Jun 19 15:53:01 2015 +0100 @@ -0,0 +1,100 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __GATT_CLIENT_H__ +#define __GATT_CLIENT_H__ + +#include "Gap.h" +#include "GattAttribute.h" +#include "ServiceDiscovery.h" + +#include "GattCallbackParamTypes.h" + +class GattClient { +public: + typedef void (*ReadCallback_t)(const GattReadCallbackParams *params); + + enum WriteOp_t { + GATT_OP_WRITE_REQ = 0x01, /**< Write Request. */ + GATT_OP_WRITE_CMD = 0x02, /**< Write Command. */ + }; + + typedef void (*WriteCallback_t)(const GattWriteCallbackParams *params); + +public: + /** + * Launch service discovery. Once launched, service discovery will remain + * active with callbacks being issued back into the application for matching + * services/characteristics. isActive() can be used to determine status; and + * a termination callback (if setup) will be invoked at the end. Service + * discovery can be terminated prematurely if needed using terminate(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. + * @param cc + * This is the application callback for matching characteristic. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. + * @param matchingCharacteristicUUIDIn + * UUID based filter for specifying characteristic in which the application + * is interested. + * + * @Note Using wildcard values for both service-UUID and characteristic- + * UUID will result in complete service discovery--callbacks being + * called for every service and characteristic. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle, + ServiceDiscovery::ServiceCallback_t sc = NULL, + ServiceDiscovery::CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0; + + virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) = 0; + + /** + * Is service-discovery currently active? + */ + virtual bool isServiceDiscoveryActive(void) const = 0; + + /** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ + virtual void terminateServiceDiscovery(void) = 0; + + /* Initiate a Gatt Client read procedure by attribute-handle.*/ + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const = 0; + + virtual ble_error_t write(GattClient::WriteOp_t cmd, Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, size_t length, const uint8_t *value) const = 0; + +protected: + GattClient() { + /* empty */ + } + +private: + /* disallow copy and assignment */ + GattClient(const GattClient &); + GattClient& operator=(const GattClient &); +}; + +#endif // ifndef __GATT_CLIENT_H__ \ No newline at end of file
--- a/public/GattServer.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/GattServer.h Fri Jun 19 15:53:01 2015 +0100 @@ -21,7 +21,7 @@ #include "GattService.h" #include "GattAttribute.h" #include "GattServerEvents.h" -#include "GattCharacteristicCallbackParams.h" +#include "GattCallbackParamTypes.h" #include "CallChainOfFunctionPointersWithContext.h" class GattServer { @@ -43,7 +43,8 @@ /* empty */ } -public: + 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(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0; @@ -62,9 +63,9 @@ void setOnDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) { onDataSent.add(objPtr, memberPtr); } - void setOnDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) {onDataWritten.add(callback);} + void setOnDataWritten(void (*callback)(const GattWriteCallbackParams *eventDataP)) {onDataWritten.add(callback);} template <typename T> - void setOnDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) { + void setOnDataWritten(T *objPtr, void (T::*memberPtr)(const GattWriteCallbackParams *context)) { onDataWritten.add(objPtr, memberPtr); } @@ -75,7 +76,7 @@ virtual bool isOnDataReadAvailable() const { return false; } - ble_error_t setOnDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) { + ble_error_t setOnDataRead(void (*callback)(const GattReadCallbackParams *eventDataP)) { if (!isOnDataReadAvailable()) { return BLE_ERROR_NOT_IMPLEMENTED; } @@ -84,7 +85,7 @@ return BLE_ERROR_NONE; } template <typename T> - ble_error_t setOnDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) { + ble_error_t setOnDataRead(T *objPtr, void (T::*memberPtr)(const GattReadCallbackParams *context)) { if (!isOnDataReadAvailable()) { return BLE_ERROR_NOT_IMPLEMENTED; } @@ -97,13 +98,13 @@ void setOnConfirmationReceived(EventCallback_t callback) {onConfirmationReceived = callback;} protected: - void handleDataWrittenEvent(const GattCharacteristicWriteCBParams *params) { + void handleDataWrittenEvent(const GattWriteCallbackParams *params) { if (onDataWritten.hasCallbacksAttached()) { onDataWritten.call(params); } } - void handleDataReadEvent(const GattCharacteristicReadCBParams *params) { + void handleDataReadEvent(const GattReadCallbackParams *params) { if (onDataRead.hasCallbacksAttached()) { onDataRead.call(params); } @@ -143,8 +144,8 @@ private: CallChainOfFunctionPointersWithContext<unsigned> onDataSent; - CallChainOfFunctionPointersWithContext<const GattCharacteristicWriteCBParams *> onDataWritten; - CallChainOfFunctionPointersWithContext<const GattCharacteristicReadCBParams *> onDataRead; + CallChainOfFunctionPointersWithContext<const GattWriteCallbackParams *> onDataWritten; + CallChainOfFunctionPointersWithContext<const GattReadCallbackParams *> onDataRead; EventCallback_t onUpdatesEnabled; EventCallback_t onUpdatesDisabled; EventCallback_t onConfirmationReceived;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/public/ServiceDiscovery.h Fri Jun 19 15:53:01 2015 +0100 @@ -0,0 +1,138 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2013 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __SERVICE_DISOVERY_H__ +#define __SERVICE_DISOVERY_H__ + +#include "UUID.h" +#include "Gap.h" +#include "GattAttribute.h" + +class DiscoveredService; +class DiscoveredCharacteristic; + +class ServiceDiscovery { +public: + /* + * Exposed application callback types. + */ + + /** + * Callback type for when a matching Service is found during service- + * discovery. The receiving function is passed in a pointer to a + * DiscoveredService object which will remain valid for the lifetime of the + * callback. Memory for this object is owned by the BLE_API eventing + * framework. The application can safely make a persistent shallow-copy of + * this object in order to work with the service beyond the callback. + */ + typedef void (*ServiceCallback_t)(const DiscoveredService *); + + /** + * Callback type for when a matching Characteristic is found during service- + * discovery. The receiving function is passed in a pointer to a + * DiscoveredCharacteristic object which will remain valid for the lifetime + * of the callback. Memory for this object is owned by the BLE_API eventing + * framework. The application can safely make a persistent shallow-copy of + * this object in order to work with the characteristic beyond the callback. + */ + typedef void (*CharacteristicCallback_t)(const DiscoveredCharacteristic *); + + /** + * Callback type for when serviceDiscovery terminates. + */ + typedef void (*TerminationCallback_t)(Gap::Handle_t connectionHandle); + +public: + /** + * Launch service discovery. Once launched, service discovery will remain + * active with callbacks being issued back into the application for matching + * services/characteristics. isActive() can be used to determine status; and + * a termination callback (if setup) will be invoked at the end. Service + * discovery can be terminated prematurely if needed using terminate(). + * + * @param connectionHandle + * Handle for the connection with the peer. + * @param sc + * This is the application callback for matching service. Taken as + * NULL by default. Note: service discovery may still be active + * when this callback is issued; calling asynchronous BLE-stack + * APIs from within this application callback might cause the + * stack to abort service discovery. If this becomes an issue, it + * may be better to make local copy of the discoveredService and + * wait for service discovery to terminate before operating on the + * service. + * @param cc + * This is the application callback for matching characteristic. + * Taken as NULL by default. Note: service discovery may still be + * active when this callback is issued; calling asynchronous + * BLE-stack APIs from within this application callback might cause + * the stack to abort service discovery. If this becomes an issue, + * it may be better to make local copy of the discoveredCharacteristic + * and wait for service discovery to terminate before operating on the + * characteristic. + * @param matchingServiceUUID + * UUID based filter for specifying a service in which the application is + * interested. By default it is set as the wildcard UUID_UNKNOWN, + * in which case it matches all services. If characteristic-UUID + * filter (below) is set to the wildcard value, then a service + * callback will be invoked for the matching service (or for every + * service if the service filter is a wildcard). + * @param matchingCharacteristicUUIDIn + * UUID based filter for specifying characteristic in which the application + * is interested. By default it is set as the wildcard UUID_UKNOWN + * to match against any characteristic. If both service-UUID + * filter and characteristic-UUID filter are used with non- wildcard + * values, then only a single characteristic callback is + * invoked for the matching characteristic. + * + * @Note Using wildcard values for both service-UUID and characteristic- + * UUID will result in complete service discovery--callbacks being + * called for every service and characteristic. + * + * @return + * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error. + */ + virtual ble_error_t launch(Gap::Handle_t connectionHandle, + ServiceCallback_t sc = NULL, + CharacteristicCallback_t cc = NULL, + const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN), + const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0; + + /** + * Is service-discovery currently active? + */ + virtual bool isActive(void) const = 0; + + /** + * Terminate an ongoing service-discovery. This should result in an + * invocation of the TerminationCallback if service-discovery is active. + */ + virtual void terminate(void) = 0; + + /** + * Setup callback to be invoked when service discovery is terminated. + */ + virtual void onTermination(TerminationCallback_t callback) = 0; + +protected: + Gap::Handle_t connHandle; /**< Connection handle as provided by the SoftDevice. */ + UUID matchingServiceUUID; + ServiceCallback_t serviceCallback; + UUID matchingCharacteristicUUID; + CharacteristicCallback_t characteristicCallback; +}; + +#endif // ifndef __SERVICE_DISOVERY_H__ \ No newline at end of file
--- a/public/UUID.h Fri Jun 19 15:53:01 2015 +0100 +++ b/public/UUID.h Fri Jun 19 15:53:01 2015 +0100 @@ -17,6 +17,7 @@ #ifndef __UUID_H__ #define __UUID_H__ +#include <stdint.h> #include <string.h> #include "blecommon.h" @@ -28,9 +29,10 @@ UUID_TYPE_LONG = 1 // Full 128-bit UUID }; + typedef uint16_t ShortUUIDBytes_t; + static const unsigned LENGTH_OF_LONG_UUID = 16; - typedef uint16_t ShortUUIDBytes_t; - typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; + typedef uint8_t LongUUIDBytes_t[LENGTH_OF_LONG_UUID]; public: /**
--- a/services/BatteryService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/BatteryService.h Fri Jun 19 15:53:01 2015 +0100 @@ -38,10 +38,16 @@ batteryLevel(level), batteryLevelCharacteristic(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, &batteryLevel, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) { + static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ + if (serviceAdded) { + return; + } + GattCharacteristic *charTable[] = {&batteryLevelCharacteristic}; GattService batteryService(GattService::UUID_BATTERY_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.addService(batteryService); + serviceAdded = true; } /** @@ -56,7 +62,7 @@ ble.updateCharacteristicValue(batteryLevelCharacteristic.getValueAttribute().getHandle(), &batteryLevel, 1); } -protected: +private: BLEDevice &ble; uint8_t batteryLevel;
--- a/services/DFUService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/DFUService.h Fri Jun 19 15:53:01 2015 +0100 @@ -54,11 +54,11 @@ */ DFUService(BLEDevice &_ble, ResetPrepare_t _handoverCallback = NULL) : ble(_ble), + controlBytes(), + packetBytes(), controlPoint(DFUServiceControlCharacteristicUUID, controlBytes, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY), packet(DFUServicePacketCharacteristicUUID, packetBytes, SIZEOF_PACKET_BYTES, SIZEOF_PACKET_BYTES, - GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE), - controlBytes(), - packetBytes() { + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE) { static bool serviceAdded = false; /* We should only ever need to add the DFU service once. */ if (serviceAdded) { return; @@ -94,8 +94,8 @@ * @param[in] params * Information about the characterisitc being updated. */ - virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { - if (params->charHandle == controlPoint.getValueHandle()) { + virtual void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == controlPoint.getValueHandle()) { /* At present, writing anything will do the trick--this needs to be improved. */ if (handoverCallback) { handoverCallback(); @@ -105,12 +105,16 @@ } } -protected: +private: static const unsigned SIZEOF_CONTROL_BYTES = 2; static const unsigned SIZEOF_PACKET_BYTES = 20; -protected: + static ResetPrepare_t handoverCallback; /**< application specific handover callback. */ + +private: BLEDevice &ble; + uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; + uint8_t packetBytes[SIZEOF_PACKET_BYTES]; /**< Writing to the control characteristic triggers the handover to dfu- * bootloader. At present, writing anything will do the trick--this needs @@ -123,11 +127,6 @@ * FOTA clients might get confused as service definitions change after * handing control over to the bootloader. */ GattCharacteristic packet; - - uint8_t controlBytes[SIZEOF_CONTROL_BYTES]; - uint8_t packetBytes[SIZEOF_PACKET_BYTES]; - - static ResetPrepare_t handoverCallback; /**< application specific handover callback. */ }; #endif /* #ifndef __BLE_DFU_SERVICE_H__*/ \ No newline at end of file
--- a/services/DeviceInformationService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/DeviceInformationService.h Fri Jun 19 15:53:01 2015 +0100 @@ -114,7 +114,7 @@ serviceAdded = true; } -protected: +private: BLEDevice &ble; GattCharacteristic manufacturersNameStringCharacteristic; GattCharacteristic modelNumberStringCharacteristic;
--- a/services/HeartRateService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/HeartRateService.h Fri Jun 19 15:53:01 2015 +0100 @@ -114,7 +114,7 @@ * @param[in] params * Information about the characterisitc being updated. */ - virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { + virtual void onDataWritten(const GattWriteCallbackParams *params) { if (params->charHandle == controlPoint.getValueAttribute().getHandle()) { /* Do something here if the new value is 1; else you can override this method by * extending this class. @@ -125,16 +125,23 @@ } } -protected: +private: void setupService(void) { + static bool serviceAdded = false; /* We should only ever need to add the heart rate service once. */ + if (serviceAdded) { + return; + } + GattCharacteristic *charTable[] = {&hrmRate, &hrmLocation, &controlPoint}; GattService hrmService(GattService::UUID_HEART_RATE_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); ble.addService(hrmService); + serviceAdded = true; + ble.onDataWritten(this, &HeartRateService::onDataWritten); } -protected: +private: /* Private internal representation for the bytes used to work with the vaulue of the heart-rate characteristic. */ struct HeartRateValueBytes { static const unsigned MAX_VALUE_BYTES = 3; /* FLAGS + up to two bytes for heart-rate */ @@ -174,13 +181,13 @@ return 1 + ((valueBytes[FLAGS_BYTE_INDEX] & VALUE_FORMAT_FLAG) ? sizeof(uint16_t) : sizeof(uint8_t)); } - private: +private: /* First byte = 8-bit values, no extra info, Second byte = uint8_t HRM value */ /* See --> https://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml */ uint8_t valueBytes[MAX_VALUE_BYTES]; }; -protected: +private: BLEDevice &ble; HeartRateValueBytes valueBytes;
--- a/services/LinkLossService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/LinkLossService.h Fri Jun 19 15:53:01 2015 +0100 @@ -80,7 +80,7 @@ * @param[in] params * Information about the characterisitc being updated. */ - virtual void onDataWritten(const GattCharacteristicWriteCBParams *params) { + virtual void onDataWritten(const GattWriteCallbackParams *params) { if (params->charHandle == alertLevelChar.getValueHandle()) { alertLevel = *reinterpret_cast<const AlertLevel_t *>(params->data); } @@ -92,7 +92,7 @@ } } -protected: +private: BLEDevice &ble; AlertLevel_t alertLevel; callback_t callback;
--- a/services/UARTService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/UARTService.h Fri Jun 19 15:53:01 2015 +0100 @@ -167,8 +167,8 @@ * function from the global onDataWritten() callback handler; or if that's * not used, this method can be used as a callback directly. */ - void onDataWritten(const GattCharacteristicWriteCBParams *params) { - if (params->charHandle == getTXCharacteristicHandle()) { + void onDataWritten(const GattWriteCallbackParams *params) { + if (params->handle == getTXCharacteristicHandle()) { uint16_t bytesRead = params->len; if (bytesRead <= BLE_UART_SERVICE_MAX_DATA_LEN) { numBytesReceived = bytesRead;
--- a/services/URIBeaconConfigService.h Fri Jun 19 15:53:01 2015 +0100 +++ b/services/URIBeaconConfigService.h Fri Jun 19 15:53:01 2015 +0100 @@ -232,8 +232,8 @@ * characteristics of this service. Attempts to do so are also applied to * the internal state of this service object. */ - void onDataWrittenCallback(const GattCharacteristicWriteCBParams *writeParams) { - uint16_t handle = writeParams->charHandle; + void onDataWrittenCallback(const GattWriteCallbackParams *writeParams) { + uint16_t handle = writeParams->handle; if (handle == lockChar.getValueHandle()) { // Validated earlier @@ -305,8 +305,8 @@ reinterpret_cast<uint8_t *>(params.advPowerLevels), sizeof(PowerLevels_t)); } -private: - void lockAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { + private: + void lockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->len != sizeof(Lock_t)) { @@ -319,7 +319,7 @@ } - void unlockAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { + void unlockAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { if (!lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_SUCCESS; } else if (authParams->len != sizeof(Lock_t)) { @@ -333,7 +333,7 @@ } } - void uriDataWriteAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { + void uriDataWriteAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->offset != 0) { @@ -343,7 +343,7 @@ } } - void powerModeAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { + void powerModeAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->len != sizeof(uint8_t)) { @@ -358,7 +358,7 @@ } template <typename T> - void basicAuthorizationCallback(GattCharacteristicWriteAuthCBParams *authParams) { + void basicAuthorizationCallback(GattWriteAuthCallbackParams *authParams) { if (lockedState) { authParams->authorizationReply = AUTH_CALLBACK_REPLY_ATTERR_INSUF_AUTHORIZATION; } else if (authParams->len != sizeof(T)) { @@ -370,7 +370,6 @@ } } -protected: BLEDevice &ble; Params_t ¶ms; @@ -392,7 +391,7 @@ ReadWriteGattCharacteristic<uint16_t> beaconPeriodChar; WriteOnlyGattCharacteristic<uint8_t> resetChar; -public: + public: /* * Encode a human-readable URI into the binary format defined by URIBeacon spec (https://github.com/google/uribeacon/tree/master/specification). */