config changes

Fork of nRF51822 by Nordic Semiconductor

Files at this revision

API Documentation at this revision

Comitter:
vcoubard
Date:
Mon Jan 11 10:19:02 2016 +0000
Parent:
541:884f95bf5351
Child:
543:53215259c0d2
Commit message:
Synchronized with git rev e15d59a7
Author: Vincent Coubard
Add Characteristic Descriptor Discovery implementation

Changed in this revision

module.json Show annotated file Show diff for this revision Revisions of this file
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/nRF5xCharacteristicDescriptorDiscoverer.cpp Show annotated file Show diff for this revision Revisions of this file
source/nRF5xCharacteristicDescriptorDiscoverer.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/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h Show annotated file Show diff for this revision Revisions of this file
--- a/module.json	Mon Jan 11 10:19:02 2016 +0000
+++ b/module.json	Mon Jan 11 10:19:02 2016 +0000
@@ -1,6 +1,6 @@
 {
   "name": "ble-nrf51822",
-  "version": "2.0.2",
+  "version": "2.0.3",
   "description": "Nordic stack and drivers for the mbed BLE API.",
   "keywords": [
     "Bluetooth",
--- a/source/btle/btle.cpp	Mon Jan 11 10:19:02 2016 +0000
+++ b/source/btle/btle.cpp	Mon Jan 11 10:19:02 2016 +0000
@@ -183,6 +183,7 @@
                     break;
             }
             nRF5xGap::getInstance().processDisconnectionEvent(handle, reason);
+            // TODO: close pending discoveries
             break;
         }
 
--- a/source/btle/btle_discovery.cpp	Mon Jan 11 10:19:02 2016 +0000
+++ b/source/btle/btle_discovery.cpp	Mon Jan 11 10:19:02 2016 +0000
@@ -1,99 +1,116 @@
-/* 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"
-#include "nRF5xGattClient.h"
-
-#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
-void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
-{
-    nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery;
-
-    switch (p_ble_evt->header.evt_id) {
-        case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
-            switch (p_ble_evt->evt.gattc_evt.gatt_status) {
-                case BLE_GATT_STATUS_SUCCESS:
-                    sdSingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
-                    break;
-
-                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
-                default:
-                    sdSingleton.terminate();
-                    break;
-            }
-            break;
-
-        case BLE_GATTC_EVT_CHAR_DISC_RSP:
-            switch (p_ble_evt->evt.gattc_evt.gatt_status) {
-                case BLE_GATT_STATUS_SUCCESS:
-                    sdSingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
-                    break;
-
-                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
-                default:
-                    sdSingleton.terminateCharacteristicDiscovery();
-                    break;
-            }
-            break;
-
-        case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
-            if (sdSingleton.isActive()) {
-                sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
-            }
-            break;
-
-        case BLE_GATTC_EVT_READ_RSP: {
-                GattReadCallbackParams response = {
-                    .connHandle = p_ble_evt->evt.gattc_evt.conn_handle,
-                    .handle     = p_ble_evt->evt.gattc_evt.params.read_rsp.handle,
-                    .offset     = p_ble_evt->evt.gattc_evt.params.read_rsp.offset,
-                    .len        = p_ble_evt->evt.gattc_evt.params.read_rsp.len,
-                    .data       = p_ble_evt->evt.gattc_evt.params.read_rsp.data,
-                };
-                nRF5xGattClient::getInstance().processReadResponse(&response);
-            }
-            break;
-
-        case BLE_GATTC_EVT_WRITE_RSP: {
-                GattWriteCallbackParams response = {
-                    .connHandle = p_ble_evt->evt.gattc_evt.conn_handle,
-                    .handle     = p_ble_evt->evt.gattc_evt.params.write_rsp.handle,
-                    .writeOp    = (GattWriteCallbackParams::WriteOp_t)(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op),
-                    .offset     = p_ble_evt->evt.gattc_evt.params.write_rsp.offset,
-                    .len        = p_ble_evt->evt.gattc_evt.params.write_rsp.len,
-                    .data       = p_ble_evt->evt.gattc_evt.params.write_rsp.data,
-                };
-                nRF5xGattClient::getInstance().processWriteResponse(&response);
-            }
-            break;
-
-        case BLE_GATTC_EVT_HVX: {
-                GattHVXCallbackParams params;
-                params.connHandle = p_ble_evt->evt.gattc_evt.conn_handle;
-                params.handle     = p_ble_evt->evt.gattc_evt.params.hvx.handle;
-                params.type       = static_cast<HVXType_t>(p_ble_evt->evt.gattc_evt.params.hvx.type);
-                params.len        = p_ble_evt->evt.gattc_evt.params.hvx.len;
-                params.data       = p_ble_evt->evt.gattc_evt.params.hvx.data;
-
-                nRF5xGattClient::getInstance().processHVXEvent(&params);
-            }
-            break;
-    }
-
-    sdSingleton.progressCharacteristicDiscovery();
-    sdSingleton.progressServiceDiscovery();
-}
-#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.
+ */
+
+#include "nRF5xServiceDiscovery.h"
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+#include "nRF5xGattClient.h"
+
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+void bleGattcEventHandler(const ble_evt_t *p_ble_evt)
+{
+    nRF5xServiceDiscovery &sdSingleton = nRF5xGattClient::getInstance().discovery;
+    nRF5xCharacteristicDescriptorDiscoverer &characteristicDescriptorDiscoverer = 
+        nRF5xGattClient::getInstance().characteristicDescriptorDiscoverer;
+
+    switch (p_ble_evt->header.evt_id) {
+        case BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP:
+            switch (p_ble_evt->evt.gattc_evt.gatt_status) {
+                case BLE_GATT_STATUS_SUCCESS:
+                    sdSingleton.setupDiscoveredServices(&p_ble_evt->evt.gattc_evt.params.prim_srvc_disc_rsp);
+                    break;
+
+                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+                default:
+                    sdSingleton.terminate();
+                    break;
+            }
+            break;
+
+        case BLE_GATTC_EVT_CHAR_DISC_RSP:
+            switch (p_ble_evt->evt.gattc_evt.gatt_status) {
+                case BLE_GATT_STATUS_SUCCESS:
+                    sdSingleton.setupDiscoveredCharacteristics(&p_ble_evt->evt.gattc_evt.params.char_disc_rsp);
+                    break;
+
+                case BLE_GATT_STATUS_ATTERR_ATTRIBUTE_NOT_FOUND:
+                default:
+                    sdSingleton.terminateCharacteristicDiscovery();
+                    break;
+            }
+            break;
+
+        case BLE_GATTC_EVT_CHAR_VAL_BY_UUID_READ_RSP:
+            if (sdSingleton.isActive()) {
+                sdSingleton.processDiscoverUUIDResponse(&p_ble_evt->evt.gattc_evt.params.char_val_by_uuid_read_rsp);
+            }
+            break;
+
+        case BLE_GATTC_EVT_READ_RSP: {
+                GattReadCallbackParams response = {
+                    .connHandle = p_ble_evt->evt.gattc_evt.conn_handle,
+                    .handle     = p_ble_evt->evt.gattc_evt.params.read_rsp.handle,
+                    .offset     = p_ble_evt->evt.gattc_evt.params.read_rsp.offset,
+                    .len        = p_ble_evt->evt.gattc_evt.params.read_rsp.len,
+                    .data       = p_ble_evt->evt.gattc_evt.params.read_rsp.data,
+                };
+                nRF5xGattClient::getInstance().processReadResponse(&response);
+            }
+            break;
+
+        case BLE_GATTC_EVT_WRITE_RSP: {
+                GattWriteCallbackParams response = {
+                    .connHandle = p_ble_evt->evt.gattc_evt.conn_handle,
+                    .handle     = p_ble_evt->evt.gattc_evt.params.write_rsp.handle,
+                    .writeOp    = (GattWriteCallbackParams::WriteOp_t)(p_ble_evt->evt.gattc_evt.params.write_rsp.write_op),
+                    .offset     = p_ble_evt->evt.gattc_evt.params.write_rsp.offset,
+                    .len        = p_ble_evt->evt.gattc_evt.params.write_rsp.len,
+                    .data       = p_ble_evt->evt.gattc_evt.params.write_rsp.data,
+                };
+                nRF5xGattClient::getInstance().processWriteResponse(&response);
+            }
+            break;
+
+        case BLE_GATTC_EVT_HVX: {
+                GattHVXCallbackParams params;
+                params.connHandle = p_ble_evt->evt.gattc_evt.conn_handle;
+                params.handle     = p_ble_evt->evt.gattc_evt.params.hvx.handle;
+                params.type       = static_cast<HVXType_t>(p_ble_evt->evt.gattc_evt.params.hvx.type);
+                params.len        = p_ble_evt->evt.gattc_evt.params.hvx.len;
+                params.data       = p_ble_evt->evt.gattc_evt.params.hvx.data;
+
+                nRF5xGattClient::getInstance().processHVXEvent(&params);
+            }
+            break;
+
+        case BLE_GATTC_EVT_DESC_DISC_RSP: {
+            uint16_t conn_handle = p_ble_evt->evt.gattc_evt.conn_handle;
+
+            if (p_ble_evt->evt.gattc_evt.gatt_status != BLE_GATT_STATUS_SUCCESS) { 
+                characteristicDescriptorDiscoverer.terminate(conn_handle);
+                return;
+            }
+
+            characteristicDescriptorDiscoverer.process(
+                conn_handle, 
+                /* discoveredDescriptors */ p_ble_evt->evt.gattc_evt.params.desc_disc_rsp
+            );
+        }   break;
+    }
+
+    sdSingleton.progressCharacteristicDiscovery();
+    sdSingleton.progressServiceDiscovery();
+}
+#endif
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xCharacteristicDescriptorDiscoverer.cpp	Mon Jan 11 10:19:02 2016 +0000
@@ -0,0 +1,168 @@
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+#include "ble_err.h"
+#include "mbed-drivers/mbed_error.h"
+#include "ble/DiscoveredCharacteristicDescriptor.h"
+
+
+
+namespace { 
+    void emptyDiscoveryCallback(const CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t*) { }
+    void emptyTerminationCallback(const CharacteristicDescriptorDiscovery::TerminationCallbackParams_t*) { }
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount) : 
+    maximumConcurrentConnectionsCount(concurrentConnectionsCount), 
+    discoveryRunning(new Discovery[concurrentConnectionsCount]) {
+
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::~nRF5xCharacteristicDescriptorDiscoverer() { 
+    delete [] discoveryRunning;
+}
+
+ble_error_t nRF5xCharacteristicDescriptorDiscoverer::launch(
+    const DiscoveredCharacteristic& characteristic, 
+    const CharacteristicDescriptorDiscovery::DiscoveryCallback_t& discoveryCallback,
+    const CharacteristicDescriptorDiscovery::TerminationCallback_t& terminationCallback
+) {
+    Gap::Handle_t connHandle = characteristic.getConnectionHandle();
+    // it is ok to deduce that the start handle for descriptors is after 
+    // the characteristic declaration and the characteristic value declaration
+    // see BLUETOOTH SPECIFICATION Version 4.2 [Vol 3, Part G] (3.3)
+    Gap::Handle_t descriptorStartHandle = characteristic.getDeclHandle() + 2;
+    Gap::Handle_t descriptorEndHandle = characteristic.getLastHandle();
+
+    // check if their is any descriptor to discover
+    if (descriptorEndHandle < descriptorStartHandle) { 
+        CharacteristicDescriptorDiscovery::TerminationCallbackParams_t termParams = { 
+            characteristic
+        };
+        terminationCallback.call(&termParams);
+        return BLE_ERROR_NONE;
+    }
+
+    // check if we can run this discovery
+    if (isConnectionInUse(connHandle)) { 
+        return BLE_STACK_BUSY;
+    }
+
+    // get a new discovery slot, if none are available, just return
+    Discovery* discovery = getAvailableDiscoverySlot();
+    if(discovery == NULL) {
+        return BLE_STACK_BUSY; 
+    }
+
+    // try to launch the discovery 
+    ble_gattc_handle_range_t discoveryRange = {
+        descriptorStartHandle,
+        descriptorEndHandle
+    };
+    uint32_t err = sd_ble_gattc_descriptors_discover(characteristic.getConnectionHandle(), &discoveryRange);
+    switch(err) { 
+        case NRF_SUCCESS:
+            // commit the new discovery to its slot
+            *discovery = Discovery(
+                characteristic,
+                discoveryCallback, 
+                terminationCallback
+            );
+
+            return BLE_ERROR_NONE;            
+        case BLE_ERROR_INVALID_CONN_HANDLE:
+            return BLE_ERROR_INVALID_PARAM;
+        case NRF_ERROR_INVALID_ADDR:
+            return BLE_ERROR_PARAM_OUT_OF_RANGE;
+        case NRF_ERROR_BUSY:
+            return BLE_STACK_BUSY;
+        default:
+            return BLE_ERROR_UNSPECIFIED;
+    }
+}
+
+bool nRF5xCharacteristicDescriptorDiscoverer::isActive(const DiscoveredCharacteristic& characteristic) const {
+    return findRunningDiscovery(characteristic) != NULL;
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::requestTerminate(const DiscoveredCharacteristic& characteristic) {
+    Discovery* discovery = findRunningDiscovery(characteristic);
+    if(discovery) { 
+        discovery->onDiscovery = emptyDiscoveryCallback;
+        // call terminate anyway
+        discovery->terminate();
+        discovery->onTerminate = emptyTerminationCallback;
+    }
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors) {
+    Discovery* discovery = findRunningDiscovery(handle);
+    if(!discovery) { 
+        error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!");
+    }
+
+    for (uint16_t i = 0; i < descriptors.count; ++i) {
+        discovery->process(
+            descriptors.descs[i].handle, UUID(descriptors.descs[i].uuid.uuid)
+        );
+    }
+}
+
+void nRF5xCharacteristicDescriptorDiscoverer::terminate(uint16_t handle) {
+    Discovery* discovery = findRunningDiscovery(handle);
+    if(!discovery) { 
+        error("logic error in nRF5xCharacteristicDescriptorDiscoverer::process !!!");
+    }
+    discovery->terminate();
+    removeDiscovery(discovery);
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery* 
+nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) {
+    for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { 
+        if(discoveryRunning[i].characteristic == characteristic) { 
+            return &discoveryRunning[i];
+        }
+    }
+    return NULL;
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery* 
+nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const {
+    for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { 
+        if(discoveryRunning[i].characteristic == characteristic) { 
+            return &discoveryRunning[i];
+        }
+    }
+    return NULL;
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery* 
+nRF5xCharacteristicDescriptorDiscoverer::findRunningDiscovery(uint16_t handle) {
+    for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { 
+        if(discoveryRunning[i].characteristic.getConnectionHandle() == handle) { 
+            return &discoveryRunning[i];
+        }
+    }
+    return NULL;
+}     
+
+void nRF5xCharacteristicDescriptorDiscoverer::removeDiscovery(Discovery* discovery) {
+    for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { 
+        if(&discoveryRunning[i] == discovery) { 
+            discoveryRunning[i] = Discovery();
+        }
+    }
+}
+
+nRF5xCharacteristicDescriptorDiscoverer::Discovery* 
+nRF5xCharacteristicDescriptorDiscoverer::getAvailableDiscoverySlot() {
+    for(size_t i = 0; i < maximumConcurrentConnectionsCount; ++i) { 
+        if(discoveryRunning[i] == Discovery()) {
+            return &discoveryRunning[i];
+        }
+    }     
+    return NULL;
+}
+
+bool nRF5xCharacteristicDescriptorDiscoverer::isConnectionInUse(uint16_t connHandle) {
+     return findRunningDiscovery(connHandle) != NULL;
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/source/nRF5xCharacteristicDescriptorDiscoverer.h	Mon Jan 11 10:19:02 2016 +0000
@@ -0,0 +1,133 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 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_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
+#define __NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__
+
+#include "ble/Gap.h"
+#include "ble/DiscoveredCharacteristic.h"
+#include "ble/CharacteristicDescriptorDiscovery.h"
+#include "ble/GattClient.h"
+#include "ble_gattc.h"
+
+/**
+ * @brief Manage the discovery of Characteristic descriptors 
+ * @details is a bridge beetween BLE API and nordic stack regarding Characteristic
+ * Descriptor discovery. The BLE API can launch, monitorate and ask for termination
+ * of a discovery. The nordic stack will provide new descriptors and indicate when
+ * the discovery is done
+ */
+class nRF5xCharacteristicDescriptorDiscoverer
+{
+    typedef CharacteristicDescriptorDiscovery::DiscoveryCallback_t DiscoveryCallback_t;
+    typedef CharacteristicDescriptorDiscovery::TerminationCallback_t TerminationCallback_t;
+
+public:
+    nRF5xCharacteristicDescriptorDiscoverer(size_t concurrentConnectionsCount = 3);
+
+    ~nRF5xCharacteristicDescriptorDiscoverer();
+
+    /**
+     * Launch a new characteristic descriptor discovery for a given 
+     * DiscoveredCharacteristic.
+     * @note: this will be called by BLE API side
+     */
+    ble_error_t launch(
+        const DiscoveredCharacteristic& characteristic, 
+        const DiscoveryCallback_t& callback,
+        const TerminationCallback_t& terminationCallback
+    );
+
+    /**
+     * @brief indicate if a characteristic descriptor discovery is active for a 
+     * given DiscoveredCharacteristic
+     * @note: this will be called by BLE API side
+     */
+    bool isActive(const DiscoveredCharacteristic& characteristic) const;
+
+    /**
+     * @brief reauest the termination of characteristic descriptor discovery 
+     * for a give DiscoveredCharacteristic
+     * @note: this will be called by BLE API side
+     */
+    void requestTerminate(const DiscoveredCharacteristic& characteristic);
+
+    /**
+     * @brief process descriptors discovered from the nordic stack
+     */
+    void process(uint16_t handle, const ble_gattc_evt_desc_disc_rsp_t& descriptors);
+
+    /**
+     * @brief Called by the nordic stack when the discovery is over.
+     */
+    void terminate(uint16_t handle);
+
+private:
+    nRF5xCharacteristicDescriptorDiscoverer(const nRF5xCharacteristicDescriptorDiscoverer&);
+    nRF5xCharacteristicDescriptorDiscoverer& operator=(const nRF5xCharacteristicDescriptorDiscoverer&);
+
+    struct Discovery {
+        Discovery() : characteristic(), onDiscovery(), onTerminate() { }
+
+        Discovery(const DiscoveredCharacteristic& c, const DiscoveryCallback_t& dCb, const TerminationCallback_t& tCb) : 
+            characteristic(c), 
+            onDiscovery(dCb), 
+            onTerminate(tCb) { 
+        }
+
+        DiscoveredCharacteristic characteristic;
+        DiscoveryCallback_t onDiscovery;
+        TerminationCallback_t onTerminate;
+
+        void process(GattAttribute::Handle_t handle, const UUID& uuid) { 
+            CharacteristicDescriptorDiscovery::DiscoveryCallbackParams_t params = { 
+                characteristic,
+                DiscoveredCharacteristicDescriptor(
+                    characteristic.getGattClient(),
+                    characteristic.getConnectionHandle(),
+                    handle,
+                    uuid
+                )
+            };
+            onDiscovery.call(&params);
+        }
+
+        void terminate() { 
+            CharacteristicDescriptorDiscovery::TerminationCallbackParams_t params = {
+                characteristic
+            };
+            onTerminate.call(&params);
+        }
+
+        friend bool operator==(const Discovery& lhs, const Discovery& rhs) {
+            return lhs.characteristic == rhs.characteristic &&
+                lhs.onDiscovery == rhs.onDiscovery &&
+                lhs.onTerminate == lhs.onTerminate;
+        }
+    };
+
+    Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic);
+    Discovery* findRunningDiscovery(const DiscoveredCharacteristic& characteristic) const;
+    Discovery* findRunningDiscovery(uint16_t handle);
+    void removeDiscovery(Discovery* discovery);
+    Discovery* getAvailableDiscoverySlot(); 
+    bool isConnectionInUse(uint16_t connHandle);
+
+    size_t maximumConcurrentConnectionsCount;
+    Discovery *discoveryRunning;
+};
+
+#endif /*__NRF_CHARACTERISTIC_DESCRIPTOR_DISCOVERY_H__*/
\ No newline at end of file
--- a/source/nRF5xGattClient.cpp	Mon Jan 11 10:19:02 2016 +0000
+++ b/source/nRF5xGattClient.cpp	Mon Jan 11 10:19:02 2016 +0000
@@ -1,38 +1,59 @@
-/* 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 &
-nRF5xGattClient::getInstance(void) {
-    static nRF5xGattClient* nRFGattClientSingleton = NULL;
-    if (nRFGattClientSingleton == NULL) {
-        nRFGattClientSingleton = new nRF5xGattClient();
-    }
-    return *nRFGattClientSingleton;
-}
-
-#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
-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);
-}
+/* 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 &
+nRF5xGattClient::getInstance(void) {
+    static nRF5xGattClient* nRFGattClientSingleton = NULL;
+    if (nRFGattClientSingleton == NULL) {
+        nRFGattClientSingleton = new nRF5xGattClient();
+    }
+    return *nRFGattClientSingleton;
+}
+
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+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);
+}
+
+ble_error_t nRF5xGattClient::discoverCharacteristicDescriptors(
+    const DiscoveredCharacteristic& characteristic,
+    CharacteristicDescriptorDiscovery::DiscoveryCallback_t discoveryCallback,
+    CharacteristicDescriptorDiscovery::TerminationCallback_t terminationCallback)
+{
+    return characteristicDescriptorDiscoverer.launch(
+        characteristic, 
+        discoveryCallback, 
+        terminationCallback
+    );
+}
+
+bool nRF5xGattClient::isCharacteristicDiscoveryActive(const DiscoveredCharacteristic& characteristic) const {
+    return characteristicDescriptorDiscoverer.isActive(characteristic);   
+}
+
+void nRF5xGattClient::terminateCharacteristicDiscovery(const DiscoveredCharacteristic& characteristic) { 
+    return characteristicDescriptorDiscoverer.requestTerminate(characteristic);
+}
+
 #endif
\ No newline at end of file
--- a/source/nRF5xGattClient.h	Mon Jan 11 10:19:02 2016 +0000
+++ b/source/nRF5xGattClient.h	Mon Jan 11 10:19:02 2016 +0000
@@ -1,167 +1,191 @@
-/* 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();
-
-    /**
-     * When using S110, all Gatt client features will return
-     * BLE_ERROR_NOT_IMPLEMENTED
-     */
-#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
-
-    /**
-     * 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.flags    = 0; /* this is inconsequential */
-        writeParams.handle   = attributeHandle;
-        writeParams.offset   = 0;
-        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 // if !S110
-};
-
+/* 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"
+#include "nRF5xCharacteristicDescriptorDiscoverer.h"
+
+class nRF5xGattClient : public GattClient
+{
+public:
+    static nRF5xGattClient &getInstance();
+
+    /**
+     * When using S110, all Gatt client features will return
+     * BLE_ERROR_NOT_IMPLEMENTED
+     */
+#if !defined(TARGET_MCU_NRF51_16K_S110) && !defined(TARGET_MCU_NRF51_32K_S110)
+
+    /**
+     * 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();
+    }
+
+    /**
+     * @brief Implementation of GattClient::discoverCharacteristicDescriptors 
+     * @see GattClient::discoverCharacteristicDescriptors 
+     */
+    virtual ble_error_t discoverCharacteristicDescriptors(
+        const DiscoveredCharacteristic& characteristic,
+        CharacteristicDescriptorDiscovery::DiscoveryCallback_t discoveryCallback,
+        CharacteristicDescriptorDiscovery::TerminationCallback_t terminationCallback
+    );
+
+    /**
+     * @brief Implementation of GattClient::isCharacteristicDiscoveryActive 
+     * @see GattClient::isCharacteristicDiscoveryActive 
+     */
+    virtual bool isCharacteristicDiscoveryActive(const DiscoveredCharacteristic& characteristic) const;
+
+    /**
+     * @brief Implementation of GattClient::terminateCharacteristicDiscovery 
+     * @see GattClient::terminateCharacteristicDiscovery 
+     */
+    virtual void terminateCharacteristicDiscovery(const DiscoveredCharacteristic& characteristic);
+
+    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.flags    = 0; /* this is inconsequential */
+        writeParams.handle   = attributeHandle;
+        writeParams.offset   = 0;
+        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;
+    nRF5xCharacteristicDescriptorDiscoverer characteristicDescriptorDiscoverer;
+
+#endif // if !S110
+};
+
 #endif // ifndef __NRF51822_GATT_CLIENT_H__
\ No newline at end of file
--- a/source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h	Mon Jan 11 10:19:02 2016 +0000
+++ b/source/nordic-sdk/components/drivers_nrf/hal/nrf_wdt.h	Mon Jan 11 10:19:02 2016 +0000
@@ -1,319 +1,299 @@
-/*
- * Copyright (c) Nordic Semiconductor ASA
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- *   1. Redistributions of source code must retain the above copyright notice, this
- *   list of conditions and the following disclaimer.
- *
- *   2. Redistributions in binary form must reproduce the above copyright notice, this
- *   list of conditions and the following disclaimer in the documentation and/or
- *   other materials provided with the distribution.
- *
- *   3. Neither the name of Nordic Semiconductor ASA nor the names of other
- *   contributors to this software may be used to endorse or promote products
- *   derived from this software without specific prior written permission.
- *
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/**
- * @defgroup nrf_wdt_hal WDT HAL
- * @{
- * @ingroup nrf_wdt
- *
- * @brief Hardware abstraction layer for accessing the watchdog timer (WDT) peripheral.
- */
-
-#ifndef NRF_WDT_H__
-#define NRF_WDT_H__
-
-#include <stddef.h>
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "nrf.h"
-
-#define NRF_WDT_CHANNEL_NUMBER 0x8UL
-#define NRF_WDT_RR_VALUE       0x6E524635UL /* Fixed value, shouldn't be modified.*/
-
-#define NRF_WDT_TASK_SET       1UL
-#define NRF_WDT_EVENT_CLEAR    0UL
-
-/**
- * @enum nrf_wdt_task_t
- * @brief WDT tasks.
- */
-typedef enum
-{
-    /*lint -save -e30 -esym(628,__INTADDR__)*/
-    NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
-    /*lint -restore*/
-} nrf_wdt_task_t;
-
-/**
- * @enum nrf_wdt_event_t
- * @brief WDT events.
- */
-typedef enum
-{
-    /*lint -save -e30*/
-    NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
-    /*lint -restore*/
-} nrf_wdt_event_t;
-
-/**
- * @enum nrf_wdt_behaviour_t
- * @brief WDT behavior in CPU SLEEP or HALT mode.
- */
-typedef enum
-{
-    NRF_WDT_BEHAVIOUR_RUN_SLEEP        = WDT_CONFIG_SLEEP_Msk,                       /**< WDT will run when CPU is in SLEEP mode. */
-    NRF_WDT_BEHAVIOUR_RUN_HALT         = WDT_CONFIG_HALT_Msk,                        /**< WDT will run when CPU is in HALT mode. */
-    NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT   = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
-    NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0,                                          /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
-} nrf_wdt_behaviour_t;
-
-/**
- * @enum nrf_wdt_rr_register_t
- * @brief WDT reload request registers.
- */
-typedef enum
-{
-    NRF_WDT_RR0 = 0, /**< Reload request register 0. */
-    NRF_WDT_RR1,     /**< Reload request register 1. */
-    NRF_WDT_RR2,     /**< Reload request register 2. */
-    NRF_WDT_RR3,     /**< Reload request register 3. */
-    NRF_WDT_RR4,     /**< Reload request register 4. */
-    NRF_WDT_RR5,     /**< Reload request register 5. */
-    NRF_WDT_RR6,     /**< Reload request register 6. */
-    NRF_WDT_RR7      /**< Reload request register 7. */
-} nrf_wdt_rr_register_t;
-
-/**
- * @enum nrf_wdt_int_mask_t
- * @brief WDT interrupts.
- */
-typedef enum
-{
-    NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
-} nrf_wdt_int_mask_t;
-
-/**
- * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
- *
- * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
- */
-__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
-{
-    NRF_WDT->CONFIG = behaviour;
-}
-
-
-/**
- * @brief Function for starting the watchdog.
- *
- * @param[in]  task             Task.
- */
-__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
-{
-    *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
-}
-
-
-/**
- * @brief Function for clearing the WDT event.
- *
- * @param[in]  event       Event.
- */
-__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
-{
-    *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
-}
-
-
-/**
- * @brief Function for retrieving the state of the WDT event.
- *
- * @param[in]  event       Event.
- *
- * @retval     true              If the event is set.
- * @retval     false             If the event is not set.
- */
-__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
-{
-    return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
-}
-
-
-/**
- * @brief Function for enabling a specific interrupt.
- *
- * @param[in]  int_mask         Interrupt.
- */
-__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
-{
-    NRF_WDT->INTENSET = int_mask;
-}
-
-
-/**
- * @brief Function for retrieving the state of given interrupt.
- *
- * @param[in]  int_mask         Interrupt.
- *
- * @retval     true                   Interrupt is enabled.
- * @retval     false                  Interrupt is not enabled.
- */
-__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
-{
-    return (bool)(NRF_WDT->INTENSET & int_mask);
-}
-
-
-/**
- * @brief Function for disabling a specific interrupt.
- *
- * @param[in]  int_mask         Interrupt.
- */
-__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
-{
-    NRF_WDT->INTENCLR = int_mask;
-}
-
-
-/**
- * @brief Function for returning the address of a specific WDT task register.
- *
- * @param[in]  task             Task.
- */
-__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
-{
-    return ((uint32_t)NRF_WDT + task);
-}
-
-
-/**
- * @brief Function for returning the address of a specific WDT event register.
- *
- * @param[in]  event       Event.
- *
- * @retval     address of requested event register
- */
-__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
-{
-    return ((uint32_t)NRF_WDT + event);
-}
-
-
-/**
- * @brief Function for retrieving the watchdog status.
- *
- * @retval     true             If the watchdog is started.
- * @retval     false            If the watchdog is not started.
- */
-__STATIC_INLINE bool nrf_wdt_started(void)
-{
-    return (bool)(NRF_WDT->RUNSTATUS);
-}
-
-
-/**
- * @brief Function for retrieving the watchdog reload request status.
- *
- * @param[in]  rr_register      Reload request register to check.
- *
- * @retval     true             If a reload request is running.
- * @retval     false            If no reload request is running.
- */
-__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
-{
-    return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
-}
-
-
-/**
- * @brief Function for setting the watchdog reload value.
- *
- * @param[in]  reload_value     Watchdog counter initial value.
- */
-__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
-{
-    NRF_WDT->CRV = reload_value;
-}
-
-
-/**
- * @brief Function for retrieving the watchdog reload value.
- *
- * @retval                      Reload value.
- */
-__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
-{
-    return (uint32_t)NRF_WDT->CRV;
-}
-
-
-/**
- * @brief Function for enabling a specific reload request register.
- *
- * @param[in]  rr_register       Reload request register to enable.
- */
-__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
-{
-    NRF_WDT->RREN |= 0x1UL << rr_register;
-}
-
-
-/**
- * @brief Function for disabling a specific reload request register.
- *
- * @param[in]  rr_register       Reload request register to disable.
- */
-__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
-{
-    NRF_WDT->RREN &= ~(0x1UL << rr_register);
-}
-
-
-/**
- * @brief Function for retrieving the status of a specific reload request register.
- *
- * @param[in]  rr_register       Reload request register to check.
- *
- * @retval     true              If the reload request register is enabled.
- * @retval     false             If the reload request register is not enabled.
- */
-__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
-{
-    return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
-}
-
-
-/**
- * @brief Function for setting a specific reload request register.
- *
- * @param[in]  rr_register       Reload request register to set.
- */
-__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
-{
-    NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
-}
-
-
-#endif
-
+/* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/**
+ * @defgroup nrf_wdt_hal WDT HAL
+ * @{
+ * @ingroup nrf_wdt
+ *
+ * @brief Hardware abstraction layer for accessing the watchdog timer (WDT) peripheral.
+ */
+
+#ifndef NRF_WDT_H__
+#define NRF_WDT_H__
+
+#include <stddef.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nrf.h"
+
+#define NRF_WDT_CHANNEL_NUMBER 0x8UL
+#define NRF_WDT_RR_VALUE       0x6E524635UL /* Fixed value, shouldn't be modified.*/
+
+#define NRF_WDT_TASK_SET       1UL
+#define NRF_WDT_EVENT_CLEAR    0UL
+
+/**
+ * @enum nrf_wdt_task_t
+ * @brief WDT tasks.
+ */
+typedef enum
+{
+    /*lint -save -e30 -esym(628,__INTADDR__)*/
+    NRF_WDT_TASK_START = offsetof(NRF_WDT_Type, TASKS_START), /**< Task for starting WDT. */
+    /*lint -restore*/
+} nrf_wdt_task_t;
+
+/**
+ * @enum nrf_wdt_event_t
+ * @brief WDT events.
+ */
+typedef enum
+{
+    /*lint -save -e30*/
+    NRF_WDT_EVENT_TIMEOUT = offsetof(NRF_WDT_Type, EVENTS_TIMEOUT), /**< Event from WDT time-out. */
+    /*lint -restore*/
+} nrf_wdt_event_t;
+
+/**
+ * @enum nrf_wdt_behaviour_t
+ * @brief WDT behavior in CPU SLEEP or HALT mode.
+ */
+typedef enum
+{
+    NRF_WDT_BEHAVIOUR_RUN_SLEEP        = WDT_CONFIG_SLEEP_Msk,                       /**< WDT will run when CPU is in SLEEP mode. */
+    NRF_WDT_BEHAVIOUR_RUN_HALT         = WDT_CONFIG_HALT_Msk,                        /**< WDT will run when CPU is in HALT mode. */
+    NRF_WDT_BEHAVIOUR_RUN_SLEEP_HALT   = WDT_CONFIG_SLEEP_Msk | WDT_CONFIG_HALT_Msk, /**< WDT will run when CPU is in SLEEP or HALT mode. */
+    NRF_WDT_BEHAVIOUR_PAUSE_SLEEP_HALT = 0,                                          /**< WDT will be paused when CPU is in SLEEP or HALT mode. */
+} nrf_wdt_behaviour_t;
+
+/**
+ * @enum nrf_wdt_rr_register_t
+ * @brief WDT reload request registers.
+ */
+typedef enum
+{
+    NRF_WDT_RR0 = 0, /**< Reload request register 0. */
+    NRF_WDT_RR1,     /**< Reload request register 1. */
+    NRF_WDT_RR2,     /**< Reload request register 2. */
+    NRF_WDT_RR3,     /**< Reload request register 3. */
+    NRF_WDT_RR4,     /**< Reload request register 4. */
+    NRF_WDT_RR5,     /**< Reload request register 5. */
+    NRF_WDT_RR6,     /**< Reload request register 6. */
+    NRF_WDT_RR7      /**< Reload request register 7. */
+} nrf_wdt_rr_register_t;
+
+/**
+ * @enum nrf_wdt_int_mask_t
+ * @brief WDT interrupts.
+ */
+typedef enum
+{
+    NRF_WDT_INT_TIMEOUT_MASK = WDT_INTENSET_TIMEOUT_Msk, /**< WDT interrupt from time-out event. */
+} nrf_wdt_int_mask_t;
+
+/**
+ * @brief Function for configuring the watchdog behavior when the CPU is sleeping or halted.
+ *
+ * @param behaviour Watchdog behavior when CPU is in SLEEP or HALT mode.
+ */
+__STATIC_INLINE void nrf_wdt_behaviour_set(nrf_wdt_behaviour_t behaviour)
+{
+    NRF_WDT->CONFIG = behaviour;
+}
+
+
+/**
+ * @brief Function for starting the watchdog.
+ *
+ * @param[in]  task             Task.
+ */
+__STATIC_INLINE void nrf_wdt_task_trigger(nrf_wdt_task_t task)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_WDT + task)) = NRF_WDT_TASK_SET;
+}
+
+
+/**
+ * @brief Function for clearing the WDT event.
+ *
+ * @param[in]  event       Event.
+ */
+__STATIC_INLINE void nrf_wdt_event_clear(nrf_wdt_event_t event)
+{
+    *((volatile uint32_t *)((uint8_t *)NRF_WDT + (uint32_t)event)) = NRF_WDT_EVENT_CLEAR;
+}
+
+
+/**
+ * @brief Function for retrieving the state of the WDT event.
+ *
+ * @param[in]  event       Event.
+ *
+ * @retval     true              If the event is set.
+ * @retval     false             If the event is not set.
+ */
+__STATIC_INLINE bool nrf_wdt_event_check(nrf_wdt_event_t event)
+{
+    return (bool)*((volatile uint32_t *)((uint8_t *)NRF_WDT + event));
+}
+
+
+/**
+ * @brief Function for enabling a specific interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_enable(uint32_t int_mask)
+{
+    NRF_WDT->INTENSET = int_mask;
+}
+
+
+/**
+ * @brief Function for retrieving the state of given interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ *
+ * @retval     true                   Interrupt is enabled.
+ * @retval     false                  Interrupt is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_int_enable_check(uint32_t int_mask)
+{
+    return (bool)(NRF_WDT->INTENSET & int_mask);
+}
+
+
+/**
+ * @brief Function for disabling a specific interrupt.
+ *
+ * @param[in]  int_mask         Interrupt.
+ */
+__STATIC_INLINE void nrf_wdt_int_disable(uint32_t int_mask)
+{
+    NRF_WDT->INTENCLR = int_mask;
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT task register.
+ *
+ * @param[in]  task             Task.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_task_address_get(nrf_wdt_task_t task)
+{
+    return ((uint32_t)NRF_WDT + task);
+}
+
+
+/**
+ * @brief Function for returning the address of a specific WDT event register.
+ *
+ * @param[in]  event       Event.
+ *
+ * @retval     address of requested event register
+ */
+__STATIC_INLINE uint32_t nrf_wdt_event_address_get(nrf_wdt_event_t event)
+{
+    return ((uint32_t)NRF_WDT + event);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog status.
+ *
+ * @retval     true             If the watchdog is started.
+ * @retval     false            If the watchdog is not started.
+ */
+__STATIC_INLINE bool nrf_wdt_started(void)
+{
+    return (bool)(NRF_WDT->RUNSTATUS);
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload request status.
+ *
+ * @param[in]  rr_register      Reload request register to check.
+ *
+ * @retval     true             If a reload request is running.
+ * @retval     false            If no reload request is running.
+ */
+__STATIC_INLINE bool nrf_wdt_request_status(nrf_wdt_rr_register_t rr_register)
+{
+    return (bool)(((NRF_WDT->REQSTATUS) >> rr_register) & 0x1UL);
+}
+
+
+/**
+ * @brief Function for setting the watchdog reload value.
+ *
+ * @param[in]  reload_value     Watchdog counter initial value.
+ */
+__STATIC_INLINE void nrf_wdt_reload_value_set(uint32_t reload_value)
+{
+    NRF_WDT->CRV = reload_value;
+}
+
+
+/**
+ * @brief Function for retrieving the watchdog reload value.
+ *
+ * @retval                      Reload value.
+ */
+__STATIC_INLINE uint32_t nrf_wdt_reload_value_get(void)
+{
+    return (uint32_t)NRF_WDT->CRV;
+}
+
+
+/**
+ * @brief Function for enabling a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to enable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_enable(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RREN |= 0x1UL << rr_register;
+}
+
+
+/**
+ * @brief Function for disabling a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to disable.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_disable(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RREN &= ~(0x1UL << rr_register);
+}
+
+
+/**
+ * @brief Function for retrieving the status of a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to check.
+ *
+ * @retval     true              If the reload request register is enabled.
+ * @retval     false             If the reload request register is not enabled.
+ */
+__STATIC_INLINE bool nrf_wdt_reload_request_is_enabled(nrf_wdt_rr_register_t rr_register)
+{
+    return (bool)(NRF_WDT->RREN & (0x1UL << rr_register));
+}
+
+
+/**
+ * @brief Function for setting a specific reload request register.
+ *
+ * @param[in]  rr_register       Reload request register to set.
+ */
+__STATIC_INLINE void nrf_wdt_reload_request_set(nrf_wdt_rr_register_t rr_register)
+{
+    NRF_WDT->RR[rr_register] = NRF_WDT_RR_VALUE;
+}
+
+
+#endif
+
 /** @} */
\ No newline at end of file