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:
311:5d5abc30e3a8
Parent:
310:4d7ccb8c2a51
Child:
312:d55797e0d632
Synchronized with git rev 12ed0b38
Author: Rohit Grover
move variants of setup into nRFDiscoveredCharacteristic.

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 311:5d5abc30e3a8 27 void setup(Gap::Handle_t connectionHandleIn,
rgrover1 311:5d5abc30e3a8 28 Properties_t propsIn,
rgrover1 311:5d5abc30e3a8 29 GattAttribute::Handle_t declHandleIn,
rgrover1 311:5d5abc30e3a8 30 GattAttribute::Handle_t valueHandleIn) {
rgrover1 311:5d5abc30e3a8 31 connHandle = connectionHandleIn;
rgrover1 311:5d5abc30e3a8 32 props = propsIn;
rgrover1 311:5d5abc30e3a8 33 declHandle = declHandleIn;
rgrover1 311:5d5abc30e3a8 34 valueHandle = valueHandleIn;
rgrover1 311:5d5abc30e3a8 35 }
rgrover1 311:5d5abc30e3a8 36
rgrover1 311:5d5abc30e3a8 37 void setup(Gap::Handle_t connectionHandleIn,
rgrover1 311:5d5abc30e3a8 38 UUID::ShortUUIDBytes_t uuidIn,
rgrover1 311:5d5abc30e3a8 39 Properties_t propsIn,
rgrover1 311:5d5abc30e3a8 40 GattAttribute::Handle_t declHandleIn,
rgrover1 311:5d5abc30e3a8 41 GattAttribute::Handle_t valueHandleIn) {
rgrover1 311:5d5abc30e3a8 42 connHandle = connectionHandleIn;
rgrover1 311:5d5abc30e3a8 43 uuid = uuidIn;
rgrover1 311:5d5abc30e3a8 44 props = propsIn;
rgrover1 311:5d5abc30e3a8 45 declHandle = declHandleIn;
rgrover1 311:5d5abc30e3a8 46 valueHandle = valueHandleIn;
rgrover1 311:5d5abc30e3a8 47 }
rgrover1 311:5d5abc30e3a8 48
rgrover1 311:5d5abc30e3a8 49 public:
rgrover1 308:482f16f3f7f5 50 /**
rgrover1 308:482f16f3f7f5 51 * Initiate (or continue) a read for the value attribute, optionally at a
rgrover1 308:482f16f3f7f5 52 * given offset. If the Characteristic or Descriptor to be read is longer
rgrover1 308:482f16f3f7f5 53 * than ATT_MTU - 1, this function must be called multiple times with
rgrover1 308:482f16f3f7f5 54 * appropriate offset to read the complete value.
rgrover1 310:4d7ccb8c2a51 55 *
rgrover1 310:4d7ccb8c2a51 56 * @return BLE_ERROR_NONE if a read has been initiated, else
rgrover1 310:4d7ccb8c2a51 57 * BLE_ERROR_INVALID_STATE if some internal state about the connection is invalid, or
rgrover1 310:4d7ccb8c2a51 58 * BLE_STACK_BUSY if some client procedure already in progress.
rgrover1 308:482f16f3f7f5 59 */
rgrover1 309:ef9e806a7b03 60 virtual ble_error_t read(uint16_t offset = 0) {
rgrover1 308:482f16f3f7f5 61 // sd_ble_gattc_read()
rgrover1 308:482f16f3f7f5 62 // SVCALL(SD_BLE_GATTC_READ, uint32_t, sd_ble_gattc_read(uint16_t conn_handle, uint16_t handle, uint16_t offset));
rgrover1 309:ef9e806a7b03 63 return BLE_ERROR_NONE;
rgrover1 308:482f16f3f7f5 64 }
rgrover1 308:482f16f3f7f5 65 };
rgrover1 308:482f16f3f7f5 66
rgrover1 250:db3c51656388 67 class NordicServiceDiscovery : public ServiceDiscovery
rgrover1 250:db3c51656388 68 {
rgrover1 248:71ef03789dd3 69 public:
rgrover1 260:ea2798f615e5 70 static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */
rgrover1 284:29fb6af6671d 71 static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */
rgrover1 260:ea2798f615e5 72
rgrover1 289:b33301b019e6 73 public:
rgrover1 248:71ef03789dd3 74 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 75 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 76
rgrover1 260:ea2798f615e5 77 public:
rgrover1 288:1d85c4a4d397 78 NordicServiceDiscovery() : serviceIndex(0),
rgrover1 288:1d85c4a4d397 79 numServices(0),
rgrover1 288:1d85c4a4d397 80 characteristicIndex(0),
rgrover1 288:1d85c4a4d397 81 numCharacteristics(0),
rgrover1 288:1d85c4a4d397 82 state(INACTIVE),
rgrover1 288:1d85c4a4d397 83 services(),
rgrover1 288:1d85c4a4d397 84 characteristics(),
rgrover1 305:293634834813 85 serviceUUIDDiscoveryQueue(this),
rgrover1 306:76e2e7349319 86 charUUIDDiscoveryQueue(this),
rgrover1 288:1d85c4a4d397 87 onTerminationCallback(NULL) {
rgrover1 288:1d85c4a4d397 88 /* empty */
rgrover1 288:1d85c4a4d397 89 }
rgrover1 288:1d85c4a4d397 90
rgrover1 288:1d85c4a4d397 91 public:
rgrover1 260:ea2798f615e5 92 ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
rgrover1 239:693a1f145b5a 93
rgrover1 239:693a1f145b5a 94 public:
rgrover1 248:71ef03789dd3 95 void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
rgrover1 248:71ef03789dd3 96 void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
rgrover1 248:71ef03789dd3 97
rgrover1 290:83c994bf62d0 98 void triggerServiceUUIDDiscovery(void);
rgrover1 290:83c994bf62d0 99 void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
rgrover1 290:83c994bf62d0 100 void removeFirstServiceNeedingUUIDDiscovery(void);
rgrover1 290:83c994bf62d0 101
rgrover1 248:71ef03789dd3 102 void terminateServiceDiscovery(void) {
rgrover1 280:cbaa4cb83548 103 bool wasActive = isActive();
rgrover1 286:042b01e59cf8 104 state = INACTIVE;
rgrover1 280:cbaa4cb83548 105
rgrover1 280:cbaa4cb83548 106 if (wasActive && onTerminationCallback) {
rgrover1 280:cbaa4cb83548 107 onTerminationCallback(connHandle);
rgrover1 280:cbaa4cb83548 108 }
rgrover1 239:693a1f145b5a 109 }
rgrover1 239:693a1f145b5a 110
rgrover1 245:3abc61d38db3 111 void terminateCharacteristicDiscovery(void) {
rgrover1 286:042b01e59cf8 112 if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
rgrover1 286:042b01e59cf8 113 state = SERVICE_DISCOVERY_ACTIVE;
rgrover1 286:042b01e59cf8 114 }
rgrover1 245:3abc61d38db3 115 serviceIndex++; /* Progress service index to keep discovery alive. */
rgrover1 245:3abc61d38db3 116 }
rgrover1 245:3abc61d38db3 117
rgrover1 279:6e5e79f1fb61 118 bool isActive(void) const {
rgrover1 286:042b01e59cf8 119 return state != INACTIVE;
rgrover1 279:6e5e79f1fb61 120 }
rgrover1 279:6e5e79f1fb61 121
rgrover1 280:cbaa4cb83548 122 void setOnTermination(TerminationCallback_t callback) {
rgrover1 280:cbaa4cb83548 123 onTerminationCallback = callback;
rgrover1 280:cbaa4cb83548 124 }
rgrover1 280:cbaa4cb83548 125
rgrover1 260:ea2798f615e5 126 private:
rgrover1 239:693a1f145b5a 127 void resetDiscoveredServices(void) {
rgrover1 242:73fc02cc20b1 128 numServices = 0;
rgrover1 242:73fc02cc20b1 129 serviceIndex = 0;
rgrover1 239:693a1f145b5a 130 memset(services, 0, sizeof(DiscoveredService) * BLE_DB_DISCOVERY_MAX_SRV);
rgrover1 239:693a1f145b5a 131 }
rgrover1 239:693a1f145b5a 132
rgrover1 245:3abc61d38db3 133 void resetDiscoveredCharacteristics(void) {
rgrover1 245:3abc61d38db3 134 numCharacteristics = 0;
rgrover1 245:3abc61d38db3 135 characteristicIndex = 0;
rgrover1 245:3abc61d38db3 136 memset(characteristics, 0, sizeof(DiscoveredCharacteristic) * BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV);
rgrover1 245:3abc61d38db3 137 }
rgrover1 245:3abc61d38db3 138
rgrover1 245:3abc61d38db3 139 public:
rgrover1 243:a966506d1e5b 140 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 291:d7590ed48009 141 connHandle = connectionHandle;
rgrover1 243:a966506d1e5b 142 resetDiscoveredServices();
rgrover1 286:042b01e59cf8 143 state = SERVICE_DISCOVERY_ACTIVE;
rgrover1 243:a966506d1e5b 144 }
rgrover1 243:a966506d1e5b 145
rgrover1 260:ea2798f615e5 146 private:
rgrover1 245:3abc61d38db3 147 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 291:d7590ed48009 148 connHandle = connectionHandle;
rgrover1 245:3abc61d38db3 149 resetDiscoveredCharacteristics();
rgrover1 286:042b01e59cf8 150 state = CHARACTERISTIC_DISCOVERY_ACTIVE;
rgrover1 245:3abc61d38db3 151 }
rgrover1 245:3abc61d38db3 152
rgrover1 251:d4e0cf5e8751 153 private:
rgrover1 293:cd86acfe41be 154 /**
rgrover1 293:cd86acfe41be 155 * A datatype to contain service-indices for which long UUIDs need to be
rgrover1 293:cd86acfe41be 156 * discovered using read_val_by_uuid().
rgrover1 293:cd86acfe41be 157 */
rgrover1 305:293634834813 158 class ServiceUUIDDiscoveryQueue {
rgrover1 292:01b717803437 159 public:
rgrover1 305:293634834813 160 ServiceUUIDDiscoveryQueue(NordicServiceDiscovery *parent) :
rgrover1 292:01b717803437 161 numIndices(0),
rgrover1 292:01b717803437 162 serviceIndices(),
rgrover1 301:59e7404a4ea3 163 parentDiscoveryObject(parent) {
rgrover1 292:01b717803437 164 /* empty */
rgrover1 292:01b717803437 165 }
rgrover1 292:01b717803437 166
rgrover1 292:01b717803437 167 public:
rgrover1 292:01b717803437 168 void reset(void) {
rgrover1 292:01b717803437 169 numIndices = 0;
rgrover1 304:8677dcdb218d 170 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
rgrover1 304:8677dcdb218d 171 serviceIndices[i] = INVALID_INDEX;
rgrover1 292:01b717803437 172 }
rgrover1 292:01b717803437 173 }
rgrover1 299:19064275c0e0 174 void enqueue(int serviceIndex) {
rgrover1 292:01b717803437 175 serviceIndices[numIndices++] = serviceIndex;
rgrover1 292:01b717803437 176 }
rgrover1 299:19064275c0e0 177 int dequeue(void) {
rgrover1 299:19064275c0e0 178 if (numIndices == 0) {
rgrover1 304:8677dcdb218d 179 return INVALID_INDEX;
rgrover1 299:19064275c0e0 180 }
rgrover1 299:19064275c0e0 181
rgrover1 299:19064275c0e0 182 unsigned valueToReturn = serviceIndices[0];
rgrover1 292:01b717803437 183 numIndices--;
rgrover1 299:19064275c0e0 184 for (unsigned i = 0; i < numIndices; i++) {
rgrover1 299:19064275c0e0 185 serviceIndices[i] = serviceIndices[i + 1];
rgrover1 292:01b717803437 186 }
rgrover1 299:19064275c0e0 187
rgrover1 299:19064275c0e0 188 return valueToReturn;
rgrover1 292:01b717803437 189 }
rgrover1 302:507e99065379 190 unsigned getFirst(void) const {
rgrover1 302:507e99065379 191 return serviceIndices[0];
rgrover1 302:507e99065379 192 }
rgrover1 292:01b717803437 193 size_t getCount(void) const {
rgrover1 292:01b717803437 194 return numIndices;
rgrover1 292:01b717803437 195 }
rgrover1 292:01b717803437 196
rgrover1 303:697d18859583 197 /**
rgrover1 303:697d18859583 198 * Trigger UUID discovery for the first of the enqueued ServiceIndices.
rgrover1 303:697d18859583 199 */
rgrover1 292:01b717803437 200 void triggerFirst(void);
rgrover1 292:01b717803437 201
rgrover1 292:01b717803437 202 private:
rgrover1 304:8677dcdb218d 203 static const int INVALID_INDEX = -1;
rgrover1 292:01b717803437 204
rgrover1 292:01b717803437 205 private:
rgrover1 292:01b717803437 206 size_t numIndices;
rgrover1 292:01b717803437 207 int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV];
rgrover1 292:01b717803437 208
rgrover1 301:59e7404a4ea3 209 NordicServiceDiscovery *parentDiscoveryObject;
rgrover1 292:01b717803437 210 };
rgrover1 305:293634834813 211 friend class ServiceUUIDDiscoveryQueue;
rgrover1 292:01b717803437 212
rgrover1 306:76e2e7349319 213 /**
rgrover1 306:76e2e7349319 214 * A datatype to contain characteristic-indices for which long UUIDs need to
rgrover1 306:76e2e7349319 215 * be discovered using read_val_by_uuid().
rgrover1 306:76e2e7349319 216 */
rgrover1 306:76e2e7349319 217 class CharUUIDDiscoveryQueue {
rgrover1 306:76e2e7349319 218 public:
rgrover1 306:76e2e7349319 219 CharUUIDDiscoveryQueue(NordicServiceDiscovery *parent) :
rgrover1 306:76e2e7349319 220 numIndices(0),
rgrover1 306:76e2e7349319 221 charIndices(),
rgrover1 306:76e2e7349319 222 parentDiscoveryObject(parent) {
rgrover1 306:76e2e7349319 223 /* empty */
rgrover1 306:76e2e7349319 224 }
rgrover1 306:76e2e7349319 225
rgrover1 306:76e2e7349319 226 public:
rgrover1 306:76e2e7349319 227 void reset(void) {
rgrover1 306:76e2e7349319 228 numIndices = 0;
rgrover1 306:76e2e7349319 229 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
rgrover1 306:76e2e7349319 230 charIndices[i] = INVALID_INDEX;
rgrover1 306:76e2e7349319 231 }
rgrover1 306:76e2e7349319 232 }
rgrover1 306:76e2e7349319 233 void enqueue(int serviceIndex) {
rgrover1 306:76e2e7349319 234 charIndices[numIndices++] = serviceIndex;
rgrover1 306:76e2e7349319 235 }
rgrover1 306:76e2e7349319 236 int dequeue(void) {
rgrover1 306:76e2e7349319 237 if (numIndices == 0) {
rgrover1 306:76e2e7349319 238 return INVALID_INDEX;
rgrover1 306:76e2e7349319 239 }
rgrover1 306:76e2e7349319 240
rgrover1 306:76e2e7349319 241 unsigned valueToReturn = charIndices[0];
rgrover1 306:76e2e7349319 242 numIndices--;
rgrover1 306:76e2e7349319 243 for (unsigned i = 0; i < numIndices; i++) {
rgrover1 306:76e2e7349319 244 charIndices[i] = charIndices[i + 1];
rgrover1 306:76e2e7349319 245 }
rgrover1 306:76e2e7349319 246
rgrover1 306:76e2e7349319 247 return valueToReturn;
rgrover1 306:76e2e7349319 248 }
rgrover1 306:76e2e7349319 249 unsigned getFirst(void) const {
rgrover1 306:76e2e7349319 250 return charIndices[0];
rgrover1 306:76e2e7349319 251 }
rgrover1 306:76e2e7349319 252 size_t getCount(void) const {
rgrover1 306:76e2e7349319 253 return numIndices;
rgrover1 306:76e2e7349319 254 }
rgrover1 306:76e2e7349319 255
rgrover1 306:76e2e7349319 256 /**
rgrover1 306:76e2e7349319 257 * Trigger UUID discovery for the first of the enqueued charIndices.
rgrover1 306:76e2e7349319 258 */
rgrover1 306:76e2e7349319 259 void triggerFirst(void);
rgrover1 306:76e2e7349319 260
rgrover1 306:76e2e7349319 261 private:
rgrover1 306:76e2e7349319 262 static const int INVALID_INDEX = -1;
rgrover1 306:76e2e7349319 263
rgrover1 306:76e2e7349319 264 private:
rgrover1 306:76e2e7349319 265 size_t numIndices;
rgrover1 306:76e2e7349319 266 int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 306:76e2e7349319 267
rgrover1 306:76e2e7349319 268 NordicServiceDiscovery *parentDiscoveryObject;
rgrover1 306:76e2e7349319 269 };
rgrover1 306:76e2e7349319 270 friend class CharUUIDDiscoveryQueue;
rgrover1 306:76e2e7349319 271
rgrover1 292:01b717803437 272 private:
rgrover1 251:d4e0cf5e8751 273 friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
rgrover1 251:d4e0cf5e8751 274 void progressCharacteristicDiscovery(void);
rgrover1 251:d4e0cf5e8751 275 void progressServiceDiscovery(void);
rgrover1 239:693a1f145b5a 276
rgrover1 248:71ef03789dd3 277 private:
rgrover1 248:71ef03789dd3 278 uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
rgrover1 248:71ef03789dd3 279 uint8_t numServices; /**< Number of services at the peers GATT database.*/
rgrover1 248:71ef03789dd3 280 uint8_t characteristicIndex; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
rgrover1 248:71ef03789dd3 281 uint8_t numCharacteristics; /**< Number of characteristics within the service.*/
rgrover1 248:71ef03789dd3 282
rgrover1 286:042b01e59cf8 283 enum State_t {
rgrover1 286:042b01e59cf8 284 INACTIVE,
rgrover1 286:042b01e59cf8 285 SERVICE_DISCOVERY_ACTIVE,
rgrover1 286:042b01e59cf8 286 CHARACTERISTIC_DISCOVERY_ACTIVE,
rgrover1 290:83c994bf62d0 287 DISCOVER_SERVICE_UUIDS,
rgrover1 306:76e2e7349319 288 DISCOVER_CHARACTERISTIC_UUIDS,
rgrover1 286:042b01e59cf8 289 } state;
rgrover1 248:71ef03789dd3 290
rgrover1 308:482f16f3f7f5 291 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
rgrover1 308:482f16f3f7f5 292 * This is intended for internal use during service discovery. */
rgrover1 308:482f16f3f7f5 293 nRFDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 280:cbaa4cb83548 294
rgrover1 308:482f16f3f7f5 295 ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue;
rgrover1 308:482f16f3f7f5 296 CharUUIDDiscoveryQueue charUUIDDiscoveryQueue;
rgrover1 292:01b717803437 297
rgrover1 308:482f16f3f7f5 298 TerminationCallback_t onTerminationCallback;
rgrover1 240:75b69581d1dd 299 };
rgrover1 240:75b69581d1dd 300
rgrover1 239:693a1f145b5a 301 #endif /*_BTLE_DISCOVERY_H_*/