library for BLE_GAP_backpack
Dependencies: nrf51-sdk
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 Wed Jul 13 2022 11:18:00 by 1.7.2