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