High level Bluetooth Low Energy API and radio abstraction layer

Fork of BLE_API by Bluetooth Low Energy

Committer:
rgrover1
Date:
Fri Jun 19 15:52:03 2015 +0100
Revision:
504:817c6240e9d9
Parent:
503:4e69a47047c5
Child:
508:31e63ad6923f
Synchronized with git rev 49ec8f8b
Author: Rohit Grover
Add GattClient::WriteResponse*

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 490:58a0313fffb5 1 /* mbed Microcontroller Library
rgrover1 490:58a0313fffb5 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 490:58a0313fffb5 3 *
rgrover1 490:58a0313fffb5 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 490:58a0313fffb5 5 * you may not use this file except in compliance with the License.
rgrover1 490:58a0313fffb5 6 * You may obtain a copy of the License at
rgrover1 490:58a0313fffb5 7 *
rgrover1 490:58a0313fffb5 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 490:58a0313fffb5 9 *
rgrover1 490:58a0313fffb5 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 490:58a0313fffb5 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 490:58a0313fffb5 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 490:58a0313fffb5 13 * See the License for the specific language governing permissions and
rgrover1 490:58a0313fffb5 14 * limitations under the License.
rgrover1 490:58a0313fffb5 15 */
rgrover1 490:58a0313fffb5 16
rgrover1 490:58a0313fffb5 17 #ifndef __GATT_CLIENT_H__
rgrover1 490:58a0313fffb5 18 #define __GATT_CLIENT_H__
rgrover1 490:58a0313fffb5 19
rgrover1 495:b0d77b1db2df 20 #include "Gap.h"
rgrover1 495:b0d77b1db2df 21 #include "GattAttribute.h"
rgrover1 497:926d444599e8 22 #include "ServiceDiscovery.h"
rgrover1 495:b0d77b1db2df 23
rgrover1 490:58a0313fffb5 24 class GattClient {
rgrover1 495:b0d77b1db2df 25 public:
rgrover1 501:ff6801633d2c 26 struct ReadResponse_t {
rgrover1 501:ff6801633d2c 27 GattAttribute::Handle_t handle; /**< Attribute Handle. */
rgrover1 501:ff6801633d2c 28 uint16_t offset; /**< Offset of the attribute data. */
rgrover1 501:ff6801633d2c 29 uint16_t len; /**< Attribute data length. */
rgrover1 501:ff6801633d2c 30 const uint8_t *data; /**< Attribute data, variable length. */
rgrover1 501:ff6801633d2c 31 };
rgrover1 501:ff6801633d2c 32 typedef void (*ReadCallback_t)(const ReadResponse_t *params);
rgrover1 501:ff6801633d2c 33
rgrover1 504:817c6240e9d9 34 enum WriteOp_t {
rgrover1 504:817c6240e9d9 35 GATT_OP_INVALID = 0x00, /**< Invalid Operation. */
rgrover1 504:817c6240e9d9 36 GATT_OP_WRITE_REQ = 0x01, /**< Write Request. */
rgrover1 504:817c6240e9d9 37 GATT_OP_WRITE_CMD = 0x02, /**< Write Command. */
rgrover1 504:817c6240e9d9 38 GATT_OP_SIGN_WRITE_CMD = 0x03, /**< Signed Write Command. */
rgrover1 504:817c6240e9d9 39 GATT_OP_PREP_WRITE_REQ = 0x04, /**< Prepare Write Request. */
rgrover1 504:817c6240e9d9 40 GATT_OP_EXEC_WRITE_REQ = 0x05, /**< Execute Write Request. */
rgrover1 504:817c6240e9d9 41 };
rgrover1 504:817c6240e9d9 42
rgrover1 504:817c6240e9d9 43 struct WriteResponse_t {
rgrover1 504:817c6240e9d9 44 GattAttribute::Handle_t handle; /**< Attribute Handle. */
rgrover1 504:817c6240e9d9 45 WriteOp_t writeOp;
rgrover1 504:817c6240e9d9 46 uint16_t offset; /**< Offset of the attribute data. */
rgrover1 504:817c6240e9d9 47 uint16_t len; /**< Attribute data length. */
rgrover1 504:817c6240e9d9 48 const uint8_t *data; /**< Attribute data, variable length. */
rgrover1 504:817c6240e9d9 49 };
rgrover1 504:817c6240e9d9 50 typedef void (*WriteCallback_t)(const WriteResponse_t *params);
rgrover1 504:817c6240e9d9 51
rgrover1 497:926d444599e8 52 public:
rgrover1 497:926d444599e8 53 /**
rgrover1 497:926d444599e8 54 * Launch service discovery. Once launched, service discovery will remain
rgrover1 497:926d444599e8 55 * active with callbacks being issued back into the application for matching
rgrover1 497:926d444599e8 56 * services/characteristics. isActive() can be used to determine status; and
rgrover1 497:926d444599e8 57 * a termination callback (if setup) will be invoked at the end. Service
rgrover1 497:926d444599e8 58 * discovery can be terminated prematurely if needed using terminate().
rgrover1 497:926d444599e8 59 *
rgrover1 497:926d444599e8 60 * @param connectionHandle
rgrover1 497:926d444599e8 61 * Handle for the connection with the peer.
rgrover1 497:926d444599e8 62 * @param sc
rgrover1 497:926d444599e8 63 * This is the application callback for matching service.
rgrover1 497:926d444599e8 64 * @param cc
rgrover1 497:926d444599e8 65 * This is the application callback for matching characteristic.
rgrover1 497:926d444599e8 66 * @param matchingServiceUUID
rgrover1 497:926d444599e8 67 * UUID based filter for specifying a service in which the application is
rgrover1 497:926d444599e8 68 * interested.
rgrover1 497:926d444599e8 69 * @param matchingCharacteristicUUIDIn
rgrover1 497:926d444599e8 70 * UUID based filter for specifying characteristic in which the application
rgrover1 497:926d444599e8 71 * is interested.
rgrover1 497:926d444599e8 72 *
rgrover1 497:926d444599e8 73 * @Note Using wildcard values for both service-UUID and characteristic-
rgrover1 497:926d444599e8 74 * UUID will result in complete service discovery--callbacks being
rgrover1 497:926d444599e8 75 * called for every service and characteristic.
rgrover1 497:926d444599e8 76 *
rgrover1 497:926d444599e8 77 * @return
rgrover1 497:926d444599e8 78 * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
rgrover1 497:926d444599e8 79 */
rgrover1 497:926d444599e8 80 virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle,
rgrover1 497:926d444599e8 81 ServiceDiscovery::ServiceCallback_t sc = NULL,
rgrover1 497:926d444599e8 82 ServiceDiscovery::CharacteristicCallback_t cc = NULL,
rgrover1 497:926d444599e8 83 const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
rgrover1 497:926d444599e8 84 const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) = 0;
rgrover1 497:926d444599e8 85
rgrover1 497:926d444599e8 86 virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) = 0;
rgrover1 497:926d444599e8 87
rgrover1 497:926d444599e8 88 /**
rgrover1 497:926d444599e8 89 * Is service-discovery currently active?
rgrover1 497:926d444599e8 90 */
rgrover1 497:926d444599e8 91 virtual bool isServiceDiscoveryActive(void) const = 0;
rgrover1 497:926d444599e8 92
rgrover1 497:926d444599e8 93 /**
rgrover1 497:926d444599e8 94 * Terminate an ongoing service-discovery. This should result in an
rgrover1 497:926d444599e8 95 * invocation of the TerminationCallback if service-discovery is active.
rgrover1 497:926d444599e8 96 */
rgrover1 497:926d444599e8 97 virtual void terminateServiceDiscovery(void) = 0;
rgrover1 497:926d444599e8 98
rgrover1 495:b0d77b1db2df 99 /* Initiate a Gatt Client read procedure by attribute-handle.*/
rgrover1 495:b0d77b1db2df 100 virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const = 0;
rgrover1 495:b0d77b1db2df 101
rgrover1 504:817c6240e9d9 102 virtual ble_error_t write(GattClient::WriteOp_t cmd, Gap::Handle_t connHandle, size_t length, const uint8_t *value) const = 0;
rgrover1 497:926d444599e8 103
rgrover1 490:58a0313fffb5 104 #if 0
rgrover1 490:58a0313fffb5 105 public:
rgrover1 490:58a0313fffb5 106 /* Event callback handlers. */
rgrover1 490:58a0313fffb5 107 typedef void (*EventCallback_t)(GattAttribute::Handle_t attributeHandle);
rgrover1 490:58a0313fffb5 108 typedef void (*ServerEventCallback_t)(void); /**< independent of any particular attribute */
rgrover1 490:58a0313fffb5 109
rgrover1 490:58a0313fffb5 110 friend class BLEDevice;
rgrover1 490:58a0313fffb5 111 private:
rgrover1 490:58a0313fffb5 112 /* These functions must be defined in the sub-class */
rgrover1 490:58a0313fffb5 113 virtual ble_error_t addService(GattService &) = 0;
rgrover1 490:58a0313fffb5 114 virtual ble_error_t readValue(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0;
rgrover1 490:58a0313fffb5 115 virtual ble_error_t readValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP) = 0;
rgrover1 490:58a0313fffb5 116 virtual ble_error_t updateValue(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false) = 0;
rgrover1 490:58a0313fffb5 117 virtual ble_error_t updateValue(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false) = 0;
rgrover1 490:58a0313fffb5 118 virtual ble_error_t initializeGATTDatabase(void) = 0;
rgrover1 490:58a0313fffb5 119
rgrover1 490:58a0313fffb5 120 // ToDo: For updateValue, check the CCCD to see if the value we are
rgrover1 490:58a0313fffb5 121 // updating has the notify or indicate bits sent, and if BOTH are set
rgrover1 490:58a0313fffb5 122 // be sure to call sd_ble_gatts_hvx() twice with notify then indicate!
rgrover1 490:58a0313fffb5 123 // Strange use case, but valid and must be covered!
rgrover1 490:58a0313fffb5 124
rgrover1 490:58a0313fffb5 125 void setOnDataSent(void (*callback)(unsigned count)) {onDataSent.add(callback);}
rgrover1 490:58a0313fffb5 126 template <typename T>
rgrover1 490:58a0313fffb5 127 void setOnDataSent(T *objPtr, void (T::*memberPtr)(unsigned count)) {
rgrover1 490:58a0313fffb5 128 onDataSent.add(objPtr, memberPtr);
rgrover1 490:58a0313fffb5 129 }
rgrover1 490:58a0313fffb5 130 void setOnDataWritten(void (*callback)(const GattCharacteristicWriteCBParams *eventDataP)) {onDataWritten.add(callback);}
rgrover1 490:58a0313fffb5 131 template <typename T>
rgrover1 490:58a0313fffb5 132 void setOnDataWritten(T *objPtr, void (T::*memberPtr)(const GattCharacteristicWriteCBParams *context)) {
rgrover1 490:58a0313fffb5 133 onDataWritten.add(objPtr, memberPtr);
rgrover1 490:58a0313fffb5 134 }
rgrover1 490:58a0313fffb5 135
rgrover1 490:58a0313fffb5 136 /**
rgrover1 490:58a0313fffb5 137 * A virtual function to allow underlying stacks to indicate if they support
rgrover1 490:58a0313fffb5 138 * onDataRead(). It should be overridden to return true as applicable.
rgrover1 490:58a0313fffb5 139 */
rgrover1 490:58a0313fffb5 140 virtual bool isOnDataReadAvailable() const {
rgrover1 490:58a0313fffb5 141 return false;
rgrover1 490:58a0313fffb5 142 }
rgrover1 490:58a0313fffb5 143 ble_error_t setOnDataRead(void (*callback)(const GattCharacteristicReadCBParams *eventDataP)) {
rgrover1 490:58a0313fffb5 144 if (!isOnDataReadAvailable()) {
rgrover1 490:58a0313fffb5 145 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 490:58a0313fffb5 146 }
rgrover1 490:58a0313fffb5 147
rgrover1 490:58a0313fffb5 148 onDataRead.add(callback);
rgrover1 490:58a0313fffb5 149 return BLE_ERROR_NONE;
rgrover1 490:58a0313fffb5 150 }
rgrover1 490:58a0313fffb5 151 template <typename T>
rgrover1 490:58a0313fffb5 152 ble_error_t setOnDataRead(T *objPtr, void (T::*memberPtr)(const GattCharacteristicReadCBParams *context)) {
rgrover1 490:58a0313fffb5 153 if (!isOnDataReadAvailable()) {
rgrover1 490:58a0313fffb5 154 return BLE_ERROR_NOT_IMPLEMENTED;
rgrover1 490:58a0313fffb5 155 }
rgrover1 490:58a0313fffb5 156
rgrover1 490:58a0313fffb5 157 onDataRead.add(objPtr, memberPtr);
rgrover1 490:58a0313fffb5 158 return BLE_ERROR_NONE;
rgrover1 490:58a0313fffb5 159 }
rgrover1 490:58a0313fffb5 160 void setOnUpdatesEnabled(EventCallback_t callback) {onUpdatesEnabled = callback;}
rgrover1 490:58a0313fffb5 161 void setOnUpdatesDisabled(EventCallback_t callback) {onUpdatesDisabled = callback;}
rgrover1 490:58a0313fffb5 162 void setOnConfirmationReceived(EventCallback_t callback) {onConfirmationReceived = callback;}
rgrover1 490:58a0313fffb5 163
rgrover1 490:58a0313fffb5 164 protected:
rgrover1 490:58a0313fffb5 165 void handleDataWrittenEvent(const GattCharacteristicWriteCBParams *params) {
rgrover1 490:58a0313fffb5 166 if (onDataWritten.hasCallbacksAttached()) {
rgrover1 490:58a0313fffb5 167 onDataWritten.call(params);
rgrover1 490:58a0313fffb5 168 }
rgrover1 490:58a0313fffb5 169 }
rgrover1 490:58a0313fffb5 170
rgrover1 490:58a0313fffb5 171 void handleDataReadEvent(const GattCharacteristicReadCBParams *params) {
rgrover1 490:58a0313fffb5 172 if (onDataRead.hasCallbacksAttached()) {
rgrover1 490:58a0313fffb5 173 onDataRead.call(params);
rgrover1 490:58a0313fffb5 174 }
rgrover1 490:58a0313fffb5 175 }
rgrover1 490:58a0313fffb5 176
rgrover1 490:58a0313fffb5 177 void handleEvent(GattServerEvents::gattEvent_e type, GattAttribute::Handle_t charHandle) {
rgrover1 490:58a0313fffb5 178 switch (type) {
rgrover1 490:58a0313fffb5 179 case GattServerEvents::GATT_EVENT_UPDATES_ENABLED:
rgrover1 490:58a0313fffb5 180 if (onUpdatesEnabled) {
rgrover1 490:58a0313fffb5 181 onUpdatesEnabled(charHandle);
rgrover1 490:58a0313fffb5 182 }
rgrover1 490:58a0313fffb5 183 break;
rgrover1 490:58a0313fffb5 184 case GattServerEvents::GATT_EVENT_UPDATES_DISABLED:
rgrover1 490:58a0313fffb5 185 if (onUpdatesDisabled) {
rgrover1 490:58a0313fffb5 186 onUpdatesDisabled(charHandle);
rgrover1 490:58a0313fffb5 187 }
rgrover1 490:58a0313fffb5 188 break;
rgrover1 490:58a0313fffb5 189 case GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED:
rgrover1 490:58a0313fffb5 190 if (onConfirmationReceived) {
rgrover1 490:58a0313fffb5 191 onConfirmationReceived(charHandle);
rgrover1 490:58a0313fffb5 192 }
rgrover1 490:58a0313fffb5 193 break;
rgrover1 490:58a0313fffb5 194 default:
rgrover1 490:58a0313fffb5 195 break;
rgrover1 490:58a0313fffb5 196 }
rgrover1 490:58a0313fffb5 197 }
rgrover1 490:58a0313fffb5 198
rgrover1 490:58a0313fffb5 199 void handleDataSentEvent(unsigned count) {
rgrover1 490:58a0313fffb5 200 if (onDataSent.hasCallbacksAttached()) {
rgrover1 490:58a0313fffb5 201 onDataSent.call(count);
rgrover1 490:58a0313fffb5 202 }
rgrover1 490:58a0313fffb5 203 }
rgrover1 490:58a0313fffb5 204
rgrover1 490:58a0313fffb5 205 protected:
rgrover1 490:58a0313fffb5 206 uint8_t serviceCount;
rgrover1 490:58a0313fffb5 207 uint8_t characteristicCount;
rgrover1 490:58a0313fffb5 208
rgrover1 490:58a0313fffb5 209 private:
rgrover1 490:58a0313fffb5 210 CallChainOfFunctionPointersWithContext<unsigned> onDataSent;
rgrover1 490:58a0313fffb5 211 CallChainOfFunctionPointersWithContext<const GattCharacteristicWriteCBParams *> onDataWritten;
rgrover1 490:58a0313fffb5 212 CallChainOfFunctionPointersWithContext<const GattCharacteristicReadCBParams *> onDataRead;
rgrover1 490:58a0313fffb5 213 EventCallback_t onUpdatesEnabled;
rgrover1 490:58a0313fffb5 214 EventCallback_t onUpdatesDisabled;
rgrover1 490:58a0313fffb5 215 EventCallback_t onConfirmationReceived;
rgrover1 490:58a0313fffb5 216 #endif
rgrover1 490:58a0313fffb5 217
rgrover1 490:58a0313fffb5 218 protected:
rgrover1 490:58a0313fffb5 219 GattClient() {
rgrover1 490:58a0313fffb5 220 /* empty */
rgrover1 490:58a0313fffb5 221 }
rgrover1 490:58a0313fffb5 222
rgrover1 490:58a0313fffb5 223 private:
rgrover1 490:58a0313fffb5 224 /* disallow copy and assignment */
rgrover1 490:58a0313fffb5 225 GattClient(const GattClient &);
rgrover1 490:58a0313fffb5 226 GattClient& operator=(const GattClient &);
rgrover1 490:58a0313fffb5 227 };
rgrover1 490:58a0313fffb5 228
rgrover1 490:58a0313fffb5 229 #endif // ifndef __GATT_CLIENT_H__