PBL mbed final
Fork of nRF51822 by
Revision 570:f162898cb6c4, committed 2016-01-11
- Comitter:
- vcoubard
- Date:
- Mon Jan 11 10:19:21 2016 +0000
- Parent:
- 569:9e72aa06ec32
- Child:
- 571:bbf6410b6a89
- Commit message:
- Synchronized with git rev 786cd0b9
Author: Andres Amaya Garcia
Modify nRF5xn::shutdown to return actual error code
Changed in this revision
--- a/source/btle/btle.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/btle/btle.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -27,9 +27,7 @@ #include "custom/custom_helper.h" #include "ble/GapEvents.h" -#include "nRF5xGap.h" -#include "nRF5xGattServer.h" -#include "nRF5xSecurityManager.h" +#include "nRF5xn.h" extern "C" { #include "pstorage.h" @@ -41,10 +39,6 @@ #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); @@ -142,6 +136,11 @@ bleGattcEventHandler(p_ble_evt); #endif + nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE); + nRF5xGap &gap = (nRF5xGap &) ble.getGap(); + nRF5xGattServer &gattServer = (nRF5xGattServer &) ble.getGattServer(); + nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager(); + /* Custom event handler */ switch (p_ble_evt->header.evt_id) { case BLE_GAP_EVT_CONNECTED: { @@ -152,11 +151,11 @@ #else Gap::Role_t role = static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role); #endif - nRF5xGap::getInstance().setConnectionHandle(handle); + gap.setConnectionHandle(handle); const Gap::ConnectionParams_t *params = reinterpret_cast<Gap::ConnectionParams_t *>(&(p_ble_evt->evt.gap_evt.params.connected.conn_params)); const ble_gap_addr_t *peer = &p_ble_evt->evt.gap_evt.params.connected.peer_addr; const ble_gap_addr_t *own = &p_ble_evt->evt.gap_evt.params.connected.own_addr; - nRF5xGap::getInstance().processConnectionEvent(handle, + gap.processConnectionEvent(handle, role, static_cast<Gap::AddressType_t>(peer->addr_type), peer->addr, static_cast<Gap::AddressType_t>(own->addr_type), own->addr, @@ -168,7 +167,7 @@ Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle; // Since we are not in a connection and have not started advertising, // store bonds - nRF5xGap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID); + gap.setConnectionHandle (BLE_CONN_HANDLE_INVALID); Gap::DisconnectionReason_t reason; switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) { @@ -187,22 +186,16 @@ 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); + gap.processDisconnectionEvent(handle, reason); break; } case BLE_GAP_EVT_PASSKEY_DISPLAY: - nRF5xSecurityManager::getInstance().processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey); + securityManager.processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey); break; case BLE_GAP_EVT_TIMEOUT: - nRF5xGap::getInstance().processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src)); + gap.processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src)); break; case BLE_GATTC_EVT_TIMEOUT: @@ -214,12 +207,12 @@ case BLE_GAP_EVT_ADV_REPORT: { const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report; - nRF5xGap::getInstance().processAdvertisementReport(advReport->peer_addr.addr, - advReport->rssi, - advReport->scan_rsp, - static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type), - advReport->dlen, - advReport->data); + gap.processAdvertisementReport(advReport->peer_addr.addr, + advReport->rssi, + advReport->scan_rsp, + static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type), + advReport->dlen, + advReport->data); break; } @@ -227,7 +220,7 @@ break; } - nRF5xGattServer::getInstance().hwCallback(p_ble_evt); + gattServer.hwCallback(p_ble_evt); } /*! @brief Callback when an error occurs inside the SoftDevice */
--- a/source/btle/btle_discovery.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/btle/btle_discovery.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -14,16 +14,15 @@ * limitations under the License. */ -#include "nRF5xServiceDiscovery.h" -#include "nRF5xCharacteristicDescriptorDiscoverer.h" -#include "nRF5xGattClient.h" +#include "nRF5xn.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(); - nRF5xCharacteristicDescriptorDiscoverer &characteristicDescriptorDiscoverer = - nRF5xGattClient::getInstance().characteristicDescriptorDiscoverer(); + nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE); + nRF5xGap &gap = (nRF5xGap &) ble.getGap(); + nRF5xGattClient &gattClient = (nRF5xGattClient &) ble.getGattClient(); + nRF5xServiceDiscovery &sdSingleton = gattClient.discovery; switch (p_ble_evt->header.evt_id) { case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: @@ -47,7 +46,7 @@ case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND: default: - sdSingleton.terminateCharacteristicDiscovery(BLE_ERROR_NONE); + sdSingleton.terminateCharacteristicDiscovery(); break; } break; @@ -66,7 +65,7 @@ .len = p_ble_evt->evt.gattc_evt.params.read_rsp.len, .data = p_ble_evt->evt.gattc_evt.params.read_rsp.data, }; - nRF5xGattClient::getInstance().processReadResponse(&response); + gattClient.processReadResponse(&response); } break; @@ -79,7 +78,7 @@ .len = p_ble_evt->evt.gattc_evt.params.write_rsp.len, .data = p_ble_evt->evt.gattc_evt.params.write_rsp.data, }; - nRF5xGattClient::getInstance().processWriteResponse(&response); + gattClient.processWriteResponse(&response); } break; @@ -91,31 +90,9 @@ params.len = p_ble_evt->evt.gattc_evt.params.hvx.len; params.data = p_ble_evt->evt.gattc_evt.params.hvx.data; - nRF5xGattClient::getInstance().processHVXEvent(¶ms); + gattClient.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();
--- a/source/btle/btle_security.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/btle/btle_security.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -16,8 +16,7 @@ #include "btle.h" -#include "nRF5xGap.h" -#include "nRF5xSecurityManager.h" +#include "nRF5xn.h" extern "C" { #include "pstorage.h" @@ -204,17 +203,20 @@ ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result) { + nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE); + nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager(); + switch (p_event->event_id) { case DM_EVT_SECURITY_SETUP: /* started */ { const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params; - nRF5xSecurityManager::getInstance().processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle, + securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle, peerParams->bond, peerParams->mitm, (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps); break; } case DM_EVT_SECURITY_SETUP_COMPLETE: - nRF5xSecurityManager::getInstance(). + securityManager. processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle, (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status)); break; @@ -248,11 +250,11 @@ break; } - nRF5xSecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode); + securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode); break; } case DM_EVT_DEVICE_CONTEXT_STORED: - nRF5xSecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle); + securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle); break; default: break;
--- a/source/nRF5xCharacteristicDescriptorDiscoverer.cpp Mon Jan 11 10:19:20 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -/* 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" - -nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer() : - discoveryRunning() { - // nothing to do -} - -nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() { - // nothing to do -} - -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 there 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 { - for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { - if(discoveryRunning[i].getCharacteristic() == characteristic) { - return true; - } - } - return false; -} - -void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) { - Discovery* discovery = findRunningDiscovery(characteristic); - if(discovery) { - // call terminate anyway - terminate(discovery, BLE_ERROR_NONE); - } -} - -void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) { - Discovery* discovery = findRunningDiscovery(connectionHandle); - // the discovery has been removed - if(!discovery) { - return; - } - - 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->getCharacteristic().getLastHandle(); - - if(startHandle > endHandle) { - terminate(discovery, BLE_ERROR_NONE); - return; - } - - ble_error_t err = gattc_descriptors_discover(connectionHandle, startHandle, endHandle); - if(err) { - terminate(discovery, err); - return; - } -} - -void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle, ble_error_t err) { - Discovery* discovery = findRunningDiscovery(handle); - // the discovery has already been terminated - if(!discovery) { - return; - } - - terminate(discovery, err); -} - -void nRF5xCharacteristicDescriptorDiscoverer::terminate(Discovery* discovery, ble_error_t err) { - // temporary copy, user code can try to launch a new discovery in the onTerminate - // callback. So, this discovery should not appear in such case. - Discovery tmp = *discovery; - *discovery = Discovery(); - tmp.terminate(err); -} - -nRF5xCharacteristicDescriptorDiscoverer::Discovery* -nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) { - for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { - if((discoveryRunning[i].getCharacteristic() == characteristic) && - (discoveryRunning[i].isEmpty() == false)) { - return &discoveryRunning[i]; - } - } - return NULL; -} - -nRF5xCharacteristicDescriptorDiscoverer::Discovery* -nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) { - for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { - if((discoveryRunning[i].getCharacteristic().getConnectionHandle() == handle) && - (discoveryRunning[i].isEmpty() == false)) { - return &discoveryRunning[i]; - } - } - return NULL; -} - -nRF5xCharacteristicDescriptorDiscoverer::Discovery* -nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() { - for(size_t i = 0; i < MAXIMUM_CONCURRENT_CONNECTIONS_COUNT; ++i) { - if(discoveryRunning[i].isEmpty()) { - 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; - } -} - -// implementation of nRF5xCharacteristicDescriptorDiscoverer::Discovery - -nRF5xCharacteristicDescriptorDiscoverer::Discovery::Discovery() : - characteristic(), onDiscovery(), onTerminate() { -} - -nRF5xCharacteristicDescriptorDiscoverer::Discovery::Discovery( - const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) : - characteristic(c), onDiscovery(dCb), onTerminate(tCb) { -} - -void nRF5xCharacteristicDescriptorDiscoverer::Discovery::process( - GattAttribute::Handle_t handle, const UUID& uuid) { - CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { - characteristic, - DiscoveredCharacteristicDescriptor( - characteristic.getGattClient(), - characteristic.getConnectionHandle(), - handle, - uuid - ) - }; - onDiscovery.call(¶ms); -} - -void nRF5xCharacteristicDescriptorDiscoverer::Discovery::terminate(ble_error_t err) { - CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = { - characteristic, - err - }; - - onTerminate.call(¶ms); -} - -bool nRF5xCharacteristicDescriptorDiscoverer::Discovery::isEmpty() const { - return *this == Discovery(); -} - -const DiscoveredCharacteristic& nRF5xCharacteristicDescriptorDiscoverer::Discovery::getCharacteristic() const { - return characteristic; -} \ No newline at end of file
--- a/source/nRF5xCharacteristicDescriptorDiscoverer.h Mon Jan 11 10:19:20 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,214 +0,0 @@ -/* 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 between BLE API and Nordic stack regarding Characteristic - * Descriptor discovery. The BLE API can launch, monitor 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: - /** - * @brief Construct a new characteristic descriptor discoverer. - */ - nRF5xCharacteristicDescriptorDiscoverer(); - - /** - * @brief Destroy a characteristic descriptor discoverer. - */ - ~nRF5xCharacteristicDescriptorDiscoverer(); - - /** - * Launch a new characteristic descriptor discovery for a given DiscoveredCharacteristic. - * @param characteristic The characteristic owning the descriptors to discover. - * @param discoveryCallback The callback called when a descriptor is discovered. - * @param terminationCallback The callback called when the discovery process end. - * @return BLE_ERROR_NONE if characteristic descriptor discovery is launched successfully; - * else an appropriate error. - * @note: this will be called by BLE API side. - */ - ble_error_t launch( - const DiscoveredCharacteristic& characteristic, - const DiscoveryCallback_t& discoveryCallback, - const TerminationCallback_t& terminationCallback - ); - - /** - * @brief indicate if a characteristic descriptor discovery is active for a - * given DiscoveredCharacteristic. - * @param characteristic The characteristic for whom the descriptor might be - * currently discovered. - * @return true if descriptors of characteristic are discovered, false otherwise. - * @note: this will be called by BLE API side. - */ - bool isActive(const DiscoveredCharacteristic& characteristic) const; - - /** - * @brief request the termination of characteristic descriptor discovery - * for a give DiscoveredCharacteristic - * @param characteristic The characteristic for whom the descriptor discovery - * should be stopped. - * @note: this will be called by BLE API side. - */ - void requestTerminate(const DiscoveredCharacteristic& characteristic); - - /** - * @brief process descriptors discovered from the Nordic stack. - * @param connectionHandle The connection handle upon which descriptors has been - * discovered. - * @param descriptors Discovered descriptors. - * @note This will be called by the Nordic stack. - */ - void process(uint16_t connectionHandle, const ble_gattc_evt_desc_disc_rsp_t& descriptors); - - /** - * @brief Called by the Nordic stack when the discovery is over. - * @param The connection handle upon which the discovery process is done. - * @param err An error if the termination is due to an error. - */ - void terminate(uint16_t connectionHandle, ble_error_t err); - -private: - // protection against copy construction and assignment - nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&); - nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&); - - /** - * @brief Discovery process, it store the DiscoveredCharacteristic, the - * discovery callback and the termination callback. - */ - class Discovery { - public: - /** - * @brief Construct an empty discovery, such can be considerate as a not running discovery. - * @note #isEmpty function will return true - */ - Discovery(); - - /** - * @brief Construct a valid discovery process. - * - * @param c the characteristic from whom descriptors will be discovered. - * @param dCb The discovery callback called each time a descriptor is discovered. - * @param tCb The termination callback called when the discovery terminate. - * - * @note #isEmpty function will return false - */ - Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb); - - /** - * @brief Process the discovery of a descriptor. - * - * @param handle The attribute handle of the descriptor found - * @param uuid The UUID of the descriptor found. - */ - void process(GattAttribute::Handle_t handle, const UUID& uuid); - - /** - * @brief Terminate the discovery process. - * - * @param err Error associate with the termination - * @note after this call #isEmpty function will return true. - */ - void terminate(ble_error_t err); - - /** - * @brief check if the discovery process is empty or not. Empty discovery are - * not running. - * - * @detail Discovery are empty after: - * - a default construction - * - a copy construction form a default constructed - * - an assignment from a default constructed Discovery - * @return true if the Discovery is empty and false otherwise. - */ - bool isEmpty() const; - - /** - * @brief return the characteristic from whom descriptors are discovered. - * @return the characteristic from whom descriptors are discovered. - */ - const DiscoveredCharacteristic& getCharacteristic() const; - - /** - * @brief equal to operator, test if two discovery process are equal - * - * @param lhs left hand side of the expression - * @param rhs right hand side of the expression - * @return true if lhs == rhs - */ - friend bool operator==(const Discovery& lhs, const Discovery& rhs) { - return lhs.characteristic == rhs.characteristic && - lhs.onDiscovery == rhs.onDiscovery && - lhs.onTerminate == rhs.onTerminate; - } - - /** - * @brief not equal to operator, test if two discovery process are not equal - * - * @param lhs left hand side of the expression - * @param rhs right hand side of the expression - * @return true if lhs != rhs - */ - friend bool operator!=(const Discovery& lhs, const Discovery& rhs) { - return !(lhs == rhs); - } - - private: - DiscoveredCharacteristic characteristic; - DiscoveryCallback_t onDiscovery; - TerminationCallback_t onTerminate; - }; - - // find a running discovery process - Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic); - Discovery* findRunningDiscovery(uint16_t handle); - - // Called to terminate a discovery is over. - void terminate(Discovery* discovery, ble_error_t err); - - // get one slot for a discovery process - Discovery* getAvailableDiscoverySlot(); - - // indicate if a connection is already running a discovery - bool isConnectionInUse(uint16_t connHandle); - - // low level start of a discovery - static ble_error_t gattc_descriptors_discover(uint16_t connection_handle, uint16_t start_handle, uint16_t end_handle); - - // count of concurrent connections which can run a descriptor discovery process - static const size_t MAXIMUM_CONCURRENT_CONNECTIONS_COUNT = 3; - - // array of running discoveries - Discovery discoveryRunning[MAXIMUM_CONCURRENT_CONNECTIONS_COUNT]; -}; - -#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/ \ No newline at end of file
--- a/source/nRF5xDiscoveredCharacteristic.h Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xDiscoveredCharacteristic.h Mon Jan 11 10:19:21 2016 +0000 @@ -36,10 +36,6 @@ ble_gatt_char_props_t propsIn, GattAttribute::Handle_t declHandleIn, GattAttribute::Handle_t valueHandleIn); - - void setLastHandle(GattAttribute::Handle_t last) { - lastHandle = last; - } }; #endif /* __NRF_DISCOVERED_CHARACTERISTIC_H__ */ \ No newline at end of file
--- a/source/nRF5xGap.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xGap.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -14,20 +14,17 @@ * limitations under the License. */ -#include "nRF5xGap.h" +#include "nRF5xn.h" #include "mbed.h" +#include "ble/BLE.h" #include "common/common.h" #include "ble_advdata.h" #include "ble_hci.h" -nRF5xGap &nRF5xGap::getInstance() { - static nRF5xGap m_instance; - return m_instance; -} - void radioNotificationStaticCallback(bool param) { - nRF5xGap::getInstance().processRadioNotificationEvent(param); + nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap(); + gap.processRadioNotificationEvent(param); } /**************************************************************************/ @@ -338,6 +335,29 @@ /**************************************************************************/ /*! + @brief Clear nRF5xGap's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t nRF5xGap::reset(void) +{ + /* Clear all state that is from the parent, including private members */ + if (Gap::reset() != 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:20 2016 +0000 +++ b/source/nRF5xGap.h Mon Jan 11 10:19:21 2016 +0000 @@ -44,8 +44,6 @@ class nRF5xGap : public Gap { public: - static nRF5xGap &getInstance(); - /* Functions that must be implemented from Gap */ virtual ble_error_t setAddress(AddressType_t type, const Address_t address); virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address); @@ -76,6 +74,8 @@ virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params); virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params); + virtual ble_error_t reset(void); + virtual ble_error_t initRadioNotification(void) { if (ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationStaticCallback) == NRF_SUCCESS) { return BLE_ERROR_NONE; @@ -196,6 +196,12 @@ private: uint16_t m_connectionHandle; + + /* + * Allow instantiation from nRF5xn when required. + */ + friend class nRF5xn; + nRF5xGap() { m_connectionHandle = BLE_CONN_HANDLE_INVALID; }
--- a/source/nRF5xGattClient.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xGattClient.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -16,15 +16,6 @@ #include "nRF5xGattClient.h" -nRF5xGattClient & -nRF5xGattClient::getInstance(void) { - static nRF5xGattClient* nRFGattClientSingleton = NULL; - if (nRFGattClientSingleton == NULL) { - nRFGattClientSingleton = new nRF5xGattClient(); - } - return *nRFGattClientSingleton; -} - #if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) ble_error_t nRF5xGattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle, @@ -33,27 +24,6 @@ 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:20 2016 +0000 +++ b/source/nRF5xGattClient.h Mon Jan 11 10:19:21 2016 +0000 @@ -19,13 +19,10 @@ #include "ble/GattClient.h" #include "nRF5xServiceDiscovery.h" -#include "nRF5xCharacteristicDescriptorDiscoverer.h" class nRF5xGattClient : public GattClient { public: - static nRF5xGattClient &getInstance(); - /** * When using S110, all Gatt client features will return * BLE_ERROR_NOT_IMPLEMENTED @@ -88,14 +85,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(); } /** @@ -103,31 +100,9 @@ * 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) { @@ -170,26 +145,42 @@ } } + /** + * @brief Clear nRF5xGattClient's state. + * + * @return + * BLE_ERROR_NONE if successful. + */ + virtual ble_error_t reset(void) { + /* Clear all state that is from the parent, including private members */ + if (GattClient::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + /* Clear derived class members */ + discovery.reset(); + + return BLE_ERROR_NONE; + } + public: - nRF5xGattClient() : _discovery(this) { + /* + * Allow instantiation from nRF5xn when required. + */ + friend class nRF5xn; + + nRF5xGattClient() : discovery(this) { /* empty */ } - nRF5xServiceDiscovery& discovery() { - return _discovery; - } - - nRF5xCharacteristicDescriptorDiscoverer& characteristicDescriptorDiscoverer() { - return _characteristicDescriptorDiscoverer; - } + friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt); private: nRF5xGattClient(const nRF5xGattClient &); const nRF5xGattClient& operator=(const nRF5xGattClient &); private: - nRF5xServiceDiscovery _discovery; - nRF5xCharacteristicDescriptorDiscoverer _characteristicDescriptorDiscoverer; + nRF5xServiceDiscovery discovery; #endif // if !S110 };
--- a/source/nRF5xGattServer.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xGattServer.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -20,12 +20,7 @@ #include "common/common.h" #include "btle/custom/custom_helper.h" -#include "nRF5xGap.h" - -nRF5xGattServer &nRF5xGattServer::getInstance(void) { - static nRF5xGattServer m_instance; - return m_instance; -} +#include "nRF5xn.h" /**************************************************************************/ /*! @@ -241,7 +236,8 @@ hvx_params.p_len = &len; if (connectionHandle == BLE_CONN_HANDLE_INVALID) { /* use the default connection handle if the caller hasn't specified a valid connectionHandle. */ - connectionHandle = nRF5xGap::getInstance().getConnectionHandle(); + nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap(); + connectionHandle = gap.getConnectionHandle(); } error_t error = (error_t) sd_ble_gatts_hvx(connectionHandle, &hvx_params); if (error != ERROR_NONE) { @@ -280,7 +276,8 @@ ble_error_t nRF5xGattServer::areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP) { /* Forward the call with the default connection handle. */ - return areUpdatesEnabled(nRF5xGap::getInstance().getConnectionHandle(), characteristic, enabledP); + nRF5xGap &gap = (nRF5xGap &) nRF5xn::Instance(BLE::DEFAULT_INSTANCE).getGap(); + return areUpdatesEnabled(gap.getConnectionHandle(), characteristic, enabledP); } ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP) @@ -312,6 +309,33 @@ /**************************************************************************/ /*! + @brief Clear nRF5xGattServer's state. + + @returns ble_error_t + + @retval BLE_ERROR_NONE + Everything executed properly +*/ +/**************************************************************************/ +ble_error_t nRF5xGattServer::reset(void) +{ + /* Clear all state that is from the parent, including private members */ + if (GattServer::reset() != 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:20 2016 +0000 +++ b/source/nRF5xGattServer.h Mon Jan 11 10:19:21 2016 +0000 @@ -27,8 +27,6 @@ class nRF5xGattServer : public GattServer { public: - static nRF5xGattServer &getInstance(); - /* Functions that must be implemented from GattServer */ virtual ble_error_t addService(GattService &); virtual ble_error_t read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP); @@ -37,11 +35,13 @@ virtual ble_error_t write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false); virtual ble_error_t areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP); virtual ble_error_t areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP); + virtual ble_error_t reset(void); /* nRF51 Functions */ void eventCallback(void); void hwCallback(ble_evt_t *p_ble_evt); + private: const static unsigned BLE_TOTAL_CHARACTERISTICS = 20; const static unsigned BLE_TOTAL_DESCRIPTORS = 8; @@ -86,6 +86,11 @@ uint8_t descriptorCount; uint16_t nrfDescriptorHandles[BLE_TOTAL_DESCRIPTORS]; + /* + * Allow instantiation from nRF5xn when required. + */ + friend class nRF5xn; + nRF5xGattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles() { /* empty */ }
--- a/source/nRF5xSecurityManager.cpp Mon Jan 11 10:19:20 2016 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -/* mbed Microcontroller Library - * Copyright (c) 2006-2013 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 "nRF5xSecurityManager.h" - -nRF5xSecurityManager &nRF5xSecurityManager::getInstance(void) { - static nRF5xSecurityManager* m_instance = NULL; - if (m_instance == NULL) { - m_instance = new nRF5xSecurityManager(); - } - return *m_instance; -} \ No newline at end of file
--- a/source/nRF5xSecurityManager.h Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xSecurityManager.h Mon Jan 11 10:19:21 2016 +0000 @@ -25,8 +25,6 @@ class nRF5xSecurityManager : public SecurityManager { public: - static nRF5xSecurityManager &getInstance(); - /* Functions that must be implemented from SecurityManager */ virtual ble_error_t init(bool enableBonding, bool requireMITM, @@ -47,7 +45,27 @@ return btle_purgeAllBondingState(); } + /** + * @brief Clear nRF5xSecurityManager's state. + * + * @return + * BLE_ERROR_NONE if successful. + */ + virtual ble_error_t reset(void) + { + if (SecurityManager::reset() != BLE_ERROR_NONE) { + return BLE_ERROR_INVALID_STATE; + } + + return BLE_ERROR_NONE; + } + public: + /* + * Allow instantiation from nRF5xn when required. + */ + friend class nRF5xn; + nRF5xSecurityManager() { /* empty */ }
--- a/source/nRF5xServiceDiscovery.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xServiceDiscovery.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -27,32 +27,22 @@ .start_handle = startHandle, .end_handle = endHandle }; - 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; + 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; + } } - if (err) { - terminateCharacteristicDiscovery(err); - } - return err; + return BLE_ERROR_NONE; } void @@ -88,6 +78,7 @@ 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. */ @@ -123,61 +114,37 @@ void nRF5xServiceDiscovery::progressCharacteristicDiscovery(void) { - if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) { - return; - } - - if ((discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) && (numCharacteristics > 0)) { - discoveredCharacteristic.setLastHandle(characteristics[0].getDeclHandle() - 1); - + /* Iterate through the previously discovered characteristics cached in characteristics[]. */ + while ((state == CHARACTERISTIC_DISCOVERY_ACTIVE) && (characteristicIndex < numCharacteristics)) { if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || - ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) && + ((matchingCharacteristicUUID == characteristics[characteristicIndex].getUUID()) && (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { if (characteristicCallback) { - characteristicCallback(&discoveredCharacteristic); + characteristicCallback(&characteristics[characteristicIndex]); } } - } - - for (uint8_t i = 0; i < numCharacteristics; ++i) { - if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) { - return; - } - - if (i == (numCharacteristics - 1)) { - discoveredCharacteristic = characteristics[i]; - break; - } else { - characteristics[i].setLastHandle(characteristics[i + 1].getDeclHandle() - 1); - } - if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || - ((matchingCharacteristicUUID == characteristics[i].getUUID()) && - (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { - if (characteristicCallback) { - characteristicCallback(&characteristics[i]); - } - } - } - - if (state != CHARACTERISTIC_DISCOVERY_ACTIVE) { - return; + characteristicIndex++; } - 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. */ + /* 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. */ - 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); + 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(); + } + } else { + terminateCharacteristicDiscovery(); } - } else { - terminateCharacteristicDiscovery(BLE_ERROR_NONE); } }
--- a/source/nRF5xServiceDiscovery.h Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xServiceDiscovery.h Mon Jan 11 10:19:21 2016 +0000 @@ -41,6 +41,7 @@ gattc(gattcIn), serviceIndex(0), numServices(0), + characteristicIndex(0), numCharacteristics(0), state(INACTIVE), services(), @@ -94,14 +95,36 @@ terminateServiceDiscovery(); } - void terminate(Gap::Handle_t connectionHandle) { - if(connHandle == connectionHandle) { - terminate(); - } + virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { + onTerminationCallback = callback; } - virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) { - onTerminationCallback = callback; + /** + * @brief Clear nRF5xServiceDiscovery's state. + * + * @return + * BLE_ERROR_NONE if successful. + */ + virtual ble_error_t reset(void) { + /* Clear all state that is from the parent, including private members */ + if (ServiceDiscovery::reset() != 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; } private: @@ -116,8 +139,6 @@ void removeFirstServiceNeedingUUIDDiscovery(void); void terminateServiceDiscovery(void) { - discoveredCharacteristic = nRF5xDiscoveredCharacteristic(); - bool wasActive = isActive(); state = INACTIVE; @@ -126,24 +147,8 @@ } } - void terminateCharacteristicDiscovery(ble_error_t err) { + void terminateCharacteristicDiscovery(void) { if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) { - if(discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) { - if(err == BLE_ERROR_NONE) { - // fullfill the last characteristic - discoveredCharacteristic.setLastHandle(services[serviceIndex].getEndHandle()); - - if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) || - ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) && - (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) { - if (characteristicCallback) { - characteristicCallback(&discoveredCharacteristic); - } - } - } - discoveredCharacteristic = nRF5xDiscoveredCharacteristic(); - } - state = SERVICE_DISCOVERY_ACTIVE; } serviceIndex++; /* Progress service index to keep discovery alive. */ @@ -157,6 +162,7 @@ void resetDiscoveredCharacteristics(void) { numCharacteristics = 0; + characteristicIndex = 0; } private: @@ -303,6 +309,7 @@ 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 { @@ -321,19 +328,6 @@ CharUUIDDiscoveryQueue charUUIDDiscoveryQueue; TerminationCallback_t onTerminationCallback; - - /* - * The currently discovered characteristic. Discovery of a characteristic - * is a two phase process. - * First, declaration handle is fetched, it provide the UUID, the value handle and - * the properties of a characteristic. - * Second, the next declaration handle is fetched, with its declaration handle, it is - * possible to compute the last handle of the discovered characteristic and fill the - * missing part of the object. - * If there is no remaining characteristic to discover, the last handle of the - * discovered characteristic will be set to the last handle of its enclosing service. - */ - nRF5xDiscoveredCharacteristic discoveredCharacteristic; }; #endif /*__NRF_SERVICE_DISCOVERY_H__*/ \ No newline at end of file
--- a/source/nRF5xn.cpp Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xn.cpp Mon Jan 11 10:19:21 2016 +0000 @@ -32,16 +32,33 @@ static nRF5xn deviceInstance; /** + * The singleton for nRF5xGap. This has been kept static because it is + * always needed for any application that uses BLE. + */ +nRF5xGap nRF5xn::_gapInstance; + +/** * BLE-API requires an implementation of the following function in order to * obtain its transport handle. */ BLEInstanceBase * createBLEInstance(void) { - return (&deviceInstance); + return &nRF5xn::Instance(BLE::DEFAULT_INSTANCE); +} + +nRF5xn& nRF5xn::Instance(BLE::InstanceID_t instanceId) +{ + return deviceInstance; } -nRF5xn::nRF5xn(void) : initialized(false), instanceID(BLE::DEFAULT_INSTANCE) +nRF5xn::nRF5xn(void) : + initialized(false), + instanceID(BLE::DEFAULT_INSTANCE), + gapInstance(NULL), + gattServerInstance(NULL), + gattClientInstance(NULL), + securityManagerInstance(NULL) { } @@ -104,16 +121,69 @@ 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 first. This is because we need to disable all + * interrupts. Otherwise if we clear the BLE API and glue code first there + * will be many NULL references and no config information which could lead + * to errors if the shutdown process is interrupted. + */ if(softdevice_handler_sd_disable() != NRF_SUCCESS) { return BLE_STACK_BUSY; } + + /* Shutdown the BLE API and nRF51 glue code */ + ble_error_t error; + + if (gattServerInstance != NULL) { + error = gattServerInstance->reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + } + + if (securityManagerInstance != NULL) { + error = securityManagerInstance->reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + } + + /* S110 does not support BLE client features, nothing to reset. */ +#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110) + if (gattClientInstance != NULL) { + error = gattClientInstance->reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + } +#endif + + /* Gap instance is always present */ + error = gapInstance->reset(); + if (error != BLE_ERROR_NONE) { + return error; + } + initialized = false; return BLE_ERROR_NONE; }
--- a/source/nRF5xn.h Mon Jan 11 10:19:20 2016 +0000 +++ b/source/nRF5xn.h Mon Jan 11 10:19:21 2016 +0000 @@ -41,32 +41,153 @@ virtual ble_error_t shutdown(void); virtual const char *getVersion(void); + /** + * Accessors to GAP. This function checks whether gapInstance points to an + * object. If if does not, then the gapInstance is updated to + * &_getInstance before returning. + * + * @return A reference to GattServer. + * + * @note Unlike the GattClient, GattServer and SecurityManager, Gap is + * always needed in a BLE application. Therefore it is allocated + * statically. + */ virtual Gap &getGap() { - return nRF5xGap::getInstance(); + if (gapInstance == NULL) { + gapInstance = &_gapInstance; + } + return *gapInstance; + }; + + /** + * Accessors to GATT Server. This function checks whether a GattServer + * object was previously instantiated. If such object does not exist, then + * it is created before returning. + * + * @return A reference to GattServer. + */ + virtual GattServer &getGattServer() { + if (gattServerInstance == NULL) { + gattServerInstance = new nRF5xGattServer(); + } + return *gattServerInstance; }; + + /** + * Accessors to GATT Client. This function checks whether a GattClient + * object was previously instantiated. If such object does not exist, then + * it is created before returning. + * + * @return A reference to GattClient. + */ + virtual GattClient &getGattClient() { + if (gattClientInstance == NULL) { + gattClientInstance = new nRF5xGattClient(); + } + return *gattClientInstance; + } + + /** + * Accessors to Security Manager. This function checks whether a SecurityManager + * object was previously instantiated. If such object does not exist, then + * it is created before returning. + * + * @return A reference to GattServer. + */ + virtual SecurityManager &getSecurityManager() { + if (securityManagerInstance == NULL) { + securityManagerInstance = new nRF5xSecurityManager(); + } + return *securityManagerInstance; + } + + /** + * Accessors to GAP. This function checks whether gapInstance points to an + * object. If if does not, then the gapInstance is updated to + * &_getInstance before returning. + * + * @return A const reference to GattServer. + * + * @note Unlike the GattClient, GattServer and SecurityManager, Gap is + * always needed in a BLE application. Therefore it is allocated + * statically. + * + * @note The accessor is able to modify the object's state because the + * internal pointer has been declared mutable. + */ virtual const Gap &getGap() const { - return nRF5xGap::getInstance(); + if (gapInstance == NULL) { + gapInstance = &_gapInstance; + } + return *gapInstance; }; - virtual GattServer &getGattServer() { - return nRF5xGattServer::getInstance(); - }; + + /** + * Accessors to GATT Server. This function checks whether a GattServer + * object was previously instantiated. If such object does not exist, then + * it is created before returning. + * + * @return A const reference to GattServer. + * + * @note The accessor is able to modify the object's state because the + * internal pointer has been declared mutable. + */ virtual const GattServer &getGattServer() const { - return nRF5xGattServer::getInstance(); + if (gattServerInstance == NULL) { + gattServerInstance = new nRF5xGattServer(); + } + return *gattServerInstance; }; - virtual GattClient &getGattClient() { - return nRF5xGattClient::getInstance(); - } + + /** + * Accessors to Security Manager. This function checks whether a SecurityManager + * object was previously instantiated. If such object does not exist, then + * it is created before returning. + * + * @return A const reference to GattServer. + * + * @note The accessor is able to modify the object's state because the + * internal pointer has been declared mutable. + */ virtual const SecurityManager &getSecurityManager() const { - return nRF5xSecurityManager::getInstance(); + if (securityManagerInstance == NULL) { + securityManagerInstance = new nRF5xSecurityManager(); + } + return *securityManagerInstance; } - virtual SecurityManager &getSecurityManager() { - return nRF5xSecurityManager::getInstance(); - } + virtual void waitForEvent(void); +public: + static nRF5xn& Instance(BLE::InstanceID_t instanceId); + private: bool initialized; BLE::InstanceID_t instanceID; + +private: + static nRF5xGap _gapInstance; /**< Gap instance whose reference is returned from a call to + * getGap(). Unlike the GattClient, GattServer and + * SecurityManager, Gap is always needed in a BLE application. + * Therefore it is allocated statically. */ + +private: + mutable nRF5xGap *gapInstance; /**< Pointer to the Gap object instance. + * If NULL, then Gap has not been initialized. + * The pointer has been declared as 'mutable' so that + * it can be assigned inside a 'const' function. */ + mutable nRF5xGattServer *gattServerInstance; /**< Pointer to the GattServer object instance. + * If NULL, then GattServer has not been initialized. + * The pointer has been declared as 'mutable' so that + * it can be assigned inside a 'const' function. */ + mutable nRF5xGattClient *gattClientInstance; /**< Pointer to the GattClient object instance. + * If NULL, then GattClient has not been initialized. + * The pointer has been declared as 'mutable' so that + * it can be assigned inside a 'const' function. */ + mutable nRF5xSecurityManager *securityManagerInstance; /**< Pointer to the SecurityManager object instance. + * If NULL, then SecurityManager has not been initialized. + * The pointer has been declared as 'mutable' so that + * it can be assigned inside a 'const' function. */ }; #endif \ No newline at end of file