diff --git a/Makefile.dep b/Makefile.dep
index 97650d319af42cb486879a0a1300a2a86f2b9db5..6d14cf96e67c2e6797e752fd94701e6e1d40193a 100644
--- a/Makefile.dep
+++ b/Makefile.dep
@@ -31,6 +31,17 @@ ifneq (,$(filter gnrc_uhcpc,$(USEMODULE)))
     USEMODULE += fmt
 endif
 
+ifneq (,$(filter nordic_softdevice_ble,$(USEPKG)))
+    USEMODULE += softdevice_handler
+    USEMODULE += ble_common
+    USEMODULE += ble_6lowpan
+    USEMODULE += gnrc_sixlowpan
+    USEMODULE += gnrc_sixlowpan_iphc
+    USEMODULE += gnrc_ipv6_default
+    USEMODULE += gnrc_netdev2
+    USEMODULE += gnrc_ipv6_netif
+endif
+
 ifneq (,$(filter gnrc_%,$(filter-out gnrc_netapi gnrc_netreg gnrc_netif% gnrc_pktbuf,$(USEMODULE))))
   USEMODULE += gnrc
 endif
diff --git a/boards/nrf52dk/Makefile.dep b/boards/nrf52dk/Makefile.dep
index 5472bf8b8d8fd463a18815c0f10e5d348f90fe51..27225b7b405afd419c4b84d080a919c820bac6bc 100644
--- a/boards/nrf52dk/Makefile.dep
+++ b/boards/nrf52dk/Makefile.dep
@@ -1,3 +1,7 @@
 ifneq (,$(filter saul_default,$(USEMODULE)))
   USEMODULE += saul_gpio
 endif
+
+ifneq (,$(filter gnrc_netdev_default,$(USEMODULE)))
+  USEPKG += nordic_softdevice_ble
+endif
diff --git a/boards/nrf52dk/Makefile.include b/boards/nrf52dk/Makefile.include
index e16b064a4d57b818b7b5138071b2070e1985c842..b2404fafa3fd8952b2cca11684d0ffcacc118e88 100644
--- a/boards/nrf52dk/Makefile.include
+++ b/boards/nrf52dk/Makefile.include
@@ -11,6 +11,13 @@ include $(RIOTBOARD)/$(BOARD)/Makefile.dep
 
 # setup JLink for flashing
 export JLINK_DEVICE := nrf52
+
+# special options when using SoftDevice
+ifneq (,$(filter nordic_softdevice_ble,$(USEPKG)))
+export JLINK_PRE_FLASH := loadfile $(BINDIR)/softdevice.hex
+export JLINK_FLASH_ADDR := 0x1f000
+export LINKER_SCRIPT ?= $(RIOTCPU)/$(CPU)/ldscripts/$(CPU_MODEL)_sd.ld
+endif
 include $(RIOTBOARD)/Makefile.include.jlink
 
 # setup serial terminal
diff --git a/boards/nrf52dk/include/periph_conf.h b/boards/nrf52dk/include/periph_conf.h
index 753d740749d4d8ab16d4cb5b707b0a2926951fcf..2975d5968f1fa624e06ebe8dadb22eb296b50195 100644
--- a/boards/nrf52dk/include/periph_conf.h
+++ b/boards/nrf52dk/include/periph_conf.h
@@ -44,10 +44,10 @@ extern "C" {
  */
 static const timer_conf_t timer_config[] = {
     /* dev, channels, width, IRQn */
-    { NRF_TIMER0, 3, TIMER_BITMODE_BITMODE_32Bit, TIMER0_IRQn }
+    { NRF_TIMER1, 3, TIMER_BITMODE_BITMODE_32Bit, TIMER1_IRQn }
 };
 
-#define TIMER_0_ISR         isr_timer0
+#define TIMER_0_ISR         isr_timer1
 
 #define TIMER_NUMOF         (sizeof(timer_config) / sizeof(timer_config[0]))
 /** @} */
@@ -57,9 +57,9 @@ static const timer_conf_t timer_config[] = {
  * @{
  */
 #define RTT_NUMOF           (1U)
-#define RTT_DEV             NRF_RTC0
-#define RTT_IRQ             RTC0_IRQn
-#define RTT_ISR             isr_rtc0
+#define RTT_DEV             NRF_RTC1
+#define RTT_IRQ             RTC1_IRQn
+#define RTT_ISR             isr_rtc1
 #define RTT_MAX_VALUE       (0xffffff)
 #define RTT_FREQUENCY       (10)            /* in Hz */
 #define RTT_PRESCALER       (3275U)         /* run with 10 Hz */
diff --git a/cpu/nrf52/cpu.c b/cpu/nrf52/cpu.c
index 9e72b02264ae552da7f0128af83cf42b454e1a12..173531915d3cd0c881da5311905abeea1bd05cb9 100644
--- a/cpu/nrf52/cpu.c
+++ b/cpu/nrf52/cpu.c
@@ -20,6 +20,8 @@
  * @}
  */
 
+#define DONT_OVERRIDE_NVIC
+
 #include "cpu.h"
 #include "periph_conf.h"
 
@@ -28,14 +30,16 @@ static bool ftpan_32(void);
 static bool ftpan_37(void);
 static bool ftpan_36(void);
 
+#ifdef SOFTDEVICE_PRESENT
+#include "softdevice_handler.h"
+uint8_t _ble_evt_buffer[BLE_STACK_EVT_MSG_BUF_SIZE];
+#endif
+
 /**
  * @brief   Initialize the CPU, set IRQ priorities
  */
 void cpu_init(void)
 {
-    /* set pendSV interrupt to lowest possible priority */
-    NVIC_SetPriority(PendSV_IRQn, 0xff);
-
     /* Workaround for FTPAN-32
      * "DIF: Debug session automatically enables TracePort pins." */
     if (ftpan_32()) {
@@ -64,6 +68,20 @@ void cpu_init(void)
 
     while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
 #endif
+
+    /* softdevice needs to be enabled from ISR context */
+#ifdef SOFTDEVICE_PRESENT
+    softdevice_handler_init(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, &_ble_evt_buffer,
+            BLE_STACK_EVT_MSG_BUF_SIZE, NULL);
+#endif
+    /* call cortexm default initialization */
+    cortexm_init();
+
+#ifdef SOFTDEVICE_PRESENT
+    /* fixup swi0 (used as softdevice PendSV trampoline) */
+    NVIC_EnableIRQ(SWI0_EGU0_IRQn);
+    NVIC_SetPriority(SWI0_EGU0_IRQn, 6);
+#endif
 }
 
 /**
diff --git a/cpu/nrf52/include/cpu_conf.h b/cpu/nrf52/include/cpu_conf.h
index 066b1cfbcac7258015ed753084c37ced470fa3da..5a60cae047abda0173328768695f63bfb6831d6f 100644
--- a/cpu/nrf52/include/cpu_conf.h
+++ b/cpu/nrf52/include/cpu_conf.h
@@ -32,11 +32,24 @@ extern "C" {
  * @brief   ARM Cortex-M specific CPU configuration
  * @{
  */
-#define CPU_DEFAULT_IRQ_PRIO            (1U)
-#define CPU_IRQ_NUMOF                   (38)
+#define CPU_DEFAULT_IRQ_PRIO            (2U)
+#define CPU_IRQ_NUMOF                   (38U)
 #define CPU_FLASH_BASE                  (0x00000000)
 /** @} */
 
+/**
+ * @brief   SoftDevice settings
+ * @{
+ */
+#ifdef SOFTDEVICE_PRESENT
+#ifndef DONT_OVERRIDE_NVIC
+#include "nrf_soc.h"
+#undef NVIC_SetPriority
+#define NVIC_SetPriority    sd_nvic_SetPriority
+#endif /* DONT_OVERRIDE_NVIC */
+#endif /* SOFTDEVICE_PRESENT */
+/** @} */
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/cpu/nrf52/ldscripts/nrf52xxaa_sd.ld b/cpu/nrf52/ldscripts/nrf52xxaa_sd.ld
new file mode 100644
index 0000000000000000000000000000000000000000..1b9f09172267e7ef6c02999dee41ddd305e88d64
--- /dev/null
+++ b/cpu/nrf52/ldscripts/nrf52xxaa_sd.ld
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2016 Freie Universität Berlin
+ *
+ * This file is subject to the terms and conditions of the GNU Lesser
+ * General Public License v2.1. See the file LICENSE in the top level
+ * directory for more details.
+ */
+
+/**
+ * @addtogroup      cpu_nrf52
+ * @{
+ *
+ * @file
+ * @brief           Memory definitions for the NRF52832XXAA
+ *
+ * @author          Hauke Petersen <hauke.petersen@fu-berlin.de>
+ *
+ * @}
+ */
+
+MEMORY
+{
+  rom (rx) : ORIGIN = 0x1f000, LENGTH = 0x61000
+  ram (rwx) :  ORIGIN = 0x20002800, LENGTH = 0xD800
+}
+
+INCLUDE cortexm_base.ld
diff --git a/cpu/nrf52/vectors.c b/cpu/nrf52/vectors.c
index 20e043de679131b721dbc47cdfcffa75a897ff86..0cb88e47e11bae2e2bbc7e17ebff2be0d3b9ad3c 100644
--- a/cpu/nrf52/vectors.c
+++ b/cpu/nrf52/vectors.c
@@ -58,7 +58,21 @@ WEAK_DEFAULT void isr_wdt(void);
 WEAK_DEFAULT void isr_rtc1(void);
 WEAK_DEFAULT void isr_qdec(void);
 WEAK_DEFAULT void isr_lpcomp(void);
+
+#ifndef SOFTDEVICE_PRESENT
 WEAK_DEFAULT void isr_swi0(void);
+#else
+/* For unknown reasons, setting PendSV pending within
+ * the softdevice ISRs leads to a crash. This workaround
+ * uses swi0 as trampoline.
+ */
+extern void thread_arch_yield(void);
+void isr_swi0(void)
+{
+    thread_arch_yield();
+}
+#endif
+
 WEAK_DEFAULT void isr_swi1(void);
 WEAK_DEFAULT void isr_swi2(void);
 WEAK_DEFAULT void isr_swi3(void);
@@ -76,6 +90,10 @@ WEAK_DEFAULT void isr_rtc2(void);
 WEAK_DEFAULT void isr_i2s(void);
 
 
+#ifdef SOFTDEVICE_PRESENT
+extern void SWI2_EGU2_IRQHandler(void);
+#endif
+
 /* interrupt vector table */
 ISR_VECTORS const void *interrupt_vector[] = {
     /* Exception stack pointer */
@@ -121,10 +139,14 @@ ISR_VECTORS const void *interrupt_vector[] = {
     (void *) isr_lpcomp,            /* lpcomp */
     (void *) isr_swi0,              /* swi0 */
     (void *) isr_swi1,              /* swi1 */
+#ifdef SOFTDEVICE_PRESENT
+    (void *) SWI2_EGU2_IRQHandler,  /* softdevice swi handler */
+#else
     (void *) isr_swi2,              /* swi2 */
-    (void *) isr_swi3,              /* swi3 */
-    (void *) isr_swi4,              /* swi4 */
-    (void *) isr_swi5,              /* swi5 */
+#endif
+    (void *) (0UL),              /* swi3 */
+    (void *) (0UL),              /* swi4 */
+    (void *) (0UL),              /* swi5 */
     (void *) isr_timer3,            /* timer 3 */
     (void *) isr_timer4,            /* timer 4 */
     (void *) isr_pwm0,              /* pwm 0 */
diff --git a/pkg/nordic_softdevice_ble/Makefile b/pkg/nordic_softdevice_ble/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0e44c05d940fd15f431eda1a0903bc0f1f3b8516
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/Makefile
@@ -0,0 +1,49 @@
+PKG_NAME = nordic_softdevice_ble
+PKG_VERSION = 3288530
+PKG_FILE = nrf5_iot_sdk_$(PKG_VERSION).zip
+PKG_URL = https://developer.nordicsemi.com/nRF5_IoT_SDK/nRF5_IoT_SDK_v0.9.x/$(PKG_FILE)
+PKG_DIR=$(CURDIR)
+PKG_BUILDDIR=$(BINDIRBASE)/pkg/$(BOARD)/$(PKG_NAME)
+PKG_SRCDIR=$(PKG_BUILDDIR)/src
+
+SOFTDEVICE := components/softdevice/s1xx_iot/s1xx-iot-prototype3_nrf52_softdevice.hex
+BLE_6LOWPAN_LIB := components/iot/ble_6lowpan/lib/ble_6lowpan.a
+MODULE_MAKEFILE := $(PKG_DIR)/Makefile.module
+
+.PHONY: all clean distclean
+
+all: $(BINDIR)/ble_6lowpan.a $(BINDIR)/softdevice.hex
+
+$(BINDIR)/ble_6lowpan.a: $(PKG_SRCDIR)/.extracted
+	cp $(PKG_SRCDIR)/$(BLE_6LOWPAN_LIB) $@
+
+$(BINDIR)/softdevice.hex: $(PKG_SRCDIR)/.extracted
+	cp $(PKG_SRCDIR)/$(SOFTDEVICE) $@
+
+$(PKG_SRCDIR)/.extracted: $(PKG_BUILDDIR)/$(PKG_FILE)
+	rm -rf $(@D)
+	mkdir -p $(@D)
+	$(AD)cd $(@D) && $(UNZIP_HERE) $(PKG_BUILDDIR)/$(PKG_FILE)
+
+# this file doesn't compile with RIOT, but is not needed either
+	rm $(PKG_BUILDDIR)/src/components/ble/common/ble_conn_params.c
+
+# setup RIOT module makefiles for nordic SDK components
+	cat $(MODULE_MAKEFILE) > $(PKG_SRCDIR)/components/softdevice/common/softdevice_handler/Makefile
+
+	echo "MODULE=ble_common" > $(PKG_SRCDIR)/components/ble/common/Makefile
+	cat $(MODULE_MAKEFILE) >> $(PKG_SRCDIR)/components/ble/common/Makefile
+
+	cat $(MODULE_MAKEFILE) > $(PKG_SRCDIR)/components/iot/ble_ipsp/Makefile
+
+	touch $@
+
+$(PKG_BUILDDIR)/$(PKG_FILE):
+	@mkdir -p $(@D)
+	$(AD)$(DOWNLOAD_TO_FILE) $@ $(PKG_URL)
+
+clean::
+	rm -rf $(PKG_SRCDIR)/
+
+distclean::
+	rm -rf $(PKG_BUILDDIR)/
diff --git a/pkg/nordic_softdevice_ble/Makefile.include b/pkg/nordic_softdevice_ble/Makefile.include
new file mode 100644
index 0000000000000000000000000000000000000000..138595464e1ef3ad6a4ef729130a91b76f94110f
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/Makefile.include
@@ -0,0 +1,32 @@
+NORDIC_SRCS := $(BINDIRBASE)/pkg/$(BOARD)/nordic_softdevice_ble/src
+
+INCLUDES += \
+			-I$(RIOTBASE)/pkg/nordic_softdevice_ble/src \
+			-I$(NORDIC_SRCS)/components/ble/common \
+			-I$(NORDIC_SRCS)/components/device \
+			-I$(NORDIC_SRCS)/components/iot/ble_6lowpan \
+			-I$(NORDIC_SRCS)/components/iot/ble_ipsp \
+			-I$(NORDIC_SRCS)/components/iot/common \
+			-I$(NORDIC_SRCS)/components/libraries/scheduler \
+			-I$(NORDIC_SRCS)/components/libraries/util \
+			-I$(NORDIC_SRCS)/components/softdevice/common/softdevice_handler \
+			-I$(NORDIC_SRCS)/components/softdevice/s1xx_iot/headers \
+			-I$(NORDIC_SRCS)/components/softdevice/s1xx_iot/headers/nrf52 \
+			-I$(NORDIC_SRCS)/components/toolchain
+
+CFLAGS += -DNRF52 \
+		  -DBLE_STACK_SUPPORT_REQD \
+		  -DISR_STACKSIZE=8192 \
+		  -DSOFTDEVICE_PRESENT \
+		  -DS132
+
+# Nordic's ble_6lowpan.a is compiled with hard-float
+# so set this, otherwise linking fails
+CFLAGS_FPU := -mfloat-abi=hard -mfpu=fpv4-sp-d16
+
+DIRS += \
+		$(RIOTBASE)/pkg/nordic_softdevice_ble/src \
+		$(NORDIC_SRCS)/components/softdevice/common/softdevice_handler \
+		$(NORDIC_SRCS)/components/ble/common \
+		$(NORDIC_SRCS)/components/iot/ble_ipsp
+
diff --git a/pkg/nordic_softdevice_ble/Makefile.module b/pkg/nordic_softdevice_ble/Makefile.module
new file mode 100644
index 0000000000000000000000000000000000000000..48422e909a47d7cd428d10fa73825060ccc8d8c2
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/Makefile.module
@@ -0,0 +1 @@
+include $(RIOTBASE)/Makefile.base
diff --git a/pkg/nordic_softdevice_ble/README-BLE-6LoWPAN.md b/pkg/nordic_softdevice_ble/README-BLE-6LoWPAN.md
new file mode 100644
index 0000000000000000000000000000000000000000..3ac44423697df4f5e9830c4059ddfea6038ac9b0
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/README-BLE-6LoWPAN.md
@@ -0,0 +1,100 @@
+This README contains information how to establish an IPv6 connecton between
+Linux BLE router and an IPSP enabled BLE device.
+
+Prerequisites
+=============
+In general, any device capable of running Linux operating system, can be used
+as a BLE router provided the following conditions are met:
+
+* Linux Kernel >3.18 is used
+* bluez, libcap-ng0, radvd tools are present.
+
+If a built-in Bluetooth device is not available then Bluetooth 4.0 compatible
+USB dongle can be used.
+
+The following procedures have been tested on Ubuntu 15.10.
+
+Establishing an IPv6 connection
+===============================
+Use the following procedure to establish a connection between an nRF52 device
+and Linux router:
+
+First enable 6LoWPAN module. This is neccessary only once per session:
+
+	# Log in as a root user.
+	sudo su
+	
+	# Mount debugfs file system.
+	mount -t debugfs none /sys/kernel/debug
+	
+	# Load 6LoWPAN module.
+	modprobe bluetooth_6lowpan
+	
+	# Enable the bluetooth 6lowpan module.
+	echo 1 > /sys/kernel/debug/bluetooth/6lowpan_enable
+	
+	# Look for available HCI devices.
+	hciconfig
+	
+	# Reset HCI device - for example hci0 device.
+	hciconfig hci0 reset
+	
+	# Read 00:AA:BB:XX:YY:ZZ address of the nRF5x device.
+	hcitool lescan
+	
+If you see device name and address in lescan output then you can connect to the
+device:
+	
+	echo "connect 00:AA:BB:XX:YY:ZZ 1" > /sys/kernel/debug/bluetooth/6lowpan_control
+	
+If above is successful then LED1 will stop blinking and LED2 will switch on.
+You can then check the connection using the following commands:
+
+	# Check if bt0 interface is present and up
+	ifconfig
+	
+	# Try to ping the device using its link-local address, for example, on bt0 interface.
+	ping6 fe80::2aa:bbff:fexx:yyzz%bt0
+	
+If you'd like to learn more about the procedure please refer to
+[Connecting devices to the router].
+
+Distributing routable IPv6 prefix
+=================================
+In Linux, Router Advertisement Daemon (RADVD) can be used to distribute prefixes
+in the network, hance configure routable IPv6 address.
+
+To configure RADVD create `/etc/radvd.conf` file and paste the following contents:
+
+	interface bt0
+	{
+	    AdvSendAdvert on;
+	    prefix 2001:db8::/64
+	    {
+	        AdvOnLink off;
+	        AdvAutonomous on;
+	        AdvRouterAddr on;
+	    };
+	};
+
+Next, start RADVD daemon:
+
+	# Set IPv6 forwarding (must be present).
+	sudo echo 1 > /proc/sys/net/ipv6/conf/all/forwarding
+	# Run radvd daemon.
+	sudo service radvd restart
+	
+If successfull then all devices connected to the host will receive
+a routable `2001:db8` prefix.
+
+This can be verified by sending echo request to the full address:
+
+	ping6 -I bt0 2001:db8::2aa:bbff:fexx:yyzz
+
+where `aa:bbff:fexx:yyzz` is device Bluetooth address.
+
+If you'd like to learn more about the procedure please refer to
+[Distributing a global IPv6 prefix].
+
+* [Connecting devices to the router]: http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00089.html
+* [Distributing a global IPv6 prefix]: http://developer.nordicsemi.com/nRF5_IoT_SDK/doc/0.9.0/html/a00090.html
diff --git a/pkg/nordic_softdevice_ble/README.md b/pkg/nordic_softdevice_ble/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..3cb357d3635e7382b4a1fbd4aa5d3ee4321a3cc1
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/README.md
@@ -0,0 +1,30 @@
+# Overview
+
+This package provides necessary Makefiles and glue code to use the Nordic S132
+SoftDevice as Bluetooth BLE transport for RIOT's 6lowpan stack.
+
+# Usage
+
+"gnrc_netdev_default" has a dependency to "nordic_softdevice_ble", so all
+examples automatically download the SDK and compile / link / flash all needed
+code.
+
+If you want to manually set up included modules, add "USEPKG +=
+nordic_softdevice_ble" to your application's Makefile.
+
+See README-BLE-6LoWPAN.md for instructions on how to set up 6lowpan over BLE on
+Linux.
+
+# Known issues
+
+- floating point ABI mismatch
+
+The Nordic binaries are compiled using hard float ABI, which RIOT currently
+doesn't support (RIOT's context switching code doesn't preserve the floating
+point registers).  If the softdevice is compiled in, RIOT will be compiled with
+hard float ABI in order for the linking to succeed.  This works for some
+application, but will lead to serious and hard-to-find bugs for code using
+floating point instructions.
+
+Hopefully, either the RIOT community adds hard-float support, or Nordic
+releases a soft-float version of the used binaries.
diff --git a/pkg/nordic_softdevice_ble/src/Makefile b/pkg/nordic_softdevice_ble/src/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..d8f0fd1b273ae6dca09955778a8553ebec50fb3e
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/Makefile
@@ -0,0 +1,2 @@
+MODULE = nordic_softdevice_ble
+include $(RIOTBASE)/Makefile.base
diff --git a/pkg/nordic_softdevice_ble/src/app_error.c b/pkg/nordic_softdevice_ble/src/app_error.c
new file mode 100644
index 0000000000000000000000000000000000000000..cb3d928334833aa96a2e8b3edc3062a66b6a1f6e
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/app_error.c
@@ -0,0 +1,9 @@
+#include "app_error.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+void app_error_handler(uint32_t error_code, uint32_t line_num, const uint8_t *p_file_name)
+{
+    puts("nordic softdevice app_error_handler()");
+}
diff --git a/pkg/nordic_softdevice_ble/src/ble-core.c b/pkg/nordic_softdevice_ble/src/ble-core.c
new file mode 100644
index 0000000000000000000000000000000000000000..7c02da95e5c8356ec950f1621d638745cc0daa09
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/ble-core.c
@@ -0,0 +1,235 @@
+/*
+ * Copyright (c) 2016, Nordic Semiconductor
+ * 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 the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ *
+ */
+/**
+ * @addtogroup cpu
+ * @{
+ *
+ * @addtogroup nrf52832
+ * @{
+ *
+ * @addtogroup nrf52832-ble Bluetooth Low Energy drivers
+ * @{
+ *
+ * @file
+ *         Basic BLE functions.
+ * @author
+ *         Wojciech Bober <wojciech.bober@nordicsemi.no>
+ *         Kaspar Schleiser <kaspar@schleiser.de>
+ *
+ */
+#include <stdbool.h>
+#include <stdint.h>
+
+//#include "boards.h"
+//#include "nordic_common.h"
+//#include "nrf_delay.h"
+#include "nrf_sdm.h"
+#include "ble_advdata.h"
+#include "ble_srv_common.h"
+#include "ble_ipsp.h"
+#include "softdevice_handler.h"
+#include "app_error.h"
+#include "iot_defines.h"
+#include "ble-core.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+#define IS_SRVC_CHANGED_CHARACT_PRESENT 1
+#define APP_ADV_TIMEOUT                 0                                  /**< Time for which the device must be advertising in non-connectable mode (in seconds). 0 disables timeout. */
+#define APP_ADV_ADV_INTERVAL            MSEC_TO_UNITS(333, UNIT_0_625_MS)  /**< The advertising interval. This value can vary between 100ms to 10.24s). */
+
+static ble_gap_adv_params_t m_adv_params; /**< Parameters to be passed to the stack when starting advertising. */
+
+static void
+ble_evt_dispatch(ble_evt_t * p_ble_evt);
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief Initialize and enable the BLE stack.
+ */
+void
+ble_stack_init(void)
+{
+  uint32_t err_code;
+
+  // Enable BLE stack.
+  ble_enable_params_t ble_enable_params;
+  memset(&ble_enable_params, 0, sizeof(ble_enable_params));
+  ble_enable_params.gatts_enable_params.attr_tab_size =
+  BLE_GATTS_ATTR_TAB_SIZE_DEFAULT;
+  ble_enable_params.gatts_enable_params.service_changed =
+  IS_SRVC_CHANGED_CHARACT_PRESENT;
+  err_code = sd_ble_enable(&ble_enable_params);
+  APP_ERROR_CHECK(err_code);
+
+  // Register with the SoftDevice handler module for BLE events.
+  err_code = softdevice_ble_evt_handler_set(ble_evt_dispatch);
+  APP_ERROR_CHECK(err_code);
+
+  // Setup address
+  ble_gap_addr_t ble_addr;
+  err_code = sd_ble_gap_address_get(&ble_addr);
+  APP_ERROR_CHECK(err_code);
+
+  ble_addr.addr[5] = 0x00;
+  ble_addr.addr_type = BLE_GAP_ADDR_TYPE_PUBLIC;
+
+  err_code = sd_ble_gap_address_set(BLE_GAP_ADDR_CYCLE_MODE_NONE, &ble_addr);
+  APP_ERROR_CHECK(err_code);
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief Return device EUI64 MAC address
+ * @param addr pointer to a buffer to store the address
+ */
+void
+ble_get_mac(uint8_t addr[8])
+{
+  uint32_t err_code;
+  ble_gap_addr_t ble_addr;
+
+  err_code = sd_ble_gap_address_get(&ble_addr);
+  APP_ERROR_CHECK(err_code);
+
+  IPV6_EUI64_CREATE_FROM_EUI48(addr, ble_addr.addr, ble_addr.addr_type);
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief Initialize BLE advertising data.
+ * @param name Human readable device name that will be advertised
+ */
+void
+ble_advertising_init(const char *name)
+{
+  uint32_t err_code;
+  ble_advdata_t advdata;
+  uint8_t flags = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+  ble_gap_conn_sec_mode_t sec_mode;
+
+  BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+
+  err_code = sd_ble_gap_device_name_set(&sec_mode, (const uint8_t *)name,
+                                        strlen(name));
+  APP_ERROR_CHECK(err_code);
+
+  ble_uuid_t adv_uuids[] = {{BLE_UUID_IPSP_SERVICE, BLE_UUID_TYPE_BLE}};
+
+  // Build and set advertising data.
+  memset(&advdata, 0, sizeof(advdata));
+
+  advdata.name_type = BLE_ADVDATA_FULL_NAME;
+  advdata.flags = flags;
+  advdata.uuids_complete.uuid_cnt = sizeof(adv_uuids) / sizeof(adv_uuids[0]);
+  advdata.uuids_complete.p_uuids = adv_uuids;
+
+  err_code = ble_advdata_set(&advdata, NULL);
+  APP_ERROR_CHECK(err_code);
+
+  // Initialize advertising parameters (used when starting advertising).
+  memset(&m_adv_params, 0, sizeof(m_adv_params));
+
+  m_adv_params.type = BLE_GAP_ADV_TYPE_ADV_IND;
+  m_adv_params.p_peer_addr = NULL; // Undirected advertisement.
+  m_adv_params.fp = BLE_GAP_ADV_FP_ANY;
+  m_adv_params.interval = APP_ADV_ADV_INTERVAL;
+  m_adv_params.timeout = APP_ADV_TIMEOUT;
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief Start BLE advertising.
+ */
+void
+ble_advertising_start(void)
+{
+  uint32_t err_code;
+
+  err_code = sd_ble_gap_adv_start(&m_adv_params);
+  APP_ERROR_CHECK(err_code);
+
+  DEBUG("ble-core: advertising started\n");
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief Print GAP address.
+ * @param addr a pointer to address
+ */
+void
+ble_gap_addr_print(const ble_gap_addr_t *addr)
+{
+  unsigned int i;
+  for(i = 0; i < sizeof(addr->addr); i++) {
+    if(i > 0) {
+      DEBUG(":");
+    }DEBUG("%02x", addr->addr[i]);
+  }DEBUG(" (%d)", addr->addr_type);
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief Function for handling the Application's BLE Stack events.
+ * @param[in]   p_ble_evt   Bluetooth stack event.
+ */
+static void
+on_ble_evt(ble_evt_t *p_ble_evt)
+{
+  switch(p_ble_evt->header.evt_id) {
+    case BLE_GAP_EVT_CONNECTED:
+      DEBUG("ble-core: connected [handle:%d, peer: ", p_ble_evt->evt.gap_evt.conn_handle);
+      ble_gap_addr_print(&(p_ble_evt->evt.gap_evt.params.connected.peer_addr));
+      DEBUG("]\n");
+      sd_ble_gap_rssi_start(p_ble_evt->evt.gap_evt.conn_handle,
+                            BLE_GAP_RSSI_THRESHOLD_INVALID,
+                            0);
+      break;
+
+    case BLE_GAP_EVT_DISCONNECTED:
+      DEBUG("ble-core: disconnected [handle:%d]\n", p_ble_evt->evt.gap_evt.conn_handle);
+      ble_advertising_start();
+      break;
+    default:
+      break;
+  }
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @brief SoftDevice BLE event callback.
+ * @param[in]   p_ble_evt   Bluetooth stack event.
+ */
+static void
+ble_evt_dispatch(ble_evt_t *p_ble_evt)
+{
+  ble_ipsp_evt_handler(p_ble_evt);
+  on_ble_evt(p_ble_evt);
+}
+/*---------------------------------------------------------------------------*/
+/**
+ * @}
+ * @}
+ * @}
+ */
diff --git a/pkg/nordic_softdevice_ble/src/ble-core.h b/pkg/nordic_softdevice_ble/src/ble-core.h
new file mode 100644
index 0000000000000000000000000000000000000000..84c181d2eff4dd41250e184a4c0f14bfdcb70680
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/ble-core.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Nordic Semiconductor
+ * 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 the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ *
+ */
+/**
+ * \addtogroup cpu
+ * @{
+ *
+ * \addtogroup nrf52832
+ * @{
+ *
+ * \addtogroup nrf52832-ble Bluetooth Low Energy drivers
+ * @{
+ *
+ * \file
+ *         Basic BLE functions.
+ * \author
+ *         Wojciech Bober <wojciech.bober@nordicsemi.no>
+ */
+#ifndef DEV_BLE_H_
+#define DEV_BLE_H_
+
+#include <stdint.h>
+
+void ble_stack_init(void);
+void ble_advertising_init(const char *name);
+void ble_advertising_start(void);
+void ble_get_mac(uint8_t addr[8]);
+
+#endif /* DEV_BLE_H_ */
+
+/**
+ * @}
+ * @}
+ * @}
+ */
diff --git a/pkg/nordic_softdevice_ble/src/ble-mac.c b/pkg/nordic_softdevice_ble/src/ble-mac.c
new file mode 100644
index 0000000000000000000000000000000000000000..e77d564ec9c2944859c8b3207d8e854d33424f3e
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/ble-mac.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright (c) 2016, Nordic Semiconductor
+ * 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 the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ *
+ */
+
+#include <stdint.h>
+#include <string.h>
+
+#define DONT_OVERRIDE_NVIC
+
+#include "ble-core.h"
+#include "ble_ipsp.h"
+#include "ble_gap.h"
+
+#include "ble-mac.h"
+
+#define ENABLE_DEBUG (0)
+#include "debug.h"
+
+#if defined(MODULE_OD) && ENABLE_DEBUG
+#include "od.h"
+#endif
+
+#ifndef BLE_MAC_MAX_INTERFACE_NUM
+#define BLE_MAC_MAX_INTERFACE_NUM (1U)  /**< Maximum number of interfaces, i.e.,
+                                             connection to master devices */
+#endif
+
+typedef struct {
+  uint8_t peer_addr[8];
+  ble_ipsp_handle_t handle;
+} ble_mac_interface_t;
+
+static ble_mac_interface_t interfaces[BLE_MAC_MAX_INTERFACE_NUM];
+
+volatile int ble_mac_busy_tx;
+volatile int ble_mac_busy_rx;
+
+static ble_mac_inbuf_t inbuf;
+static ble_mac_callback_t _callback;
+
+/**
+ * @brief Lookup interface by IPSP connection.
+ *
+ * @param[in] handle    a pointer to IPSP handle.
+ * @return a pointer to interface structure
+ * @return NULL if no interface has been found for a given handle
+ */
+static ble_mac_interface_t *ble_mac_interface_lookup(ble_ipsp_handle_t *handle)
+{
+    for (int i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) {
+        if (interfaces[i].handle.conn_handle == handle->conn_handle &&
+            interfaces[i].handle.cid == handle->cid) {
+            return &interfaces[i];
+        }
+    }
+    return NULL;
+}
+
+/**
+ * @brief Add IPSP connection to the interface table.
+ *
+ * This function binds IPSP connection with peer address.
+ *
+ * @param[in] peer      a pointer to eui64 address
+ * @param[in] handle    a pointer to IPSP handle
+ *
+ * @return  a pointer to an interface structure on success
+ * @return  NULL if interface table is full
+ */
+static ble_mac_interface_t *ble_mac_interface_add(uint8_t peer[8],
+                                                  ble_ipsp_handle_t *handle)
+{
+    DEBUG("ble_mac_interface_add()");
+    for (int i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) {
+        if (interfaces[i].handle.conn_handle == 0 && interfaces[i].handle.cid == 0) {
+            memcpy(&interfaces[i].handle, handle, sizeof(ble_ipsp_handle_t));
+            memcpy(&interfaces[i].peer_addr, peer, 8);
+
+            /* notify handler thread */
+            /* msg_t m = { .type = BLE_IFACE_ADDED, .content.ptr = &interfaces[i] }; */
+            /* msg_send(&m, gnrc_nordic_ble_6lowpan_pid); */
+
+            return &interfaces[i];
+        }
+    }
+    return NULL;
+}
+
+/**
+ * @brief       Remove interface from the interface table.
+ * @param[in]   interface a pointer to interface
+ */
+static void ble_mac_interface_delete(ble_mac_interface_t *interface)
+{
+    DEBUG("ble_mac_interface_delete()");
+    memset(interface, 0, sizeof(ble_mac_interface_t));
+}
+
+/**
+ * @brief Lookup IPSP handle by peer address.
+ *
+ * @param[in] addr a pointer to eui64 address.
+ * @retval a pointer to IPSP handle on success
+ * @retval NULL if an IPSP handle for given address haven't been found
+ */
+static ble_ipsp_handle_t *_find_handle(const uint8_t *addr)
+{
+    for (int i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) {
+        if (memcmp(interfaces[i].peer_addr, addr, BLE_SIXLOWPAN_L2_ADDR_LEN) == 0) {
+            return &interfaces[i].handle;
+        }
+    }
+    return NULL;
+}
+
+/**
+ * @brief Send packet on a given IPSP handle.
+ *
+ * @param[in] handle a pointer to IPSP handle.
+ * @return 1 on success, 0 otherwise
+ */
+static int _send_to_peer(ble_ipsp_handle_t *handle, void *data, size_t len)
+{
+  DEBUG("ble-mac: sending packet[GAP handle:%d CID:0x%04X]\n",
+          handle->conn_handle, handle->cid);
+  return ble_ipsp_send(handle, data, len);
+}
+
+static int _is_broadcast(uint8_t dest[8])
+{
+    uint32_t *_dest = (uint32_t*)dest;
+    for (int i = 0; i < 2; i++) {
+        if (_dest[i]) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
+int ble_mac_send(uint8_t dest[8], void *data, size_t len)
+{
+    DEBUG("ble_mac_send(): sending pkt with len %u\n", (unsigned)len);
+
+#if defined(MODULE_OD) && ENABLE_DEBUG
+    od_hex_dump(dest, 8, OD_WIDTH_DEFAULT);
+    od_hex_dump(data, len, OD_WIDTH_DEFAULT);
+#endif
+
+    int i;
+    ble_ipsp_handle_t *handle;
+    int ret = -1;
+
+    if ((!dest) || _is_broadcast(dest)) {
+        DEBUG("broadcast\n");
+        for (i = 0; i < BLE_MAC_MAX_INTERFACE_NUM; i++) {
+            if (interfaces[i].handle.cid != 0 && interfaces[i].handle.conn_handle != 0) {
+                ret = _send_to_peer(&interfaces[i].handle, data, len);
+                DEBUG("ret=%i\n", ret);
+            }
+        }
+    }
+    else if ((handle = _find_handle(dest)) != NULL) {
+        DEBUG("unicast\n");
+        ret = _send_to_peer(handle, data, len);
+    }
+    else {
+        DEBUG("ble-mac: no connection found for peer\n");
+    }
+
+    if (ret == NRF_SUCCESS) {
+        ble_mac_busy_tx = 1;
+        return 0;
+    }
+    else {
+        DEBUG("ble-mac: send error: %i\n", ret);
+        return -1;
+    }
+}
+
+static uint32_t ble_mac_ipsp_evt_handler_irq(ble_ipsp_handle_t *p_handle, ble_ipsp_evt_t *p_evt)
+{
+    uint32_t retval = NRF_SUCCESS;
+
+    ble_mac_interface_t *p_instance = NULL;
+
+    p_instance = ble_mac_interface_lookup(p_handle);
+
+    if (p_handle) {
+        DEBUG("ble-mac: IPSP event [handle:%d CID 0x%04X]\n", p_handle->conn_handle, p_handle->cid);
+    }
+
+    switch (p_evt->evt_id) {
+        case BLE_IPSP_EVT_CHANNEL_CONNECTED: {
+            uint8_t peer_addr[8];
+
+            DEBUG("ble-mac: channel connected\n");
+            ble_eui64_from_eui48(peer_addr, p_evt->evt_param->params.ch_conn_request.peer_addr.addr,
+                                 p_evt->evt_param->params.ch_conn_request.peer_addr.addr_type ==
+                                 BLE_GAP_ADDR_TYPE_PUBLIC);
+
+            p_instance = ble_mac_interface_add(peer_addr, p_handle);
+
+            if (p_instance != NULL) {
+                DEBUG("ble-mac: added new IPSP interface\n");
+            }
+            else {
+                DEBUG("ble-mac: cannot add new interface. Table is full\n");
+                ble_ipsp_disconnect(p_handle);
+            }
+            break;
+        }
+
+        case BLE_IPSP_EVT_CHANNEL_DISCONNECTED: {
+            DEBUG("ble-mac: channel disconnected\n");
+            if (p_instance != NULL) {
+                DEBUG("ble-mac: removed IPSP interface\n");
+                ble_mac_interface_delete(p_instance);
+            }
+            break;
+        }
+
+        case BLE_IPSP_EVT_CHANNEL_DATA_RX: {
+            DEBUG("ble-mac: data received\n");
+            if (p_instance != NULL) {
+                if (ble_mac_busy_rx) {
+                    DEBUG("ble-mac: packet dropped as input buffer is busy\n");
+                    break;
+                }
+
+                if (p_evt->evt_param->params.ch_rx.len > BLE_SIXLOWPAN_MTU) {
+                    DEBUG("ble-mac: packet buffer is too small!\n");
+                    break;
+                }
+
+                ble_mac_busy_rx = 1;
+
+                inbuf.len = p_evt->evt_param->params.ch_rx.len;
+                memcpy(inbuf.payload, p_evt->evt_param->params.ch_rx.p_data, inbuf.len);
+                memcpy(inbuf.src, p_instance->peer_addr, 8);
+                sd_ble_gap_rssi_get(p_handle->conn_handle, &inbuf.rssi);
+
+                _callback(BLE_EVENT_RX_DONE, &inbuf);
+            }
+            else {
+                DEBUG("ble-mac: got data to unknown interface!\n");
+            }
+            break;
+        }
+
+        case BLE_IPSP_EVT_CHANNEL_DATA_TX_COMPLETE: {
+            DEBUG("ble-mac: data transmitted\n");
+            ble_mac_busy_tx = 0;
+            //_callback(BLE_EVENT_TX_DONE, NULL);
+            break;
+        }
+    }
+
+    if (sched_context_switch_request) {
+        NVIC_SetPendingIRQ( SWI0_EGU0_IRQn );
+    }
+
+    return retval;
+}
+
+void ble_mac_init(ble_mac_callback_t callback)
+{
+    assert(callback);
+
+    uint32_t res;
+    ble_ipsp_init_t ipsp_init_params = {
+        .evt_handler = ble_mac_ipsp_evt_handler_irq
+    };
+
+    _callback = callback;
+
+    res = ble_ipsp_init(&ipsp_init_params);
+    DEBUG("ble_ipsp_init() res = %" PRIu32 "\n", res);
+    (void)res;
+}
diff --git a/pkg/nordic_softdevice_ble/src/ble-mac.h b/pkg/nordic_softdevice_ble/src/ble-mac.h
new file mode 100644
index 0000000000000000000000000000000000000000..19eaefb03ab9caa827f24c0f08eb2b7ea76d9881
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/ble-mac.h
@@ -0,0 +1,50 @@
+#ifndef BLE_MAC_H
+#define BLE_MAC_H
+
+typedef enum {
+    BLE_EVENT_RX_DONE = 20000,
+} ble_mac_event_enum_t;
+
+#define BLE_IFACE_ADDED             (10000)
+
+#define BLE_SIXLOWPAN_MTU           (1280U)
+#define BLE_SIXLOWPAN_L2_ADDR_LEN   (8)
+
+#define IPV6_IID_FLIP_VALUE         (0x02)
+
+#include "net/eui64.h"
+
+static inline void ble_eui64_from_eui48(uint8_t eui64[8], uint8_t eui48[6], int _public)
+{
+    eui64[0] = eui48[5];
+    eui64[1] = eui48[4];
+    eui64[2] = eui48[3];
+    eui64[3] = 0xFF;
+    eui64[4] = 0xFE;
+    eui64[5] = eui48[2];
+    eui64[6] = eui48[1];
+    eui64[7] = eui48[0];
+    if (_public) {
+        eui64[0] &= ~(IPV6_IID_FLIP_VALUE);
+    }
+    else {
+        eui64[0] |= IPV6_IID_FLIP_VALUE;
+    }
+}
+
+typedef struct {
+    uint8_t src[8];
+    uint8_t payload[BLE_SIXLOWPAN_MTU];
+    uint16_t len;
+    int8_t rssi;
+} ble_mac_inbuf_t;
+
+typedef void (*ble_mac_callback_t)(ble_mac_event_enum_t event, void*arg);
+void ble_mac_init(ble_mac_callback_t callback);
+int ble_mac_send(uint8_t dest[8], void *data, size_t len);
+
+extern volatile int ble_mac_busy_tx;    /**< Flag is set to 1 when the driver
+                                             is busy transmitting a packet. */
+extern volatile int ble_mac_busy_rx;    /**< Flag is set to 1 when there is a
+                                             received packet pending. */
+#endif /* BLE_MAC_H */
diff --git a/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c b/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c
new file mode 100644
index 0000000000000000000000000000000000000000..156c2289d0e61a42316bd16d665340cfdea12df9
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.c
@@ -0,0 +1,318 @@
+/*
+ * Copyright (c) 2016, Nordic Semiconductor
+ * 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 the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ *
+ */
+
+/**
+ * @{
+ * @ingroup     net
+ * @file
+ * @brief       Glue for Nordic's SoftDevice BLE 6lowpan blob to netapi
+ *
+ * @author      Kaspar Schleiser <kaspar@schleiser.de>
+ * @}
+ */
+
+#include <assert.h>
+#include <errno.h>
+
+#include "msg.h"
+#include "thread.h"
+
+#include "net/gnrc.h"
+#include "net/gnrc/nettype.h"
+
+#include "ble-core.h"
+#include "softdevice_handler.h"
+
+#include "ble-mac.h"
+
+#define ENABLE_DEBUG    (0)
+#include "debug.h"
+
+#if defined(MODULE_OD) && ENABLE_DEBUG
+#include "od.h"
+#endif
+
+#define BLE_NETAPI_MSG_QUEUE_SIZE   (8U)
+#define BLE_PRIO                    (THREAD_PRIORITY_MAIN - 1)
+
+kernel_pid_t gnrc_nordic_ble_6lowpan_pid;
+static char _stack[(THREAD_STACKSIZE_DEFAULT + DEBUG_EXTRA_STACKSIZE)];
+
+static uint8_t _own_mac_addr[BLE_SIXLOWPAN_L2_ADDR_LEN];
+
+static uint8_t _sendbuf[BLE_SIXLOWPAN_MTU];
+
+static void _ble_mac_callback(ble_mac_event_enum_t event, void* arg)
+{
+    msg_t m = { .type=event, .content.ptr=arg };
+
+    if (!msg_send_int(&m, gnrc_nordic_ble_6lowpan_pid)) {
+        puts("_ble_mac_callback(): possibly lost interrupt");
+    }
+}
+
+static void _handle_raw_sixlowpan(ble_mac_inbuf_t *inbuf)
+{
+    gnrc_pktsnip_t *pkt = NULL;
+
+    pkt = gnrc_pktbuf_add(NULL, inbuf->payload,
+            inbuf->len,
+            GNRC_NETTYPE_SIXLOWPAN);
+
+    if(!pkt) {
+        DEBUG("_handle_raw_sixlowpan(): no space left in packet buffer.\n");
+        return;
+    }
+
+    /* create netif header */
+    gnrc_pktsnip_t *netif_hdr;
+    netif_hdr = gnrc_pktbuf_add(NULL, NULL,
+            sizeof(gnrc_netif_hdr_t) + (2 * sizeof(eui64_t)),
+            GNRC_NETTYPE_NETIF);
+
+    if (netif_hdr == NULL) {
+        DEBUG("_handle_raw_sixlowpan(): no space left in packet buffer.\n");
+        gnrc_pktbuf_release(pkt);
+        return;
+    }
+
+    gnrc_netif_hdr_init(netif_hdr->data, BLE_SIXLOWPAN_L2_ADDR_LEN, BLE_SIXLOWPAN_L2_ADDR_LEN);
+    gnrc_netif_hdr_set_src_addr(netif_hdr->data, inbuf->src, BLE_SIXLOWPAN_L2_ADDR_LEN);
+    gnrc_netif_hdr_set_dst_addr(netif_hdr->data, _own_mac_addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
+    ((gnrc_netif_hdr_t *)netif_hdr->data)->if_pid = gnrc_nordic_ble_6lowpan_pid;
+
+    DEBUG("_handle_raw_sixlowpan(): received packet from %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
+            "of length %d\n",
+            inbuf->src[0], inbuf->src[1], inbuf->src[2], inbuf->src[3], inbuf->src[4],
+            inbuf->src[5], inbuf->src[6], inbuf->src[7], inbuf->len);
+#if defined(MODULE_OD) && ENABLE_DEBUG
+    od_hex_dump(inbuf->payload, inbuf->len, OD_WIDTH_DEFAULT);
+#endif
+
+    LL_APPEND(pkt, netif_hdr);
+
+    /* throw away packet if no one is interested */
+    if (!gnrc_netapi_dispatch_receive(pkt->type, GNRC_NETREG_DEMUX_CTX_ALL, pkt)) {
+        DEBUG("_handle_raw_sixlowpan: unable to forward packet of type %i\n", pkt->type);
+        gnrc_pktbuf_release(pkt);
+    }
+}
+
+static int _send(gnrc_pktsnip_t *pkt)
+{
+    gnrc_netif_hdr_t *netif_hdr;
+    gnrc_pktsnip_t *payload = pkt->next;
+    uint8_t *dst;
+
+    if (ble_mac_busy_tx) {
+        DEBUG("_send(): ble_mac_busy_tx\n");
+        return -EBUSY;
+    }
+
+    uint8_t *buf = _sendbuf;
+    unsigned len = 0;
+
+    if (pkt == NULL) {
+        DEBUG("_send_ble: pkt was NULL\n");
+        return -EINVAL;
+    }
+    if (pkt->type != GNRC_NETTYPE_NETIF) {
+        DEBUG("_send_ble: first header is not generic netif header\n");
+        return -EBADMSG;
+    }
+
+    netif_hdr = pkt->data;
+
+    /* prepare destination address */
+    if (netif_hdr->flags &
+        (GNRC_NETIF_HDR_FLAGS_BROADCAST | GNRC_NETIF_HDR_FLAGS_MULTICAST)) {
+        dst = NULL;
+    }
+    else {
+        dst = gnrc_netif_hdr_get_dst_addr(netif_hdr);
+    }
+
+    /* prepare packet for sending */
+    while (payload) {
+        memcpy(buf, payload->data, payload->size);
+        len += payload->size;
+        buf +=  payload->size;
+        payload = payload->next;
+    }
+
+    gnrc_pktbuf_release(pkt);
+
+    if (ble_mac_send(dst, _sendbuf, len) == -1) {
+        return -EBADMSG;
+    }
+
+    return 0;
+}
+static int _handle_get(gnrc_netapi_opt_t *_opt)
+{
+    int res = -ENOTSUP;
+    uint8_t *value = _opt->data;
+
+    switch (_opt->opt) {
+        case NETOPT_ACK_REQ:
+        case NETOPT_CHANNEL:
+        case NETOPT_NID:
+        case NETOPT_ADDRESS:
+            /* -ENOTSUP */
+            break;
+        case NETOPT_ADDRESS_LONG:
+            assert(_opt->data_len >= BLE_SIXLOWPAN_L2_ADDR_LEN);
+            memcpy(value, _own_mac_addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
+            value[0] = IPV6_IID_FLIP_VALUE;
+            res = BLE_SIXLOWPAN_L2_ADDR_LEN;
+            break;
+        case NETOPT_ADDR_LEN:
+        case NETOPT_SRC_LEN:
+            assert(_opt->data_len == sizeof(uint16_t));
+            *((uint16_t *)value) = BLE_SIXLOWPAN_L2_ADDR_LEN;
+            res = sizeof(uint16_t);
+            break;
+#ifdef MODULE_GNRC
+        case NETOPT_PROTO:
+            assert(_opt->data_len == sizeof(gnrc_nettype_t));
+            *((gnrc_nettype_t *)value) = GNRC_NETTYPE_SIXLOWPAN;
+            res = sizeof(gnrc_nettype_t);
+            break;
+#endif
+/*        case NETOPT_DEVICE_TYPE:
+            assert(_opt->data_len == sizeof(uint16_t));
+            *((uint16_t *)value) = NETDEV2_TYPE_IEEE802154;
+            res = sizeof(uint16_t);
+            break;*/
+        case NETOPT_IPV6_IID:
+            memcpy(value, _own_mac_addr, BLE_SIXLOWPAN_L2_ADDR_LEN);
+            value[0] = IPV6_IID_FLIP_VALUE;
+            res = BLE_SIXLOWPAN_L2_ADDR_LEN;
+            break;
+        default:
+            break;
+    }
+    return res;
+}
+
+/**
+ * @brief   Startup code and event loop of the gnrc_nordic_ble_6lowpan layer
+ *
+ * @return          never returns
+ */
+static void *_gnrc_nordic_ble_6lowpan_thread(void *args)
+{
+    (void)args;
+
+    DEBUG("gnrc_nordic_ble_6lowpan: starting thread\n");
+
+    gnrc_nordic_ble_6lowpan_pid = thread_getpid();
+
+    gnrc_netapi_opt_t *opt;
+    int res;
+    msg_t msg, reply, msg_queue[BLE_NETAPI_MSG_QUEUE_SIZE];
+
+    /* setup the message queue */
+    msg_init_queue(msg_queue, BLE_NETAPI_MSG_QUEUE_SIZE);
+
+    /* initialize BLE stack */
+    assert((unsigned)softdevice_handler_isEnabled());
+
+    ble_stack_init();
+    ble_get_mac(_own_mac_addr);
+
+    ble_mac_init(_ble_mac_callback);
+
+    ble_advertising_init("RIOT BLE");
+    ble_advertising_start();
+
+    /* register the device to the network stack*/
+    gnrc_netif_add(thread_getpid());
+
+    /* start the event loop */
+    while (1) {
+//        DEBUG("gnrc_nordic_ble_6lowpan: waiting for incoming messages\n");
+        msg_receive(&msg);
+        /* dispatch NETDEV and NETAPI messages */
+        switch (msg.type) {
+            case BLE_EVENT_RX_DONE:
+                {
+                    DEBUG("ble rx:\n");
+                    _handle_raw_sixlowpan(msg.content.ptr);
+                    ble_mac_busy_rx = 0;
+                    break;
+                }
+            case GNRC_NETAPI_MSG_TYPE_SND:
+                DEBUG("gnrc_nordic_ble_6lowpan: GNRC_NETAPI_MSG_TYPE_SND received\n");
+                _send(msg.content.ptr);
+                break;
+            case GNRC_NETAPI_MSG_TYPE_SET:
+                /* read incoming options */
+                opt = msg.content.ptr;
+                DEBUG("gnrc_nordic_ble_6lowpan: GNRC_NETAPI_MSG_TYPE_SET received. opt=%s\n",
+                      netopt2str(opt->opt));
+                /* set option for device driver */
+                res = ENOTSUP;
+                DEBUG("gnrc_nordic_ble_6lowpan: response of netdev->set: %i\n", res);
+                /* send reply to calling thread */
+                reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
+                reply.content.value = (uint32_t)res;
+                msg_reply(&msg, &reply);
+                break;
+            case GNRC_NETAPI_MSG_TYPE_GET:
+                /* read incoming options */
+                opt = msg.content.ptr;
+                DEBUG("gnrc_nordic_ble_6lowpan: GNRC_NETAPI_MSG_TYPE_GET received. opt=%s\n",
+                      netopt2str(opt->opt));
+                res = _handle_get(opt);
+                DEBUG("gnrc_nordic_ble_6lowpan: response of netdev->get: %i\n", res);
+                /* send reply to calling thread */
+                reply.type = GNRC_NETAPI_MSG_TYPE_ACK;
+                reply.content.value = (uint32_t)res;
+                msg_reply(&msg, &reply);
+                break;
+            default:
+                DEBUG("gnrc_nordic_ble_6lowpan: Unknown command %" PRIu16 "\n", msg.type);
+                break;
+        }
+    }
+    /* never reached */
+    return NULL;
+}
+
+void gnrc_nordic_ble_6lowpan_init(void)
+{
+    kernel_pid_t res = thread_create(_stack, sizeof(_stack), BLE_PRIO,
+                        THREAD_CREATE_STACKTEST,
+                        _gnrc_nordic_ble_6lowpan_thread, NULL,
+                        "ble");
+    assert(res > 0);
+    (void)res;
+}
diff --git a/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.h b/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.h
new file mode 100644
index 0000000000000000000000000000000000000000..27dde2fd1a3c9c20b35d336f02e3d3e67de04e34
--- /dev/null
+++ b/pkg/nordic_softdevice_ble/src/gnrc_nordic_ble_6lowpan.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2016, Nordic Semiconductor
+ * 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 the Institute nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE 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 INSTITUTE 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.
+ *
+ */
+#ifndef GNRC_NORDIC_BLE_6LOWPAN_H
+#define GNRC_NORDIC_BLE_6LOWPAN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void gnrc_nordic_ble_6lowpan_init(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* GNRC_NORDIC_BLE_6LOWPAN_H */
diff --git a/sys/auto_init/auto_init.c b/sys/auto_init/auto_init.c
index 63c9e6ec0050dfef1dafcd6e84ca91fe74162602..44f75bf3a8ff551f73228f034974a0b53424c005 100644
--- a/sys/auto_init/auto_init.c
+++ b/sys/auto_init/auto_init.c
@@ -225,6 +225,11 @@ void auto_init(void)
     auto_init_netdev2_tap();
 #endif
 
+#ifdef MODULE_NORDIC_SOFTDEVICE_BLE
+    extern void gnrc_nordic_ble_6lowpan_init(void);
+    gnrc_nordic_ble_6lowpan_init();
+#endif
+
 #endif /* MODULE_AUTO_INIT_GNRC_NETIF */
 
 #ifdef MODULE_GNRC_IPV6_NETIF