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
nRF5xCharacteristicDescriptorDiscoverer.cpp
00001 /* mbed Microcontroller Library 00002 * Copyright (c) 2006-2015 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 #include "nRF5xCharacteristicDescriptorDiscoverer.h" 00017 #include "ble_err.h" 00018 #include "ble/DiscoveredCharacteristicDescriptor.h" 00019 00020 nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer() : 00021 discoveryRunning() { 00022 // nothing to do 00023 } 00024 00025 nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() { 00026 // nothing to do 00027 } 00028 00029 ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch( 00030 const DiscoveredCharacteristic& characteristic, 00031 const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, 00032 const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback 00033 ) { 00034 Gap::Handle_t connHandle = characteristic.getConnectionHandle(); 00035 // it is ok to deduce that the start handle for descriptors is after 00036 // the characteristic declaration and the characteristic value declaration 00037 // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] (3.3) 00038 Gap::Handle_t descriptorStartHandle = characteristic.getDeclHandle() + 2; 00039 Gap::Handle_t descriptorEndHandle = characteristic.getLastHandle(); 00040 00041 // check if there is any descriptor to discover 00042 if (descriptorEndHandle < descriptorStartHandle) { 00043 CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = { 00044 characteristic, 00045 BLE_ERROR_NONE 00046 }; 00047 terminationCallback.call(&termParams); 00048 return BLE_ERROR_NONE; 00049 } 00050 00051 // check if we can run this discovery 00052 if (isConnectionInUse(connHandle)) { 00053 return BLE_STACK_BUSY; 00054 } 00055 00056 // get a new discovery slot, if none are available, just return 00057 Discovery* discovery = getAvailableDiscoverySlot(); 00058 if(discovery == NULL) { 00059 return BLE_STACK_BUSY; 00060 } 00061 00062 // try to launch the discovery 00063 ble_error_t err = gattc_descriptors_discover(connHandle, descriptorStartHandle, descriptorEndHandle); 00064 if(!err) { 00065 // commit the new discovery to its slot 00066 *discovery = Discovery(characteristic, discoveryCallback, terminationCallback); 00067 } 00068 00069 return err; 00070 } 00071 00072 bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const { 00073 for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { 00074 if(discoveryRunning[i].getCharacteristic() == characteristic) { 00075 return true; 00076 } 00077 } 00078 return false; 00079 } 00080 00081 void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) { 00082 Discovery* discovery = findRunningDiscovery(characteristic); 00083 if(discovery) { 00084 // call terminate anyway 00085 terminate(discovery, BLE_ERROR_NONE); 00086 } 00087 } 00088 00089 void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) { 00090 Discovery* discovery = findRunningDiscovery(connectionHandle); 00091 // the discovery has been removed 00092 if(!discovery) { 00093 return; 00094 } 00095 00096 for (uint16_t i = 0; i < descriptors.count; ++i) { 00097 discovery->process( 00098 descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid) 00099 ); 00100 } 00101 00102 // prepare the next discovery request (if needed) 00103 uint16_t startHandle = descriptors.descs[descriptors.count - 1].handle + 1; 00104 uint16_t endHandle = discovery->getCharacteristic().getLastHandle(); 00105 00106 if(startHandle > endHandle) { 00107 terminate(discovery, BLE_ERROR_NONE); 00108 return; 00109 } 00110 00111 ble_error_t err = gattc_descriptors_discover(connectionHandle, startHandle, endHandle); 00112 if(err) { 00113 terminate(discovery, err); 00114 return; 00115 } 00116 } 00117 00118 void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle, ble_error_t err) { 00119 Discovery* discovery = findRunningDiscovery(handle); 00120 // the discovery has already been terminated 00121 if(!discovery) { 00122 return; 00123 } 00124 00125 terminate(discovery, err); 00126 } 00127 00128 void nRF5xCharacteristicDescriptorDiscoverer::terminate(Discovery* discovery, ble_error_t err) { 00129 // temporary copy, user code can try to launch a new discovery in the onTerminate 00130 // callback. So, this discovery should not appear in such case. 00131 Discovery tmp = *discovery; 00132 *discovery = Discovery(); 00133 tmp.terminate(err); 00134 } 00135 00136 nRF5xCharacteristicDescriptorDiscoverer::Discovery* 00137 nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) { 00138 for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { 00139 if((discoveryRunning[i].getCharacteristic() == characteristic) && 00140 (discoveryRunning[i].isEmpty() == false)) { 00141 return &discoveryRunning[i]; 00142 } 00143 } 00144 return NULL; 00145 } 00146 00147 nRF5xCharacteristicDescriptorDiscoverer::Discovery* 00148 nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) { 00149 for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { 00150 if((discoveryRunning[i].getCharacteristic().getConnectionHandle() == handle) && 00151 (discoveryRunning[i].isEmpty() == false)) { 00152 return &discoveryRunning[i]; 00153 } 00154 } 00155 return NULL; 00156 } 00157 00158 nRF5xCharacteristicDescriptorDiscoverer::Discovery* 00159 nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() { 00160 for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { 00161 if(discoveryRunning[i].isEmpty()) { 00162 return &discoveryRunning[i]; 00163 } 00164 } 00165 return NULL; 00166 } 00167 00168 bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) { 00169 return findRunningDiscovery(connHandle) != NULL; 00170 } 00171 00172 ble_error_t nRF5xCharacteristicDescriptorDiscoverer::gattc_descriptors_discover( 00173 uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle) { 00174 00175 ble_gattc_handle_range_t discoveryRange = { 00176 start_handle, 00177 end_handle 00178 }; 00179 uint32_t err = sd_ble_gattc_descriptors_discover(connection_handle, &discoveryRange); 00180 00181 switch(err) { 00182 case NRF_SUCCESS: 00183 return BLE_ERROR_NONE; 00184 case BLE_ERROR_INVALID_CONN_HANDLE: 00185 return BLE_ERROR_INVALID_PARAM; 00186 case NRF_ERROR_INVALID_ADDR: 00187 return BLE_ERROR_PARAM_OUT_OF_RANGE; 00188 case NRF_ERROR_BUSY: 00189 return BLE_STACK_BUSY; 00190 default: 00191 return BLE_ERROR_UNSPECIFIED; 00192 } 00193 } 00194 00195 // implementation of nRF5xCharacteristicDescriptorDiscoverer::Discovery 00196 00197 nRF5xCharacteristicDescriptorDiscoverer::Discovery::Discovery() : 00198 characteristic(), onDiscovery(), onTerminate() { 00199 } 00200 00201 nRF5xCharacteristicDescriptorDiscoverer::Discovery::Discovery( 00202 const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) : 00203 characteristic(c), onDiscovery(dCb), onTerminate(tCb) { 00204 } 00205 00206 void nRF5xCharacteristicDescriptorDiscoverer::Discovery::process( 00207 GattAttribute::Handle_t handle, const UUID& uuid) { 00208 CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { 00209 characteristic, 00210 DiscoveredCharacteristicDescriptor( 00211 characteristic.getGattClient(), 00212 characteristic.getConnectionHandle(), 00213 handle, 00214 uuid 00215 ) 00216 }; 00217 onDiscovery.call(¶ms); 00218 } 00219 00220 void nRF5xCharacteristicDescriptorDiscoverer::Discovery::terminate(ble_error_t err) { 00221 CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { 00222 characteristic, 00223 err 00224 }; 00225 00226 onTerminate.call(¶ms); 00227 } 00228 00229 bool nRF5xCharacteristicDescriptorDiscoverer::Discovery::isEmpty() const { 00230 return *this == Discovery(); 00231 } 00232 00233 const DiscoveredCharacteristic& nRF5xCharacteristicDescriptorDiscoverer::Discovery::getCharacteristic() const { 00234 return characteristic; 00235 }
Generated on Fri Jul 15 2022 12:51:28 by
