Nordic stack and drivers for the mbed BLE API

Dependents:   BLE_ANCS_SDAPI BLE_temperature BLE_HeartRate writable_gatt ... more

Files at this revision

API Documentation at this revision

Comitter:
vcoubard
Date:
Mon Apr 11 15:07:15 2016 +0100
Parent:
630:435a3d9e6456
Child:
632:e29695758978
Commit message:
Synchronized with git rev 4e6cc020
Author: Vincent Coubard
Replace inclusion of nordic header ble.h into nrf_ble.h

This change has been introduced in the SDK to mitigate
compilation issues with mbed-classic.

Changed in this revision

source/btle/btle.h Show annotated file Show diff for this revision Revisions of this file
source/btle/custom/custom_helper.h 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/nRF5xGattServer.h 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
--- a/source/btle/btle.h	Mon Apr 11 15:07:10 2016 +0100
+++ b/source/btle/btle.h	Mon Apr 11 15:07:15 2016 +0100
@@ -24,7 +24,7 @@
 #include "common/common.h"
 
 #include "ble_srv_common.h"
-#include "ble.h"
+#include "nrf_ble.h"
 
 error_t     btle_init(void);
 
--- a/source/btle/custom/custom_helper.h	Mon Apr 11 15:07:10 2016 +0100
+++ b/source/btle/custom/custom_helper.h	Mon Apr 11 15:07:15 2016 +0100
@@ -1,60 +1,60 @@
-/* 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 _CUSTOM_HELPER_H_
-#define _CUSTOM_HELPER_H_
-
-#include "common/common.h"
-#include "ble.h"
-#include "ble/UUID.h"
-#include "ble/GattCharacteristic.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base);
-error_t custom_decode_uuid(uint8_t const *const p_uuid_base,
-                           ble_uuid_t          *p_uuid);
-ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid);
-
-error_t custom_add_in_characteristic(uint16_t                  service_handle,
-                                     ble_uuid_t               *p_uuid,
-                                     uint8_t                   properties,
-                                     SecurityManager::SecurityMode_t requiredSecurity,
-                                     uint8_t                  *p_data,
-                                     uint16_t                  length,
-                                     uint16_t                  max_length,
-                                     bool                      has_variable_len,
-                                     const uint8_t            *userDescriptionDescriptorValuePtr,
-                                     uint16_t                  userDescriptionDescriptorValueLen,
-                                     bool                      readAuthorization,
-                                     bool                      writeAuthorization,
-                                     ble_gatts_char_handles_t *p_char_handle);
-
-error_t custom_add_in_descriptor(uint16_t                      char_handle,
-                                     ble_uuid_t               *p_uuid,
-                                     uint8_t                  *p_data,
-                                     uint16_t                  length,
-                                     uint16_t                  max_length,
-                                     bool                      has_variable_len,
-                                     uint16_t                 *p_desc_handle);
-
-#ifdef __cplusplus
-}
-#endif
-
+/* 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 _CUSTOM_HELPER_H_
+#define _CUSTOM_HELPER_H_
+
+#include "common/common.h"
+#include "nrf_ble.h"
+#include "ble/UUID.h"
+#include "ble/GattCharacteristic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+uint8_t custom_add_uuid_base(uint8_t const *const p_uuid_base);
+error_t custom_decode_uuid(uint8_t const *const p_uuid_base,
+                           ble_uuid_t          *p_uuid);
+ble_uuid_t custom_convert_to_nordic_uuid(const UUID &uuid);
+
+error_t custom_add_in_characteristic(uint16_t                  service_handle,
+                                     ble_uuid_t               *p_uuid,
+                                     uint8_t                   properties,
+                                     SecurityManager::SecurityMode_t requiredSecurity,
+                                     uint8_t                  *p_data,
+                                     uint16_t                  length,
+                                     uint16_t                  max_length,
+                                     bool                      has_variable_len,
+                                     const uint8_t            *userDescriptionDescriptorValuePtr,
+                                     uint16_t                  userDescriptionDescriptorValueLen,
+                                     bool                      readAuthorization,
+                                     bool                      writeAuthorization,
+                                     ble_gatts_char_handles_t *p_char_handle);
+
+error_t custom_add_in_descriptor(uint16_t                      char_handle,
+                                     ble_uuid_t               *p_uuid,
+                                     uint8_t                  *p_data,
+                                     uint16_t                  length,
+                                     uint16_t                  max_length,
+                                     bool                      has_variable_len,
+                                     uint16_t                 *p_desc_handle);
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif // ifndef _CUSTOM_HELPER_H_
\ No newline at end of file
--- a/source/nRF5xGap.h	Mon Apr 11 15:07:10 2016 +0100
+++ b/source/nRF5xGap.h	Mon Apr 11 15:07:15 2016 +0100
@@ -1,246 +1,246 @@
-/* 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__
-
-#ifdef YOTTA_CFG_MBED_OS
-    #include "mbed-drivers/mbed.h"
-#else
-    #include "mbed.h"
-#endif
-#ifndef YOTTA_CFG_WHITELIST_MAX_SIZE
-    #define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
-#elif YOTTA_CFG_WHITELIST_MAX_SIZE > BLE_GAP_WHITELIST_ADDR_MAX_COUNT
-    #undef YOTTA_CFG_WHITELIST_MAX_SIZE
-    #define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
-#endif
-#ifndef YOTTA_CFG_IRK_TABLE_MAX_SIZE
-    #define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
-#elif YOTTA_CFG_IRK_TABLE_MAX_SIZE > BLE_GAP_WHITELIST_IRK_MAX_COUNT
-    #undef YOTTA_CFG_IRK_TABLE_MAX_SIZE
-    #define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
-#endif
-#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"
-
-extern "C" {
-#include "ble_radio_notification.h"
-}
-
-#include "btle_security.h"
-
-void radioNotificationStaticCallback(bool param);
-
-/**************************************************************************/
-/*!
-    \brief
-
-*/
-/**************************************************************************/
-class nRF5xGap : public Gap
-{
-public:
-    /* 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 GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MIN);}
-    virtual uint16_t    getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);}
-    virtual uint16_t    getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::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, BLEProtocol::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 ble_error_t reset(void);
-
-    /*
-     * The following functions are part of the whitelisting experimental API.
-     * Therefore, this functionality can change in the near future.
-     */
-    virtual uint8_t getMaxWhitelistSize(void) const;
-    virtual ble_error_t getWhitelist(Gap::Whitelist_t &whitelistOut) const;
-    virtual ble_error_t setWhitelist(const Gap::Whitelist_t &whitelistIn);
-
-    virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode);
-    virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode);
-    virtual ble_error_t setInitiatorPolicyMode(InitiatorPolicyMode_t mode);
-    virtual Gap::AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const;
-    virtual Gap::ScanningPolicyMode_t getScanningPolicyMode(void) const;
-    virtual Gap::InitiatorPolicyMode_t getInitiatorPolicyMode(void) const;
-
-    virtual ble_error_t initRadioNotification(void) {
-        if (ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationStaticCallback) == NRF_SUCCESS) {
-            return BLE_ERROR_NONE;
-        }
-
-        return BLE_ERROR_UNSPECIFIED;
-    }
-
-/* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */
-#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
-    virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams);
-    virtual ble_error_t stopScan(void);
-#endif
-
-private:
-    /*
-     * Whitelisting API related structures and helper functions.
-     */
-
-    /* Policy modes set by the user. By default these are set to ignore the whitelist */
-    Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
-    Gap::ScanningPolicyMode_t    scanningPolicyMode;
-
-    /* Internal representation of a whitelist */
-    uint8_t         whitelistAddressesSize;
-    ble_gap_addr_t  whitelistAddresses[YOTTA_CFG_WHITELIST_MAX_SIZE];
-
-    /*
-     * An internal function used to populate the ble_gap_whitelist_t that will be used by
-     * the SoftDevice for filtering requests. This function is needed because for the BLE
-     * API the whitelist is just a collection of keys, but for the stack it also includes
-     * the IRK table.
-     */
-    ble_error_t generateStackWhitelist(ble_gap_whitelist_t &whitelist);
-
-private:
-    bool    radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */
-    Timeout radioNotificationTimeout;
-
-    /*
-     * A helper function to post radio notification callbacks with low interrupt priority.
-     */
-    void postRadioNotificationCallback(void) {
-#ifdef YOTTA_CFG_MBED_OS
-        /*
-         * In mbed OS, all user-facing BLE events (interrupts) are posted to the
-         * MINAR scheduler to be executed as callbacks in thread mode. MINAR guards
-         * its critical sections from interrupts by acquiring CriticalSectionLock,
-         * which results in a call to sd_nvic_critical_region_enter(). Thus, it is
-         * safe to invoke MINAR APIs from interrupt context as long as those
-         * interrupts are blocked by sd_nvic_critical_region_enter().
-         *
-         * Radio notifications are a special case for the above. The Radio
-         * Notification IRQ is handled at a very high priority--higher than the
-         * level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification
-         * events can preempt MINAR's critical sections. Using MINAR APIs (such as
-         * posting an event) directly in processRadioNotification() may result in a
-         * race condition ending in a hard-fault.
-         *
-         * The solution is to *not* call MINAR APIs directly from the Radio
-         * Notification handling; i.e. to do the bulk of RadioNotification
-         * processing at a reduced priority which respects MINAR's critical
-         * sections. Unfortunately, on a cortex-M0, there is no clean way to demote
-         * priority for the currently executing interrupt--we wouldn't want to
-         * demote the radio notification handling anyway because it is sensitive to
-         * timing, and the system expects to finish this handling very quickly. The
-         * workaround is to employ a Timeout to trigger
-         * postRadioNotificationCallback() after a very short delay (~0 us) and post
-         * the MINAR callback that context.
-         *
-         * !!!WARNING!!! Radio notifications are very time critical events. The
-         * current solution is expected to work under the assumption that
-         * postRadioNotificationCalback() will be executed BEFORE the next radio
-         * notification event is generated.
-         */
-        minar::Scheduler::postCallback(
-            mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam)
-        );
-#else
-        /*
-         * In mbed classic, all user-facing BLE events execute callbacks in interrupt
-         * mode. Radio Notifications are a special case because its IRQ is handled at
-         * a very high priority. Thus Radio Notification events can preempt other
-         * operations that require interaction with the SoftDevice such as advertising
-         * payload updates and changing the Gap state. Therefore, executing a Radio
-         * Notification callback directly from processRadioNotification() may result
-         * in a race condition ending in a hard-fault.
-         *
-         * The solution is to *not* execute the Radio Notification callback directly
-         * from the Radio Notification handling; i.e. to do the bulk of the
-         * Radio Notification processing at a reduced priority. Unfortunately, on a
-         * cortex-M0, there is no clean way to demote priority for the currently
-         * executing interrupt--we wouldn't want to demote the radio notification
-         * handling anyway because it is sensitive to timing, and the system expects
-         * to finish this handling very quickly. The workaround is to employ a Timeout
-         * to trigger postRadioNotificationCallback() after a very short delay (~0 us)
-         * and execute the callback in that context.
-         *
-         * !!!WARNING!!! Radio notifications are very time critical events. The
-         * current solution is expected to work under the assumption that
-         * postRadioNotificationCalback() will be executed BEFORE the next radio
-         * notification event is generated.
-         */
-        radioNotificationCallback.call(radioNotificationCallbackParam);
-#endif /* #ifdef YOTTA_CFG_MBED_OS */
-    }
-
-    /**
-     * A helper function to process radio-notification events; to be called internally.
-     * @param param [description]
-     */
-    void processRadioNotificationEvent(bool param) {
-        radioNotificationCallbackParam = param;
-        radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0);
-    }
-    friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */
-
-private:
-    uint16_t m_connectionHandle;
-
-    /*
-     * Allow instantiation from nRF5xn when required.
-     */
-    friend class nRF5xn;
-
-    nRF5xGap() :
-        advertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST),
-        scanningPolicyMode(Gap::SCAN_POLICY_IGNORE_WHITELIST),
-        whitelistAddressesSize(0) {
-        m_connectionHandle = BLE_CONN_HANDLE_INVALID;
-    }
-
-    nRF5xGap(nRF5xGap const &);
-    void operator=(nRF5xGap const &);
-};
-
+/* 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__
+
+#ifdef YOTTA_CFG_MBED_OS
+    #include "mbed-drivers/mbed.h"
+#else
+    #include "mbed.h"
+#endif
+#ifndef YOTTA_CFG_WHITELIST_MAX_SIZE
+    #define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
+#elif YOTTA_CFG_WHITELIST_MAX_SIZE > BLE_GAP_WHITELIST_ADDR_MAX_COUNT
+    #undef YOTTA_CFG_WHITELIST_MAX_SIZE
+    #define YOTTA_CFG_WHITELIST_MAX_SIZE BLE_GAP_WHITELIST_ADDR_MAX_COUNT
+#endif
+#ifndef YOTTA_CFG_IRK_TABLE_MAX_SIZE
+    #define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
+#elif YOTTA_CFG_IRK_TABLE_MAX_SIZE > BLE_GAP_WHITELIST_IRK_MAX_COUNT
+    #undef YOTTA_CFG_IRK_TABLE_MAX_SIZE
+    #define YOTTA_CFG_IRK_TABLE_MAX_SIZE BLE_GAP_WHITELIST_IRK_MAX_COUNT
+#endif
+#include "ble/blecommon.h"
+#include "nrf_ble.h"
+#include "ble/GapAdvertisingParams.h"
+#include "ble/GapAdvertisingData.h"
+#include "ble/Gap.h"
+#include "ble/GapScanningParams.h"
+
+#include "nrf_soc.h"
+
+extern "C" {
+#include "ble_radio_notification.h"
+}
+
+#include "btle_security.h"
+
+void radioNotificationStaticCallback(bool param);
+
+/**************************************************************************/
+/*!
+    \brief
+
+*/
+/**************************************************************************/
+class nRF5xGap : public Gap
+{
+public:
+    /* 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 GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_INTERVAL_MIN);}
+    virtual uint16_t    getMinNonConnectableAdvertisingInterval(void) const {return GapAdvertisingParams::ADVERTISEMENT_DURATION_UNITS_TO_MS(BLE_GAP_ADV_NONCON_INTERVAL_MIN);}
+    virtual uint16_t    getMaxAdvertisingInterval(void) const {return GapAdvertisingParams::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, BLEProtocol::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 ble_error_t reset(void);
+
+    /*
+     * The following functions are part of the whitelisting experimental API.
+     * Therefore, this functionality can change in the near future.
+     */
+    virtual uint8_t getMaxWhitelistSize(void) const;
+    virtual ble_error_t getWhitelist(Gap::Whitelist_t &whitelistOut) const;
+    virtual ble_error_t setWhitelist(const Gap::Whitelist_t &whitelistIn);
+
+    virtual ble_error_t setAdvertisingPolicyMode(AdvertisingPolicyMode_t mode);
+    virtual ble_error_t setScanningPolicyMode(ScanningPolicyMode_t mode);
+    virtual ble_error_t setInitiatorPolicyMode(InitiatorPolicyMode_t mode);
+    virtual Gap::AdvertisingPolicyMode_t getAdvertisingPolicyMode(void) const;
+    virtual Gap::ScanningPolicyMode_t getScanningPolicyMode(void) const;
+    virtual Gap::InitiatorPolicyMode_t getInitiatorPolicyMode(void) const;
+
+    virtual ble_error_t initRadioNotification(void) {
+        if (ble_radio_notification_init(NRF_APP_PRIORITY_HIGH, NRF_RADIO_NOTIFICATION_DISTANCE_800US, radioNotificationStaticCallback) == NRF_SUCCESS) {
+            return BLE_ERROR_NONE;
+        }
+
+        return BLE_ERROR_UNSPECIFIED;
+    }
+
+/* Observer role is not supported by S110, return BLE_ERROR_NOT_IMPLEMENTED */
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+    virtual ble_error_t startRadioScan(const GapScanningParams &scanningParams);
+    virtual ble_error_t stopScan(void);
+#endif
+
+private:
+    /*
+     * Whitelisting API related structures and helper functions.
+     */
+
+    /* Policy modes set by the user. By default these are set to ignore the whitelist */
+    Gap::AdvertisingPolicyMode_t advertisingPolicyMode;
+    Gap::ScanningPolicyMode_t    scanningPolicyMode;
+
+    /* Internal representation of a whitelist */
+    uint8_t         whitelistAddressesSize;
+    ble_gap_addr_t  whitelistAddresses[YOTTA_CFG_WHITELIST_MAX_SIZE];
+
+    /*
+     * An internal function used to populate the ble_gap_whitelist_t that will be used by
+     * the SoftDevice for filtering requests. This function is needed because for the BLE
+     * API the whitelist is just a collection of keys, but for the stack it also includes
+     * the IRK table.
+     */
+    ble_error_t generateStackWhitelist(ble_gap_whitelist_t &whitelist);
+
+private:
+    bool    radioNotificationCallbackParam; /* parameter to be passed into the Timeout-generated radio notification callback. */
+    Timeout radioNotificationTimeout;
+
+    /*
+     * A helper function to post radio notification callbacks with low interrupt priority.
+     */
+    void postRadioNotificationCallback(void) {
+#ifdef YOTTA_CFG_MBED_OS
+        /*
+         * In mbed OS, all user-facing BLE events (interrupts) are posted to the
+         * MINAR scheduler to be executed as callbacks in thread mode. MINAR guards
+         * its critical sections from interrupts by acquiring CriticalSectionLock,
+         * which results in a call to sd_nvic_critical_region_enter(). Thus, it is
+         * safe to invoke MINAR APIs from interrupt context as long as those
+         * interrupts are blocked by sd_nvic_critical_region_enter().
+         *
+         * Radio notifications are a special case for the above. The Radio
+         * Notification IRQ is handled at a very high priority--higher than the
+         * level blocked by sd_nvic_critical_region_enter(). Thus Radio Notification
+         * events can preempt MINAR's critical sections. Using MINAR APIs (such as
+         * posting an event) directly in processRadioNotification() may result in a
+         * race condition ending in a hard-fault.
+         *
+         * The solution is to *not* call MINAR APIs directly from the Radio
+         * Notification handling; i.e. to do the bulk of RadioNotification
+         * processing at a reduced priority which respects MINAR's critical
+         * sections. Unfortunately, on a cortex-M0, there is no clean way to demote
+         * priority for the currently executing interrupt--we wouldn't want to
+         * demote the radio notification handling anyway because it is sensitive to
+         * timing, and the system expects to finish this handling very quickly. The
+         * workaround is to employ a Timeout to trigger
+         * postRadioNotificationCallback() after a very short delay (~0 us) and post
+         * the MINAR callback that context.
+         *
+         * !!!WARNING!!! Radio notifications are very time critical events. The
+         * current solution is expected to work under the assumption that
+         * postRadioNotificationCalback() will be executed BEFORE the next radio
+         * notification event is generated.
+         */
+        minar::Scheduler::postCallback(
+            mbed::util::FunctionPointer1<void, bool>(&radioNotificationCallback, &FunctionPointerWithContext<bool>::call).bind(radioNotificationCallbackParam)
+        );
+#else
+        /*
+         * In mbed classic, all user-facing BLE events execute callbacks in interrupt
+         * mode. Radio Notifications are a special case because its IRQ is handled at
+         * a very high priority. Thus Radio Notification events can preempt other
+         * operations that require interaction with the SoftDevice such as advertising
+         * payload updates and changing the Gap state. Therefore, executing a Radio
+         * Notification callback directly from processRadioNotification() may result
+         * in a race condition ending in a hard-fault.
+         *
+         * The solution is to *not* execute the Radio Notification callback directly
+         * from the Radio Notification handling; i.e. to do the bulk of the
+         * Radio Notification processing at a reduced priority. Unfortunately, on a
+         * cortex-M0, there is no clean way to demote priority for the currently
+         * executing interrupt--we wouldn't want to demote the radio notification
+         * handling anyway because it is sensitive to timing, and the system expects
+         * to finish this handling very quickly. The workaround is to employ a Timeout
+         * to trigger postRadioNotificationCallback() after a very short delay (~0 us)
+         * and execute the callback in that context.
+         *
+         * !!!WARNING!!! Radio notifications are very time critical events. The
+         * current solution is expected to work under the assumption that
+         * postRadioNotificationCalback() will be executed BEFORE the next radio
+         * notification event is generated.
+         */
+        radioNotificationCallback.call(radioNotificationCallbackParam);
+#endif /* #ifdef YOTTA_CFG_MBED_OS */
+    }
+
+    /**
+     * A helper function to process radio-notification events; to be called internally.
+     * @param param [description]
+     */
+    void processRadioNotificationEvent(bool param) {
+        radioNotificationCallbackParam = param;
+        radioNotificationTimeout.attach_us(this, &nRF5xGap::postRadioNotificationCallback, 0);
+    }
+    friend void radioNotificationStaticCallback(bool param); /* allow invocations of processRadioNotificationEvent() */
+
+private:
+    uint16_t m_connectionHandle;
+
+    /*
+     * Allow instantiation from nRF5xn when required.
+     */
+    friend class nRF5xn;
+
+    nRF5xGap() :
+        advertisingPolicyMode(Gap::ADV_POLICY_IGNORE_WHITELIST),
+        scanningPolicyMode(Gap::SCAN_POLICY_IGNORE_WHITELIST),
+        whitelistAddressesSize(0) {
+        m_connectionHandle = BLE_CONN_HANDLE_INVALID;
+    }
+
+    nRF5xGap(nRF5xGap const &);
+    void operator=(nRF5xGap const &);
+};
+
 #endif // ifndef __NRF5x_GAP_H__
\ No newline at end of file
--- a/source/nRF5xGattServer.h	Mon Apr 11 15:07:10 2016 +0100
+++ b/source/nRF5xGattServer.h	Mon Apr 11 15:07:15 2016 +0100
@@ -1,103 +1,103 @@
-/* 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:
-    /* 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);
-    virtual ble_error_t reset(void);
-
-    /* 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];
-
-    /*
-     * Allow instantiation from nRF5xn when required.
-     */
-    friend class nRF5xn;
-
-    nRF5xGattServer() : GattServer(), p_characteristics(), nrfCharacteristicHandles(), p_descriptors(), descriptorCount(0), nrfDescriptorHandles() {
-        /* empty */
-    }
-
-private:
-    nRF5xGattServer(const nRF5xGattServer &);
-    const nRF5xGattServer& operator=(const nRF5xGattServer &);
-};
-
+/* 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 "nrf_ble.h" /* nordic ble */
+#include "ble/Gap.h"
+#include "ble/GattServer.h"
+
+class nRF5xGattServer : public GattServer
+{
+public:
+    /* 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);
+    virtual ble_error_t reset(void);
+
+    /* 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];
+
+    /*
+     * Allow instantiation from nRF5xn when required.
+     */
+    friend class nRF5xn;
+
+    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
--- a/source/nRF5xServiceDiscovery.h	Mon Apr 11 15:07:10 2016 +0100
+++ b/source/nRF5xServiceDiscovery.h	Mon Apr 11 15:07:15 2016 +0100
@@ -1,366 +1,366 @@
-/* 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),
-        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();
-    }
-
-    void terminate(Gap::Handle_t connectionHandle) {
-        if(connHandle == connectionHandle) {
-            terminate();
-        }
-    }
-
-    virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) {
-        onTerminationCallback = callback;
-    }
-
-    /**
-     * @brief  Clear nRF5xServiceDiscovery's state.
-     *
-     * @return
-     *           BLE_ERROR_NONE if successful.
-     */
-    virtual ble_error_t reset(void) {
-        /* Clear all state that is from the parent, including private members */
-        if (ServiceDiscovery::reset() != BLE_ERROR_NONE) {
-            return BLE_ERROR_INVALID_STATE;
-        }
-
-        /* Clear derived class members */
-        serviceIndex = 0;
-        numServices = 0;
-        numCharacteristics = 0;
-
-        state = INACTIVE;
-
-        serviceUUIDDiscoveryQueue.reset();
-        charUUIDDiscoveryQueue.reset();
-
-        onTerminationCallback = NULL;
-
-        return BLE_ERROR_NONE;
-    }
-
-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) {
-        discoveredCharacteristic = nRF5xDiscoveredCharacteristic();
-
-        bool wasActive = isActive();
-        state = INACTIVE;
-
-        if (wasActive && onTerminationCallback) {
-            onTerminationCallback(connHandle);
-        }
-    }
-
-    void terminateCharacteristicDiscovery(ble_error_t err) {
-        if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
-            if(discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) {
-               if(err == BLE_ERROR_NONE) {
-                    // fullfill the last characteristic
-                    discoveredCharacteristic.setLastHandle(services[serviceIndex].getEndHandle());
-
-                    if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
-                        ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) &&
-                         (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
-                        if (characteristicCallback) {
-                            characteristicCallback(&discoveredCharacteristic);
-                        }
-                    }
-               }
-               discoveredCharacteristic = nRF5xDiscoveredCharacteristic();
-            }
-
-            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;
-    }
-
-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  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;
-
-    /*
-     * The currently discovered characteristic. Discovery of a characteristic
-     * is a two phase process.
-     * First, declaration handle is fetched, it provide the UUID, the value handle and
-     * the properties of a characteristic.
-     * Second, the next declaration handle is fetched, with its declaration handle, it is
-     * possible to compute the last handle of the discovered characteristic and fill the
-     * missing part of the object.
-     * If there is no remaining characteristic to discover, the last handle of the
-     * discovered characteristic will be set to the last handle of its enclosing service.
-     */
-    nRF5xDiscoveredCharacteristic discoveredCharacteristic;
-};
-
+/* 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 "nrf_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),
+        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();
+    }
+
+    void terminate(Gap::Handle_t connectionHandle) {
+        if(connHandle == connectionHandle) {
+            terminate();
+        }
+    }
+
+    virtual void onTermination(ServiceDiscovery::TerminationCallback_t callback) {
+        onTerminationCallback = callback;
+    }
+
+    /**
+     * @brief  Clear nRF5xServiceDiscovery's state.
+     *
+     * @return
+     *           BLE_ERROR_NONE if successful.
+     */
+    virtual ble_error_t reset(void) {
+        /* Clear all state that is from the parent, including private members */
+        if (ServiceDiscovery::reset() != BLE_ERROR_NONE) {
+            return BLE_ERROR_INVALID_STATE;
+        }
+
+        /* Clear derived class members */
+        serviceIndex = 0;
+        numServices = 0;
+        numCharacteristics = 0;
+
+        state = INACTIVE;
+
+        serviceUUIDDiscoveryQueue.reset();
+        charUUIDDiscoveryQueue.reset();
+
+        onTerminationCallback = NULL;
+
+        return BLE_ERROR_NONE;
+    }
+
+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) {
+        discoveredCharacteristic = nRF5xDiscoveredCharacteristic();
+
+        bool wasActive = isActive();
+        state = INACTIVE;
+
+        if (wasActive && onTerminationCallback) {
+            onTerminationCallback(connHandle);
+        }
+    }
+
+    void terminateCharacteristicDiscovery(ble_error_t err) {
+        if (state == CHARACTERISTIC_DISCOVERY_ACTIVE) {
+            if(discoveredCharacteristic != nRF5xDiscoveredCharacteristic()) {
+               if(err == BLE_ERROR_NONE) {
+                    // fullfill the last characteristic
+                    discoveredCharacteristic.setLastHandle(services[serviceIndex].getEndHandle());
+
+                    if ((matchingCharacteristicUUID == UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)) ||
+                        ((matchingCharacteristicUUID == discoveredCharacteristic.getUUID()) &&
+                         (matchingServiceUUID != UUID::ShortUUIDBytes_t(BLE_UUID_UNKNOWN)))) {
+                        if (characteristicCallback) {
+                            characteristicCallback(&discoveredCharacteristic);
+                        }
+                    }
+               }
+               discoveredCharacteristic = nRF5xDiscoveredCharacteristic();
+            }
+
+            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;
+    }
+
+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  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;
+
+    /*
+     * The currently discovered characteristic. Discovery of a characteristic
+     * is a two phase process.
+     * First, declaration handle is fetched, it provide the UUID, the value handle and
+     * the properties of a characteristic.
+     * Second, the next declaration handle is fetched, with its declaration handle, it is
+     * possible to compute the last handle of the discovered characteristic and fill the
+     * missing part of the object.
+     * If there is no remaining characteristic to discover, the last handle of the
+     * discovered characteristic will be set to the last handle of its enclosing service.
+     */
+    nRF5xDiscoveredCharacteristic discoveredCharacteristic;
+};
+
 #endif /*__NRF_SERVICE_DISCOVERY_H__*/
\ No newline at end of file