sa
Fork of nRF51822 by
Revision 563:9c4b96f7be8d, committed 2016-01-11
- Comitter:
- vcoubard
- Date:
- Mon Jan 11 10:19:16 2016 +0000
- Parent:
- 562:0d32ae12429e
- Child:
- 564:77d4fcde8f2a
- Commit message:
- Synchronized with git rev 7e784e0e
Author: Vincent Coubard
Merge branch 'develop' of https://github.com/ARMmbed/ble-nrf51822 into characteristicDescriptorDiscovery
Changed in this revision
--- a/source/btle/btle.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/btle/btle.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -41,6 +41,10 @@ #include "ble_hci.h" #include "btle_discovery.h" +#include "nRF5xGattClient.h" +#include "nRF5xServiceDiscovery.h" +#include "nRF5xCharacteristicDescriptorDiscoverer.h" + extern "C" void assert_nrf_callback(uint16_t line_num, const uint8_t *p_file_name); void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name); @@ -183,6 +187,12 @@ reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason); break; } + + // Close all pending discoveries for this connection + nRF5xGattClient& gattClient = nRF5xGattClient::getInstance(); + gattClient.characteristicDescriptorDiscoverer().terminate(handle, BLE_ERROR_INVALID_STATE); + gattClient.discovery().terminate(handle); + nRF5xGap::getInstance().processDisconnectionEvent(handle, reason); break; }
--- a/source/btle/btle_discovery.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/btle/btle_discovery.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -15,12 +15,15 @@ */ #include "nRF5xServiceDiscovery.h" +#include "nRF5xCharacteristicDescriptorDiscoverer.h" #include "nRF5xGattClient.h" #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) void bleGattcEventHandler(const ble_evt_t *p_ble_evt) { - nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery; + nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery(); + nRF5xCharacteristicDescriptorDiscoverer &characteristicDescriptorDiscoverer = + nRF5xGattClient::getInstance().characteristicDescriptorDiscoverer(); switch (p_ble_evt->header.evt_id) { case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: @@ -44,7 +47,7 @@ case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: default: - sdSingleton.terminateCharacteristicDiscovery(); + sdSingleton.terminateCharacteristicDiscovery(BLE_ERROR_NONE); break; } break; @@ -91,6 +94,28 @@ nRF5xGattClient::getInstance().processHVXEvent(¶ms); } break; + + case BLE_GATTC_EVT_DESC_DISC_RSP: { + uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle; + uint16_t status = p_ble_evt->evt.gattc_evt.gatt_status; + const ble_gattc_evt_desc_disc_rsp_t& discovered_descriptors = p_ble_evt->evt.gattc_evt.params.desc_disc_rsp; + + switch(status) { + case BLE_GATT_STATUS_SUCCESS: + characteristicDescriptorDiscoverer.process( + conn_handle, + discovered_descriptors + ); + break; + case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: + // end of discovery + characteristicDescriptorDiscoverer.terminate(conn_handle, BLE_ERROR_NONE); + break; + default: + characteristicDescriptorDiscoverer.terminate(conn_handle, BLE_ERROR_UNSPECIFIED); + break; + } + } break; } sdSingleton.progressCharacteristicDiscovery();
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/nRF5xCharacteristicDescriptorDiscoverer.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -0,0 +1,208 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "nRF5xCharacteristicDescriptorDiscoverer.h" +#include "ble_err.h" +#include "mbed-drivers/mbed_error.h" +#include "ble/DiscoveredCharacteristicDescriptor.h" + +namespace { + void emptyDiscoveryCallback(const CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t*) { } + void emptyTerminationCallback(const CharacteristicDescriptorDiscovery::TerminationCallbackParams_t*) { } +} + +nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount) : + maximumConcurrentConnectionsCount(concurrentConnectionsCount), + discoveryRunning(new Discovery[concurrentConnectionsCount]) { + +} + +nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() { + delete [] discoveryRunning; +} + +ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback +) { + Gap::Handle_t connHandle = characteristic.getConnectionHandle(); + // it is ok to deduce that the start handle for descriptors is after + // the characteristic declaration and the characteristic value declaration + // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] (3.3) + Gap::Handle_t descriptorStartHandle = characteristic.getDeclHandle() + 2; + Gap::Handle_t descriptorEndHandle = characteristic.getLastHandle(); + + // check if their is any descriptor to discover + if (descriptorEndHandle < descriptorStartHandle) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = { + characteristic, + BLE_ERROR_NONE + }; + terminationCallback.call(&termParams); + return BLE_ERROR_NONE; + } + + // check if we can run this discovery + if (isConnectionInUse(connHandle)) { + return BLE_STACK_BUSY; + } + + // get a new discovery slot, if none are available, just return + Discovery* discovery = getAvailableDiscoverySlot(); + if(discovery == NULL) { + return BLE_STACK_BUSY; + } + + // try to launch the discovery + ble_error_t err = gattc_descriptors_discover(connHandle, descriptorStartHandle, descriptorEndHandle); + if(!err) { + // commit the new discovery to its slot + *discovery = Discovery(characteristic, discoveryCallback, terminationCallback); + } + + return err; +} + +bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const { + return findRunningDiscovery(characteristic) != NULL; +} + +void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) { + Discovery* discovery = findRunningDiscovery(characteristic); + if(discovery) { + discovery->onDiscovery = emptyDiscoveryCallback; + // call terminate anyway + discovery->terminate(BLE_ERROR_NONE); + discovery->onTerminate = emptyTerminationCallback; + } +} + +void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) { + Discovery* discovery = findRunningDiscovery(connectionHandle); + if(!discovery) { + error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!"); + } + + for (uint16_t i = 0; i < descriptors.count; ++i) { + discovery->process( + descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid) + ); + } + + // prepare the next discovery request (if needed) + uint16_t startHandle = descriptors.descs[descriptors.count - 1].handle + 1; + uint16_t endHandle = discovery->characteristic.getLastHandle(); + + if(startHandle > endHandle || + (discovery->onDiscovery == emptyDiscoveryCallback && discovery->onTerminate == emptyTerminationCallback)) { + terminate(connectionHandle, BLE_ERROR_NONE); + return; + } + + ble_error_t err = gattc_descriptors_discover(connectionHandle, startHandle, endHandle); + if(err) { + terminate(connectionHandle, err); + return; + } +} + +void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle, ble_error_t err) { + Discovery* discovery = findRunningDiscovery(handle); + if(!discovery) { + error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!"); + } + + Discovery tmp = *discovery; + *discovery = Discovery(); + tmp.terminate(err); +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i].characteristic == characteristic) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i].characteristic == characteristic) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i].characteristic.getConnectionHandle() == handle && + discoveryRunning[i] != Discovery()) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +void nRF5xCharacteristicDescriptorDiscoverer::removeDiscovery(Discovery* discovery) { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(&discoveryRunning[i] == discovery) { + discoveryRunning[i] = Discovery(); + } + } +} + +nRF5xCharacteristicDescriptorDiscoverer::Discovery* +nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() { + for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { + if(discoveryRunning[i] == Discovery()) { + return &discoveryRunning[i]; + } + } + return NULL; +} + +bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) { + return findRunningDiscovery(connHandle) != NULL; +} + +ble_error_t nRF5xCharacteristicDescriptorDiscoverer::gattc_descriptors_discover( + uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle) { + + ble_gattc_handle_range_t discoveryRange = { + start_handle, + end_handle + }; + uint32_t err = sd_ble_gattc_descriptors_discover(connection_handle, &discoveryRange); + + switch(err) { + case NRF_SUCCESS: + return BLE_ERROR_NONE; + case BLE_ERROR_INVALID_CONN_HANDLE: + return BLE_ERROR_INVALID_PARAM; + case NRF_ERROR_INVALID_ADDR: + return BLE_ERROR_PARAM_OUT_OF_RANGE; + case NRF_ERROR_BUSY: + return BLE_STACK_BUSY; + default: + return BLE_ERROR_UNSPECIFIED; + } +} \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/source/nRF5xCharacteristicDescriptorDiscoverer.h Mon Jan 11 10:19:16 2016 +0000 @@ -0,0 +1,140 @@ +/* mbed Microcontroller Library + * Copyright (c) 2006-2015 ARM Limited + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ +#define __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__ + +#include "ble/Gap.h" +#include "ble/DiscoveredCharacteristic.h" +#include "ble/CharacteristicDescriptorDiscovery.h" +#include "ble/GattClient.h" +#include "ble_gattc.h" + +/** + * @brief Manage the discovery of Characteristic descriptors + * @details is a bridge beetween BLE API and nordic stack regarding Characteristic + * Descriptor discovery. The BLE API can launch, monitorate and ask for termination + * of a discovery. The nordic stack will provide new descriptors and indicate when + * the discovery is done + */ +class nRF5xCharacteristicDescriptorDiscoverer +{ + typedef CharacteristicDescriptorDiscovery::DiscoveryCallback_t DiscoveryCallback_t; + typedef CharacteristicDescriptorDiscovery::TerminationCallback_t TerminationCallback_t; + +public: + nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount = 3); + + ~nRF5xCharacteristicDescriptorDiscoverer(); + + /** + * Launch a new characteristic descriptor discovery for a given + * DiscoveredCharacteristic. + * @note: this will be called by BLE API side + */ + ble_error_t launch( + const DiscoveredCharacteristic& characteristic, + const DiscoveryCallback_t& callback, + const TerminationCallback_t& terminationCallback + ); + + /** + * @brief indicate if a characteristic descriptor discovery is active for a + * given DiscoveredCharacteristic + * @note: this will be called by BLE API side + */ + bool isActive(const DiscoveredCharacteristic& characteristic) const; + + /** + * @brief reauest the termination of characteristic descriptor discovery + * for a give DiscoveredCharacteristic + * @note: this will be called by BLE API side + */ + void requestTerminate(const DiscoveredCharacteristic& characteristic); + + /** + * @brief process descriptors discovered from the nordic stack + */ + void process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors); + + /** + * @brief Called by the nordic stack when the discovery is over. + */ + void terminate(uint16_t handle, ble_error_t err); + +private: + nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&); + nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&); + + struct Discovery { + Discovery() : characteristic(), onDiscovery(), onTerminate() { } + + Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) : + characteristic(c), + onDiscovery(dCb), + onTerminate(tCb) { + } + + DiscoveredCharacteristic characteristic; + DiscoveryCallback_t onDiscovery; + TerminationCallback_t onTerminate; + + void process(GattAttribute::Handle_t handle, const UUID& uuid) { + CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { + characteristic, + DiscoveredCharacteristicDescriptor( + characteristic.getGattClient(), + characteristic.getConnectionHandle(), + handle, + uuid + ) + }; + onDiscovery.call(¶ms); + } + + void terminate(ble_error_t err) { + CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { + characteristic, + err + }; + onTerminate.call(¶ms); + } + + friend bool operator==(const Discovery& lhs, const Discovery& rhs) { + return lhs.characteristic == rhs.characteristic && + lhs.onDiscovery == rhs.onDiscovery && + lhs.onTerminate == rhs.onTerminate; + } + + friend bool operator!=(const Discovery& lhs, const Discovery& rhs) { + return !(lhs == rhs); + } + }; + + Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic); + Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const; + Discovery* findRunningDiscovery(uint16_t handle); + void removeDiscovery(Discovery* discovery); + Discovery* getAvailableDiscoverySlot(); + bool isConnectionInUse(uint16_t connHandle); + static ble_error_t gattc_descriptors_discover(uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle); + + + size_t maximumConcurrentConnectionsCount; + Discovery *discoveryRunning; +}; + +#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/ \ No newline at end of file
--- a/source/nRF5xGap.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xGap.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -23,9 +23,6 @@ nRF5xGap &nRF5xGap::getInstance() { static nRF5xGap m_instance; - if (gapInstance == NULL) { - gapInstance = &m_instance; - } return m_instance; } @@ -341,29 +338,6 @@ /**************************************************************************/ /*! - @brief Clear nRF5xGap's state. - - @returns ble_error_t - - @retval BLE_ERROR_NONE - Everything executed properly -*/ -/**************************************************************************/ -ble_error_t nRF5xGap::cleanup(void) -{ - /* Clear all state that is from the parent, including private members */ - if (Gap::cleanup() != BLE_ERROR_NONE) { - return BLE_ERROR_INVALID_STATE; - } - - /* Clear derived class members */ - m_connectionHandle = BLE_CONN_HANDLE_INVALID; - - return BLE_ERROR_NONE; -} - -/**************************************************************************/ -/*! @brief Sets the 16-bit connection handle */ /**************************************************************************/
--- a/source/nRF5xGap.h Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xGap.h Mon Jan 11 10:19:16 2016 +0000 @@ -112,9 +112,6 @@ } #endif -protected: - virtual ble_error_t cleanup(void); - private: bool radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */ Timeout radioNotificationTimeout;
--- a/source/nRF5xGattClient.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xGattClient.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -18,10 +18,11 @@ nRF5xGattClient & nRF5xGattClient::getInstance(void) { - if (gattClientInstance == NULL) { - gattClientInstance = new nRF5xGattClient(); + static nRF5xGattClient* nRFGattClientSingleton = NULL; + if (nRFGattClientSingleton == NULL) { + nRFGattClientSingleton = new nRF5xGattClient(); } - return (nRF5xGattClient &) *gattClientInstance; + return *nRFGattClientSingleton; } #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) @@ -32,6 +33,27 @@ const UUID &matchingServiceUUIDIn, const UUID &matchingCharacteristicUUIDIn) { - return discovery.launch(connectionHandle, sc, cc, matchingServiceUUIDIn, matchingCharacteristicUUIDIn); + return _discovery.launch(connectionHandle, sc, cc, matchingServiceUUIDIn, matchingCharacteristicUUIDIn); } + +ble_error_t nRF5xGattClient::discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback) +{ + return _characteristicDescriptorDiscoverer.launch( + characteristic, + discoveryCallback, + terminationCallback + ); +} + +bool nRF5xGattClient::isCharacteristicDescriptorsDiscoveryActive(const DiscoveredCharacteristic& characteristic) const { + return _characteristicDescriptorDiscoverer.isActive(characteristic); +} + +void nRF5xGattClient::terminateCharacteristicDescriptorsDiscovery(const DiscoveredCharacteristic& characteristic) { + return _characteristicDescriptorDiscoverer.requestTerminate(characteristic); +} + #endif \ No newline at end of file
--- a/source/nRF5xGattClient.h Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xGattClient.h Mon Jan 11 10:19:16 2016 +0000 @@ -19,6 +19,7 @@ #include "ble/GattClient.h" #include "nRF5xServiceDiscovery.h" +#include "nRF5xCharacteristicDescriptorDiscoverer.h" class nRF5xGattClient : public GattClient { @@ -87,14 +88,14 @@ const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)); virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) { - discovery.onTermination(callback); + _discovery.onTermination(callback); } /** * Is service-discovery currently active? */ virtual bool isServiceDiscoveryActive(void) const { - return discovery.isActive(); + return _discovery.isActive(); } /** @@ -102,9 +103,31 @@ * invocation of the TerminationCallback if service-discovery is active. */ virtual void terminateServiceDiscovery(void) { - discovery.terminate(); + _discovery.terminate(); } + /** + * @brief Implementation of GattClient::discoverCharacteristicDescriptors + * @see GattClient::discoverCharacteristicDescriptors + */ + virtual ble_error_t discoverCharacteristicDescriptors( + const DiscoveredCharacteristic& characteristic, + const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback, + const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback + ); + + /** + * @brief Implementation of GattClient::isCharacteristicDiscoveryActive + * @see GattClient::isCharacteristicDiscoveryActive + */ + virtual bool isCharacteristicDescriptorsDiscoveryActive(const DiscoveredCharacteristic& characteristic) const; + + /** + * @brief Implementation of GattClient::terminateCharacteristicDiscovery + * @see GattClient::terminateCharacteristicDiscovery + */ + virtual void terminateCharacteristicDescriptorsDiscovery(const DiscoveredCharacteristic& characteristic); + virtual ble_error_t read(Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, uint16_t offset) const { uint32_t rc = sd_ble_gattc_read(connHandle, attributeHandle, offset); if (rc == NRF_SUCCESS) { @@ -147,38 +170,26 @@ } } -protected: - /** - * @brief Clear nRF5xGattClient's state. - * - * @return - * BLE_ERROR_NONE if successful. - */ - virtual ble_error_t cleanup(void) { - /* Clear all state that is from the parent, including private members */ - if (GattClient::cleanup() != BLE_ERROR_NONE) { - return BLE_ERROR_INVALID_STATE; - } - - /* Clear derived class members */ - discovery.cleanup(); - - return BLE_ERROR_NONE; - } - public: - nRF5xGattClient() : discovery(this) { + nRF5xGattClient() : _discovery(this) { /* empty */ } - friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); + nRF5xServiceDiscovery& discovery() { + return _discovery; + } + + nRF5xCharacteristicDescriptorDiscoverer& characteristicDescriptorDiscoverer() { + return _characteristicDescriptorDiscoverer; + } private: nRF5xGattClient(const nRF5xGattClient &); const nRF5xGattClient& operator=(const nRF5xGattClient &); private: - nRF5xServiceDiscovery discovery; + nRF5xServiceDiscovery _discovery; + nRF5xCharacteristicDescriptorDiscoverer _characteristicDescriptorDiscoverer; #endif // if !S110 };
--- a/source/nRF5xGattServer.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xGattServer.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -23,10 +23,8 @@ #include "nRF5xGap.h" nRF5xGattServer &nRF5xGattServer::getInstance(void) { - if (gattServerInstance == NULL) { - gattServerInstance = new nRF5xGattServer(); - } - return (nRF5xGattServer &) *gattServerInstance; + static nRF5xGattServer m_instance; + return m_instance; } /**************************************************************************/ @@ -314,33 +312,6 @@ /**************************************************************************/ /*! - @brief Clear nRF5xGattServer's state. - - @returns ble_error_t - - @retval BLE_ERROR_NONE - Everything executed properly -*/ -/**************************************************************************/ -ble_error_t nRF5xGattServer::cleanup(void) -{ - /* Clear all state that is from the parent, including private members */ - if (GattServer::cleanup() != BLE_ERROR_NONE) { - return BLE_ERROR_INVALID_STATE; - } - - /* Clear derived class members */ - memset(p_characteristics, 0, sizeof(p_characteristics)); - memset(p_descriptors, 0, sizeof(p_descriptors)); - memset(nrfCharacteristicHandles, 0, sizeof(ble_gatts_char_handles_t)); - memset(nrfDescriptorHandles, 0, sizeof(nrfDescriptorHandles)); - descriptorCount = 0; - - return BLE_ERROR_NONE; -} - -/**************************************************************************/ -/*! @brief Callback handler for events getting pushed up from the SD */ /**************************************************************************/
--- a/source/nRF5xGattServer.h Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xGattServer.h Mon Jan 11 10:19:16 2016 +0000 @@ -42,9 +42,6 @@ void eventCallback(void); void hwCallback(ble_evt_t *p_ble_evt); -protected: - virtual ble_error_t cleanup(void); - private: const static unsigned BLE_TOTAL_CHARACTERISTICS = 20; const static unsigned BLE_TOTAL_DESCRIPTORS = 8;
--- a/source/nRF5xSecurityManager.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xSecurityManager.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -17,8 +17,9 @@ #include "nRF5xSecurityManager.h" nRF5xSecurityManager &nRF5xSecurityManager::getInstance(void) { - if (securityManagerInstance == NULL) { - securityManagerInstance = new nRF5xSecurityManager(); + static nRF5xSecurityManager* m_instance = NULL; + if (m_instance == NULL) { + m_instance = new nRF5xSecurityManager(); } - return (nRF5xSecurityManager &) *securityManagerInstance; + return *m_instance; } \ No newline at end of file
--- a/source/nRF5xSecurityManager.h Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xSecurityManager.h Mon Jan 11 10:19:16 2016 +0000 @@ -47,21 +47,6 @@ return btle_purgeAllBondingState(); } - /** - * @brief Clear nRF5xSecurityManager's state. - * - * @return - * BLE_ERROR_NONE if successful. - */ - virtual ble_error_t cleanup(void) - { - if (SecurityManager::cleanup() != BLE_ERROR_NONE) { - return BLE_ERROR_INVALID_STATE; - } - - return BLE_ERROR_NONE; - } - public: nRF5xSecurityManager() { /* empty */
--- a/source/nRF5xServiceDiscovery.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xServiceDiscovery.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -27,22 +27,32 @@ .start_handle = startHandle, .end_handle = endHandle }; - uint32_t rc; - if ((rc = sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange)) != NRF_SUCCESS) { - terminateCharacteristicDiscovery(); - switch (rc) { - case BLE_ERROR_INVALID_CONN_HANDLE: - case NRF_ERROR_INVALID_ADDR: - return BLE_ERROR_INVALID_PARAM; - case NRF_ERROR_BUSY: - return BLE_STACK_BUSY; - default: - case NRF_ERROR_INVALID_STATE: - return BLE_ERROR_INVALID_STATE; - } + uint32_t rc = sd_ble_gattc_characteristics_discover(connectionHandle, &handleRange); + ble_error_t err = BLE_ERROR_NONE; + + switch (rc) { + case NRF_SUCCESS: + err = BLE_ERROR_NONE; + break; + case BLE_ERROR_INVALID_CONN_HANDLE: + case NRF_ERROR_INVALID_ADDR: + err = BLE_ERROR_INVALID_PARAM; + break; + case NRF_ERROR_BUSY: + err = BLE_STACK_BUSY; + break; + case NRF_ERROR_INVALID_STATE: + err = BLE_ERROR_INVALID_STATE; + break; + default: + err = BLE_ERROR_UNSPECIFIED; + break; } - return BLE_ERROR_NONE; + if(err) { + terminateCharacteristicDiscovery(err); + } + return err; } void @@ -78,7 +88,6 @@ void nRF5xServiceDiscovery::setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response) { - characteristicIndex = 0; numCharacteristics = response->count; /* Account for the limitation on the number of discovered characteristics we can handle at a time. */ @@ -114,38 +123,63 @@ void nRF5xServiceDiscovery::progressCharacteristicDiscovery(void) { - /* Iterate through the previously discovered characteristics cached in characteristics[]. */ - while ((state == CHARACTERISTIC_DISCOVERY_ACTIVE) && (characteristicIndex < numCharacteristics)) { + if(state != CHARACTERISTIC_DISCOVERY_ACTIVE) { + return; + } + + if(remainingCharacteristic != nRF5xDiscoveredCharacteristic() && numCharacteristics > 0) { + remainingCharacteristic.setLastHandle(characteristics[0].getDeclHandle() - 1); + if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || - ((matchingCharacteristicUUID == characteristics[characteristicIndex].getUUID()) && + ((matchingCharacteristicUUID == remainingCharacteristic.getUUID()) && (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { if (characteristicCallback) { - characteristicCallback(&characteristics[characteristicIndex]); + characteristicCallback(&remainingCharacteristic); } } - - characteristicIndex++; } - /* Relaunch discovery of new characteristics beyond the last entry cached in characteristics[]. */ - if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) { - /* Determine the ending handle of the last cached characteristic. */ - Gap::Handle_t startHandle = characteristics[characteristicIndex - 1].getValueHandle() + 1; - Gap::Handle_t endHandle = services[serviceIndex].getEndHandle(); - resetDiscoveredCharacteristics(); /* Note: resetDiscoveredCharacteristics() must come after fetching start and end Handles. */ + for(uint8_t i = 0; i < numCharacteristics; ++i) { + if(state != CHARACTERISTIC_DISCOVERY_ACTIVE) { + return; + } + + if(i == numCharacteristics - 1) { + remainingCharacteristic = characteristics[i]; + break; + } else { + characteristics[i].setLastHandle(characteristics[i + 1].getDeclHandle() - 1); + } - if (startHandle < endHandle) { - ble_gattc_handle_range_t handleRange = { - .start_handle = startHandle, - .end_handle = endHandle - }; - if (sd_ble_gattc_characteristics_discover(connHandle, &handleRange) != NRF_SUCCESS) { - terminateCharacteristicDiscovery(); + if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || + ((matchingCharacteristicUUID == characteristics[i].getUUID()) && + (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { + if (characteristicCallback) { + characteristicCallback(&characteristics[i]); } - } else { - terminateCharacteristicDiscovery(); } } + + if(state != CHARACTERISTIC_DISCOVERY_ACTIVE) { + return; + } + + + Gap::Handle_t startHandle = (numCharacteristics > 0) ? characteristics[numCharacteristics - 1].getValueHandle() + 1 : SRV_DISC_END_HANDLE; + Gap::Handle_t endHandle = services[serviceIndex].getEndHandle(); + resetDiscoveredCharacteristics(); /* Note: resetDiscoveredCharacteristics() must come after fetching start and end Handles. */ + + if (startHandle < endHandle) { + ble_gattc_handle_range_t handleRange = { + .start_handle = startHandle, + .end_handle = endHandle + }; + if (sd_ble_gattc_characteristics_discover(connHandle, &handleRange) != NRF_SUCCESS) { + terminateCharacteristicDiscovery(BLE_ERROR_UNSPECIFIED); + } + } else { + terminateCharacteristicDiscovery(BLE_ERROR_NONE); + } } void
--- a/source/nRF5xServiceDiscovery.h Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xServiceDiscovery.h Mon Jan 11 10:19:16 2016 +0000 @@ -41,7 +41,6 @@ gattc(gattcIn), serviceIndex(0), numServices(0), - characteristicIndex(0), numCharacteristics(0), state(INACTIVE), services(), @@ -95,36 +94,14 @@ terminateServiceDiscovery(); } - virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { - onTerminationCallback = callback; + void terminate(Gap::Handle_t connectionHandle) { + if(connHandle == connectionHandle) { + terminate(); + } } - /** - * @brief Clear nRF5xServiceDiscovery's state. - * - * @return - * BLE_ERROR_NONE if successful. - */ - virtual ble_error_t cleanup(void) { - /* Clear all state that is from the parent, including private members */ - if (ServiceDiscovery::cleanup() != BLE_ERROR_NONE) { - return BLE_ERROR_INVALID_STATE; - } - - /* Clear derived class members */ - serviceIndex = 0; - numServices = 0; - characteristicIndex = 0; - numCharacteristics = 0; - - state = INACTIVE; - - serviceUUIDDiscoveryQueue.reset(); - charUUIDDiscoveryQueue.reset(); - - onTerminationCallback = NULL; - - return BLE_ERROR_NONE; + virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { + onTerminationCallback = callback; } private: @@ -139,6 +116,8 @@ void removeFirstServiceNeedingUUIDDiscovery(void); void terminateServiceDiscovery(void) { + remainingCharacteristic = nRF5xDiscoveredCharacteristic(); + bool wasActive = isActive(); state = INACTIVE; @@ -147,8 +126,24 @@ } } - void terminateCharacteristicDiscovery(void) { + void terminateCharacteristicDiscovery(ble_error_t err) { if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) { + if(remainingCharacteristic != nRF5xDiscoveredCharacteristic()) { + if(err == BLE_ERROR_NONE) { + // fullfill the last characteristic + remainingCharacteristic.setLastHandle(services[serviceIndex].getEndHandle()); + + if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || + ((matchingCharacteristicUUID == remainingCharacteristic.getUUID()) && + (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { + if (characteristicCallback) { + characteristicCallback(&remainingCharacteristic); + } + } + } + remainingCharacteristic = nRF5xDiscoveredCharacteristic(); + } + state = SERVICE_DISCOVERY_ACTIVE; } serviceIndex++; /* Progress service index to keep discovery alive. */ @@ -162,7 +157,6 @@ void resetDiscoveredCharacteristics(void) { numCharacteristics = 0; - characteristicIndex = 0; } private: @@ -309,7 +303,6 @@ private: uint8_t serviceIndex; /**< Index of the current service being discovered. This is intended for internal use during service discovery.*/ uint8_t numServices; /**< Number of services at the peers GATT database.*/ - uint8_t characteristicIndex; /**< Index of the current characteristic being discovered. This is intended for internal use during service discovery.*/ uint8_t numCharacteristics; /**< Number of characteristics within the service.*/ enum State_t { @@ -328,6 +321,8 @@ CharUUIDDiscoveryQueue charUUIDDiscoveryQueue; TerminationCallback_t onTerminationCallback; + + nRF5xDiscoveredCharacteristic remainingCharacteristic; }; #endif /*__NRF_SERVICE_DISCOVERY_H__*/ \ No newline at end of file
--- a/source/nRF5xn.cpp Mon Jan 11 10:19:15 2016 +0000 +++ b/source/nRF5xn.cpp Mon Jan 11 10:19:16 2016 +0000 @@ -104,44 +104,16 @@ return BLE_ERROR_NONE; } -/**************************************************************************/ -/*! - @brief Purge the BLE stack of GATT and GAP state. - - @returns ble_error_t - - @retval BLE_ERROR_NONE - Everything executed properly - - @note When using S110, GattClient::shutdown() will not be called - since Gatt client features are not supported. -*/ -/**************************************************************************/ ble_error_t nRF5xn::shutdown(void) { if (!initialized) { return BLE_ERROR_INITIALIZATION_INCOMPLETE; } - /* Shutdown the SoftDevice */ if(softdevice_handler_sd_disable() != NRF_SUCCESS) { return BLE_STACK_BUSY; } - /* Shutdown the BLE API and nRF51 glue code */ -#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) - if (GattServer::shutdown() != BLE_ERROR_NONE || - SecurityManager::shutdown() != BLE_ERROR_NONE || - GattClient::shutdown() != BLE_ERROR_NONE || - Gap::shutdown() != BLE_ERROR_NONE) { -#else - if (GattServer::shutdown() != BLE_ERROR_NONE || - SecurityManager::shutdown() != BLE_ERROR_NONE || - Gap::shutdown() != BLE_ERROR_NONE) { -#endif - return BLE_ERROR_INVALID_STATE; - } - initialized = false; return BLE_ERROR_NONE; }