1

Fork of nRF51822 by Nordic Semiconductor

Files at this revision

API Documentation at this revision

Comitter:
rgrover1
Date:
Tue Jul 21 13:23:45 2015 +0100
Parent:
392:b21c1373df4d
Child:
394:95444484329c
Commit message:
Synchronized with git rev c0a8c6b5
Author: Rohit Grover
Merge branch 'master' of https://github.com/adfernandes/nRF51822 into afernandes

Changed in this revision

source/btle/btle.cpp Show annotated file Show diff for this revision Revisions of this file
source/btle/btle_discovery.cpp Show annotated file Show diff for this revision Revisions of this file
source/btle/btle_security.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF51822n.cpp Show diff for this revision Revisions of this file
source/nRF51822n.h Show diff for this revision Revisions of this file
source/nRF51DiscoveredCharacteristic.cpp Show diff for this revision Revisions of this file
source/nRF51DiscoveredCharacteristic.h Show diff for this revision Revisions of this file
source/nRF51Gap.cpp Show diff for this revision Revisions of this file
source/nRF51Gap.h Show diff for this revision Revisions of this file
source/nRF51GattClient.cpp Show diff for this revision Revisions of this file
source/nRF51GattClient.h Show diff for this revision Revisions of this file
source/nRF51GattServer.cpp Show diff for this revision Revisions of this file
source/nRF51GattServer.h Show diff for this revision Revisions of this file
source/nRF51SecurityManager.cpp Show diff for this revision Revisions of this file
source/nRF51SecurityManager.h Show diff for this revision Revisions of this file
source/nRF51ServiceDiscovery.cpp Show diff for this revision Revisions of this file
source/nRF51ServiceDiscovery.h Show diff for this revision Revisions of this file
source/nRF5xDiscoveredCharacteristic.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xDiscoveredCharacteristic.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGap.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGap.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGattClient.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGattClient.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGattServer.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xGattServer.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xSecurityManager.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xSecurityManager.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xServiceDiscovery.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xServiceDiscovery.h Show annotated file Show diff for this revision Revisions of this file
source/nRF5xn.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xn.h Show annotated file Show diff for this revision Revisions of this file
--- a/source/btle/btle.cpp	Tue Jul 21 13:23:45 2015 +0100
+++ b/source/btle/btle.cpp	Tue Jul 21 13:23:45 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:45 2015 +0100
+++ b/source/btle/btle_discovery.cpp	Tue Jul 21 13:23:45 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(&params);
+                nRF5xGattClient::getInstance().processHVXEvent(&params);
             }
             break;
     }
--- a/source/btle/btle_security.cpp	Tue Jul 21 13:23:45 2015 +0100
+++ b/source/btle/btle_security.cpp	Tue Jul 21 13:23:45 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:45 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:45 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:45 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:45 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:45 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 &params)
-{
-    /* 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:45 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:45 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:45 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:45 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:45 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:45 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:45 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:45 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].getUUID()) &&
-             (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())) {
-
-            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:45 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:45 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:45 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:45 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 &params)
+{
+    /* 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:45 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:45 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:45 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:45 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:45 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:45 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:45 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:45 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].getUUID()) &&
+             (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())) {
+
+            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:45 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:45 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:45 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