test

Dependencies:   nrf51-sdk

Dependents:   microbit-dal

Fork of nRF51822 by Lancaster University

Committer:
rgrover1
Date:
Fri Jun 19 15:55:30 2015 +0100
Revision:
309:ef9e806a7b03
Parent:
308:482f16f3f7f5
Child:
310:4d7ccb8c2a51
Synchronized with git rev 853d4925
Author: Rohit Grover
DiscoveredCharacteristic::read() returns ble_error_t

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 239:693a1f145b5a 1 /* mbed Microcontroller Library
rgrover1 239:693a1f145b5a 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 239:693a1f145b5a 3 *
rgrover1 239:693a1f145b5a 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 239:693a1f145b5a 5 * you may not use this file except in compliance with the License.
rgrover1 239:693a1f145b5a 6 * You may obtain a copy of the License at
rgrover1 239:693a1f145b5a 7 *
rgrover1 239:693a1f145b5a 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 239:693a1f145b5a 9 *
rgrover1 239:693a1f145b5a 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 239:693a1f145b5a 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 239:693a1f145b5a 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 239:693a1f145b5a 13 * See the License for the specific language governing permissions and
rgrover1 239:693a1f145b5a 14 * limitations under the License.
rgrover1 239:693a1f145b5a 15 */
rgrover1 239:693a1f145b5a 16
rgrover1 239:693a1f145b5a 17 #ifndef _BTLE_DISCOVERY_H_
rgrover1 239:693a1f145b5a 18 #define _BTLE_DISCOVERY_H_
rgrover1 239:693a1f145b5a 19
rgrover1 247:df37e7bb3f71 20 #include "ble.h"
rgrover1 263:d5da37e9a93b 21 #include "ServiceDiscovery.h"
rgrover1 247:df37e7bb3f71 22
rgrover1 247:df37e7bb3f71 23 void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
rgrover1 239:693a1f145b5a 24
rgrover1 308:482f16f3f7f5 25 class nRFDiscoveredCharacteristic : public DiscoveredCharacteristic {
rgrover1 308:482f16f3f7f5 26 public:
rgrover1 308:482f16f3f7f5 27 /**
rgrover1 308:482f16f3f7f5 28 * Initiate (or continue) a read for the value attribute, optionally at a
rgrover1 308:482f16f3f7f5 29 * given offset. If the Characteristic or Descriptor to be read is longer
rgrover1 308:482f16f3f7f5 30 * than ATT_MTU - 1, this function must be called multiple times with
rgrover1 308:482f16f3f7f5 31 * appropriate offset to read the complete value.
rgrover1 308:482f16f3f7f5 32 */
rgrover1 309:ef9e806a7b03 33 virtual ble_error_t read(uint16_t offset = 0) {
rgrover1 308:482f16f3f7f5 34 /**@brief Initiate or continue a GATT Read (Long) Characteristic or Descriptor procedure.
rgrover1 308:482f16f3f7f5 35 *
rgrover1 308:482f16f3f7f5 36 * @details This function initiates or resumes a GATT Read (Long) Characteristic or Descriptor procedure. If the Characteristic or Descriptor
rgrover1 308:482f16f3f7f5 37 * to be read is longer than ATT_MTU - 1, this function must be called multiple times with appropriate offset to read the
rgrover1 308:482f16f3f7f5 38 * complete value.
rgrover1 308:482f16f3f7f5 39 *
rgrover1 308:482f16f3f7f5 40 * @param[in] conn_handle The connection handle identifying the connection to perform this procedure on.
rgrover1 308:482f16f3f7f5 41 * @param[in] handle The handle of the attribute to be read.
rgrover1 308:482f16f3f7f5 42 * @param[in] offset Offset into the attribute value to be read.
rgrover1 308:482f16f3f7f5 43 *
rgrover1 308:482f16f3f7f5 44 * @retval ::NRF_SUCCESS Successfully started or resumed the Read (Long) procedure.
rgrover1 308:482f16f3f7f5 45 * @retval ::BLE_ERROR_INVALID_CONN_HANDLE Invalid Connection Handle.
rgrover1 308:482f16f3f7f5 46 * @retval ::NRF_ERROR_INVALID_STATE Invalid Connection State.
rgrover1 308:482f16f3f7f5 47 * @retval ::NRF_ERROR_INVALID_ADDR Invalid pointer supplied.
rgrover1 308:482f16f3f7f5 48 * @retval ::NRF_ERROR_BUSY Client procedure already in progress.
rgrover1 308:482f16f3f7f5 49 */
rgrover1 308:482f16f3f7f5 50 // sd_ble_gattc_read()
rgrover1 308:482f16f3f7f5 51 // SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
rgrover1 309:ef9e806a7b03 52 return BLE_ERROR_NONE;
rgrover1 308:482f16f3f7f5 53 }
rgrover1 308:482f16f3f7f5 54 };
rgrover1 308:482f16f3f7f5 55
rgrover1 250:db3c51656388 56 class NordicServiceDiscovery : public ServiceDiscovery
rgrover1 250:db3c51656388 57 {
rgrover1 248:71ef03789dd3 58 public:
rgrover1 260:ea2798f615e5 59 static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */
rgrover1 284:29fb6af6671d 60 static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */
rgrover1 260:ea2798f615e5 61
rgrover1 289:b33301b019e6 62 public:
rgrover1 248:71ef03789dd3 63 static const unsigned BLE_DB_DISCOVERY_MAX_SRV = 4; /**< Maximum number of services we can retain information for after a single discovery. */
rgrover1 248:71ef03789dd3 64 static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service we can retain information for. */
rgrover1 260:ea2798f615e5 65
rgrover1 260:ea2798f615e5 66 public:
rgrover1 288:1d85c4a4d397 67 NordicServiceDiscovery() : serviceIndex(0),
rgrover1 288:1d85c4a4d397 68 numServices(0),
rgrover1 288:1d85c4a4d397 69 characteristicIndex(0),
rgrover1 288:1d85c4a4d397 70 numCharacteristics(0),
rgrover1 288:1d85c4a4d397 71 state(INACTIVE),
rgrover1 288:1d85c4a4d397 72 services(),
rgrover1 288:1d85c4a4d397 73 characteristics(),
rgrover1 305:293634834813 74 serviceUUIDDiscoveryQueue(this),
rgrover1 306:76e2e7349319 75 charUUIDDiscoveryQueue(this),
rgrover1 288:1d85c4a4d397 76 onTerminationCallback(NULL) {
rgrover1 288:1d85c4a4d397 77 /* empty */
rgrover1 288:1d85c4a4d397 78 }
rgrover1 288:1d85c4a4d397 79
rgrover1 288:1d85c4a4d397 80 public:
rgrover1 260:ea2798f615e5 81 ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
rgrover1 239:693a1f145b5a 82
rgrover1 239:693a1f145b5a 83 public:
rgrover1 248:71ef03789dd3 84 void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
rgrover1 248:71ef03789dd3 85 void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
rgrover1 248:71ef03789dd3 86
rgrover1 290:83c994bf62d0 87 void triggerServiceUUIDDiscovery(void);
rgrover1 290:83c994bf62d0 88 void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
rgrover1 290:83c994bf62d0 89 void removeFirstServiceNeedingUUIDDiscovery(void);
rgrover1 290:83c994bf62d0 90
rgrover1 248:71ef03789dd3 91 void terminateServiceDiscovery(void) {
rgrover1 280:cbaa4cb83548 92 bool wasActive = isActive();
rgrover1 286:042b01e59cf8 93 state = INACTIVE;
rgrover1 280:cbaa4cb83548 94
rgrover1 280:cbaa4cb83548 95 if (wasActive && onTerminationCallback) {
rgrover1 280:cbaa4cb83548 96 onTerminationCallback(connHandle);
rgrover1 280:cbaa4cb83548 97 }
rgrover1 239:693a1f145b5a 98 }
rgrover1 239:693a1f145b5a 99
rgrover1 245:3abc61d38db3 100 void terminateCharacteristicDiscovery(void) {
rgrover1 286:042b01e59cf8 101 if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
rgrover1 286:042b01e59cf8 102 state = SERVICE_DISCOVERY_ACTIVE;
rgrover1 286:042b01e59cf8 103 }
rgrover1 245:3abc61d38db3 104 serviceIndex++; /* Progress service index to keep discovery alive. */
rgrover1 245:3abc61d38db3 105 }
rgrover1 245:3abc61d38db3 106
rgrover1 279:6e5e79f1fb61 107 bool isActive(void) const {
rgrover1 286:042b01e59cf8 108 return state != INACTIVE;
rgrover1 279:6e5e79f1fb61 109 }
rgrover1 279:6e5e79f1fb61 110
rgrover1 280:cbaa4cb83548 111 void setOnTermination(TerminationCallback_t callback) {
rgrover1 280:cbaa4cb83548 112 onTerminationCallback = callback;
rgrover1 280:cbaa4cb83548 113 }
rgrover1 280:cbaa4cb83548 114
rgrover1 260:ea2798f615e5 115 private:
rgrover1 239:693a1f145b5a 116 void resetDiscoveredServices(void) {
rgrover1 242:73fc02cc20b1 117 numServices = 0;
rgrover1 242:73fc02cc20b1 118 serviceIndex = 0;
rgrover1 239:693a1f145b5a 119 memset(services, 0, sizeof(DiscoveredService) * BLE_DB_DISCOVERY_MAX_SRV);
rgrover1 239:693a1f145b5a 120 }
rgrover1 239:693a1f145b5a 121
rgrover1 245:3abc61d38db3 122 void resetDiscoveredCharacteristics(void) {
rgrover1 245:3abc61d38db3 123 numCharacteristics = 0;
rgrover1 245:3abc61d38db3 124 characteristicIndex = 0;
rgrover1 245:3abc61d38db3 125 memset(characteristics, 0, sizeof(DiscoveredCharacteristic) * BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV);
rgrover1 245:3abc61d38db3 126 }
rgrover1 245:3abc61d38db3 127
rgrover1 245:3abc61d38db3 128 public:
rgrover1 243:a966506d1e5b 129 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 291:d7590ed48009 130 connHandle = connectionHandle;
rgrover1 243:a966506d1e5b 131 resetDiscoveredServices();
rgrover1 286:042b01e59cf8 132 state = SERVICE_DISCOVERY_ACTIVE;
rgrover1 243:a966506d1e5b 133 }
rgrover1 243:a966506d1e5b 134
rgrover1 260:ea2798f615e5 135 private:
rgrover1 245:3abc61d38db3 136 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 291:d7590ed48009 137 connHandle = connectionHandle;
rgrover1 245:3abc61d38db3 138 resetDiscoveredCharacteristics();
rgrover1 286:042b01e59cf8 139 state = CHARACTERISTIC_DISCOVERY_ACTIVE;
rgrover1 245:3abc61d38db3 140 }
rgrover1 245:3abc61d38db3 141
rgrover1 251:d4e0cf5e8751 142 private:
rgrover1 293:cd86acfe41be 143 /**
rgrover1 293:cd86acfe41be 144 * A datatype to contain service-indices for which long UUIDs need to be
rgrover1 293:cd86acfe41be 145 * discovered using read_val_by_uuid().
rgrover1 293:cd86acfe41be 146 */
rgrover1 305:293634834813 147 class ServiceUUIDDiscoveryQueue {
rgrover1 292:01b717803437 148 public:
rgrover1 305:293634834813 149 ServiceUUIDDiscoveryQueue(NordicServiceDiscovery *parent) :
rgrover1 292:01b717803437 150 numIndices(0),
rgrover1 292:01b717803437 151 serviceIndices(),
rgrover1 301:59e7404a4ea3 152 parentDiscoveryObject(parent) {
rgrover1 292:01b717803437 153 /* empty */
rgrover1 292:01b717803437 154 }
rgrover1 292:01b717803437 155
rgrover1 292:01b717803437 156 public:
rgrover1 292:01b717803437 157 void reset(void) {
rgrover1 292:01b717803437 158 numIndices = 0;
rgrover1 304:8677dcdb218d 159 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
rgrover1 304:8677dcdb218d 160 serviceIndices[i] = INVALID_INDEX;
rgrover1 292:01b717803437 161 }
rgrover1 292:01b717803437 162 }
rgrover1 299:19064275c0e0 163 void enqueue(int serviceIndex) {
rgrover1 292:01b717803437 164 serviceIndices[numIndices++] = serviceIndex;
rgrover1 292:01b717803437 165 }
rgrover1 299:19064275c0e0 166 int dequeue(void) {
rgrover1 299:19064275c0e0 167 if (numIndices == 0) {
rgrover1 304:8677dcdb218d 168 return INVALID_INDEX;
rgrover1 299:19064275c0e0 169 }
rgrover1 299:19064275c0e0 170
rgrover1 299:19064275c0e0 171 unsigned valueToReturn = serviceIndices[0];
rgrover1 292:01b717803437 172 numIndices--;
rgrover1 299:19064275c0e0 173 for (unsigned i = 0; i < numIndices; i++) {
rgrover1 299:19064275c0e0 174 serviceIndices[i] = serviceIndices[i + 1];
rgrover1 292:01b717803437 175 }
rgrover1 299:19064275c0e0 176
rgrover1 299:19064275c0e0 177 return valueToReturn;
rgrover1 292:01b717803437 178 }
rgrover1 302:507e99065379 179 unsigned getFirst(void) const {
rgrover1 302:507e99065379 180 return serviceIndices[0];
rgrover1 302:507e99065379 181 }
rgrover1 292:01b717803437 182 size_t getCount(void) const {
rgrover1 292:01b717803437 183 return numIndices;
rgrover1 292:01b717803437 184 }
rgrover1 292:01b717803437 185
rgrover1 303:697d18859583 186 /**
rgrover1 303:697d18859583 187 * Trigger UUID discovery for the first of the enqueued ServiceIndices.
rgrover1 303:697d18859583 188 */
rgrover1 292:01b717803437 189 void triggerFirst(void);
rgrover1 292:01b717803437 190
rgrover1 292:01b717803437 191 private:
rgrover1 304:8677dcdb218d 192 static const int INVALID_INDEX = -1;
rgrover1 292:01b717803437 193
rgrover1 292:01b717803437 194 private:
rgrover1 292:01b717803437 195 size_t numIndices;
rgrover1 292:01b717803437 196 int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV];
rgrover1 292:01b717803437 197
rgrover1 301:59e7404a4ea3 198 NordicServiceDiscovery *parentDiscoveryObject;
rgrover1 292:01b717803437 199 };
rgrover1 305:293634834813 200 friend class ServiceUUIDDiscoveryQueue;
rgrover1 292:01b717803437 201
rgrover1 306:76e2e7349319 202 /**
rgrover1 306:76e2e7349319 203 * A datatype to contain characteristic-indices for which long UUIDs need to
rgrover1 306:76e2e7349319 204 * be discovered using read_val_by_uuid().
rgrover1 306:76e2e7349319 205 */
rgrover1 306:76e2e7349319 206 class CharUUIDDiscoveryQueue {
rgrover1 306:76e2e7349319 207 public:
rgrover1 306:76e2e7349319 208 CharUUIDDiscoveryQueue(NordicServiceDiscovery *parent) :
rgrover1 306:76e2e7349319 209 numIndices(0),
rgrover1 306:76e2e7349319 210 charIndices(),
rgrover1 306:76e2e7349319 211 parentDiscoveryObject(parent) {
rgrover1 306:76e2e7349319 212 /* empty */
rgrover1 306:76e2e7349319 213 }
rgrover1 306:76e2e7349319 214
rgrover1 306:76e2e7349319 215 public:
rgrover1 306:76e2e7349319 216 void reset(void) {
rgrover1 306:76e2e7349319 217 numIndices = 0;
rgrover1 306:76e2e7349319 218 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
rgrover1 306:76e2e7349319 219 charIndices[i] = INVALID_INDEX;
rgrover1 306:76e2e7349319 220 }
rgrover1 306:76e2e7349319 221 }
rgrover1 306:76e2e7349319 222 void enqueue(int serviceIndex) {
rgrover1 306:76e2e7349319 223 charIndices[numIndices++] = serviceIndex;
rgrover1 306:76e2e7349319 224 }
rgrover1 306:76e2e7349319 225 int dequeue(void) {
rgrover1 306:76e2e7349319 226 if (numIndices == 0) {
rgrover1 306:76e2e7349319 227 return INVALID_INDEX;
rgrover1 306:76e2e7349319 228 }
rgrover1 306:76e2e7349319 229
rgrover1 306:76e2e7349319 230 unsigned valueToReturn = charIndices[0];
rgrover1 306:76e2e7349319 231 numIndices--;
rgrover1 306:76e2e7349319 232 for (unsigned i = 0; i < numIndices; i++) {
rgrover1 306:76e2e7349319 233 charIndices[i] = charIndices[i + 1];
rgrover1 306:76e2e7349319 234 }
rgrover1 306:76e2e7349319 235
rgrover1 306:76e2e7349319 236 return valueToReturn;
rgrover1 306:76e2e7349319 237 }
rgrover1 306:76e2e7349319 238 unsigned getFirst(void) const {
rgrover1 306:76e2e7349319 239 return charIndices[0];
rgrover1 306:76e2e7349319 240 }
rgrover1 306:76e2e7349319 241 size_t getCount(void) const {
rgrover1 306:76e2e7349319 242 return numIndices;
rgrover1 306:76e2e7349319 243 }
rgrover1 306:76e2e7349319 244
rgrover1 306:76e2e7349319 245 /**
rgrover1 306:76e2e7349319 246 * Trigger UUID discovery for the first of the enqueued charIndices.
rgrover1 306:76e2e7349319 247 */
rgrover1 306:76e2e7349319 248 void triggerFirst(void);
rgrover1 306:76e2e7349319 249
rgrover1 306:76e2e7349319 250 private:
rgrover1 306:76e2e7349319 251 static const int INVALID_INDEX = -1;
rgrover1 306:76e2e7349319 252
rgrover1 306:76e2e7349319 253 private:
rgrover1 306:76e2e7349319 254 size_t numIndices;
rgrover1 306:76e2e7349319 255 int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 306:76e2e7349319 256
rgrover1 306:76e2e7349319 257 NordicServiceDiscovery *parentDiscoveryObject;
rgrover1 306:76e2e7349319 258 };
rgrover1 306:76e2e7349319 259 friend class CharUUIDDiscoveryQueue;
rgrover1 306:76e2e7349319 260
rgrover1 292:01b717803437 261 private:
rgrover1 251:d4e0cf5e8751 262 friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
rgrover1 251:d4e0cf5e8751 263 void progressCharacteristicDiscovery(void);
rgrover1 251:d4e0cf5e8751 264 void progressServiceDiscovery(void);
rgrover1 239:693a1f145b5a 265
rgrover1 248:71ef03789dd3 266 private:
rgrover1 248:71ef03789dd3 267 uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
rgrover1 248:71ef03789dd3 268 uint8_t numServices; /**< Number of services at the peers GATT database.*/
rgrover1 248:71ef03789dd3 269 uint8_t characteristicIndex; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
rgrover1 248:71ef03789dd3 270 uint8_t numCharacteristics; /**< Number of characteristics within the service.*/
rgrover1 248:71ef03789dd3 271
rgrover1 286:042b01e59cf8 272 enum State_t {
rgrover1 286:042b01e59cf8 273 INACTIVE,
rgrover1 286:042b01e59cf8 274 SERVICE_DISCOVERY_ACTIVE,
rgrover1 286:042b01e59cf8 275 CHARACTERISTIC_DISCOVERY_ACTIVE,
rgrover1 290:83c994bf62d0 276 DISCOVER_SERVICE_UUIDS,
rgrover1 306:76e2e7349319 277 DISCOVER_CHARACTERISTIC_UUIDS,
rgrover1 286:042b01e59cf8 278 } state;
rgrover1 248:71ef03789dd3 279
rgrover1 308:482f16f3f7f5 280 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
rgrover1 308:482f16f3f7f5 281 * This is intended for internal use during service discovery. */
rgrover1 308:482f16f3f7f5 282 nRFDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 280:cbaa4cb83548 283
rgrover1 308:482f16f3f7f5 284 ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue;
rgrover1 308:482f16f3f7f5 285 CharUUIDDiscoveryQueue charUUIDDiscoveryQueue;
rgrover1 292:01b717803437 286
rgrover1 308:482f16f3f7f5 287 TerminationCallback_t onTerminationCallback;
rgrover1 240:75b69581d1dd 288 };
rgrover1 240:75b69581d1dd 289
rgrover1 239:693a1f145b5a 290 #endif /*_BTLE_DISCOVERY_H_*/