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.
Dependents: BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more
Revision 388:db85a09c27ef, committed 2015-07-21
- Comitter:
- rgrover1
- Date:
- Tue Jul 21 13:23:44 2015 +0100
- Parent:
- 387:b13ab9a7ddb9
- Child:
- 389:5982ee136c47
- Commit message:
- Synchronized with git rev 0eb58d86
Author: Rohit Grover
rename nRF51... to nRF5x...
This prepares us to support nRF52.
Changed in this revision
--- a/source/btle/btle.cpp Tue Jul 21 13:23:44 2015 +0100
+++ b/source/btle/btle.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -31,9 +31,9 @@
#include "pstorage.h"
#include "ble/GapEvents.h"
-#include "nRF51Gap.h"
-#include "nRF51GattServer.h"
-#include "nRF51SecurityManager.h"
+#include "nRF5xGap.h"
+#include "nRF5xGattServer.h"
+#include "nRF5xSecurityManager.h"
#include "device_manager.h"
@@ -113,11 +113,11 @@
switch (p_ble_evt->header.evt_id) {
case BLE_GAP_EVT_CONNECTED: {
Gap::Handle_t handle = p_ble_evt->evt.gap_evt.conn_handle;
- nRF51Gap::getInstance().setConnectionHandle(handle);
+ nRF5xGap::getInstance().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;
- nRF51Gap::getInstance().processConnectionEvent(handle,
+ nRF5xGap::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,
@@ -129,7 +129,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
- nRF51Gap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
+ nRF5xGap::getInstance().setConnectionHandle (BLE_CONN_HANDLE_INVALID);
Gap::DisconnectionReason_t reason;
switch (p_ble_evt->evt.gap_evt.params.disconnected.reason) {
@@ -148,16 +148,16 @@
reason = static_cast<Gap::DisconnectionReason_t>(p_ble_evt->evt.gap_evt.params.disconnected.reason);
break;
}
- nRF51Gap::getInstance().processDisconnectionEvent(handle, reason);
+ nRF5xGap::getInstance().processDisconnectionEvent(handle, reason);
break;
}
case BLE_GAP_EVT_PASSKEY_DISPLAY:
- nRF51SecurityManager::getInstance().processPasskeyDisplayEvent(p_ble_evt->evt.gap_evt.conn_handle, p_ble_evt->evt.gap_evt.params.passkey_display.passkey);
+ nRF5xSecurityManager::getInstance().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:
- nRF51Gap::getInstance().processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
+ nRF5xGap::getInstance().processTimeoutEvent(static_cast<Gap::TimeoutSource_t>(p_ble_evt->evt.gap_evt.params.timeout.src));
break;
case BLE_GATTC_EVT_TIMEOUT:
@@ -169,7 +169,7 @@
case BLE_GAP_EVT_ADV_REPORT: {
const ble_gap_evt_adv_report_t *advReport = &p_ble_evt->evt.gap_evt.params.adv_report;
- nRF51Gap::getInstance().processAdvertisementReport(advReport->peer_addr.addr,
+ nRF5xGap::getInstance().processAdvertisementReport(advReport->peer_addr.addr,
advReport->rssi,
advReport->scan_rsp,
static_cast<GapAdvertisingParams::AdvertisingType_t>(advReport->type),
@@ -182,7 +182,7 @@
break;
}
- nRF51GattServer::getInstance().hwCallback(p_ble_evt);
+ nRF5xGattServer::getInstance().hwCallback(p_ble_evt);
}
/*! @brief Callback when an error occurs inside the SoftDevice */
--- a/source/btle/btle_discovery.cpp Tue Jul 21 13:23:44 2015 +0100
+++ b/source/btle/btle_discovery.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -14,12 +14,12 @@
* limitations under the License.
*/
-#include "nRF51ServiceDiscovery.h"
-#include "nRF51GattClient.h"
+#include "nRF5xServiceDiscovery.h"
+#include "nRF5xGattClient.h"
void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
{
- nRF51ServiceDiscovery &sdSingleton = nRF51GattClient::getInstance().discovery;
+ nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery;
switch (p_ble_evt->header.evt_id) {
case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
@@ -61,7 +61,7 @@
.len = p_ble_evt->evt.gattc_evt.params.read_rsp.len,
.data = p_ble_evt->evt.gattc_evt.params.read_rsp.data,
};
- nRF51GattClient::getInstance().processReadResponse(&response);
+ nRF5xGattClient::getInstance().processReadResponse(&response);
}
break;
@@ -73,7 +73,7 @@
.len = p_ble_evt->evt.gattc_evt.params.write_rsp.len,
.data = p_ble_evt->evt.gattc_evt.params.write_rsp.data,
};
- nRF51GattClient::getInstance().processWriteResponse(&response);
+ nRF5xGattClient::getInstance().processWriteResponse(&response);
}
break;
@@ -84,7 +84,7 @@
params.len = p_ble_evt->evt.gattc_evt.params.hvx.len;
params.data = p_ble_evt->evt.gattc_evt.params.hvx.data;
- nRF51GattClient::getInstance().processHVXEvent(¶ms);
+ nRF5xGattClient::getInstance().processHVXEvent(¶ms);
}
break;
}
--- a/source/btle/btle_security.cpp Tue Jul 21 13:23:44 2015 +0100
+++ b/source/btle/btle_security.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -17,8 +17,8 @@
#include "btle.h"
#include "pstorage.h"
-#include "nRF51Gap.h"
-#include "nRF51SecurityManager.h"
+#include "nRF5xGap.h"
+#include "nRF5xSecurityManager.h"
#include "device_manager.h"
#include "btle_security.h"
@@ -154,14 +154,14 @@
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;
- nRF51SecurityManager::getInstance().processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
+ nRF5xSecurityManager::getInstance().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:
- nRF51SecurityManager::getInstance().
+ nRF5xSecurityManager::getInstance().
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;
@@ -195,11 +195,11 @@
break;
}
- nRF51SecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
+ nRF5xSecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
break;
}
case DM_EVT_DEVICE_CONTEXT_STORED:
- nRF51SecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
+ nRF5xSecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
break;
default:
break;
--- a/source/nRF51822n.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,91 +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 "mbed.h"
-#include "nRF51822n.h"
-#include "nrf_soc.h"
-
-#include "btle/btle.h"
-#include "nrf_delay.h"
-
-#include "softdevice_handler.h"
-
-/**
- * The singleton which represents the nRF51822 transport for the BLE.
- */
-static nRF51822n deviceInstance;
-
-/**
- * BLE-API requires an implementation of the following function in order to
- * obtain its transport handle.
- */
-BLEInstanceBase *
-createBLEInstance(void)
-{
- return (&deviceInstance);
-}
-
-nRF51822n::nRF51822n(void)
-{
-}
-
-nRF51822n::~nRF51822n(void)
-{
-}
-
-const char *nRF51822n::getVersion(void)
-{
- static char versionString[32];
- static bool versionFetched = false;
-
- if (!versionFetched) {
- ble_version_t version;
- if ((sd_ble_version_get(&version) == NRF_SUCCESS) && (version.company_id == 0x0059)) {
- switch (version.version_number) {
- case 0x07:
- snprintf(versionString, sizeof(versionString), "Nordic BLE4.1 fw:%04x", version.subversion_number);
- break;
- default:
- snprintf(versionString, sizeof(versionString), "Nordic (spec unknown) fw:%04x", version.subversion_number);
- break;
- }
- versionFetched = true;
- } else {
- strncpy(versionString, "unknown", sizeof(versionString));
- }
- }
-
- return versionString;
-}
-
-ble_error_t nRF51822n::init(void)
-{
- /* ToDo: Clear memory contents, reset the SD, etc. */
- btle_init();
-
- return BLE_ERROR_NONE;
-}
-
-ble_error_t nRF51822n::shutdown(void)
-{
- return (softdevice_handler_sd_disable() == NRF_SUCCESS) ? BLE_ERROR_NONE : BLE_STACK_BUSY;
-}
-
-void
-nRF51822n::waitForEvent(void)
-{
- sd_app_evt_wait();
-}
\ No newline at end of file
--- a/source/nRF51822n.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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.
- */
-
-#ifndef __NRF51822_H__
-#define __NRF51822_H__
-
-#include "mbed.h"
-#include "ble/blecommon.h"
-#include "ble/BLE.h"
-#include "nRF51Gap.h"
-#include "nRF51GattServer.h"
-#include "nRF51GattClient.h"
-#include "nRF51SecurityManager.h"
-#include "btle.h"
-
-class nRF51822n : public BLEInstanceBase
-{
-public:
- nRF51822n(void);
- virtual ~nRF51822n(void);
-
- virtual ble_error_t init(void);
- virtual ble_error_t shutdown(void);
- virtual const char *getVersion(void);
-
- virtual Gap &getGap() {
- return nRF51Gap::getInstance();
- };
- virtual const Gap &getGap() const {
- return nRF51Gap::getInstance();
- };
- virtual GattServer &getGattServer() {
- return nRF51GattServer::getInstance();
- };
- virtual const GattServer &getGattServer() const {
- return nRF51GattServer::getInstance();
- };
- virtual GattClient &getGattClient() {
- return nRF51GattClient::getInstance();
- }
- virtual const SecurityManager &getSecurityManager() const {
- return nRF51SecurityManager::getInstance();
- }
- virtual SecurityManager &getSecurityManager() {
- return nRF51SecurityManager::getInstance();
- }
- virtual void waitForEvent(void);
-};
-
-#endif
\ No newline at end of file
--- a/source/nRF51DiscoveredCharacteristic.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +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 "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
--- a/source/nRF51DiscoveredCharacteristic.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,41 +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.
- */
-
-#ifndef __NRF_DISCOVERED_CHARACTERISTIC_H__
-#define __NRF_DISCOVERED_CHARACTERISTIC_H__
-
-#include "ble/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/source/nRF51Gap.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,465 +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 "nRF51Gap.h"
-#include "mbed.h"
-
-#include "common/common.h"
-#include "ble_advdata.h"
-#include "ble_hci.h"
-
-nRF51Gap &nRF51Gap::getInstance() {
- static nRF51Gap m_instance;
- return m_instance;
-}
-
-/**************************************************************************/
-/*!
- @brief Sets the advertising parameters and payload for the device
-
- @param[in] params
- Basic advertising details, including the advertising
- delay, timeout and how the device should be advertised
- @params[in] advData
- The primary advertising data payload
- @params[in] scanResponse
- The optional Scan Response payload if the advertising
- type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
- in \ref GapAdveritinngParams
-
- @returns \ref ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-
- @retval BLE_ERROR_BUFFER_OVERFLOW
- The proposed action would cause a buffer overflow. All
- advertising payloads must be <= 31 bytes, for example.
-
- @retval BLE_ERROR_NOT_IMPLEMENTED
- A feature was requested that is not yet supported in the
- nRF51 firmware or hardware.
-
- @retval BLE_ERROR_PARAM_OUT_OF_RANGE
- One of the proposed values is outside the valid range.
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-ble_error_t nRF51Gap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
-{
- /* Make sure we don't exceed the advertising payload length */
- if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
- return BLE_ERROR_BUFFER_OVERFLOW;
- }
-
- /* Make sure we have a payload! */
- if (advData.getPayloadLen() == 0) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-
- /* Check the scan response payload limits */
- //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
- //{
- // /* Check if we're within the upper limit */
- // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
- // {
- // return BLE_ERROR_BUFFER_OVERFLOW;
- // }
- // /* Make sure we have a payload! */
- // if (advData.getPayloadLen() == 0)
- // {
- // return BLE_ERROR_PARAM_OUT_OF_RANGE;
- // }
- //}
-
- /* Send advertising data! */
- ASSERT(ERROR_NONE ==
- sd_ble_gap_adv_data_set(advData.getPayload(),
- advData.getPayloadLen(),
- scanResponse.getPayload(),
- scanResponse.getPayloadLen()),
- BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- /* Make sure the GAP Service appearance value is aligned with the
- *appearance from GapAdvertisingData */
- ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()),
- BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
- /* contains a flags AD type, etc. */
-
- return BLE_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Starts the BLE HW, initialising any services that were
- added before this function was called.
-
- @note All services must be added before calling this function!
-
- @returns ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-ble_error_t nRF51Gap::startAdvertising(const GapAdvertisingParams ¶ms)
-{
- /* Make sure we support the advertising type */
- if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
- /* ToDo: This requires a propery security implementation, etc. */
- return BLE_ERROR_NOT_IMPLEMENTED;
- }
-
- /* Check interval range */
- if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
- /* Min delay is slightly longer for unconnectable devices */
- if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
- (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
- } else {
- if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
- (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
- }
-
- /* Check timeout is zero for Connectable Directed */
- if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
- /* Timeout must be 0 with this type, although we'll never get here */
- /* since this isn't implemented yet anyway */
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-
- /* Check timeout for other advertising types */
- if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
- (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-
- /* Start Advertising */
- ble_gap_adv_params_t adv_para = {0};
-
- adv_para.type = params.getAdvertisingType();
- adv_para.p_peer_addr = NULL; // Undirected advertisement
- adv_para.fp = BLE_GAP_ADV_FP_ANY;
- adv_para.p_whitelist = NULL;
- adv_para.interval = params.getInterval(); // advertising interval (in units of 0.625 ms)
- adv_para.timeout = params.getTimeout();
-
- ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- state.advertising = 1;
-
- return BLE_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Stops the BLE HW and disconnects from any devices
-
- @returns ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-ble_error_t nRF51Gap::stopAdvertising(void)
-{
- /* Stop Advertising */
- ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- state.advertising = 0;
-
- 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;
- }
-}
-
-ble_error_t nRF51Gap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
-{
- state.advertising = 0;
- state.connected = 0;
-
- uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
- switch (reason) {
- case REMOTE_USER_TERMINATED_CONNECTION:
- code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
- break;
- case CONN_INTERVAL_UNACCEPTABLE:
- code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE;
- break;
- default:
- break;
- }
-
- /* Disconnect if we are connected to a central device */
- ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- return BLE_ERROR_NONE;
-}
-
-/*!
- @brief Disconnects if we are connected to a central device
-
- @returns ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-*/
-ble_error_t nRF51Gap::disconnect(DisconnectionReason_t reason)
-{
- return disconnect(m_connectionHandle, reason);
-}
-
-ble_error_t nRF51Gap::getPreferredConnectionParams(ConnectionParams_t *params)
-{
- ASSERT_INT(NRF_SUCCESS,
- sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)),
- BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- return BLE_ERROR_NONE;
-}
-
-ble_error_t nRF51Gap::setPreferredConnectionParams(const ConnectionParams_t *params)
-{
- ASSERT_INT(NRF_SUCCESS,
- sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)),
- BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- return BLE_ERROR_NONE;
-}
-
-ble_error_t nRF51Gap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
-{
- uint32_t rc;
-
- rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams)));
- if (rc == NRF_SUCCESS) {
- return BLE_ERROR_NONE;
- } else {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-}
-
-/**************************************************************************/
-/*!
- @brief Sets the 16-bit connection handle
-*/
-/**************************************************************************/
-void nRF51Gap::setConnectionHandle(uint16_t con_handle)
-{
- m_connectionHandle = con_handle;
-}
-
-/**************************************************************************/
-/*!
- @brief Gets the 16-bit connection handle
-*/
-/**************************************************************************/
-uint16_t nRF51Gap::getConnectionHandle(void)
-{
- return m_connectionHandle;
-}
-
-/**************************************************************************/
-/*!
- @brief Sets the BLE device address
-
- @returns ble_error_t
-
- @section EXAMPLE
-
- @code
-
- uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 };
- nrf.getGap().setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, device_address);
-
- @endcode
-*/
-/**************************************************************************/
-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;
- }
-
- ble_gap_addr_t dev_addr;
- dev_addr.addr_type = type;
- memcpy(dev_addr.addr, address, ADDR_LEN);
-
- ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- return BLE_ERROR_NONE;
-}
-
-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) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-
- if (typeP != NULL) {
- *typeP = static_cast<AddressType_t>(dev_addr.addr_type);
- }
- if (address != NULL) {
- memcpy(address, dev_addr.addr, ADDR_LEN);
- }
- return BLE_ERROR_NONE;
-}
-
-ble_error_t nRF51Gap::setDeviceName(const uint8_t *deviceName)
-{
- ble_gap_conn_sec_mode_t sec_mode;
- BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed
-
- if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) {
- return BLE_ERROR_NONE;
- } else {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-}
-
-ble_error_t nRF51Gap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
-{
- if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) {
- return BLE_ERROR_NONE;
- } else {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-}
-
-ble_error_t nRF51Gap::setAppearance(GapAdvertisingData::Appearance appearance)
-{
- if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) {
- return BLE_ERROR_NONE;
- } else {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-}
-
-ble_error_t nRF51Gap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
-{
- if (sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP))) {
- return BLE_ERROR_NONE;
- } else {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-}
-
-/* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
-ble_error_t nRF51Gap::setTxPower(int8_t txPower)
-{
- unsigned rc;
- if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) {
- switch (rc) {
- case NRF_ERROR_BUSY:
- return BLE_STACK_BUSY;
- case NRF_ERROR_INVALID_PARAM:
- default:
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
- }
-
- return BLE_ERROR_NONE;
-}
-
-void nRF51Gap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
-{
- static const int8_t permittedTxValues[] = {
- -40, -30, -20, -16, -12, -8, -4, 0, 4
- };
-
- *valueArrayPP = permittedTxValues;
- *countP = sizeof(permittedTxValues) / sizeof(int8_t);
-}
\ No newline at end of file
--- a/source/nRF51Gap.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,113 +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.
- */
-
-#ifndef __NRF51822_GAP_H__
-#define __NRF51822_GAP_H__
-
-#include "mbed.h"
-#include "ble/blecommon.h"
-#include "ble.h"
-#include "ble/GapAdvertisingParams.h"
-#include "ble/GapAdvertisingData.h"
-#include "ble/Gap.h"
-#include "ble/GapScanningParams.h"
-
-#include "nrf_soc.h"
-#include "ble_radio_notification.h"
-#include "btle_security.h"
-
-/**************************************************************************/
-/*!
- \brief
-
-*/
-/**************************************************************************/
-class nRF51Gap : public Gap
-{
-public:
- 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 setAdvertisingData(const GapAdvertisingData &, const GapAdvertisingData &);
-
- virtual uint16_t getMinAdvertisingInterval(void) const {return ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MIN);}
- virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);}
- virtual uint16_t getMaxAdvertisingInterval(void) const {return ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MAX);}
-
- 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(Handle_t connectionHandle, DisconnectionReason_t reason);
- virtual ble_error_t disconnect(DisconnectionReason_t reason);
-
- virtual ble_error_t setDeviceName(const uint8_t *deviceName);
- virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
- virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance);
- virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP);
-
- virtual ble_error_t setTxPower(int8_t txPower);
- virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP);
-
- void setConnectionHandle(uint16_t con_handle);
- uint16_t getConnectionHandle(void);
-
- virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params);
- virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params);
- virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params);
-
- virtual void onRadioNotification(RadioNotificationEventCallback_t callback) {
- Gap::onRadioNotification(callback);
- ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationCallback);
- }
-
- virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) {
- ble_gap_scan_params_t scanParams = {
- .active = scanningParams.getActiveScanning(), /**< If 1, perform active scanning (scan requests). */
- .selective = 0, /**< If 1, ignore unknown devices (non whitelisted). */
- .p_whitelist = NULL, /**< Pointer to whitelist, NULL if none is given. */
- .interval = scanningParams.getInterval(), /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
- .window = scanningParams.getWindow(), /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
- .timeout = scanningParams.getTimeout(), /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
- };
-
- if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) {
- return BLE_ERROR_PARAM_OUT_OF_RANGE;
- }
-
- return BLE_ERROR_NONE;
- }
-
- virtual ble_error_t stopScan(void) {
- if (sd_ble_gap_scan_stop() == NRF_SUCCESS) {
- return BLE_ERROR_NONE;
- }
-
- return BLE_STACK_BUSY;
- }
-
-private:
- uint16_t m_connectionHandle;
- nRF51Gap() {
- m_connectionHandle = BLE_CONN_HANDLE_INVALID;
- }
-
- nRF51Gap(nRF51Gap const &);
- void operator=(nRF51Gap const &);
-};
-
-#endif // ifndef __NRF51822_GAP_H__
\ No newline at end of file
--- a/source/nRF51GattClient.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,34 +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 "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
--- a/source/nRF51GattClient.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,157 +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.
- */
-
-#ifndef __NRF51822_GATT_CLIENT_H__
-#define __NRF51822_GATT_CLIENT_H__
-
-#include "ble/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 = { };
- writeParams.write_op = cmd;
- writeParams.handle = attributeHandle;
- writeParams.len = length;
- writeParams.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/source/nRF51GattServer.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,457 +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 "nRF51GattServer.h"
-#include "mbed.h"
-
-#include "common/common.h"
-#include "btle/custom/custom_helper.h"
-
-#include "nRF51Gap.h"
-
-nRF51GattServer &nRF51GattServer::getInstance(void) {
- static nRF51GattServer m_instance;
- return m_instance;
-}
-
-/**************************************************************************/
-/*!
- @brief Adds a new service to the GATT table on the peripheral
-
- @returns ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-
- @section EXAMPLE
-
- @code
-
- @endcode
-*/
-/**************************************************************************/
-ble_error_t nRF51GattServer::addService(GattService &service)
-{
- /* ToDo: Make sure we don't overflow the array, etc. */
- /* ToDo: Make sure this service UUID doesn't already exist (?) */
- /* ToDo: Basic validation */
-
- /* Add the service to the nRF51 */
- ble_uuid_t nordicUUID;
- nordicUUID = custom_convert_to_nordic_uuid(service.getUUID());
-
- uint16_t serviceHandle;
- ASSERT( ERROR_NONE ==
- sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
- &nordicUUID,
- &serviceHandle),
- BLE_ERROR_PARAM_OUT_OF_RANGE );
- service.setHandle(serviceHandle);
-
- /* Add characteristics to the service */
- for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
- GattCharacteristic *p_char = service.getCharacteristic(i);
-
- /* Skip any incompletely defined, read-only characteristics. */
- if ((p_char->getValueAttribute().getValuePtr() == NULL) &&
- (p_char->getValueAttribute().getInitialLength() == 0) &&
- (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) {
- continue;
- }
-
- nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());
-
- /* The user-description descriptor is a special case which needs to be
- * handled at the time of adding the characteristic. The following block
- * is meant to discover its presence. */
- const uint8_t *userDescriptionDescriptorValuePtr = NULL;
- uint16_t userDescriptionDescriptorValueLen = 0;
- for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
- GattAttribute *p_desc = p_char->getDescriptor(j);
- if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
- userDescriptionDescriptorValuePtr = p_desc->getValuePtr();
- userDescriptionDescriptorValueLen = p_desc->getLength();
- }
- }
-
- ASSERT ( ERROR_NONE ==
- custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
- &nordicUUID,
- p_char->getProperties(),
- p_char->getRequiredSecurity(),
- p_char->getValueAttribute().getValuePtr(),
- p_char->getValueAttribute().getInitialLength(),
- p_char->getValueAttribute().getMaxLength(),
- userDescriptionDescriptorValuePtr,
- userDescriptionDescriptorValueLen,
- p_char->isReadAuthorizationEnabled(),
- p_char->isWriteAuthorizationEnabled(),
- &nrfCharacteristicHandles[characteristicCount]),
- BLE_ERROR_PARAM_OUT_OF_RANGE );
-
- /* Update the characteristic handle */
- p_characteristics[characteristicCount] = p_char;
- p_char->getValueAttribute().setHandle(nrfCharacteristicHandles[characteristicCount].value_handle);
- characteristicCount++;
-
- /* Add optional descriptors if any */
- /* ToDo: Make sure we don't overflow the array */
- for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
- GattAttribute *p_desc = p_char->getDescriptor(j);
- /* skip the user-description-descriptor here; this has already been handled when adding the characteristic (above). */
- if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
- continue;
- }
-
- nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
-
- ASSERT(ERROR_NONE ==
- custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID,
- &nordicUUID,
- p_desc->getValuePtr(),
- p_desc->getInitialLength(),
- p_desc->getMaxLength(),
- &nrfDescriptorHandles[descriptorCount]),
- BLE_ERROR_PARAM_OUT_OF_RANGE);
-
- p_descriptors[descriptorCount++] = p_desc;
- p_desc->setHandle(nrfDescriptorHandles[descriptorCount]);
- }
- }
-
- serviceCount++;
-
- return BLE_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Reads the value of a characteristic, based on the service
- and characteristic index fields
-
- @param[in] attributeHandle
- The handle of the GattCharacteristic to read from
- @param[in] buffer
- Buffer to hold the the characteristic's value
- (raw byte array in LSB format)
- @param[in/out] len
- input: Length in bytes to be read.
- output: Total length of attribute value upon successful return.
-
- @returns ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-*/
-/**************************************************************************/
-ble_error_t nRF51GattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
-{
- return read(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, lengthP);
-}
-
-ble_error_t nRF51GattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
-{
- ble_gatts_value_t value = {
- .len = *lengthP,
- .offset = 0,
- .p_value = buffer,
- };
-
- ASSERT( ERROR_NONE ==
- sd_ble_gatts_value_get(connectionHandle, attributeHandle, &value),
- BLE_ERROR_PARAM_OUT_OF_RANGE);
- *lengthP = value.len;
-
- return BLE_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Updates the value of a characteristic, based on the service
- and characteristic index fields
-
- @param[in] charHandle
- The handle of the GattCharacteristic to write to
- @param[in] buffer
- Data to use when updating the characteristic's value
- (raw byte array in LSB format)
- @param[in] len
- The number of bytes in buffer
-
- @returns ble_error_t
-
- @retval BLE_ERROR_NONE
- Everything executed properly
-*/
-/**************************************************************************/
-ble_error_t nRF51GattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
-{
- return write(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, len, localOnly);
-}
-
-ble_error_t nRF51GattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
-{
- uint16_t gapConnectionHandle = nRF51Gap::getInstance().getConnectionHandle();
- ble_error_t returnValue = BLE_ERROR_NONE;
-
- ble_gatts_value_t value = {
- .len = len,
- .offset = 0,
- .p_value = const_cast<uint8_t *>(buffer),
- };
-
- if (localOnly) {
- /* Only update locally regardless of notify/indicate */
- ASSERT_INT( ERROR_NONE,
- sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
- BLE_ERROR_PARAM_OUT_OF_RANGE );
- return BLE_ERROR_NONE;
- }
-
- int characteristicIndex = resolveValueHandleToCharIndex(attributeHandle);
- if ((characteristicIndex != -1) &&
- (p_characteristics[characteristicIndex]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
- (gapConnectionHandle != connectionHandle)) {
- /* HVX update for the characteristic value */
- ble_gatts_hvx_params_t hvx_params;
-
- hvx_params.handle = attributeHandle;
- hvx_params.type =
- (p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
- hvx_params.offset = 0;
- hvx_params.p_data = const_cast<uint8_t *>(buffer);
- hvx_params.p_len = &len;
-
- error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params);
-
- /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and ERROR_NO_TX_BUFFERS the ATT table has been updated. */
- if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) && (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) && (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) {
- ASSERT_INT( ERROR_NONE,
- sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
- BLE_ERROR_PARAM_OUT_OF_RANGE );
- }
-
- /* Notifications consume application buffers. The return value can
- be used for resending notifications.
- */
- if (error != ERROR_NONE) {
- returnValue = BLE_STACK_BUSY;
- }
- } else {
- ASSERT_INT( ERROR_NONE,
- sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
- BLE_ERROR_PARAM_OUT_OF_RANGE );
- }
-
- return returnValue;
-}
-
-ble_error_t nRF51GattServer::areUpdatesEnabled(const GattCharacteristic &characteristic, bool *enabledP)
-{
- /* Forward the call with the default connection handle. */
- return areUpdatesEnabled(nRF51Gap::getInstance().getConnectionHandle(), characteristic, enabledP);
-}
-
-ble_error_t nRF51GattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP)
-{
- int characteristicIndex = resolveValueHandleToCharIndex(characteristic.getValueHandle());
- if (characteristicIndex == -1) {
- return BLE_ERROR_INVALID_PARAM;
- }
-
- /* Read the cccd value from the GATT server. */
- GattAttribute::Handle_t cccdHandle = nrfCharacteristicHandles[characteristicIndex].cccd_handle;
- uint16_t cccdValue;
- uint16_t length = sizeof(cccdValue);
- ble_error_t rc = read(connectionHandle, cccdHandle, reinterpret_cast<uint8_t *>(&cccdValue), &length);
- if (rc != BLE_ERROR_NONE) {
- return rc;
- }
- if (length != sizeof(cccdValue)) {
- return BLE_ERROR_INVALID_STATE;
- }
-
- /* Check for NOTFICATION or INDICATION in CCCD. */
- if ((cccdValue & BLE_GATT_HVX_NOTIFICATION) || (cccdValue & BLE_GATT_HVX_INDICATION)) {
- *enabledP = true;
- }
-
- return BLE_ERROR_NONE;
-}
-
-/**************************************************************************/
-/*!
- @brief Callback handler for events getting pushed up from the SD
-*/
-/**************************************************************************/
-void nRF51GattServer::hwCallback(ble_evt_t *p_ble_evt)
-{
- GattAttribute::Handle_t handle_value;
- GattServerEvents::gattEvent_t eventType;
- const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt;
-
- switch (p_ble_evt->header.evt_id) {
- case BLE_GATTS_EVT_WRITE: {
- /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */
-
- /* 1.) Handle CCCD changes */
- handle_value = gattsEventP->params.write.handle;
- int characteristicIndex = resolveCCCDHandleToCharIndex(handle_value);
- if ((characteristicIndex != -1) &&
- (p_characteristics[characteristicIndex]->getProperties() &
- (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) {
-
- uint16_t cccd_value = (gattsEventP->params.write.data[1] << 8) | gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */
-
- if (((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) ||
- ((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) {
- eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
- } else {
- eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
- }
-
- handleEvent(eventType, p_characteristics[characteristicIndex]->getValueHandle());
- return;
- }
-
- /* 2.) Changes to the characteristic value will be handled with other events below */
- eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
- }
- break;
-
- case BLE_GATTS_EVT_HVC:
- /* Indication confirmation received */
- eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
- handle_value = gattsEventP->params.hvc.handle;
- break;
-
- case BLE_EVT_TX_COMPLETE: {
- handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count);
- return;
- }
-
- case BLE_GATTS_EVT_SYS_ATTR_MISSING:
- sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0, 0);
- return;
-
- case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
- switch (gattsEventP->params.authorize_request.type) {
- case BLE_GATTS_AUTHORIZE_TYPE_READ:
- eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ;
- handle_value = gattsEventP->params.authorize_request.request.read.handle;
- break;
- case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
- eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ;
- handle_value = gattsEventP->params.authorize_request.request.write.handle;
- break;
- default:
- return;
- }
- break;
-
- default:
- return;
- }
-
- int characteristicIndex = resolveValueHandleToCharIndex(handle_value);
- if (characteristicIndex == -1) {
- return;
- }
-
- /* Find index (charHandle) in the pool */
- switch (eventType) {
- case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
- GattWriteCallbackParams cbParams = {
- .handle = handle_value,
- .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: {
- GattWriteAuthCallbackParams cbParams = {
- .handle = handle_value,
- .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,
- .params = {
- .write = {
- .gatt_status = p_characteristics[characteristicIndex]->authorizeWrite(&cbParams)
- }
- }
- };
- sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
-
- /*
- * If write-authorization is enabled for a characteristic,
- * AUTHORIZATION_REQ event (if replied with true) is *not*
- * followed by another DATA_WRITTEN event; so we still need
- * to invoke handleDataWritten(), much the same as we would
- * have done if write-authorization had not been enabled.
- */
- if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) {
- GattWriteCallbackParams cbParams = {
- .handle = handle_value,
- .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: {
- GattReadAuthCallbackParams cbParams = {
- .handle = handle_value,
- .offset = gattsEventP->params.authorize_request.request.read.offset,
- .len = 0,
- .data = NULL
- };
-
- ble_gatts_rw_authorize_reply_params_t reply = {
- .type = BLE_GATTS_AUTHORIZE_TYPE_READ,
- .params = {
- .read = {
- .gatt_status = p_characteristics[characteristicIndex]->authorizeRead(&cbParams)
- }
- }
- };
-
- if (cbParams.authorizationReply == BLE_GATT_STATUS_SUCCESS) {
- if (cbParams.data != NULL) {
- reply.params.read.update = 1;
- reply.params.read.offset = cbParams.offset;
- reply.params.read.len = cbParams.len;
- reply.params.read.p_data = cbParams.data;
- }
- }
-
- sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
- break;
- }
-
- default:
- handleEvent(eventType, handle_value);
- break;
- }
-}
\ No newline at end of file
--- a/source/nRF51GattServer.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +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.
- */
-
-#ifndef __NRF51822_GATT_SERVER_H__
-#define __NRF51822_GATT_SERVER_H__
-
-#include <stddef.h>
-
-#include "ble/blecommon.h"
-#include "ble.h" /* nordic ble */
-#include "ble/Gap.h"
-#include "ble/GattServer.h"
-
-class nRF51GattServer : public GattServer
-{
-public:
- static nRF51GattServer &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);
- virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
- virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
- 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);
-
- /* 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;
-
-private:
- /**
- * resolve a value attribute to its owning characteristic.
- * @param valueHandle the value handle to be resolved.
- * @return characteristic index if a resolution is found, else -1.
- */
- int resolveValueHandleToCharIndex(GattAttribute::Handle_t valueHandle) const {
- unsigned charIndex;
- for (charIndex = 0; charIndex < characteristicCount; charIndex++) {
- if (nrfCharacteristicHandles[charIndex].value_handle == valueHandle) {
- return charIndex;
- }
- }
-
- return -1;
- }
-
- /**
- * resolve a CCCD attribute handle to its owning characteristic.
- * @param cccdHandle the CCCD handle to be resolved.
- * @return characteristic index if a resolution is found, else -1.
- */
- int resolveCCCDHandleToCharIndex(GattAttribute::Handle_t cccdHandle) const {
- unsigned charIndex;
- for (charIndex = 0; charIndex < characteristicCount; charIndex++) {
- if (nrfCharacteristicHandles[charIndex].cccd_handle == cccdHandle) {
- return charIndex;
- }
- }
-
- return -1;
- }
-
-private:
- GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
- ble_gatts_char_handles_t nrfCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
- GattAttribute *p_descriptors[BLE_TOTAL_DESCRIPTORS];
- uint8_t descriptorCount;
- uint16_t nrfDescriptorHandles[BLE_TOTAL_DESCRIPTORS];
-
- nRF51GattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles() {
- /* empty */
- }
-
-private:
- nRF51GattServer(const nRF51GattServer &);
- const nRF51GattServer& operator=(const nRF51GattServer &);
-};
-
-#endif // ifndef __NRF51822_GATT_SERVER_H__
\ No newline at end of file
--- a/source/nRF51SecurityManager.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +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 "nRF51SecurityManager.h"
-
-nRF51SecurityManager &nRF51SecurityManager::getInstance(void) {
- static nRF51SecurityManager m_instance;
- return m_instance;
-}
\ No newline at end of file
--- a/source/nRF51SecurityManager.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,56 +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.
- */
-
-#ifndef __NRF51822_SECURITY_MANAGER_H__
-#define __NRF51822_SECURITY_MANAGER_H__
-
-#include <stddef.h>
-
-#include "ble/SecurityManager.h"
-#include "btle_security.h"
-
-class nRF51SecurityManager : public SecurityManager
-{
-public:
- static nRF51SecurityManager &getInstance();
-
- /* Functions that must be implemented from SecurityManager */
- virtual ble_error_t init(bool enableBonding,
- bool requireMITM,
- SecurityIOCapabilities_t iocaps,
- const Passkey_t passkey) {
- return btle_initializeSecurity(enableBonding, requireMITM, iocaps, passkey);
- }
-
- virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
- return btle_getLinkSecurity(connectionHandle, securityStatusP);
- }
-
- virtual ble_error_t purgeAllBondingState(void) {
- return btle_purgeAllBondingState();
- }
-
-public:
- nRF51SecurityManager() {
- /* empty */
- }
-
-private:
- nRF51SecurityManager(const nRF51SecurityManager &);
- const nRF51SecurityManager& operator=(const nRF51SecurityManager &);
-};
-
-#endif // ifndef __NRF51822_SECURITY_MANAGER_H__
\ No newline at end of file
--- a/source/nRF51ServiceDiscovery.cpp Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,282 +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 "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 = { };
- handleRange.start_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle();
- handleRange.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
--- a/source/nRF51ServiceDiscovery.h Tue Jul 21 13:23:44 2015 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,305 +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.
- */
-
-#ifndef __NRF_SERVICE_DISCOVERY_H__
-#define __NRF_SERVICE_DISCOVERY_H__
-
-#include "ble/ServiceDiscovery.h"
-#include "ble/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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xDiscoveredCharacteristic.cpp Tue Jul 21 13:23:44 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 "nRF5xDiscoveredCharacteristic.h"
+#include "nRF5xGattClient.h"
+#include "ble_gatt.h"
+
+void
+nRF5xDiscoveredCharacteristic::setup(nRF5xGattClient *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
+nRF5xDiscoveredCharacteristic::setup(nRF5xGattClient *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/source/nRF5xDiscoveredCharacteristic.h Tue Jul 21 13:23:44 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 "ble/DiscoveredCharacteristic.h"
+#include "ble_gatt.h"
+
+class nRF5xGattClient; /* forward declaration */
+
+class nRF5xDiscoveredCharacteristic : public DiscoveredCharacteristic {
+public:
+ void setup(nRF5xGattClient *gattcIn,
+ Gap::Handle_t connectionHandleIn,
+ ble_gatt_char_props_t propsIn,
+ GattAttribute::Handle_t declHandleIn,
+ GattAttribute::Handle_t valueHandleIn);
+
+ void setup(nRF5xGattClient *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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xGap.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,465 @@
+/* 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 "nRF5xGap.h"
+#include "mbed.h"
+
+#include "common/common.h"
+#include "ble_advdata.h"
+#include "ble_hci.h"
+
+nRF5xGap &nRF5xGap::getInstance() {
+ static nRF5xGap m_instance;
+ return m_instance;
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the advertising parameters and payload for the device
+
+ @param[in] params
+ Basic advertising details, including the advertising
+ delay, timeout and how the device should be advertised
+ @params[in] advData
+ The primary advertising data payload
+ @params[in] scanResponse
+ The optional Scan Response payload if the advertising
+ type is set to \ref GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED
+ in \ref GapAdveritinngParams
+
+ @returns \ref ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @retval BLE_ERROR_BUFFER_OVERFLOW
+ The proposed action would cause a buffer overflow. All
+ advertising payloads must be <= 31 bytes, for example.
+
+ @retval BLE_ERROR_NOT_IMPLEMENTED
+ A feature was requested that is not yet supported in the
+ nRF51 firmware or hardware.
+
+ @retval BLE_ERROR_PARAM_OUT_OF_RANGE
+ One of the proposed values is outside the valid range.
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setAdvertisingData(const GapAdvertisingData &advData, const GapAdvertisingData &scanResponse)
+{
+ /* Make sure we don't exceed the advertising payload length */
+ if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD) {
+ return BLE_ERROR_BUFFER_OVERFLOW;
+ }
+
+ /* Make sure we have a payload! */
+ if (advData.getPayloadLen() == 0) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ /* Check the scan response payload limits */
+ //if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_SCANNABLE_UNDIRECTED))
+ //{
+ // /* Check if we're within the upper limit */
+ // if (advData.getPayloadLen() > GAP_ADVERTISING_DATA_MAX_PAYLOAD)
+ // {
+ // return BLE_ERROR_BUFFER_OVERFLOW;
+ // }
+ // /* Make sure we have a payload! */
+ // if (advData.getPayloadLen() == 0)
+ // {
+ // return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ // }
+ //}
+
+ /* Send advertising data! */
+ ASSERT(ERROR_NONE ==
+ sd_ble_gap_adv_data_set(advData.getPayload(),
+ advData.getPayloadLen(),
+ scanResponse.getPayload(),
+ scanResponse.getPayloadLen()),
+ BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ /* Make sure the GAP Service appearance value is aligned with the
+ *appearance from GapAdvertisingData */
+ ASSERT(ERROR_NONE == sd_ble_gap_appearance_set(advData.getAppearance()),
+ BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ /* ToDo: Perform some checks on the payload, for example the Scan Response can't */
+ /* contains a flags AD type, etc. */
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Starts the BLE HW, initialising any services that were
+ added before this function was called.
+
+ @note All services must be added before calling this function!
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::startAdvertising(const GapAdvertisingParams ¶ms)
+{
+ /* Make sure we support the advertising type */
+ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) {
+ /* ToDo: This requires a propery security implementation, etc. */
+ return BLE_ERROR_NOT_IMPLEMENTED;
+ }
+
+ /* Check interval range */
+ if (params.getAdvertisingType() == GapAdvertisingParams::ADV_NON_CONNECTABLE_UNDIRECTED) {
+ /* Min delay is slightly longer for unconnectable devices */
+ if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN_NONCON) ||
+ (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ } else {
+ if ((params.getInterval() < GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MIN) ||
+ (params.getInterval() > GapAdvertisingParams::GAP_ADV_PARAMS_INTERVAL_MAX)) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ }
+
+ /* Check timeout is zero for Connectable Directed */
+ if ((params.getAdvertisingType() == GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) && (params.getTimeout() != 0)) {
+ /* Timeout must be 0 with this type, although we'll never get here */
+ /* since this isn't implemented yet anyway */
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ /* Check timeout for other advertising types */
+ if ((params.getAdvertisingType() != GapAdvertisingParams::ADV_CONNECTABLE_DIRECTED) &&
+ (params.getTimeout() > GapAdvertisingParams::GAP_ADV_PARAMS_TIMEOUT_MAX)) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ /* Start Advertising */
+ ble_gap_adv_params_t adv_para = {0};
+
+ adv_para.type = params.getAdvertisingType();
+ adv_para.p_peer_addr = NULL; // Undirected advertisement
+ adv_para.fp = BLE_GAP_ADV_FP_ANY;
+ adv_para.p_whitelist = NULL;
+ adv_para.interval = params.getInterval(); // advertising interval (in units of 0.625 ms)
+ adv_para.timeout = params.getTimeout();
+
+ ASSERT(ERROR_NONE == sd_ble_gap_adv_start(&adv_para), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ state.advertising = 1;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Stops the BLE HW and disconnects from any devices
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::stopAdvertising(void)
+{
+ /* Stop Advertising */
+ ASSERT(ERROR_NONE == sd_ble_gap_adv_stop(), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ state.advertising = 0;
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::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;
+ }
+}
+
+ble_error_t nRF5xGap::disconnect(Handle_t connectionHandle, DisconnectionReason_t reason)
+{
+ state.advertising = 0;
+ state.connected = 0;
+
+ uint8_t code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
+ switch (reason) {
+ case REMOTE_USER_TERMINATED_CONNECTION:
+ code = BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION;
+ break;
+ case CONN_INTERVAL_UNACCEPTABLE:
+ code = BLE_HCI_CONN_INTERVAL_UNACCEPTABLE;
+ break;
+ default:
+ break;
+ }
+
+ /* Disconnect if we are connected to a central device */
+ ASSERT_INT(ERROR_NONE, sd_ble_gap_disconnect(connectionHandle, code), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ return BLE_ERROR_NONE;
+}
+
+/*!
+ @brief Disconnects if we are connected to a central device
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+ble_error_t nRF5xGap::disconnect(DisconnectionReason_t reason)
+{
+ return disconnect(m_connectionHandle, reason);
+}
+
+ble_error_t nRF5xGap::getPreferredConnectionParams(ConnectionParams_t *params)
+{
+ ASSERT_INT(NRF_SUCCESS,
+ sd_ble_gap_ppcp_get(reinterpret_cast<ble_gap_conn_params_t *>(params)),
+ BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::setPreferredConnectionParams(const ConnectionParams_t *params)
+{
+ ASSERT_INT(NRF_SUCCESS,
+ sd_ble_gap_ppcp_set(reinterpret_cast<const ble_gap_conn_params_t *>(params)),
+ BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::updateConnectionParams(Handle_t handle, const ConnectionParams_t *newParams)
+{
+ uint32_t rc;
+
+ rc = sd_ble_gap_conn_param_update(handle, reinterpret_cast<ble_gap_conn_params_t *>(const_cast<ConnectionParams_t*>(newParams)));
+ if (rc == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the 16-bit connection handle
+*/
+/**************************************************************************/
+void nRF5xGap::setConnectionHandle(uint16_t con_handle)
+{
+ m_connectionHandle = con_handle;
+}
+
+/**************************************************************************/
+/*!
+ @brief Gets the 16-bit connection handle
+*/
+/**************************************************************************/
+uint16_t nRF5xGap::getConnectionHandle(void)
+{
+ return m_connectionHandle;
+}
+
+/**************************************************************************/
+/*!
+ @brief Sets the BLE device address
+
+ @returns ble_error_t
+
+ @section EXAMPLE
+
+ @code
+
+ uint8_t device_address[6] = { 0xca, 0xfe, 0xf0, 0xf0, 0xf0, 0xf0 };
+ nrf.getGap().setAddress(Gap::ADDR_TYPE_RANDOM_STATIC, device_address);
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGap::setAddress(AddressType_t type, const Address_t address)
+{
+ if (type > ADDR_TYPE_RANDOM_PRIVATE_NON_RESOLVABLE) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ ble_gap_addr_t dev_addr;
+ dev_addr.addr_type = type;
+ memcpy(dev_addr.addr, address, ADDR_LEN);
+
+ ASSERT_INT(ERROR_NONE, sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &dev_addr), BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::getAddress(AddressType_t *typeP, Address_t address)
+{
+ ble_gap_addr_t dev_addr;
+ if (sd_ble_gap_address_get(&dev_addr) != NRF_SUCCESS) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ if (typeP != NULL) {
+ *typeP = static_cast<AddressType_t>(dev_addr.addr_type);
+ }
+ if (address != NULL) {
+ memcpy(address, dev_addr.addr, ADDR_LEN);
+ }
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xGap::setDeviceName(const uint8_t *deviceName)
+{
+ ble_gap_conn_sec_mode_t sec_mode;
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode); // no security is needed
+
+ if (sd_ble_gap_device_name_set(&sec_mode, deviceName, strlen((const char *)deviceName)) == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+}
+
+ble_error_t nRF5xGap::getDeviceName(uint8_t *deviceName, unsigned *lengthP)
+{
+ if (sd_ble_gap_device_name_get(deviceName, (uint16_t *)lengthP) == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+}
+
+ble_error_t nRF5xGap::setAppearance(GapAdvertisingData::Appearance appearance)
+{
+ if (sd_ble_gap_appearance_set(appearance) == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+}
+
+ble_error_t nRF5xGap::getAppearance(GapAdvertisingData::Appearance *appearanceP)
+{
+ if (sd_ble_gap_appearance_get(reinterpret_cast<uint16_t *>(appearanceP))) {
+ return BLE_ERROR_NONE;
+ } else {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+}
+
+/* (Valid values are -40, -20, -16, -12, -8, -4, 0, 4) */
+ble_error_t nRF5xGap::setTxPower(int8_t txPower)
+{
+ unsigned rc;
+ if ((rc = sd_ble_gap_tx_power_set(txPower)) != NRF_SUCCESS) {
+ switch (rc) {
+ case NRF_ERROR_BUSY:
+ return BLE_STACK_BUSY;
+ case NRF_ERROR_INVALID_PARAM:
+ default:
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+void nRF5xGap::getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP)
+{
+ static const int8_t permittedTxValues[] = {
+ -40, -30, -20, -16, -12, -8, -4, 0, 4
+ };
+
+ *valueArrayPP = permittedTxValues;
+ *countP = sizeof(permittedTxValues) / sizeof(int8_t);
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xGap.h Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,113 @@
+/* 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 __NRF5x_GAP_H__
+#define __NRF5x_GAP_H__
+
+#include "mbed.h"
+#include "ble/blecommon.h"
+#include "ble.h"
+#include "ble/GapAdvertisingParams.h"
+#include "ble/GapAdvertisingData.h"
+#include "ble/Gap.h"
+#include "ble/GapScanningParams.h"
+
+#include "nrf_soc.h"
+#include "ble_radio_notification.h"
+#include "btle_security.h"
+
+/**************************************************************************/
+/*!
+ \brief
+
+*/
+/**************************************************************************/
+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);
+ 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);}
+ virtual uint16_t getMinNonConnectableAdvertisingInterval(void) const {return ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);}
+ virtual uint16_t getMaxAdvertisingInterval(void) const {return ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MAX);}
+
+ 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(Handle_t connectionHandle, DisconnectionReason_t reason);
+ virtual ble_error_t disconnect(DisconnectionReason_t reason);
+
+ virtual ble_error_t setDeviceName(const uint8_t *deviceName);
+ virtual ble_error_t getDeviceName(uint8_t *deviceName, unsigned *lengthP);
+ virtual ble_error_t setAppearance(GapAdvertisingData::Appearance appearance);
+ virtual ble_error_t getAppearance(GapAdvertisingData::Appearance *appearanceP);
+
+ virtual ble_error_t setTxPower(int8_t txPower);
+ virtual void getPermittedTxPowerValues(const int8_t **valueArrayPP, size_t *countP);
+
+ void setConnectionHandle(uint16_t con_handle);
+ uint16_t getConnectionHandle(void);
+
+ virtual ble_error_t getPreferredConnectionParams(ConnectionParams_t *params);
+ virtual ble_error_t setPreferredConnectionParams(const ConnectionParams_t *params);
+ virtual ble_error_t updateConnectionParams(Handle_t handle, const ConnectionParams_t *params);
+
+ virtual void onRadioNotification(RadioNotificationEventCallback_t callback) {
+ Gap::onRadioNotification(callback);
+ ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationCallback);
+ }
+
+ virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams) {
+ ble_gap_scan_params_t scanParams = {
+ .active = scanningParams.getActiveScanning(), /**< If 1, perform active scanning (scan requests). */
+ .selective = 0, /**< If 1, ignore unknown devices (non whitelisted). */
+ .p_whitelist = NULL, /**< Pointer to whitelist, NULL if none is given. */
+ .interval = scanningParams.getInterval(), /**< Scan interval between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+ .window = scanningParams.getWindow(), /**< Scan window between 0x0004 and 0x4000 in 0.625ms units (2.5ms to 10.24s). */
+ .timeout = scanningParams.getTimeout(), /**< Scan timeout between 0x0001 and 0xFFFF in seconds, 0x0000 disables timeout. */
+ };
+
+ if (sd_ble_gap_scan_start(&scanParams) != NRF_SUCCESS) {
+ return BLE_ERROR_PARAM_OUT_OF_RANGE;
+ }
+
+ return BLE_ERROR_NONE;
+ }
+
+ virtual ble_error_t stopScan(void) {
+ if (sd_ble_gap_scan_stop() == NRF_SUCCESS) {
+ return BLE_ERROR_NONE;
+ }
+
+ return BLE_STACK_BUSY;
+ }
+
+private:
+ uint16_t m_connectionHandle;
+ nRF5xGap() {
+ m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+ }
+
+ nRF5xGap(nRF5xGap const &);
+ void operator=(nRF5xGap const &);
+};
+
+#endif // ifndef __NRF5x_GAP_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xGattClient.cpp Tue Jul 21 13:23:44 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 "nRF5xGattClient.h"
+
+nRF5xGattClient nRFGattClientSingleton;
+
+nRF5xGattClient &
+nRF5xGattClient::getInstance(void) {
+ return nRFGattClientSingleton;
+}
+
+ble_error_t
+nRF5xGattClient::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/source/nRF5xGattClient.h Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,157 @@
+/* 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 "ble/GattClient.h"
+#include "nRF5xServiceDiscovery.h"
+
+class nRF5xGattClient : public GattClient
+{
+public:
+ static nRF5xGattClient &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 = { };
+ writeParams.write_op = cmd;
+ writeParams.handle = attributeHandle;
+ writeParams.len = length;
+ writeParams.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:
+ nRF5xGattClient() : discovery(this) {
+ /* empty */
+ }
+
+ friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
+
+private:
+ nRF5xGattClient(const nRF5xGattClient &);
+ const nRF5xGattClient& operator=(const nRF5xGattClient &);
+
+private:
+ nRF5xServiceDiscovery discovery;
+};
+
+#endif // ifndef __NRF51822_GATT_CLIENT_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xGattServer.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,457 @@
+/* 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 "nRF5xGattServer.h"
+#include "mbed.h"
+
+#include "common/common.h"
+#include "btle/custom/custom_helper.h"
+
+#include "nRF5xGap.h"
+
+nRF5xGattServer &nRF5xGattServer::getInstance(void) {
+ static nRF5xGattServer m_instance;
+ return m_instance;
+}
+
+/**************************************************************************/
+/*!
+ @brief Adds a new service to the GATT table on the peripheral
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+
+ @section EXAMPLE
+
+ @code
+
+ @endcode
+*/
+/**************************************************************************/
+ble_error_t nRF5xGattServer::addService(GattService &service)
+{
+ /* ToDo: Make sure we don't overflow the array, etc. */
+ /* ToDo: Make sure this service UUID doesn't already exist (?) */
+ /* ToDo: Basic validation */
+
+ /* Add the service to the nRF51 */
+ ble_uuid_t nordicUUID;
+ nordicUUID = custom_convert_to_nordic_uuid(service.getUUID());
+
+ uint16_t serviceHandle;
+ ASSERT( ERROR_NONE ==
+ sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &nordicUUID,
+ &serviceHandle),
+ BLE_ERROR_PARAM_OUT_OF_RANGE );
+ service.setHandle(serviceHandle);
+
+ /* Add characteristics to the service */
+ for (uint8_t i = 0; i < service.getCharacteristicCount(); i++) {
+ GattCharacteristic *p_char = service.getCharacteristic(i);
+
+ /* Skip any incompletely defined, read-only characteristics. */
+ if ((p_char->getValueAttribute().getValuePtr() == NULL) &&
+ (p_char->getValueAttribute().getInitialLength() == 0) &&
+ (p_char->getProperties() == GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ)) {
+ continue;
+ }
+
+ nordicUUID = custom_convert_to_nordic_uuid(p_char->getValueAttribute().getUUID());
+
+ /* The user-description descriptor is a special case which needs to be
+ * handled at the time of adding the characteristic. The following block
+ * is meant to discover its presence. */
+ const uint8_t *userDescriptionDescriptorValuePtr = NULL;
+ uint16_t userDescriptionDescriptorValueLen = 0;
+ for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
+ GattAttribute *p_desc = p_char->getDescriptor(j);
+ if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
+ userDescriptionDescriptorValuePtr = p_desc->getValuePtr();
+ userDescriptionDescriptorValueLen = p_desc->getLength();
+ }
+ }
+
+ ASSERT ( ERROR_NONE ==
+ custom_add_in_characteristic(BLE_GATT_HANDLE_INVALID,
+ &nordicUUID,
+ p_char->getProperties(),
+ p_char->getRequiredSecurity(),
+ p_char->getValueAttribute().getValuePtr(),
+ p_char->getValueAttribute().getInitialLength(),
+ p_char->getValueAttribute().getMaxLength(),
+ userDescriptionDescriptorValuePtr,
+ userDescriptionDescriptorValueLen,
+ p_char->isReadAuthorizationEnabled(),
+ p_char->isWriteAuthorizationEnabled(),
+ &nrfCharacteristicHandles[characteristicCount]),
+ BLE_ERROR_PARAM_OUT_OF_RANGE );
+
+ /* Update the characteristic handle */
+ p_characteristics[characteristicCount] = p_char;
+ p_char->getValueAttribute().setHandle(nrfCharacteristicHandles[characteristicCount].value_handle);
+ characteristicCount++;
+
+ /* Add optional descriptors if any */
+ /* ToDo: Make sure we don't overflow the array */
+ for (uint8_t j = 0; j < p_char->getDescriptorCount(); j++) {
+ GattAttribute *p_desc = p_char->getDescriptor(j);
+ /* skip the user-description-descriptor here; this has already been handled when adding the characteristic (above). */
+ if (p_desc->getUUID() == BLE_UUID_DESCRIPTOR_CHAR_USER_DESC) {
+ continue;
+ }
+
+ nordicUUID = custom_convert_to_nordic_uuid(p_desc->getUUID());
+
+ ASSERT(ERROR_NONE ==
+ custom_add_in_descriptor(BLE_GATT_HANDLE_INVALID,
+ &nordicUUID,
+ p_desc->getValuePtr(),
+ p_desc->getInitialLength(),
+ p_desc->getMaxLength(),
+ &nrfDescriptorHandles[descriptorCount]),
+ BLE_ERROR_PARAM_OUT_OF_RANGE);
+
+ p_descriptors[descriptorCount++] = p_desc;
+ p_desc->setHandle(nrfDescriptorHandles[descriptorCount]);
+ }
+ }
+
+ serviceCount++;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Reads the value of a characteristic, based on the service
+ and characteristic index fields
+
+ @param[in] attributeHandle
+ The handle of the GattCharacteristic to read from
+ @param[in] buffer
+ Buffer to hold the the characteristic's value
+ (raw byte array in LSB format)
+ @param[in/out] len
+ input: Length in bytes to be read.
+ output: Total length of attribute value upon successful return.
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t nRF5xGattServer::read(GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
+{
+ return read(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, lengthP);
+}
+
+ble_error_t nRF5xGattServer::read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP)
+{
+ ble_gatts_value_t value = {
+ .len = *lengthP,
+ .offset = 0,
+ .p_value = buffer,
+ };
+
+ ASSERT( ERROR_NONE ==
+ sd_ble_gatts_value_get(connectionHandle, attributeHandle, &value),
+ BLE_ERROR_PARAM_OUT_OF_RANGE);
+ *lengthP = value.len;
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Updates the value of a characteristic, based on the service
+ and characteristic index fields
+
+ @param[in] charHandle
+ The handle of the GattCharacteristic to write to
+ @param[in] buffer
+ Data to use when updating the characteristic's value
+ (raw byte array in LSB format)
+ @param[in] len
+ The number of bytes in buffer
+
+ @returns ble_error_t
+
+ @retval BLE_ERROR_NONE
+ Everything executed properly
+*/
+/**************************************************************************/
+ble_error_t nRF5xGattServer::write(GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+{
+ return write(BLE_CONN_HANDLE_INVALID, attributeHandle, buffer, len, localOnly);
+}
+
+ble_error_t nRF5xGattServer::write(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, const uint8_t buffer[], uint16_t len, bool localOnly)
+{
+ uint16_t gapConnectionHandle = nRF5xGap::getInstance().getConnectionHandle();
+ ble_error_t returnValue = BLE_ERROR_NONE;
+
+ ble_gatts_value_t value = {
+ .len = len,
+ .offset = 0,
+ .p_value = const_cast<uint8_t *>(buffer),
+ };
+
+ if (localOnly) {
+ /* Only update locally regardless of notify/indicate */
+ ASSERT_INT( ERROR_NONE,
+ sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
+ BLE_ERROR_PARAM_OUT_OF_RANGE );
+ return BLE_ERROR_NONE;
+ }
+
+ int characteristicIndex = resolveValueHandleToCharIndex(attributeHandle);
+ if ((characteristicIndex != -1) &&
+ (p_characteristics[characteristicIndex]->getProperties() & (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)) &&
+ (gapConnectionHandle != connectionHandle)) {
+ /* HVX update for the characteristic value */
+ ble_gatts_hvx_params_t hvx_params;
+
+ hvx_params.handle = attributeHandle;
+ hvx_params.type =
+ (p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) ? BLE_GATT_HVX_NOTIFICATION : BLE_GATT_HVX_INDICATION;
+ hvx_params.offset = 0;
+ hvx_params.p_data = const_cast<uint8_t *>(buffer);
+ hvx_params.p_len = &len;
+
+ error_t error = (error_t) sd_ble_gatts_hvx(gapConnectionHandle, &hvx_params);
+
+ /* ERROR_INVALID_STATE, ERROR_BUSY, ERROR_GATTS_SYS_ATTR_MISSING and ERROR_NO_TX_BUFFERS the ATT table has been updated. */
+ if ((error != ERROR_NONE) && (error != ERROR_INVALID_STATE) && (error != ERROR_BLE_NO_TX_BUFFERS) && (error != ERROR_BUSY) && (error != ERROR_BLEGATTS_SYS_ATTR_MISSING)) {
+ ASSERT_INT( ERROR_NONE,
+ sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
+ BLE_ERROR_PARAM_OUT_OF_RANGE );
+ }
+
+ /* Notifications consume application buffers. The return value can
+ be used for resending notifications.
+ */
+ if (error != ERROR_NONE) {
+ returnValue = BLE_STACK_BUSY;
+ }
+ } else {
+ ASSERT_INT( ERROR_NONE,
+ sd_ble_gatts_value_set(connectionHandle, attributeHandle, &value),
+ BLE_ERROR_PARAM_OUT_OF_RANGE );
+ }
+
+ return returnValue;
+}
+
+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);
+}
+
+ble_error_t nRF5xGattServer::areUpdatesEnabled(Gap::Handle_t connectionHandle, const GattCharacteristic &characteristic, bool *enabledP)
+{
+ int characteristicIndex = resolveValueHandleToCharIndex(characteristic.getValueHandle());
+ if (characteristicIndex == -1) {
+ return BLE_ERROR_INVALID_PARAM;
+ }
+
+ /* Read the cccd value from the GATT server. */
+ GattAttribute::Handle_t cccdHandle = nrfCharacteristicHandles[characteristicIndex].cccd_handle;
+ uint16_t cccdValue;
+ uint16_t length = sizeof(cccdValue);
+ ble_error_t rc = read(connectionHandle, cccdHandle, reinterpret_cast<uint8_t *>(&cccdValue), &length);
+ if (rc != BLE_ERROR_NONE) {
+ return rc;
+ }
+ if (length != sizeof(cccdValue)) {
+ return BLE_ERROR_INVALID_STATE;
+ }
+
+ /* Check for NOTFICATION or INDICATION in CCCD. */
+ if ((cccdValue & BLE_GATT_HVX_NOTIFICATION) || (cccdValue & BLE_GATT_HVX_INDICATION)) {
+ *enabledP = true;
+ }
+
+ return BLE_ERROR_NONE;
+}
+
+/**************************************************************************/
+/*!
+ @brief Callback handler for events getting pushed up from the SD
+*/
+/**************************************************************************/
+void nRF5xGattServer::hwCallback(ble_evt_t *p_ble_evt)
+{
+ GattAttribute::Handle_t handle_value;
+ GattServerEvents::gattEvent_t eventType;
+ const ble_gatts_evt_t *gattsEventP = &p_ble_evt->evt.gatts_evt;
+
+ switch (p_ble_evt->header.evt_id) {
+ case BLE_GATTS_EVT_WRITE: {
+ /* There are 2 use case here: Values being updated & CCCD (indicate/notify) enabled */
+
+ /* 1.) Handle CCCD changes */
+ handle_value = gattsEventP->params.write.handle;
+ int characteristicIndex = resolveCCCDHandleToCharIndex(handle_value);
+ if ((characteristicIndex != -1) &&
+ (p_characteristics[characteristicIndex]->getProperties() &
+ (GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY))) {
+
+ uint16_t cccd_value = (gattsEventP->params.write.data[1] << 8) | gattsEventP->params.write.data[0]; /* Little Endian but M0 may be mis-aligned */
+
+ if (((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE) && (cccd_value & BLE_GATT_HVX_INDICATION)) ||
+ ((p_characteristics[characteristicIndex]->getProperties() & GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) && (cccd_value & BLE_GATT_HVX_NOTIFICATION))) {
+ eventType = GattServerEvents::GATT_EVENT_UPDATES_ENABLED;
+ } else {
+ eventType = GattServerEvents::GATT_EVENT_UPDATES_DISABLED;
+ }
+
+ handleEvent(eventType, p_characteristics[characteristicIndex]->getValueHandle());
+ return;
+ }
+
+ /* 2.) Changes to the characteristic value will be handled with other events below */
+ eventType = GattServerEvents::GATT_EVENT_DATA_WRITTEN;
+ }
+ break;
+
+ case BLE_GATTS_EVT_HVC:
+ /* Indication confirmation received */
+ eventType = GattServerEvents::GATT_EVENT_CONFIRMATION_RECEIVED;
+ handle_value = gattsEventP->params.hvc.handle;
+ break;
+
+ case BLE_EVT_TX_COMPLETE: {
+ handleDataSentEvent(p_ble_evt->evt.common_evt.params.tx_complete.count);
+ return;
+ }
+
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ sd_ble_gatts_sys_attr_set(gattsEventP->conn_handle, NULL, 0, 0);
+ return;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ switch (gattsEventP->params.authorize_request.type) {
+ case BLE_GATTS_AUTHORIZE_TYPE_READ:
+ eventType = GattServerEvents::GATT_EVENT_READ_AUTHORIZATION_REQ;
+ handle_value = gattsEventP->params.authorize_request.request.read.handle;
+ break;
+ case BLE_GATTS_AUTHORIZE_TYPE_WRITE:
+ eventType = GattServerEvents::GATT_EVENT_WRITE_AUTHORIZATION_REQ;
+ handle_value = gattsEventP->params.authorize_request.request.write.handle;
+ break;
+ default:
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ int characteristicIndex = resolveValueHandleToCharIndex(handle_value);
+ if (characteristicIndex == -1) {
+ return;
+ }
+
+ /* Find index (charHandle) in the pool */
+ switch (eventType) {
+ case GattServerEvents::GATT_EVENT_DATA_WRITTEN: {
+ GattWriteCallbackParams cbParams = {
+ .handle = handle_value,
+ .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: {
+ GattWriteAuthCallbackParams cbParams = {
+ .handle = handle_value,
+ .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,
+ .params = {
+ .write = {
+ .gatt_status = p_characteristics[characteristicIndex]->authorizeWrite(&cbParams)
+ }
+ }
+ };
+ sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
+
+ /*
+ * If write-authorization is enabled for a characteristic,
+ * AUTHORIZATION_REQ event (if replied with true) is *not*
+ * followed by another DATA_WRITTEN event; so we still need
+ * to invoke handleDataWritten(), much the same as we would
+ * have done if write-authorization had not been enabled.
+ */
+ if (reply.params.write.gatt_status == BLE_GATT_STATUS_SUCCESS) {
+ GattWriteCallbackParams cbParams = {
+ .handle = handle_value,
+ .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: {
+ GattReadAuthCallbackParams cbParams = {
+ .handle = handle_value,
+ .offset = gattsEventP->params.authorize_request.request.read.offset,
+ .len = 0,
+ .data = NULL
+ };
+
+ ble_gatts_rw_authorize_reply_params_t reply = {
+ .type = BLE_GATTS_AUTHORIZE_TYPE_READ,
+ .params = {
+ .read = {
+ .gatt_status = p_characteristics[characteristicIndex]->authorizeRead(&cbParams)
+ }
+ }
+ };
+
+ if (cbParams.authorizationReply == BLE_GATT_STATUS_SUCCESS) {
+ if (cbParams.data != NULL) {
+ reply.params.read.update = 1;
+ reply.params.read.offset = cbParams.offset;
+ reply.params.read.len = cbParams.len;
+ reply.params.read.p_data = cbParams.data;
+ }
+ }
+
+ sd_ble_gatts_rw_authorize_reply(gattsEventP->conn_handle, &reply);
+ break;
+ }
+
+ default:
+ handleEvent(eventType, handle_value);
+ break;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xGattServer.h Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,98 @@
+/* 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_SERVER_H__
+#define __NRF51822_GATT_SERVER_H__
+
+#include <stddef.h>
+
+#include "ble/blecommon.h"
+#include "ble.h" /* nordic ble */
+#include "ble/Gap.h"
+#include "ble/GattServer.h"
+
+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);
+ virtual ble_error_t read(Gap::Handle_t connectionHandle, GattAttribute::Handle_t attributeHandle, uint8_t buffer[], uint16_t *lengthP);
+ virtual ble_error_t write(GattAttribute::Handle_t, const uint8_t[], uint16_t, bool localOnly = false);
+ 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);
+
+ /* 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;
+
+private:
+ /**
+ * resolve a value attribute to its owning characteristic.
+ * @param valueHandle the value handle to be resolved.
+ * @return characteristic index if a resolution is found, else -1.
+ */
+ int resolveValueHandleToCharIndex(GattAttribute::Handle_t valueHandle) const {
+ unsigned charIndex;
+ for (charIndex = 0; charIndex < characteristicCount; charIndex++) {
+ if (nrfCharacteristicHandles[charIndex].value_handle == valueHandle) {
+ return charIndex;
+ }
+ }
+
+ return -1;
+ }
+
+ /**
+ * resolve a CCCD attribute handle to its owning characteristic.
+ * @param cccdHandle the CCCD handle to be resolved.
+ * @return characteristic index if a resolution is found, else -1.
+ */
+ int resolveCCCDHandleToCharIndex(GattAttribute::Handle_t cccdHandle) const {
+ unsigned charIndex;
+ for (charIndex = 0; charIndex < characteristicCount; charIndex++) {
+ if (nrfCharacteristicHandles[charIndex].cccd_handle == cccdHandle) {
+ return charIndex;
+ }
+ }
+
+ return -1;
+ }
+
+private:
+ GattCharacteristic *p_characteristics[BLE_TOTAL_CHARACTERISTICS];
+ ble_gatts_char_handles_t nrfCharacteristicHandles[BLE_TOTAL_CHARACTERISTICS];
+ GattAttribute *p_descriptors[BLE_TOTAL_DESCRIPTORS];
+ uint8_t descriptorCount;
+ uint16_t nrfDescriptorHandles[BLE_TOTAL_DESCRIPTORS];
+
+ nRF5xGattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles() {
+ /* empty */
+ }
+
+private:
+ nRF5xGattServer(const nRF5xGattServer &);
+ const nRF5xGattServer& operator=(const nRF5xGattServer &);
+};
+
+#endif // ifndef __NRF51822_GATT_SERVER_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xSecurityManager.cpp Tue Jul 21 13:23:44 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.
+ */
+
+#include "nRF5xSecurityManager.h"
+
+nRF5xSecurityManager &nRF5xSecurityManager::getInstance(void) {
+ static nRF5xSecurityManager m_instance;
+ return m_instance;
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xSecurityManager.h Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,56 @@
+/* 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_SECURITY_MANAGER_H__
+#define __NRF51822_SECURITY_MANAGER_H__
+
+#include <stddef.h>
+
+#include "ble/SecurityManager.h"
+#include "btle_security.h"
+
+class nRF5xSecurityManager : public SecurityManager
+{
+public:
+ static nRF5xSecurityManager &getInstance();
+
+ /* Functions that must be implemented from SecurityManager */
+ virtual ble_error_t init(bool enableBonding,
+ bool requireMITM,
+ SecurityIOCapabilities_t iocaps,
+ const Passkey_t passkey) {
+ return btle_initializeSecurity(enableBonding, requireMITM, iocaps, passkey);
+ }
+
+ virtual ble_error_t getLinkSecurity(Gap::Handle_t connectionHandle, LinkSecurityStatus_t *securityStatusP) {
+ return btle_getLinkSecurity(connectionHandle, securityStatusP);
+ }
+
+ virtual ble_error_t purgeAllBondingState(void) {
+ return btle_purgeAllBondingState();
+ }
+
+public:
+ nRF5xSecurityManager() {
+ /* empty */
+ }
+
+private:
+ nRF5xSecurityManager(const nRF5xSecurityManager &);
+ const nRF5xSecurityManager& operator=(const nRF5xSecurityManager &);
+};
+
+#endif // ifndef __NRF51822_SECURITY_MANAGER_H__
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xServiceDiscovery.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,282 @@
+/* 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 "nRF5xServiceDiscovery.h"
+
+ble_error_t
+nRF5xServiceDiscovery::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
+nRF5xServiceDiscovery::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
+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. */
+ 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
+nRF5xServiceDiscovery::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
+nRF5xServiceDiscovery::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
+nRF5xServiceDiscovery::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
+nRF5xServiceDiscovery::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 = { };
+ handleRange.start_handle = parentDiscoveryObject->characteristics[charIndex].getDeclHandle();
+ handleRange.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
+nRF5xServiceDiscovery::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/source/nRF5xServiceDiscovery.h Tue Jul 21 13:23:44 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 "ble/ServiceDiscovery.h"
+#include "ble/DiscoveredService.h"
+#include "nRF5xDiscoveredCharacteristic.h"
+
+#include "ble.h"
+#include "ble_gattc.h"
+
+class nRF5xGattClient; /* forward declaration */
+
+class nRF5xServiceDiscovery : 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:
+ nRF5xServiceDiscovery(nRF5xGattClient *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(nRF5xServiceDiscovery *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];
+
+ nRF5xServiceDiscovery *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(nRF5xServiceDiscovery *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];
+
+ nRF5xServiceDiscovery *parentDiscoveryObject;
+ };
+ friend class CharUUIDDiscoveryQueue;
+
+private:
+ friend void bleGattcEventHandler(const ble_evt_t *p_ble_evt);
+ void progressCharacteristicDiscovery(void);
+ void progressServiceDiscovery(void);
+
+private:
+ nRF5xGattClient *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. */
+ nRF5xDiscoveredCharacteristic 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
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xn.cpp Tue Jul 21 13:23:44 2015 +0100
@@ -0,0 +1,91 @@
+/* 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 "mbed.h"
+#include "nRF5xn.h"
+#include "nrf_soc.h"
+
+#include "btle/btle.h"
+#include "nrf_delay.h"
+
+#include "softdevice_handler.h"
+
+/**
+ * The singleton which represents the nRF51822 transport for the BLE.
+ */
+static nRF5xn deviceInstance;
+
+/**
+ * BLE-API requires an implementation of the following function in order to
+ * obtain its transport handle.
+ */
+BLEInstanceBase *
+createBLEInstance(void)
+{
+ return (&deviceInstance);
+}
+
+nRF5xn::nRF5xn(void)
+{
+}
+
+nRF5xn::~nRF5xn(void)
+{
+}
+
+const char *nRF5xn::getVersion(void)
+{
+ static char versionString[32];
+ static bool versionFetched = false;
+
+ if (!versionFetched) {
+ ble_version_t version;
+ if ((sd_ble_version_get(&version) == NRF_SUCCESS) && (version.company_id == 0x0059)) {
+ switch (version.version_number) {
+ case 0x07:
+ snprintf(versionString, sizeof(versionString), "Nordic BLE4.1 fw:%04x", version.subversion_number);
+ break;
+ default:
+ snprintf(versionString, sizeof(versionString), "Nordic (spec unknown) fw:%04x", version.subversion_number);
+ break;
+ }
+ versionFetched = true;
+ } else {
+ strncpy(versionString, "unknown", sizeof(versionString));
+ }
+ }
+
+ return versionString;
+}
+
+ble_error_t nRF5xn::init(void)
+{
+ /* ToDo: Clear memory contents, reset the SD, etc. */
+ btle_init();
+
+ return BLE_ERROR_NONE;
+}
+
+ble_error_t nRF5xn::shutdown(void)
+{
+ return (softdevice_handler_sd_disable() == NRF_SUCCESS) ? BLE_ERROR_NONE : BLE_STACK_BUSY;
+}
+
+void
+nRF5xn::waitForEvent(void)
+{
+ sd_app_evt_wait();
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xn.h Tue Jul 21 13:23:44 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.
+ */
+
+#ifndef __NRF51822_H__
+#define __NRF51822_H__
+
+#include "mbed.h"
+#include "ble/blecommon.h"
+#include "ble/BLE.h"
+#include "nRF5xGap.h"
+#include "nRF5xGattServer.h"
+#include "nRF5xGattClient.h"
+#include "nRF5xSecurityManager.h"
+#include "btle.h"
+
+class nRF5xn : public BLEInstanceBase
+{
+public:
+ nRF5xn(void);
+ virtual ~nRF5xn(void);
+
+ virtual ble_error_t init(void);
+ virtual ble_error_t shutdown(void);
+ virtual const char *getVersion(void);
+
+ virtual Gap &getGap() {
+ return nRF5xGap::getInstance();
+ };
+ virtual const Gap &getGap() const {
+ return nRF5xGap::getInstance();
+ };
+ virtual GattServer &getGattServer() {
+ return nRF5xGattServer::getInstance();
+ };
+ virtual const GattServer &getGattServer() const {
+ return nRF5xGattServer::getInstance();
+ };
+ virtual GattClient &getGattClient() {
+ return nRF5xGattClient::getInstance();
+ }
+ virtual const SecurityManager &getSecurityManager() const {
+ return nRF5xSecurityManager::getInstance();
+ }
+ virtual SecurityManager &getSecurityManager() {
+ return nRF5xSecurityManager::getInstance();
+ }
+ virtual void waitForEvent(void);
+};
+
+#endif
\ No newline at end of file

