Nordic stack and drivers for the mbed BLE API. Version to work around build bug.
Dependents: microbit_rubber_ducky microbit_mouse_BLE microbit_mouse_BLE_daybreak_version microbit_presenter
Fork of nRF51822 by
nRF5xServiceDiscovery.h
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2013 ARM Limited 00003 * 00004 * Licensed under the Apache License, Version 2.0 (the "License"); 00005 * you may not use this file except in compliance with the License. 00006 * You may obtain a copy of the License at 00007 * 00008 * http://www.apache.org/licenses/LICENSE-2.0 00009 * 00010 * Unless required by applicable law or agreed to in writing, software 00011 * distributed under the License is distributed on an "AS IS" BASIS, 00012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00013 * See the License for the specific language governing permissions and 00014 * limitations under the License. 00015 */ 00016 00017 #ifndef __NRF_SERVICE_DISCOVERY_H__ 00018 #define __NRF_SERVICE_DISCOVERY_H__ 00019 00020 #include "ble/ServiceDiscovery.h" 00021 #include "ble/DiscoveredService.h" 00022 #include "nRF5xDiscoveredCharacteristic.h" 00023 00024 #include "ble.h" 00025 #include "ble_gattc.h" 00026 00027 class nRF5xGattClient; /* forward declaration */ 00028 00029 class nRF5xServiceDiscovery : public ServiceDiscovery 00030 { 00031 public: 00032 static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */ 00033 static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */ 00034 00035 public: 00036 static const unsigned BLE_DB_DISCOVERY_MAX_SRV = 4; /**< Maximum number of services we can retain information for after a single discovery. */ 00037 static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service we can retain information for. */ 00038 00039 public: 00040 nRF5xServiceDiscovery(nRF5xGattClient *gattcIn) : 00041 gattc(gattcIn), 00042 serviceIndex(0), 00043 numServices(0), 00044 numCharacteristics(0), 00045 state(INACTIVE), 00046 services(), 00047 characteristics(), 00048 serviceUUIDDiscoveryQueue(this), 00049 charUUIDDiscoveryQueue(this), 00050 onTerminationCallback(NULL) { 00051 /* empty */ 00052 } 00053 00054 virtual ble_error_t launch(Gap::Handle_t connectionHandle, 00055 ServiceDiscovery::ServiceCallback_t sc, 00056 ServiceDiscovery::CharacteristicCallback_t cc, 00057 const UUID &matchingServiceUUIDIn, 00058 const UUID &matchingCharacteristicUUIDIn) 00059 { 00060 if (isActive()) { 00061 return BLE_ERROR_INVALID_STATE; 00062 } 00063 00064 serviceCallback = sc; 00065 characteristicCallback = cc; 00066 matchingServiceUUID = matchingServiceUUIDIn; 00067 matchingCharacteristicUUID = matchingCharacteristicUUIDIn; 00068 00069 serviceDiscoveryStarted(connectionHandle); 00070 00071 uint32_t rc; 00072 if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) { 00073 terminate(); 00074 switch (rc) { 00075 case NRF_ERROR_INVALID_PARAM: 00076 case BLE_ERROR_INVALID_CONN_HANDLE: 00077 return BLE_ERROR_INVALID_PARAM; 00078 case NRF_ERROR_BUSY: 00079 return BLE_STACK_BUSY; 00080 default: 00081 case NRF_ERROR_INVALID_STATE: 00082 return BLE_ERROR_INVALID_STATE; 00083 } 00084 } 00085 00086 return BLE_ERROR_NONE; 00087 } 00088 00089 virtual bool isActive(void) const { 00090 return state != INACTIVE; 00091 } 00092 00093 virtual void terminate(void) { 00094 terminateServiceDiscovery(); 00095 } 00096 00097 void terminate(Gap::Handle_t connectionHandle) { 00098 if(connHandle == connectionHandle) { 00099 terminate(); 00100 } 00101 } 00102 00103 virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { 00104 onTerminationCallback = callback; 00105 } 00106 00107 /** 00108 * @brief Clear nRF5xServiceDiscovery's state. 00109 * 00110 * @return 00111 * BLE_ERROR_NONE if successful. 00112 */ 00113 virtual ble_error_t reset(void) { 00114 /* Clear all state that is from the parent, including private members */ 00115 if (ServiceDiscovery::reset() != BLE_ERROR_NONE) { 00116 return BLE_ERROR_INVALID_STATE; 00117 } 00118 00119 /* Clear derived class members */ 00120 serviceIndex = 0; 00121 numServices = 0; 00122 numCharacteristics = 0; 00123 00124 state = INACTIVE; 00125 00126 serviceUUIDDiscoveryQueue.reset(); 00127 charUUIDDiscoveryQueue.reset(); 00128 00129 onTerminationCallback = NULL; 00130 00131 return BLE_ERROR_NONE; 00132 } 00133 00134 private: 00135 ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle); 00136 00137 private: 00138 void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response); 00139 void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response); 00140 00141 void triggerServiceUUIDDiscovery(void); 00142 void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response); 00143 void removeFirstServiceNeedingUUIDDiscovery(void); 00144 00145 void terminateServiceDiscovery(void) { 00146 discoveredCharacteristic = nRF5xDiscoveredCharacteristic(); 00147 00148 bool wasActive = isActive(); 00149 state = INACTIVE; 00150 00151 if (wasActive && onTerminationCallback) { 00152 onTerminationCallback(connHandle); 00153 } 00154 } 00155 00156 void terminateCharacteristicDiscovery(ble_error_t err) { 00157 if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) { 00158 if(discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) { 00159 if(err == BLE_ERROR_NONE) { 00160 // fullfill the last characteristic 00161 discoveredCharacteristic.setLastHandle(services[serviceIndex].getEndHandle()); 00162 00163 if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || 00164 ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) && 00165 (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { 00166 if (characteristicCallback) { 00167 characteristicCallback(&discoveredCharacteristic); 00168 } 00169 } 00170 } 00171 discoveredCharacteristic = nRF5xDiscoveredCharacteristic(); 00172 } 00173 00174 state = SERVICE_DISCOVERY_ACTIVE; 00175 } 00176 serviceIndex++; /* Progress service index to keep discovery alive. */ 00177 } 00178 00179 private: 00180 void resetDiscoveredServices(void) { 00181 numServices = 0; 00182 serviceIndex = 0; 00183 } 00184 00185 void resetDiscoveredCharacteristics(void) { 00186 numCharacteristics = 0; 00187 } 00188 00189 private: 00190 void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) { 00191 connHandle = connectionHandle; 00192 resetDiscoveredServices(); 00193 state = SERVICE_DISCOVERY_ACTIVE; 00194 } 00195 00196 private: 00197 void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) { 00198 connHandle = connectionHandle; 00199 resetDiscoveredCharacteristics(); 00200 state = CHARACTERISTIC_DISCOVERY_ACTIVE; 00201 } 00202 00203 private: 00204 /** 00205 * A datatype to contain service-indices for which long UUIDs need to be 00206 * discovered using read_val_by_uuid(). 00207 */ 00208 class ServiceUUIDDiscoveryQueue { 00209 public: 00210 ServiceUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) : 00211 numIndices(0), 00212 serviceIndices(), 00213 parentDiscoveryObject(parent) { 00214 /* empty */ 00215 } 00216 00217 public: 00218 void reset(void) { 00219 numIndices = 0; 00220 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) { 00221 serviceIndices[i] = INVALID_INDEX; 00222 } 00223 } 00224 void enqueue(int serviceIndex) { 00225 serviceIndices[numIndices++] = serviceIndex; 00226 } 00227 int dequeue(void) { 00228 if (numIndices == 0) { 00229 return INVALID_INDEX; 00230 } 00231 00232 unsigned valueToReturn = serviceIndices[0]; 00233 numIndices--; 00234 for (unsigned i = 0; i < numIndices; i++) { 00235 serviceIndices[i] = serviceIndices[i + 1]; 00236 } 00237 00238 return valueToReturn; 00239 } 00240 unsigned getFirst(void) const { 00241 return serviceIndices[0]; 00242 } 00243 size_t getCount(void) const { 00244 return numIndices; 00245 } 00246 00247 /** 00248 * Trigger UUID discovery for the first of the enqueued ServiceIndices. 00249 */ 00250 void triggerFirst(void); 00251 00252 private: 00253 static const int INVALID_INDEX = -1; 00254 00255 private: 00256 size_t numIndices; 00257 int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV]; 00258 00259 nRF5xServiceDiscovery *parentDiscoveryObject; 00260 }; 00261 friend class ServiceUUIDDiscoveryQueue; 00262 00263 /** 00264 * A datatype to contain characteristic-indices for which long UUIDs need to 00265 * be discovered using read_val_by_uuid(). 00266 */ 00267 class CharUUIDDiscoveryQueue { 00268 public: 00269 CharUUIDDiscoveryQueue(nRF5xServiceDiscovery *parent) : 00270 numIndices(0), 00271 charIndices(), 00272 parentDiscoveryObject(parent) { 00273 /* empty */ 00274 } 00275 00276 public: 00277 void reset(void) { 00278 numIndices = 0; 00279 for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) { 00280 charIndices[i] = INVALID_INDEX; 00281 } 00282 } 00283 void enqueue(int serviceIndex) { 00284 charIndices[numIndices++] = serviceIndex; 00285 } 00286 int dequeue(void) { 00287 if (numIndices == 0) { 00288 return INVALID_INDEX; 00289 } 00290 00291 unsigned valueToReturn = charIndices[0]; 00292 numIndices--; 00293 for (unsigned i = 0; i < numIndices; i++) { 00294 charIndices[i] = charIndices[i + 1]; 00295 } 00296 00297 return valueToReturn; 00298 } 00299 unsigned getFirst(void) const { 00300 return charIndices[0]; 00301 } 00302 size_t getCount(void) const { 00303 return numIndices; 00304 } 00305 00306 /** 00307 * Trigger UUID discovery for the first of the enqueued charIndices. 00308 */ 00309 void triggerFirst(void); 00310 00311 private: 00312 static const int INVALID_INDEX = -1; 00313 00314 private: 00315 size_t numIndices; 00316 int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV]; 00317 00318 nRF5xServiceDiscovery *parentDiscoveryObject; 00319 }; 00320 friend class CharUUIDDiscoveryQueue; 00321 00322 private: 00323 friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); 00324 void progressCharacteristicDiscovery(void); 00325 void progressServiceDiscovery(void); 00326 00327 private: 00328 nRF5xGattClient *gattc; 00329 00330 private: 00331 uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/ 00332 uint8_t numServices; /**< Number of services at the peers GATT database.*/ 00333 uint8_t numCharacteristics; /**< Number of characteristics within the service.*/ 00334 00335 enum State_t { 00336 INACTIVE, 00337 SERVICE_DISCOVERY_ACTIVE, 00338 CHARACTERISTIC_DISCOVERY_ACTIVE, 00339 DISCOVER_SERVICE_UUIDS, 00340 DISCOVER_CHARACTERISTIC_UUIDS, 00341 } state; 00342 00343 DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered. 00344 * This is intended for internal use during service discovery. */ 00345 nRF5xDiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV]; 00346 00347 ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue; 00348 CharUUIDDiscoveryQueue charUUIDDiscoveryQueue; 00349 00350 TerminationCallback_t onTerminationCallback; 00351 00352 /* 00353 * The currently discovered characteristic. Discovery of a characteristic 00354 * is a two phase process. 00355 * First, declaration handle is fetched, it provide the UUID, the value handle and 00356 * the properties of a characteristic. 00357 * Second, the next declaration handle is fetched, with its declaration handle, it is 00358 * possible to compute the last handle of the discovered characteristic and fill the 00359 * missing part of the object. 00360 * If there is no remaining characteristic to discover, the last handle of the 00361 * discovered characteristic will be set to the last handle of its enclosing service. 00362 */ 00363 nRF5xDiscoveredCharacteristic discoveredCharacteristic; 00364 }; 00365 00366 #endif /*__NRF_SERVICE_DISCOVERY_H__*/
Generated on Tue Jul 12 2022 19:52:03 by 1.7.2