Michael Galis / nRF51822

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Fri Jun 19 15:55:32 2015 +0100
Revision:
332:b054000833d4
Parent:
331:352bc4a36ea0
Child:
333:8eedcd324853
Synchronized with git rev 5a4e62f1
Author: Rohit Grover
one massive commit to integrate with GattClient.
DiscoveredCharacteristic still needs to setup gattc pointers.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 331:352bc4a36ea0 1 /* mbed Microcontroller Library
rgrover1 331:352bc4a36ea0 2 * Copyright (c) 2006-2013 ARM Limited
rgrover1 331:352bc4a36ea0 3 *
rgrover1 331:352bc4a36ea0 4 * Licensed under the Apache License, Version 2.0 (the "License");
rgrover1 331:352bc4a36ea0 5 * you may not use this file except in compliance with the License.
rgrover1 331:352bc4a36ea0 6 * You may obtain a copy of the License at
rgrover1 331:352bc4a36ea0 7 *
rgrover1 331:352bc4a36ea0 8 * http://www.apache.org/licenses/LICENSE-2.0
rgrover1 331:352bc4a36ea0 9 *
rgrover1 331:352bc4a36ea0 10 * Unless required by applicable law or agreed to in writing, software
rgrover1 331:352bc4a36ea0 11 * distributed under the License is distributed on an "AS IS" BASIS,
rgrover1 331:352bc4a36ea0 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
rgrover1 331:352bc4a36ea0 13 * See the License for the specific language governing permissions and
rgrover1 331:352bc4a36ea0 14 * limitations under the License.
rgrover1 331:352bc4a36ea0 15 */
rgrover1 331:352bc4a36ea0 16
rgrover1 331:352bc4a36ea0 17 #ifndef __NRF_SERVICE_DISCOVERY_H__
rgrover1 331:352bc4a36ea0 18 #define __NRF_SERVICE_DISCOVERY_H__
rgrover1 331:352bc4a36ea0 19
rgrover1 331:352bc4a36ea0 20 #include "ServiceDiscovery.h"
rgrover1 331:352bc4a36ea0 21 #include "nRFDiscoveredCharacteristic.h"
rgrover1 331:352bc4a36ea0 22
rgrover1 332:b054000833d4 23 #include "ble.h"
rgrover1 332:b054000833d4 24 #include "ble_gattc.h"
rgrover1 331:352bc4a36ea0 25
rgrover1 331:352bc4a36ea0 26 class nRFServiceDiscovery : public ServiceDiscovery
rgrover1 331:352bc4a36ea0 27 {
rgrover1 331:352bc4a36ea0 28 public:
rgrover1 331:352bc4a36ea0 29 static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */
rgrover1 331:352bc4a36ea0 30 static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */
rgrover1 331:352bc4a36ea0 31
rgrover1 331:352bc4a36ea0 32 public:
rgrover1 331:352bc4a36ea0 33 static const unsigned BLE_DB_DISCOVERY_MAX_SRV = 4; /**< Maximum number of services we can retain information for after a single discovery. */
rgrover1 331:352bc4a36ea0 34 static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service we can retain information for. */
rgrover1 331:352bc4a36ea0 35
rgrover1 331:352bc4a36ea0 36 public:
rgrover1 331:352bc4a36ea0 37 nRFServiceDiscovery() : serviceIndex(0),
rgrover1 332:b054000833d4 38 numServices(0),
rgrover1 332:b054000833d4 39 characteristicIndex(0),
rgrover1 332:b054000833d4 40 numCharacteristics(0),
rgrover1 332:b054000833d4 41 state(INACTIVE),
rgrover1 332:b054000833d4 42 services(),
rgrover1 332:b054000833d4 43 characteristics(),
rgrover1 332:b054000833d4 44 serviceUUIDDiscoveryQueue(this),
rgrover1 332:b054000833d4 45 charUUIDDiscoveryQueue(this),
rgrover1 332:b054000833d4 46 onTerminationCallback(NULL) {
rgrover1 331:352bc4a36ea0 47 /* empty */
rgrover1 331:352bc4a36ea0 48 }
rgrover1 331:352bc4a36ea0 49
rgrover1 332:b054000833d4 50 virtual ble_error_t launch(Gap::Handle_t connectionHandle,
rgrover1 332:b054000833d4 51 ServiceDiscovery::ServiceCallback_t sc,
rgrover1 332:b054000833d4 52 ServiceDiscovery::CharacteristicCallback_t cc,
rgrover1 332:b054000833d4 53 const UUID &matchingServiceUUIDIn,
rgrover1 332:b054000833d4 54 const UUID &matchingCharacteristicUUIDIn)
rgrover1 332:b054000833d4 55 {
rgrover1 332:b054000833d4 56 if (isActive()) {
rgrover1 332:b054000833d4 57 return BLE_ERROR_INVALID_STATE;
rgrover1 332:b054000833d4 58 }
rgrover1 332:b054000833d4 59
rgrover1 332:b054000833d4 60 serviceCallback = sc;
rgrover1 332:b054000833d4 61 characteristicCallback = cc;
rgrover1 332:b054000833d4 62 matchingServiceUUID = matchingServiceUUIDIn;
rgrover1 332:b054000833d4 63 matchingCharacteristicUUID = matchingCharacteristicUUIDIn;
rgrover1 332:b054000833d4 64
rgrover1 332:b054000833d4 65 serviceDiscoveryStarted(connectionHandle);
rgrover1 332:b054000833d4 66
rgrover1 332:b054000833d4 67 uint32_t rc;
rgrover1 332:b054000833d4 68 if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) {
rgrover1 332:b054000833d4 69 terminate();
rgrover1 332:b054000833d4 70 switch (rc) {
rgrover1 332:b054000833d4 71 case NRF_ERROR_INVALID_PARAM:
rgrover1 332:b054000833d4 72 case BLE_ERROR_INVALID_CONN_HANDLE:
rgrover1 332:b054000833d4 73 return BLE_ERROR_INVALID_PARAM;
rgrover1 332:b054000833d4 74 case NRF_ERROR_BUSY:
rgrover1 332:b054000833d4 75 return BLE_STACK_BUSY;
rgrover1 332:b054000833d4 76 default:
rgrover1 332:b054000833d4 77 case NRF_ERROR_INVALID_STATE:
rgrover1 332:b054000833d4 78 return BLE_ERROR_INVALID_STATE;
rgrover1 332:b054000833d4 79 }
rgrover1 332:b054000833d4 80 }
rgrover1 332:b054000833d4 81
rgrover1 332:b054000833d4 82 return BLE_ERROR_NONE;
rgrover1 332:b054000833d4 83 }
rgrover1 332:b054000833d4 84
rgrover1 332:b054000833d4 85 virtual bool isActive(void) const {
rgrover1 332:b054000833d4 86 return state != INACTIVE;
rgrover1 332:b054000833d4 87 }
rgrover1 332:b054000833d4 88
rgrover1 332:b054000833d4 89 virtual void terminate(void) {
rgrover1 332:b054000833d4 90 terminateServiceDiscovery();
rgrover1 332:b054000833d4 91 }
rgrover1 332:b054000833d4 92
rgrover1 332:b054000833d4 93 virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) {
rgrover1 332:b054000833d4 94 onTerminationCallback = callback;
rgrover1 332:b054000833d4 95 }
rgrover1 332:b054000833d4 96
rgrover1 332:b054000833d4 97 private:
rgrover1 331:352bc4a36ea0 98 ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
rgrover1 331:352bc4a36ea0 99
rgrover1 332:b054000833d4 100 private:
rgrover1 331:352bc4a36ea0 101 void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
rgrover1 331:352bc4a36ea0 102 void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
rgrover1 331:352bc4a36ea0 103
rgrover1 331:352bc4a36ea0 104 void triggerServiceUUIDDiscovery(void);
rgrover1 331:352bc4a36ea0 105 void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
rgrover1 331:352bc4a36ea0 106 void removeFirstServiceNeedingUUIDDiscovery(void);
rgrover1 331:352bc4a36ea0 107
rgrover1 331:352bc4a36ea0 108 void terminateServiceDiscovery(void) {
rgrover1 331:352bc4a36ea0 109 bool wasActive = isActive();
rgrover1 331:352bc4a36ea0 110 state = INACTIVE;
rgrover1 331:352bc4a36ea0 111
rgrover1 331:352bc4a36ea0 112 if (wasActive && onTerminationCallback) {
rgrover1 331:352bc4a36ea0 113 onTerminationCallback(connHandle);
rgrover1 331:352bc4a36ea0 114 }
rgrover1 331:352bc4a36ea0 115 }
rgrover1 331:352bc4a36ea0 116
rgrover1 331:352bc4a36ea0 117 void terminateCharacteristicDiscovery(void) {
rgrover1 331:352bc4a36ea0 118 if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
rgrover1 331:352bc4a36ea0 119 state = SERVICE_DISCOVERY_ACTIVE;
rgrover1 331:352bc4a36ea0 120 }
rgrover1 331:352bc4a36ea0 121 serviceIndex++; /* Progress service index to keep discovery alive. */
rgrover1 331:352bc4a36ea0 122 }
rgrover1 331:352bc4a36ea0 123
rgrover1 331:352bc4a36ea0 124 private:
rgrover1 331:352bc4a36ea0 125 void resetDiscoveredServices(void) {
rgrover1 331:352bc4a36ea0 126 numServices = 0;
rgrover1 331:352bc4a36ea0 127 serviceIndex = 0;
rgrover1 331:352bc4a36ea0 128 }
rgrover1 331:352bc4a36ea0 129
rgrover1 331:352bc4a36ea0 130 void resetDiscoveredCharacteristics(void) {
rgrover1 331:352bc4a36ea0 131 numCharacteristics = 0;
rgrover1 331:352bc4a36ea0 132 characteristicIndex = 0;
rgrover1 331:352bc4a36ea0 133 }
rgrover1 331:352bc4a36ea0 134
rgrover1 332:b054000833d4 135 private:
rgrover1 331:352bc4a36ea0 136 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 331:352bc4a36ea0 137 connHandle = connectionHandle;
rgrover1 331:352bc4a36ea0 138 resetDiscoveredServices();
rgrover1 331:352bc4a36ea0 139 state = SERVICE_DISCOVERY_ACTIVE;
rgrover1 331:352bc4a36ea0 140 }
rgrover1 331:352bc4a36ea0 141
rgrover1 331:352bc4a36ea0 142 private:
rgrover1 331:352bc4a36ea0 143 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
rgrover1 331:352bc4a36ea0 144 connHandle = connectionHandle;
rgrover1 331:352bc4a36ea0 145 resetDiscoveredCharacteristics();
rgrover1 331:352bc4a36ea0 146 state = CHARACTERISTIC_DISCOVERY_ACTIVE;
rgrover1 331:352bc4a36ea0 147 }
rgrover1 331:352bc4a36ea0 148
rgrover1 331:352bc4a36ea0 149 private:
rgrover1 331:352bc4a36ea0 150 /**
rgrover1 331:352bc4a36ea0 151 * A datatype to contain service-indices for which long UUIDs need to be
rgrover1 331:352bc4a36ea0 152 * discovered using read_val_by_uuid().
rgrover1 331:352bc4a36ea0 153 */
rgrover1 331:352bc4a36ea0 154 class ServiceUUIDDiscoveryQueue {
rgrover1 331:352bc4a36ea0 155 public:
rgrover1 331:352bc4a36ea0 156 ServiceUUIDDiscoveryQueue(nRFServiceDiscovery *parent) :
rgrover1 331:352bc4a36ea0 157 numIndices(0),
rgrover1 331:352bc4a36ea0 158 serviceIndices(),
rgrover1 331:352bc4a36ea0 159 parentDiscoveryObject(parent) {
rgrover1 331:352bc4a36ea0 160 /* empty */
rgrover1 331:352bc4a36ea0 161 }
rgrover1 331:352bc4a36ea0 162
rgrover1 331:352bc4a36ea0 163 public:
rgrover1 331:352bc4a36ea0 164 void reset(void) {
rgrover1 331:352bc4a36ea0 165 numIndices = 0;
rgrover1 331:352bc4a36ea0 166 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
rgrover1 331:352bc4a36ea0 167 serviceIndices[i] = INVALID_INDEX;
rgrover1 331:352bc4a36ea0 168 }
rgrover1 331:352bc4a36ea0 169 }
rgrover1 331:352bc4a36ea0 170 void enqueue(int serviceIndex) {
rgrover1 331:352bc4a36ea0 171 serviceIndices[numIndices++] = serviceIndex;
rgrover1 331:352bc4a36ea0 172 }
rgrover1 331:352bc4a36ea0 173 int dequeue(void) {
rgrover1 331:352bc4a36ea0 174 if (numIndices == 0) {
rgrover1 331:352bc4a36ea0 175 return INVALID_INDEX;
rgrover1 331:352bc4a36ea0 176 }
rgrover1 331:352bc4a36ea0 177
rgrover1 331:352bc4a36ea0 178 unsigned valueToReturn = serviceIndices[0];
rgrover1 331:352bc4a36ea0 179 numIndices--;
rgrover1 331:352bc4a36ea0 180 for (unsigned i = 0; i < numIndices; i++) {
rgrover1 331:352bc4a36ea0 181 serviceIndices[i] = serviceIndices[i + 1];
rgrover1 331:352bc4a36ea0 182 }
rgrover1 331:352bc4a36ea0 183
rgrover1 331:352bc4a36ea0 184 return valueToReturn;
rgrover1 331:352bc4a36ea0 185 }
rgrover1 331:352bc4a36ea0 186 unsigned getFirst(void) const {
rgrover1 331:352bc4a36ea0 187 return serviceIndices[0];
rgrover1 331:352bc4a36ea0 188 }
rgrover1 331:352bc4a36ea0 189 size_t getCount(void) const {
rgrover1 331:352bc4a36ea0 190 return numIndices;
rgrover1 331:352bc4a36ea0 191 }
rgrover1 331:352bc4a36ea0 192
rgrover1 331:352bc4a36ea0 193 /**
rgrover1 331:352bc4a36ea0 194 * Trigger UUID discovery for the first of the enqueued ServiceIndices.
rgrover1 331:352bc4a36ea0 195 */
rgrover1 331:352bc4a36ea0 196 void triggerFirst(void);
rgrover1 331:352bc4a36ea0 197
rgrover1 331:352bc4a36ea0 198 private:
rgrover1 331:352bc4a36ea0 199 static const int INVALID_INDEX = -1;
rgrover1 331:352bc4a36ea0 200
rgrover1 331:352bc4a36ea0 201 private:
rgrover1 331:352bc4a36ea0 202 size_t numIndices;
rgrover1 331:352bc4a36ea0 203 int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV];
rgrover1 331:352bc4a36ea0 204
rgrover1 331:352bc4a36ea0 205 nRFServiceDiscovery *parentDiscoveryObject;
rgrover1 331:352bc4a36ea0 206 };
rgrover1 331:352bc4a36ea0 207 friend class ServiceUUIDDiscoveryQueue;
rgrover1 331:352bc4a36ea0 208
rgrover1 331:352bc4a36ea0 209 /**
rgrover1 331:352bc4a36ea0 210 * A datatype to contain characteristic-indices for which long UUIDs need to
rgrover1 331:352bc4a36ea0 211 * be discovered using read_val_by_uuid().
rgrover1 331:352bc4a36ea0 212 */
rgrover1 331:352bc4a36ea0 213 class CharUUIDDiscoveryQueue {
rgrover1 331:352bc4a36ea0 214 public:
rgrover1 331:352bc4a36ea0 215 CharUUIDDiscoveryQueue(nRFServiceDiscovery *parent) :
rgrover1 331:352bc4a36ea0 216 numIndices(0),
rgrover1 331:352bc4a36ea0 217 charIndices(),
rgrover1 331:352bc4a36ea0 218 parentDiscoveryObject(parent) {
rgrover1 331:352bc4a36ea0 219 /* empty */
rgrover1 331:352bc4a36ea0 220 }
rgrover1 331:352bc4a36ea0 221
rgrover1 331:352bc4a36ea0 222 public:
rgrover1 331:352bc4a36ea0 223 void reset(void) {
rgrover1 331:352bc4a36ea0 224 numIndices = 0;
rgrover1 331:352bc4a36ea0 225 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
rgrover1 331:352bc4a36ea0 226 charIndices[i] = INVALID_INDEX;
rgrover1 331:352bc4a36ea0 227 }
rgrover1 331:352bc4a36ea0 228 }
rgrover1 331:352bc4a36ea0 229 void enqueue(int serviceIndex) {
rgrover1 331:352bc4a36ea0 230 charIndices[numIndices++] = serviceIndex;
rgrover1 331:352bc4a36ea0 231 }
rgrover1 331:352bc4a36ea0 232 int dequeue(void) {
rgrover1 331:352bc4a36ea0 233 if (numIndices == 0) {
rgrover1 331:352bc4a36ea0 234 return INVALID_INDEX;
rgrover1 331:352bc4a36ea0 235 }
rgrover1 331:352bc4a36ea0 236
rgrover1 331:352bc4a36ea0 237 unsigned valueToReturn = charIndices[0];
rgrover1 331:352bc4a36ea0 238 numIndices--;
rgrover1 331:352bc4a36ea0 239 for (unsigned i = 0; i < numIndices; i++) {
rgrover1 331:352bc4a36ea0 240 charIndices[i] = charIndices[i + 1];
rgrover1 331:352bc4a36ea0 241 }
rgrover1 331:352bc4a36ea0 242
rgrover1 331:352bc4a36ea0 243 return valueToReturn;
rgrover1 331:352bc4a36ea0 244 }
rgrover1 331:352bc4a36ea0 245 unsigned getFirst(void) const {
rgrover1 331:352bc4a36ea0 246 return charIndices[0];
rgrover1 331:352bc4a36ea0 247 }
rgrover1 331:352bc4a36ea0 248 size_t getCount(void) const {
rgrover1 331:352bc4a36ea0 249 return numIndices;
rgrover1 331:352bc4a36ea0 250 }
rgrover1 331:352bc4a36ea0 251
rgrover1 331:352bc4a36ea0 252 /**
rgrover1 331:352bc4a36ea0 253 * Trigger UUID discovery for the first of the enqueued charIndices.
rgrover1 331:352bc4a36ea0 254 */
rgrover1 331:352bc4a36ea0 255 void triggerFirst(void);
rgrover1 331:352bc4a36ea0 256
rgrover1 331:352bc4a36ea0 257 private:
rgrover1 331:352bc4a36ea0 258 static const int INVALID_INDEX = -1;
rgrover1 331:352bc4a36ea0 259
rgrover1 331:352bc4a36ea0 260 private:
rgrover1 331:352bc4a36ea0 261 size_t numIndices;
rgrover1 331:352bc4a36ea0 262 int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 331:352bc4a36ea0 263
rgrover1 331:352bc4a36ea0 264 nRFServiceDiscovery *parentDiscoveryObject;
rgrover1 331:352bc4a36ea0 265 };
rgrover1 331:352bc4a36ea0 266 friend class CharUUIDDiscoveryQueue;
rgrover1 331:352bc4a36ea0 267
rgrover1 331:352bc4a36ea0 268 private:
rgrover1 331:352bc4a36ea0 269 friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
rgrover1 331:352bc4a36ea0 270 void progressCharacteristicDiscovery(void);
rgrover1 331:352bc4a36ea0 271 void progressServiceDiscovery(void);
rgrover1 331:352bc4a36ea0 272
rgrover1 331:352bc4a36ea0 273 private:
rgrover1 331:352bc4a36ea0 274 uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/
rgrover1 331:352bc4a36ea0 275 uint8_t numServices; /**< Number of services at the peers GATT database.*/
rgrover1 331:352bc4a36ea0 276 uint8_t characteristicIndex; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/
rgrover1 331:352bc4a36ea0 277 uint8_t numCharacteristics; /**< Number of characteristics within the service.*/
rgrover1 331:352bc4a36ea0 278
rgrover1 331:352bc4a36ea0 279 enum State_t {
rgrover1 331:352bc4a36ea0 280 INACTIVE,
rgrover1 331:352bc4a36ea0 281 SERVICE_DISCOVERY_ACTIVE,
rgrover1 331:352bc4a36ea0 282 CHARACTERISTIC_DISCOVERY_ACTIVE,
rgrover1 331:352bc4a36ea0 283 DISCOVER_SERVICE_UUIDS,
rgrover1 331:352bc4a36ea0 284 DISCOVER_CHARACTERISTIC_UUIDS,
rgrover1 331:352bc4a36ea0 285 } state;
rgrover1 331:352bc4a36ea0 286
rgrover1 331:352bc4a36ea0 287 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
rgrover1 331:352bc4a36ea0 288 * This is intended for internal use during service discovery. */
rgrover1 331:352bc4a36ea0 289 nRFDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
rgrover1 331:352bc4a36ea0 290
rgrover1 331:352bc4a36ea0 291 ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue;
rgrover1 331:352bc4a36ea0 292 CharUUIDDiscoveryQueue charUUIDDiscoveryQueue;
rgrover1 331:352bc4a36ea0 293
rgrover1 331:352bc4a36ea0 294 TerminationCallback_t onTerminationCallback;
rgrover1 331:352bc4a36ea0 295 };
rgrover1 331:352bc4a36ea0 296
rgrover1 331:352bc4a36ea0 297 #endif /*__NRF_SERVICE_DISCOVERY_H__*/