Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
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 Fri Jul 15 2022 12:51:28 by
1.7.2
