Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of nRF51822 by
Revision 344:2a44e5fd26bc, committed 2015-06-19
- Comitter:
- rgrover1
- Date:
- Fri Jun 19 15:55:34 2015 +0100
- Parent:
- 343:6675661fa600
- Child:
- 345:dfde56236c36
- Commit message:
- Synchronized with git rev c796271c
Author: Rohit Grover
Merge branch 'gattClient' into develop
Changed in this revision
--- a/btle/btle.cpp Fri Jun 19 15:55:34 2015 +0100
+++ b/btle/btle.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -36,6 +36,7 @@
#include "device_manager.h"
#include "ble_hci.h"
+#include "btle_discovery.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);
@@ -104,6 +105,8 @@
dm_ble_evt_handler(p_ble_evt);
+ bleGattcEventHandler(p_ble_evt);
+
/* Custom event handler */
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED: {
@@ -113,6 +116,7 @@
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;
nRF51Gap::getInstance().processConnectionEvent(handle,
+ static_cast<Gap::Role_t>(p_ble_evt->evt.gap_evt.params.connected.role),
static_cast<Gap::AddressType_t>(peer->addr_type), peer->addr,
static_cast<Gap::AddressType_t>(own->addr_type), own->addr,
params);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/btle/btle_discovery.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,85 @@
+/* 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 "nRF51ServiceDiscovery.h"
+#include "nRF51GattClient.h"
+
+void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
+{
+ nRF51ServiceDiscovery &sdSingleton = nRF51GattClient::getInstance().discovery;
+
+ switch (p_ble_evt->header.evt_id) {
+ case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+ switch (p_ble_evt->evt.gattc_evt.gatt_status) {
+ case BLE_GATT_STATUS_SUCCESS:
+ sdSingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
+ break;
+
+ case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+ default:
+ sdSingleton.terminate();
+ break;
+ }
+ break;
+
+ case BLE_GATTC_EVT_CHAR_DISC_RSP:
+ switch (p_ble_evt->evt.gattc_evt.gatt_status) {
+ case BLE_GATT_STATUS_SUCCESS:
+ sdSingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
+ break;
+
+ case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+ default:
+ sdSingleton.terminateCharacteristicDiscovery();
+ break;
+ }
+ break;
+
+ case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
+ if (sdSingleton.isActive()) {
+ sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
+ }
+ break;
+
+ case BLE_GATTC_EVT_READ_RSP:
+ if (DiscoveredCharacteristic::onDataReadCallback != NULL) {
+ GattReadCallbackParams response = {
+ .handle = p_ble_evt->evt.gattc_evt.params.read_rsp.handle,
+ .offset = p_ble_evt->evt.gattc_evt.params.read_rsp.offset,
+ .len = p_ble_evt->evt.gattc_evt.params.read_rsp.len,
+ .data = p_ble_evt->evt.gattc_evt.params.read_rsp.data,
+ };
+ DiscoveredCharacteristic::onDataReadCallback(&response);
+ }
+ break;
+
+ case BLE_GATTC_EVT_WRITE_RSP:
+ if (DiscoveredCharacteristic::onDataWriteCallback != NULL) {
+ GattWriteCallbackParams response = {
+ .handle = p_ble_evt->evt.gattc_evt.params.write_rsp.handle,
+ .writeOp = (GattWriteCallbackParams::WriteOp_t)(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op),
+ .offset = p_ble_evt->evt.gattc_evt.params.write_rsp.offset,
+ .len = p_ble_evt->evt.gattc_evt.params.write_rsp.len,
+ .data = p_ble_evt->evt.gattc_evt.params.write_rsp.data,
+ };
+ DiscoveredCharacteristic::onDataWriteCallback(&response);
+ }
+ break;
+ }
+
+ sdSingleton.progressCharacteristicDiscovery();
+ sdSingleton.progressServiceDiscovery();
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/btle/btle_discovery.h Fri Jun 19 15:55:34 2015 +0100 @@ -0,0 +1,22 @@ +/* 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. + */ + +#ifndef _BTLE_DISCOVERY_H_ +#define _BTLE_DISCOVERY_H_ + +void bleGattcEventHandler(const ble_evt_t *p_ble_evt); + +#endif /*_BTLE_DISCOVERY_H_*/ \ No newline at end of file
--- a/nRF51822n.h Fri Jun 19 15:55:34 2015 +0100
+++ b/nRF51822n.h Fri Jun 19 15:55:34 2015 +0100
@@ -22,6 +22,7 @@
#include "BLEDevice.h"
#include "nRF51Gap.h"
#include "nRF51GattServer.h"
+#include "nRF51GattClient.h"
#include "btle.h"
#include "btle_security.h"
@@ -39,6 +40,9 @@
virtual GattServer &getGattServer() {
return nRF51GattServer::getInstance();
};
+ virtual GattClient &getGattClient() {
+ return nRF51GattClient::getInstance();
+ }
virtual ble_error_t init(void);
virtual ble_error_t shutdown(void);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51DiscoveredCharacteristic.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,63 @@
+/* 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 "nRF51DiscoveredCharacteristic.h"
+#include "nRF51GattClient.h"
+#include "ble_gatt.h"
+
+void
+nRF51DiscoveredCharacteristic::setup(nRF51GattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ ble_gatt_char_props_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn)
+{
+ gattc = gattcIn;
+ connHandle = connectionHandleIn;
+ declHandle = declHandleIn;
+ valueHandle = valueHandleIn;
+
+ props._broadcast = propsIn.broadcast;
+ props._read = propsIn.read;
+ props._writeWoResp = propsIn.write_wo_resp;
+ props._write = propsIn.write;
+ props._notify = propsIn.notify;
+ props._indicate = propsIn.indicate;
+ props._authSignedWrite = propsIn.auth_signed_wr;
+}
+
+void
+nRF51DiscoveredCharacteristic::setup(nRF51GattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ UUID::ShortUUIDBytes_t uuidIn,
+ ble_gatt_char_props_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn)
+{
+ gattc = gattcIn;
+ connHandle = connectionHandleIn;
+ uuid = uuidIn;
+ declHandle = declHandleIn;
+ valueHandle = valueHandleIn;
+
+ props._broadcast = propsIn.broadcast;
+ props._read = propsIn.read;
+ props._writeWoResp = propsIn.write_wo_resp;
+ props._write = propsIn.write;
+ props._notify = propsIn.notify;
+ props._indicate = propsIn.indicate;
+ props._authSignedWrite = propsIn.auth_signed_wr;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51DiscoveredCharacteristic.h Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,41 @@
+/* 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.
+ */
+
+#ifndef __NRF_DISCOVERED_CHARACTERISTIC_H__
+#define __NRF_DISCOVERED_CHARACTERISTIC_H__
+
+#include "DiscoveredCharacteristic.h"
+#include "ble_gatt.h"
+
+class nRF51GattClient; /* forward declaration */
+
+class nRF51DiscoveredCharacteristic : public DiscoveredCharacteristic {
+public:
+ void setup(nRF51GattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ ble_gatt_char_props_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn);
+
+ void setup(nRF51GattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ UUID::ShortUUIDBytes_t uuidIn,
+ ble_gatt_char_props_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn);
+};
+
+#endif /* __NRF_DISCOVERED_CHARACTERISTIC_H__ */
\ No newline at end of file
--- a/nRF51Gap.cpp Fri Jun 19 15:55:34 2015 +0100
+++ b/nRF51Gap.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -206,6 +206,66 @@
return BLE_ERROR_NONE;
}
+ble_error_t nRF51Gap::connect(const Address_t peerAddr,
+ Gap::AddressType_t peerAddrType,
+ const ConnectionParams_t *connectionParams,
+ const GapScanningParams *scanParamsIn)
+{
+ ble_gap_addr_t addr;
+ addr.addr_type = peerAddrType;
+ memcpy(addr.addr, peerAddr, Gap::ADDR_LEN);
+
+ ble_gap_conn_params_t connParams;
+ if (connectionParams != NULL) {
+ connParams.min_conn_interval = connectionParams->minConnectionInterval;
+ connParams.max_conn_interval = connectionParams->maxConnectionInterval;
+ connParams.slave_latency = connectionParams->slaveLatency;
+ connParams.conn_sup_timeout = connectionParams->connectionSupervisionTimeout;
+ } else {
+ connParams.min_conn_interval = 50;
+ connParams.max_conn_interval = 100;
+ connParams.slave_latency = 0;
+ connParams.conn_sup_timeout = 600;
+ }
+
+ ble_gap_scan_params_t scanParams;
+ scanParams.active = 0; /**< If 1, perform active scanning (scan requests). */
+ scanParams.selective = 0; /**< If 1, ignore unknown devices (non whitelisted). */
+ scanParams.p_whitelist = NULL; /**< Pointer to whitelist, NULL if none is given. */
+ if (scanParamsIn != NULL) {
+ scanParams.interval = scanParamsIn->getInterval(); /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+ scanParams.window = scanParamsIn->getWindow(); /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+ scanParams.timeout = scanParamsIn->getTimeout(); /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+ } else {
+ scanParams.interval = 500; /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+ scanParams.window = 200; /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+ scanParams.timeout = 0; /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+ }
+
+ uint32_t rc = sd_ble_gap_connect(&addr, &scanParams, &connParams);
+ if (rc == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ }
+ switch (rc) {
+ case NRF_ERROR_INVALID_ADDR:
+ return BLE_ERROR_INVALID_PARAM;
+ case NRF_ERROR_INVALID_PARAM:
+ return BLE_ERROR_INVALID_PARAM;
+ case NRF_ERROR_INVALID_STATE:
+ return BLE_ERROR_INVALID_STATE;
+ case BLE_ERROR_GAP_INVALID_BLE_ADDR:
+ return BLE_ERROR_INVALID_PARAM;
+ case NRF_ERROR_NO_MEM:
+ return BLE_ERROR_NO_MEM;
+ case NRF_ERROR_BUSY:
+ return BLE_STACK_BUSY;
+ default:
+ case BLE_ERROR_GAP_WHITELIST_IN_USE:
+ return BLE_ERROR_UNSPECIFIED;
+ }
+}
+
+
/**************************************************************************/
/*!
@brief Disconnects if we are connected to a central device
@@ -309,7 +369,7 @@
@endcode
*/
/**************************************************************************/
-ble_error_t nRF51Gap::setAddress(AddressType_t type, const address_t address)
+ble_error_t nRF51Gap::setAddress(AddressType_t type, const Address_t address)
{
if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
return BLE_ERROR_PARAM_OUT_OF_RANGE;
@@ -324,7 +384,7 @@
return BLE_ERROR_NONE;
}
-ble_error_t nRF51Gap::getAddress(AddressType_t *typeP, address_t address)
+ble_error_t nRF51Gap::getAddress(AddressType_t *typeP, Address_t address)
{
ble_gap_addr_t dev_addr;
if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
--- a/nRF51Gap.h Fri Jun 19 15:55:34 2015 +0100
+++ b/nRF51Gap.h Fri Jun 19 15:55:34 2015 +0100
@@ -41,8 +41,8 @@
static nRF51Gap &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);
+ virtual ble_error_t setAddress(AddressType_t type, const Address_t address);
+ virtual ble_error_t getAddress(AddressType_t *typeP, Address_t address);
virtual ble_error_t setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
virtual uint16_t getMinAdvertisingInterval(void) const {return ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MIN);}
@@ -51,6 +51,7 @@
virtual ble_error_t startAdvertising(const GapAdvertisingParams &);
virtual ble_error_t stopAdvertising(void);
+ virtual ble_error_t connect(const Address_t, Gap::AddressType_t peerAddrType, const ConnectionParams_t *connectionParams, const GapScanningParams *scanParams);
virtual ble_error_t disconnect(DisconnectionReason_t reason);
virtual ble_error_t purgeAllBondingState(void) {return btle_purgeAllBondingState();}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51GattClient.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,34 @@
+/* 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 "nRF51GattClient.h"
+
+nRF51GattClient nRFGattClientSingleton;
+
+nRF51GattClient &
+nRF51GattClient::getInstance(void) {
+ return nRFGattClientSingleton;
+}
+
+ble_error_t
+nRF51GattClient::launchServiceDiscovery(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t sc,
+ ServiceDiscovery::CharacteristicCallback_t cc,
+ const UUID &matchingServiceUUIDIn,
+ const UUID &matchingCharacteristicUUIDIn)
+{
+ return discovery.launch(connectionHandle, sc, cc, matchingServiceUUIDIn, matchingCharacteristicUUIDIn);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51GattClient.h Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,160 @@
+/* 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.
+ */
+
+#ifndef __NRF51822_GATT_CLIENT_H__
+#define __NRF51822_GATT_CLIENT_H__
+
+#include "GattClient.h"
+#include "nRF51ServiceDiscovery.h"
+
+class nRF51GattClient : public GattClient
+{
+public:
+ static nRF51GattClient &getInstance();
+
+ /**
+ * Launch service discovery. Once launched, service discovery will remain
+ * active with callbacks being issued back into the application for matching
+ * services/characteristics. isActive() can be used to determine status; and
+ * a termination callback (if setup) will be invoked at the end. Service
+ * discovery can be terminated prematurely if needed using terminate().
+ *
+ * @param connectionHandle
+ * Handle for the connection with the peer.
+ * @param sc
+ * This is the application callback for matching service. Taken as
+ * NULL by default. Note: service discovery may still be active
+ * when this callback is issued; calling asynchronous BLE-stack
+ * APIs from within this application callback might cause the
+ * stack to abort service discovery. If this becomes an issue, it
+ * may be better to make local copy of the discoveredService and
+ * wait for service discovery to terminate before operating on the
+ * service.
+ * @param cc
+ * This is the application callback for matching characteristic.
+ * Taken as NULL by default. Note: service discovery may still be
+ * active when this callback is issued; calling asynchronous
+ * BLE-stack APIs from within this application callback might cause
+ * the stack to abort service discovery. If this becomes an issue,
+ * it may be better to make local copy of the discoveredCharacteristic
+ * and wait for service discovery to terminate before operating on the
+ * characteristic.
+ * @param matchingServiceUUID
+ * UUID based filter for specifying a service in which the application is
+ * interested. By default it is set as the wildcard UUID_UNKNOWN,
+ * in which case it matches all services. If characteristic-UUID
+ * filter (below) is set to the wildcard value, then a service
+ * callback will be invoked for the matching service (or for every
+ * service if the service filter is a wildcard).
+ * @param matchingCharacteristicUUIDIn
+ * UUID based filter for specifying characteristic in which the application
+ * is interested. By default it is set as the wildcard UUID_UKNOWN
+ * to match against any characteristic. If both service-UUID
+ * filter and characteristic-UUID filter are used with non- wildcard
+ * values, then only a single characteristic callback is
+ * invoked for the matching characteristic.
+ *
+ * @Note Using wildcard values for both service-UUID and characteristic-
+ * UUID will result in complete service discovery--callbacks being
+ * called for every service and characteristic.
+ *
+ * @return
+ * BLE_ERROR_NONE if service discovery is launched successfully; else an appropriate error.
+ */
+ virtual ble_error_t launchServiceDiscovery(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t sc = NULL,
+ ServiceDiscovery::CharacteristicCallback_t cc = NULL,
+ const UUID &matchingServiceUUID = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN),
+ const UUID &matchingCharacteristicUUIDIn = UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN));
+
+ virtual void onServiceDiscoveryTermination(ServiceDiscovery::TerminationCallback_t callback) {
+ discovery.onTermination(callback);
+ }
+
+ /**
+ * Is service-discovery currently active?
+ */
+ virtual bool isServiceDiscoveryActive(void) const {
+ return discovery.isActive();
+ }
+
+ /**
+ * Terminate an ongoing service-discovery. This should result in an
+ * invocation of the TerminationCallback if service-discovery is active.
+ */
+ virtual void terminateServiceDiscovery(void) {
+ discovery.terminate();
+ }
+
+ 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) {
+ return BLE_ERROR_NONE;
+ }
+ switch (rc) {
+ case NRF_ERROR_BUSY:
+ return BLE_STACK_BUSY;
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ case NRF_ERROR_INVALID_STATE:
+ case NRF_ERROR_INVALID_ADDR:
+ default:
+ return BLE_ERROR_INVALID_STATE;
+ }
+ }
+
+ virtual ble_error_t write(GattClient::WriteOp_t cmd, Gap::Handle_t connHandle, GattAttribute::Handle_t attributeHandle, size_t length, const uint8_t *value) const {
+ ble_gattc_write_params_t writeParams = {
+ .write_op = cmd,
+ // .flags = 0,
+ .handle = attributeHandle,
+ .offset = 0,
+ .len = length,
+ .p_value = const_cast<uint8_t *>(value),
+ };
+
+ uint32_t rc = sd_ble_gattc_write(connHandle, &writeParams);
+ if (rc == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ }
+ switch (rc) {
+ case NRF_ERROR_BUSY:
+ return BLE_STACK_BUSY;
+ case BLE_ERROR_NO_TX_BUFFERS:
+ return BLE_ERROR_NO_MEM;
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ case NRF_ERROR_INVALID_STATE:
+ case NRF_ERROR_INVALID_ADDR:
+ default:
+ return BLE_ERROR_INVALID_STATE;
+ }
+ }
+
+public:
+ nRF51GattClient() : discovery(this) {
+ /* empty */
+ }
+
+ friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
+
+private:
+ nRF51GattClient(const nRF51GattClient &);
+ const nRF51GattClient& operator=(const nRF51GattClient &);
+
+private:
+ nRF51ServiceDiscovery discovery;
+};
+
+#endif // ifndef __NRF51822_GATT_CLIENT_H__
\ No newline at end of file
--- a/nRF51GattServer.cpp Fri Jun 19 15:55:34 2015 +0100
+++ b/nRF51GattServer.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -336,22 +336,22 @@
if (nrfCharacteristicHandles[i].value_handle == handle_value) {
switch (eventType) {
case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
- GattCharacteristicWriteCBParams cbParams = {
- .charHandle = i,
- .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.write.op),
- .offset = gattsEventP->params.write.offset,
- .len = gattsEventP->params.write.len,
- .data = gattsEventP->params.write.data
+ GattWriteCallbackParams cbParams = {
+ .handle = i,
+ .writeOp = static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.write.op),
+ .offset = gattsEventP->params.write.offset,
+ .len = gattsEventP->params.write.len,
+ .data = gattsEventP->params.write.data
};
handleDataWrittenEvent(&cbParams);
break;
}
case GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ: {
- GattCharacteristicWriteAuthCBParams cbParams = {
- .charHandle = i,
- .offset = gattsEventP->params.authorize_request.request.write.offset,
- .len = gattsEventP->params.authorize_request.request.write.len,
- .data = gattsEventP->params.authorize_request.request.write.data,
+ GattWriteAuthCallbackParams cbParams = {
+ .handle = i,
+ .offset = gattsEventP->params.authorize_request.request.write.offset,
+ .len = gattsEventP->params.authorize_request.request.write.len,
+ .data = gattsEventP->params.authorize_request.request.write.data,
};
ble_gatts_rw_authorize_reply_params_t reply = {
.type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
@@ -371,23 +371,23 @@
* have done if write-authorization had not been enabled.
*/
if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) {
- GattCharacteristicWriteCBParams cbParams = {
- .charHandle = i,
- .op = static_cast<GattCharacteristicWriteCBParams::Type>(gattsEventP->params.authorize_request.request.write.op),
- .offset = gattsEventP->params.authorize_request.request.write.offset,
- .len = gattsEventP->params.authorize_request.request.write.len,
- .data = gattsEventP->params.authorize_request.request.write.data,
+ GattWriteCallbackParams cbParams = {
+ .handle = i,
+ .writeOp = static_cast<GattWriteCallbackParams::WriteOp_t>(gattsEventP->params.authorize_request.request.write.op),
+ .offset = gattsEventP->params.authorize_request.request.write.offset,
+ .len = gattsEventP->params.authorize_request.request.write.len,
+ .data = gattsEventP->params.authorize_request.request.write.data,
};
handleDataWrittenEvent(&cbParams);
}
break;
}
case GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ: {
- GattCharacteristicReadAuthCBParams cbParams = {
- .charHandle = i,
- .offset = gattsEventP->params.authorize_request.request.read.offset,
- .len = 0,
- .data = NULL
+ GattReadAuthCallbackParams cbParams = {
+ .handle = i,
+ .offset = gattsEventP->params.authorize_request.request.read.offset,
+ .len = 0,
+ .data = NULL
};
ble_gatts_rw_authorize_reply_params_t reply = {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51ServiceDiscovery.cpp Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,283 @@
+/* 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 "nRF51ServiceDiscovery.h"
+
+ble_error_t
+nRF51ServiceDiscovery::launchCharacteristicDiscovery(Gap::Handle_t connectionHandle,
+ Gap::Handle_t startHandle,
+ Gap::Handle_t endHandle)
+{
+ characteristicDiscoveryStarted(connectionHandle);
+
+ ble_gattc_handle_range_t handleRange = {
+ .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;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+void
+nRF51ServiceDiscovery::setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response)
+{
+ serviceIndex = 0;
+ numServices = response->count;
+
+ /* Account for the limitation on the number of discovered services we can handle at a time. */
+ if (numServices > BLE_DB_DISCOVERY_MAX_SRV) {
+ numServices = BLE_DB_DISCOVERY_MAX_SRV;
+ }
+
+ serviceUUIDDiscoveryQueue.reset();
+ for (unsigned serviceIndex = 0; serviceIndex < numServices; serviceIndex++) {
+ if (response->services[serviceIndex].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
+ serviceUUIDDiscoveryQueue.enqueue(serviceIndex);
+ services[serviceIndex].setup(response->services[serviceIndex].handle_range.start_handle,
+ response->services[serviceIndex].handle_range.end_handle);
+ } else {
+ services[serviceIndex].setup(response->services[serviceIndex].uuid.uuid,
+ response->services[serviceIndex].handle_range.start_handle,
+ response->services[serviceIndex].handle_range.end_handle);
+ }
+ }
+
+ /* Trigger discovery of service UUID if necessary. */
+ if (serviceUUIDDiscoveryQueue.getCount()) {
+ serviceUUIDDiscoveryQueue.triggerFirst();
+ }
+}
+
+void
+nRF51ServiceDiscovery::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. */
+ if (numCharacteristics > BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV) {
+ numCharacteristics = BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV;
+ }
+
+ charUUIDDiscoveryQueue.reset();
+ for (unsigned charIndex = 0; charIndex < numCharacteristics; charIndex++) {
+ if (response->chars[charIndex].uuid.type == BLE_UUID_TYPE_UNKNOWN) {
+ charUUIDDiscoveryQueue.enqueue(charIndex);
+ characteristics[charIndex].setup(gattc,
+ connHandle,
+ response->chars[charIndex].char_props,
+ response->chars[charIndex].handle_decl,
+ response->chars[charIndex].handle_value);
+ } else {
+ characteristics[charIndex].setup(gattc,
+ connHandle,
+ response->chars[charIndex].uuid.uuid,
+ response->chars[charIndex].char_props,
+ response->chars[charIndex].handle_decl,
+ response->chars[charIndex].handle_value);
+ }
+ }
+
+ /* Trigger discovery of char UUID if necessary. */
+ if (charUUIDDiscoveryQueue.getCount()) {
+ charUUIDDiscoveryQueue.triggerFirst();
+ }
+}
+
+void
+nRF51ServiceDiscovery::progressCharacteristicDiscovery(void)
+{
+ /* 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 == characteristics[characteristicIndex].getShortUUID()) &&
+ (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
+ if (characteristicCallback) {
+ characteristicCallback(&characteristics[characteristicIndex]);
+ }
+ }
+
+ 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. */
+
+ 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();
+ }
+ }
+}
+
+void
+nRF51ServiceDiscovery::progressServiceDiscovery(void)
+{
+ /* Iterate through the previously discovered services cached in services[]. */
+ while ((state == SERVICE_DISCOVERY_ACTIVE) && (serviceIndex < numServices)) {
+ if ((matchingServiceUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
+ (matchingServiceUUID == services[serviceIndex].getUUID().getShortUUID())) {
+
+ if (serviceCallback && (matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN))) {
+ serviceCallback(&services[serviceIndex]);
+ }
+
+ if ((state == SERVICE_DISCOVERY_ACTIVE) && characteristicCallback) {
+ launchCharacteristicDiscovery(connHandle, services[serviceIndex].getStartHandle(), services[serviceIndex].getEndHandle());
+ } else {
+ serviceIndex++;
+ }
+ } else {
+ serviceIndex++;
+ }
+ }
+
+ /* Relaunch discovery of new services beyond the last entry cached in services[]. */
+ if ((state == SERVICE_DISCOVERY_ACTIVE) && (numServices > 0) && (serviceIndex > 0)) {
+ /* Determine the ending handle of the last cached service. */
+ Gap::Handle_t endHandle = services[serviceIndex - 1].getEndHandle();
+ resetDiscoveredServices(); /* Note: resetDiscoveredServices() must come after fetching endHandle. */
+
+ if (endHandle == SRV_DISC_END_HANDLE) {
+ terminateServiceDiscovery();
+ } else {
+ if (sd_ble_gattc_primary_services_discover(connHandle, endHandle, NULL) != NRF_SUCCESS) {
+ terminateServiceDiscovery();
+ }
+ }
+ }
+}
+
+void
+nRF51ServiceDiscovery::ServiceUUIDDiscoveryQueue::triggerFirst(void)
+{
+ while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
+ parentDiscoveryObject->state = DISCOVER_SERVICE_UUIDS;
+
+ unsigned serviceIndex = getFirst();
+ ble_uuid_t uuid = {
+ .uuid = BLE_UUID_SERVICE_PRIMARY,
+ .type = BLE_UUID_TYPE_BLE,
+ };
+ ble_gattc_handle_range_t handleRange = {
+ .start_handle = parentDiscoveryObject->services[serviceIndex].getStartHandle(),
+ .end_handle = parentDiscoveryObject->services[serviceIndex].getEndHandle(),
+ };
+ if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
+ return;
+ }
+
+ /* Skip this service if we fail to launch a read for its service-declaration
+ * attribute. Its UUID will remain INVALID, and it may not match any filters. */
+ dequeue();
+ }
+
+ /* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
+ if (parentDiscoveryObject->state == DISCOVER_SERVICE_UUIDS) {
+ parentDiscoveryObject->state = SERVICE_DISCOVERY_ACTIVE;
+ }
+}
+
+void
+nRF51ServiceDiscovery::CharUUIDDiscoveryQueue::triggerFirst(void)
+{
+ while (numIndices) { /* loop until a call to char_value_by_uuid_read() succeeds or we run out of pending indices. */
+ parentDiscoveryObject->state = DISCOVER_CHARACTERISTIC_UUIDS;
+
+ unsigned charIndex = getFirst();
+ ble_uuid_t uuid = {
+ .uuid = BLE_UUID_CHARACTERISTIC,
+ .type = BLE_UUID_TYPE_BLE,
+ };
+ ble_gattc_handle_range_t handleRange = {
+ .start_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle(),
+ .end_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle() + 1,
+ };
+ if (sd_ble_gattc_char_value_by_uuid_read(parentDiscoveryObject->connHandle, &uuid, &handleRange) == NRF_SUCCESS) {
+ return;
+ }
+
+ /* Skip this service if we fail to launch a read for its service-declaration
+ * attribute. Its UUID will remain INVALID, and it may not match any filters. */
+ dequeue();
+ }
+
+ /* Switch back to service discovery upon exhausting the service-indices pending UUID discovery. */
+ if (parentDiscoveryObject->state == DISCOVER_CHARACTERISTIC_UUIDS) {
+ parentDiscoveryObject->state = CHARACTERISTIC_DISCOVERY_ACTIVE;
+ }
+}
+
+void
+nRF51ServiceDiscovery::processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response)
+{
+ if (state == DISCOVER_SERVICE_UUIDS) {
+ if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID)) {
+ UUID::LongUUIDBytes_t uuid;
+ /* Switch longUUID bytes to MSB */
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ uuid[i] = response->handle_value[0].p_value[UUID::LENGTH_OF_LONG_UUID - 1 - i];
+ }
+
+ unsigned serviceIndex = serviceUUIDDiscoveryQueue.dequeue();
+ services[serviceIndex].setupLongUUID(uuid);
+
+ serviceUUIDDiscoveryQueue.triggerFirst();
+ } else {
+ serviceUUIDDiscoveryQueue.dequeue();
+ }
+ } else if (state == DISCOVER_CHARACTERISTIC_UUIDS) {
+ if ((response->count == 1) && (response->value_len == UUID::LENGTH_OF_LONG_UUID + 1 /* props */ + 2 /* value handle */)) {
+ UUID::LongUUIDBytes_t uuid;
+ /* Switch longUUID bytes to MSB */
+ for (unsigned i = 0; i < UUID::LENGTH_OF_LONG_UUID; i++) {
+ uuid[i] = response->handle_value[0].p_value[3 + UUID::LENGTH_OF_LONG_UUID - 1 - i];
+ }
+
+ unsigned charIndex = charUUIDDiscoveryQueue.dequeue();
+ characteristics[charIndex].setupLongUUID(uuid);
+
+ charUUIDDiscoveryQueue.triggerFirst();
+ } else {
+ charUUIDDiscoveryQueue.dequeue();
+ }
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nRF51ServiceDiscovery.h Fri Jun 19 15:55:34 2015 +0100
@@ -0,0 +1,305 @@
+/* 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.
+ */
+
+#ifndef __NRF_SERVICE_DISCOVERY_H__
+#define __NRF_SERVICE_DISCOVERY_H__
+
+#include "ServiceDiscovery.h"
+#include "DiscoveredService.h"
+#include "nRF51DiscoveredCharacteristic.h"
+
+#include "ble.h"
+#include "ble_gattc.h"
+
+class nRF51GattClient; /* forward declaration */
+
+class nRF51ServiceDiscovery : public ServiceDiscovery
+{
+public:
+ static const uint16_t SRV_DISC_START_HANDLE = 0x0001; /**< The start handle value used during service discovery. */
+ static const uint16_t SRV_DISC_END_HANDLE = 0xFFFF; /**< The end handle value used during service discovery. */
+
+public:
+ static const unsigned BLE_DB_DISCOVERY_MAX_SRV = 4; /**< Maximum number of services we can retain information for after a single discovery. */
+ static const unsigned BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV = 4; /**< Maximum number of characteristics per service we can retain information for. */
+
+public:
+ nRF51ServiceDiscovery(nRF51GattClient *gattcIn) :
+ gattc(gattcIn),
+ serviceIndex(0),
+ numServices(0),
+ characteristicIndex(0),
+ numCharacteristics(0),
+ state(INACTIVE),
+ services(),
+ characteristics(),
+ serviceUUIDDiscoveryQueue(this),
+ charUUIDDiscoveryQueue(this),
+ onTerminationCallback(NULL) {
+ /* empty */
+ }
+
+ virtual ble_error_t launch(Gap::Handle_t connectionHandle,
+ ServiceDiscovery::ServiceCallback_t sc,
+ ServiceDiscovery::CharacteristicCallback_t cc,
+ const UUID &matchingServiceUUIDIn,
+ const UUID &matchingCharacteristicUUIDIn)
+ {
+ if (isActive()) {
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+ serviceCallback = sc;
+ characteristicCallback = cc;
+ matchingServiceUUID = matchingServiceUUIDIn;
+ matchingCharacteristicUUID = matchingCharacteristicUUIDIn;
+
+ serviceDiscoveryStarted(connectionHandle);
+
+ uint32_t rc;
+ if ((rc = sd_ble_gattc_primary_services_discover(connectionHandle, SRV_DISC_START_HANDLE, NULL)) != NRF_SUCCESS) {
+ terminate();
+ switch (rc) {
+ case NRF_ERROR_INVALID_PARAM:
+ case BLE_ERROR_INVALID_CONN_HANDLE:
+ return BLE_ERROR_INVALID_PARAM;
+ case NRF_ERROR_BUSY:
+ return BLE_STACK_BUSY;
+ default:
+ case NRF_ERROR_INVALID_STATE:
+ return BLE_ERROR_INVALID_STATE;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+ }
+
+ virtual bool isActive(void) const {
+ return state != INACTIVE;
+ }
+
+ virtual void terminate(void) {
+ terminateServiceDiscovery();
+ }
+
+ virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) {
+ onTerminationCallback = callback;
+ }
+
+private:
+ ble_error_t launchCharacteristicDiscovery(Gap::Handle_t connectionHandle, Gap::Handle_t startHandle, Gap::Handle_t endHandle);
+
+private:
+ void setupDiscoveredServices(const ble_gattc_evt_prim_srvc_disc_rsp_t *response);
+ void setupDiscoveredCharacteristics(const ble_gattc_evt_char_disc_rsp_t *response);
+
+ void triggerServiceUUIDDiscovery(void);
+ void processDiscoverUUIDResponse(const ble_gattc_evt_char_val_by_uuid_read_rsp_t *response);
+ void removeFirstServiceNeedingUUIDDiscovery(void);
+
+ void terminateServiceDiscovery(void) {
+ bool wasActive = isActive();
+ state = INACTIVE;
+
+ if (wasActive && onTerminationCallback) {
+ onTerminationCallback(connHandle);
+ }
+ }
+
+ void terminateCharacteristicDiscovery(void) {
+ if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
+ state = SERVICE_DISCOVERY_ACTIVE;
+ }
+ serviceIndex++; /* Progress service index to keep discovery alive. */
+ }
+
+private:
+ void resetDiscoveredServices(void) {
+ numServices = 0;
+ serviceIndex = 0;
+ }
+
+ void resetDiscoveredCharacteristics(void) {
+ numCharacteristics = 0;
+ characteristicIndex = 0;
+ }
+
+private:
+ void serviceDiscoveryStarted(Gap::Handle_t connectionHandle) {
+ connHandle = connectionHandle;
+ resetDiscoveredServices();
+ state = SERVICE_DISCOVERY_ACTIVE;
+ }
+
+private:
+ void characteristicDiscoveryStarted(Gap::Handle_t connectionHandle) {
+ connHandle = connectionHandle;
+ resetDiscoveredCharacteristics();
+ state = CHARACTERISTIC_DISCOVERY_ACTIVE;
+ }
+
+private:
+ /**
+ * A datatype to contain service-indices for which long UUIDs need to be
+ * discovered using read_val_by_uuid().
+ */
+ class ServiceUUIDDiscoveryQueue {
+ public:
+ ServiceUUIDDiscoveryQueue(nRF51ServiceDiscovery *parent) :
+ numIndices(0),
+ serviceIndices(),
+ parentDiscoveryObject(parent) {
+ /* empty */
+ }
+
+ public:
+ void reset(void) {
+ numIndices = 0;
+ for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
+ serviceIndices[i] = INVALID_INDEX;
+ }
+ }
+ void enqueue(int serviceIndex) {
+ serviceIndices[numIndices++] = serviceIndex;
+ }
+ int dequeue(void) {
+ if (numIndices == 0) {
+ return INVALID_INDEX;
+ }
+
+ unsigned valueToReturn = serviceIndices[0];
+ numIndices--;
+ for (unsigned i = 0; i < numIndices; i++) {
+ serviceIndices[i] = serviceIndices[i + 1];
+ }
+
+ return valueToReturn;
+ }
+ unsigned getFirst(void) const {
+ return serviceIndices[0];
+ }
+ size_t getCount(void) const {
+ return numIndices;
+ }
+
+ /**
+ * Trigger UUID discovery for the first of the enqueued ServiceIndices.
+ */
+ void triggerFirst(void);
+
+ private:
+ static const int INVALID_INDEX = -1;
+
+ private:
+ size_t numIndices;
+ int serviceIndices[BLE_DB_DISCOVERY_MAX_SRV];
+
+ nRF51ServiceDiscovery *parentDiscoveryObject;
+ };
+ friend class ServiceUUIDDiscoveryQueue;
+
+ /**
+ * A datatype to contain characteristic-indices for which long UUIDs need to
+ * be discovered using read_val_by_uuid().
+ */
+ class CharUUIDDiscoveryQueue {
+ public:
+ CharUUIDDiscoveryQueue(nRF51ServiceDiscovery *parent) :
+ numIndices(0),
+ charIndices(),
+ parentDiscoveryObject(parent) {
+ /* empty */
+ }
+
+ public:
+ void reset(void) {
+ numIndices = 0;
+ for (unsigned i = 0; i < BLE_DB_DISCOVERY_MAX_SRV; i++) {
+ charIndices[i] = INVALID_INDEX;
+ }
+ }
+ void enqueue(int serviceIndex) {
+ charIndices[numIndices++] = serviceIndex;
+ }
+ int dequeue(void) {
+ if (numIndices == 0) {
+ return INVALID_INDEX;
+ }
+
+ unsigned valueToReturn = charIndices[0];
+ numIndices--;
+ for (unsigned i = 0; i < numIndices; i++) {
+ charIndices[i] = charIndices[i + 1];
+ }
+
+ return valueToReturn;
+ }
+ unsigned getFirst(void) const {
+ return charIndices[0];
+ }
+ size_t getCount(void) const {
+ return numIndices;
+ }
+
+ /**
+ * Trigger UUID discovery for the first of the enqueued charIndices.
+ */
+ void triggerFirst(void);
+
+ private:
+ static const int INVALID_INDEX = -1;
+
+ private:
+ size_t numIndices;
+ int charIndices[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
+
+ nRF51ServiceDiscovery *parentDiscoveryObject;
+ };
+ friend class CharUUIDDiscoveryQueue;
+
+private:
+ friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
+ void progressCharacteristicDiscovery(void);
+ void progressServiceDiscovery(void);
+
+private:
+ nRF51GattClient *gattc;
+
+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 {
+ INACTIVE,
+ SERVICE_DISCOVERY_ACTIVE,
+ CHARACTERISTIC_DISCOVERY_ACTIVE,
+ DISCOVER_SERVICE_UUIDS,
+ DISCOVER_CHARACTERISTIC_UUIDS,
+ } state;
+
+ DiscoveredService services[BLE_DB_DISCOVERY_MAX_SRV]; /**< Information related to the current service being discovered.
+ * This is intended for internal use during service discovery. */
+ nRF51DiscoveredCharacteristic characteristics[BLE_DB_DISCOVERY_MAX_CHAR_PER_SRV];
+
+ ServiceUUIDDiscoveryQueue serviceUUIDDiscoveryQueue;
+ CharUUIDDiscoveryQueue charUUIDDiscoveryQueue;
+
+ TerminationCallback_t onTerminationCallback;
+};
+
+#endif /*__NRF_SERVICE_DISCOVERY_H__*/
\ No newline at end of file
