Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: nrf51-sdk-bluetooth-mdw
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;
}
