You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/05/12 21:13:13 UTC

[GitHub] turon closed pull request #4: [linux] initial port and osal additions.

turon closed pull request #4: [linux] initial port and osal additions.
URL: https://github.com/apache/mynewt-nimble/pull/4
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/README.md b/README.md
index 42dfdbaf..abb36626 100644
--- a/README.md
+++ b/README.md
@@ -69,3 +69,44 @@ application is built and flashed as other examples in nRF5 SDK:
     $ make -C porting/freertos_nrf5_sdk flash
 ````
 
+### Linux
+
+1. Build the sample application
+
+```no-highlight
+   cd porting/linux
+   make
+```
+
+2. Run the sample application
+
+First insert a USB Bluetooth dongle.  These are typically BLE 4.0 capable.
+
+Verify the dongle is connected with hciconfig:
+
+```no-highlight
+   $ hciconfig
+hci0:	Type: BR/EDR  Bus: USB
+	BD Address: 00:1B:DC:06:62:5E  ACL MTU: 310:10  SCO MTU: 64:8
+	DOWN
+	RX bytes:5470 acl:0 sco:0 events:40 errors:0
+	TX bytes:5537 acl:176 sco:0 commands:139 errors:1
+```
+
+Then run the application built in step one.  The application is configured
+in sysconfig.h to use hci0.
+
+```no-highlight
+   cd porting/linux
+   sudo ./_build/nimble_linux.out
+```
+
+3. Build and run the unit tests
+
+The Operating System Abstraction Layer (OSAL) used to port Nimble to Linux
+has a suite of unit tests.
+
+```no-highlight
+   cd tests/unit/porting/os
+   make test
+```
diff --git a/nimble/host/src/ble_hs_startup.c b/nimble/host/src/ble_hs_startup.c
index 5de4256c..552b90eb 100644
--- a/nimble/host/src/ble_hs_startup.c
+++ b/nimble/host/src/ble_hs_startup.c
@@ -157,19 +157,29 @@ static int
 ble_hs_startup_le_set_evmask_tx(void)
 {
     uint8_t buf[BLE_HCI_SET_LE_EVENT_MASK_LEN];
-    int rc;
+    int rc = -1;
+    uint64_t versions[] = {
+        0x00000000000F1A7F,   // Try v5.0 first,
+        0x000000000000027F,   // then v4.2,
+        0x000000000000003F,   // then v4.1,
+        0x000000000000001F,   // and finally v4.0.
+    };
 
     /**
      * Enable the following LE events:
+     *                        ===== BLE 4.0 ====
      *     0x0000000000000001 LE Connection Complete Event
      *     0x0000000000000002 LE Advertising Report Event
      *     0x0000000000000004 LE Connection Update Complete Event
      *     0x0000000000000008 LE Read Remote Used Features Complete Event
      *     0x0000000000000010 LE Long Term Key Request Event
+     *                        ===== BLE 4.1 ====
      *     0x0000000000000020 LE Remote Connection Parameter Request Event
+     *                        ===== BLE 4.2 ====
      *     0x0000000000000040 LE Data Length Change Event
      *     0x0000000000000200 LE Enhanced Connection Complete Event
      *     0x0000000000000400 LE Directed Advertising Report Event
+     *                        ===== BLE 5.0 ====
      *     0x0000000000000800 LE PHY Update Complete Event
      *     0x0000000000001000 LE Extended Advertising Report Event
      *     0x0000000000010000 LE Extended Scan Timeout Event
@@ -177,15 +187,17 @@ ble_hs_startup_le_set_evmask_tx(void)
      *     0x0000000000040000 LE Scan Request Received Event
      *     0x0000000000080000 LE Channel Selection Algorithm Event
      */
-    ble_hs_hci_cmd_build_le_set_event_mask(0x00000000000F1A7F, buf, sizeof buf);
-    rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
-                                                BLE_HCI_OCF_LE_SET_EVENT_MASK),
-                                     buf, sizeof(buf));
-    if (rc != 0) {
-        return rc;
+
+    for (int i = 0; i < sizeof(versions); i++)
+    {
+        ble_hs_hci_cmd_build_le_set_event_mask(versions[i], buf, sizeof buf);
+	rc = ble_hs_hci_cmd_tx_empty_ack(BLE_HCI_OP(BLE_HCI_OGF_LE,
+						    BLE_HCI_OCF_LE_SET_EVENT_MASK),
+					 buf, sizeof(buf));
+	if (rc == 0) return rc;
     }
 
-    return 0;
+    return rc;
 }
 
 static int
diff --git a/nimble/transport/socket/src/ble_hci_socket.c b/nimble/transport/socket/src/ble_hci_socket.c
index 8c12b348..b35c7eae 100755
--- a/nimble/transport/socket/src/ble_hci_socket.c
+++ b/nimble/transport/socket/src/ble_hci_socket.c
@@ -56,6 +56,8 @@
 #define HCI_CHANNEL_RAW		0
 #define HCI_CHANNEL_USER	1
 #define HCIDEVUP	_IOW('H', 201, int)
+#define HCIDEVDOWN	_IOW('H', 202, int)
+#define HCIDEVRESET	_IOW('H', 203, int)
 #define HCIGETDEVLIST	_IOR('H', 210, int)
 
 struct sockaddr_hci {
@@ -488,6 +490,10 @@ ble_hci_sock_config(void)
         goto err;
     }
 
+    // HCI User Channel requires exclusive access to the device.
+    // The device has to be down at the time of binding.
+    ioctl(s, HCIDEVDOWN, shci.hci_dev);
+
     rc = bind(s, (struct sockaddr *)&shci, sizeof(shci));
     if (rc) {
         dprintf(1, "bind() failed %d\n", errno);
@@ -733,14 +739,14 @@ ble_hci_sock_init_task(void)
     pstack = malloc(sizeof(os_stack_t)*BLE_SOCK_STACK_SIZE);
     assert(pstack);
 
-    os_task_init(&ble_sock_task, "hci_sock", ble_hci_sock_ack_handler, NULL,
-                 MYNEWT_VAL(BLE_SOCK_TASK_PRIO), OS_WAIT_FOREVER, pstack,
-                 BLE_SOCK_STACK_SIZE);
-
     os_eventq_init(&ble_hci_sock_state.evq);
     os_callout_stop(&ble_hci_sock_state.timer);
     os_callout_init(&ble_hci_sock_state.timer, &ble_hci_sock_state.evq,
                     ble_hci_sock_rx_ev, NULL);
+
+    os_task_init(&ble_sock_task, "hci_sock", ble_hci_sock_ack_handler, NULL,
+                 MYNEWT_VAL(BLE_SOCK_TASK_PRIO), OS_WAIT_FOREVER, pstack,
+                 BLE_SOCK_STACK_SIZE);
 }
 
 /**
diff --git a/porting/common/include/os/os_arch.h b/porting/common/include/os/os_arch.h
old mode 100755
new mode 100644
diff --git a/porting/common/include/os/os_mempool.h b/porting/common/include/os/os_mempool.h
index 0f5cca96..97ef7345 100644
--- a/porting/common/include/os/os_mempool.h
+++ b/porting/common/include/os/os_mempool.h
@@ -49,7 +49,7 @@ struct os_mempool {
     int mp_num_blocks;          /* The number of memory blocks. */
     int mp_num_free;            /* The number of free blocks left */
     int mp_min_free;            /* The lowest number of free blocks seen */
-    uint32_t mp_membuf_addr;    /* Address of memory buffer used by pool */
+    uintptr_t mp_membuf_addr;   /* Address of memory buffer used by pool */
     STAILQ_ENTRY(os_mempool) mp_list;
     SLIST_HEAD(,os_memblock);   /* Pointer to list of free blocks */
     char *name;                 /* Name for memory block */
diff --git a/porting/common/src/os/os_mempool.c b/porting/common/src/os/os_mempool.c
index 55a8f123..b67fa4e0 100644
--- a/porting/common/src/os/os_mempool.c
+++ b/porting/common/src/os/os_mempool.c
@@ -37,7 +37,7 @@ STAILQ_HEAD(, os_mempool) g_os_mempool_list =
     STAILQ_HEAD_INITIALIZER(g_os_mempool_list);
 
 #if MYNEWT_VAL(OS_MEMPOOL_POISON)
-static uint32_t os_mem_poison = 0xde7ec7ed;
+static uintptr_t os_mem_poison = 0xde7ec7ed;
 
 static void
 os_mempool_poison(void *start, int sz)
@@ -175,12 +175,12 @@ os_mempool_is_sane(const struct os_mempool *mp)
 int
 os_memblock_from(const struct os_mempool *mp, const void *block_addr)
 {
-    uint32_t  true_block_size;
+    uintptr_t true_block_size;
     uintptr_t baddr_ptr;
-    uint32_t  end;
+    uintptr_t end;
 
     _Static_assert(sizeof block_addr == sizeof baddr_ptr,
-                   "Pointer to void must be 32-bits.");
+                   "Pointer to void must be native word size.");
 
     baddr_ptr = (uintptr_t)block_addr;
     true_block_size = OS_MEMPOOL_TRUE_BLOCK_SIZE(mp);
diff --git a/porting/common/src/os/os_msys_init.c b/porting/common/src/os/os_msys_init.c
index a907b413..d949e4c1 100644
--- a/porting/common/src/os/os_msys_init.c
+++ b/porting/common/src/os/os_msys_init.c
@@ -27,7 +27,7 @@
 
 #if MYNEWT_VAL(MSYS_1_BLOCK_COUNT) > 0
 #define SYSINIT_MSYS_1_MEMBLOCK_SIZE                \
-    OS_ALIGN(MYNEWT_VAL(MSYS_1_BLOCK_SIZE), 4)
+    OS_ALIGN(MYNEWT_VAL(MSYS_1_BLOCK_SIZE), OS_ALIGNMENT)
 #define SYSINIT_MSYS_1_MEMPOOL_SIZE                 \
     OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_1_BLOCK_COUNT),  \
                     SYSINIT_MSYS_1_MEMBLOCK_SIZE)
@@ -38,7 +38,7 @@ static struct os_mempool os_msys_init_1_mempool;
 
 #if MYNEWT_VAL(MSYS_2_BLOCK_COUNT) > 0
 #define SYSINIT_MSYS_2_MEMBLOCK_SIZE                \
-    OS_ALIGN(MYNEWT_VAL(MSYS_2_BLOCK_SIZE), 4)
+    OS_ALIGN(MYNEWT_VAL(MSYS_2_BLOCK_SIZE), OS_ALIGNMENT)
 #define SYSINIT_MSYS_2_MEMPOOL_SIZE                 \
     OS_MEMPOOL_SIZE(MYNEWT_VAL(MSYS_2_BLOCK_COUNT),  \
                     SYSINIT_MSYS_2_MEMBLOCK_SIZE)
diff --git a/porting/common/src/sysinit/sysinit.c b/porting/common/src/sysinit/sysinit.c
index 393d1c54..64ac1cd5 100644
--- a/porting/common/src/sysinit/sysinit.c
+++ b/porting/common/src/sysinit/sysinit.c
@@ -17,6 +17,7 @@
  * under the License.
  */
 
+#include <assert.h>
 #include <stdio.h>
 #include <stddef.h>
 #include <limits.h>
@@ -24,6 +25,7 @@
 #include "syscfg/syscfg.h"
 #include "sysinit/sysinit.h"
 
+
 static void
 sysinit_dflt_panic_cb(const char *file, int line, const char *func,
                       const char *expr, const char *msg)
@@ -34,7 +36,11 @@ sysinit_dflt_panic_cb(const char *file, int line, const char *func,
     }
 #endif
 
+#ifdef __linux__
+    __assert_fail(msg, file, line, func);
+#else
     __assert_func(file, line, func, expr);
+#endif
 }
 
 sysinit_panic_fn *sysinit_panic_cb = sysinit_dflt_panic_cb;
diff --git a/porting/linux/Makefile b/porting/linux/Makefile
new file mode 100644
index 00000000..46583bb9
--- /dev/null
+++ b/porting/linux/Makefile
@@ -0,0 +1,278 @@
+PROJECT_NAME     := nimble_linux
+TARGETS          := nimble_linux
+OUTPUT_DIRECTORY := _build
+
+NRF5_SDK_ROOT ?= ./nrf5_sdk
+PROJ_ROOT := ../..
+
+$(OUTPUT_DIRECTORY)/linux.out: \
+  LINKER_SCRIPT  := nimble_linux.ld
+
+# Source files for OSAL
+SRC_FILES += \
+  ./os/os_atomic.c   \
+  ./os/os_callout.c  \
+  ./os/os_eventq.cc  \
+  ./os/os_mutex.c    \
+  ./os/os_sched.c    \
+  ./os/os_sem.c      \
+  ./os/os_task.c     \
+  ./os/os_time.c     \
+  $(PROJ_ROOT)/porting/common/src/mem/mem.c \
+  $(PROJ_ROOT)/porting/common/src/os/endian.c \
+  $(PROJ_ROOT)/porting/common/src/os/os_cputime_pwr2.c \
+  $(PROJ_ROOT)/porting/common/src/os/os_mbuf.c \
+  $(PROJ_ROOT)/porting/common/src/os/os_mempool.c \
+  $(PROJ_ROOT)/porting/common/src/os/os_msys_init.c \
+  $(PROJ_ROOT)/porting/common/src/sysinit/sysinit.c \
+  $(NULL)
+
+#  $(PROJ_ROOT)/porting/common/src/os/os_cputime.c \
+
+# Source files common to all targets
+#SRC_FILES += \
+#  $(NRF5_SDK_ROOT)/components/libraries/log/src/nrf_log_backend_serial.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/log/src/nrf_log_frontend.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/button/app_button.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/util/app_error.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/util/app_error_weak.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/timer/app_timer_freertos.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/util/app_util_platform.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/util/nrf_assert.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/util/sdk_errors.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/croutine.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/event_groups.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/portable/MemMang/heap_1.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/list.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/portable/GCC/nrf52/port.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/portable/CMSIS/nrf52/port_cmsis.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/portable/CMSIS/nrf52/port_cmsis_systick.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/queue.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/tasks.c \
+#  $(NRF5_SDK_ROOT)/external/freertos/source/timers.c \
+#  $(NRF5_SDK_ROOT)/components/boards/boards.c \
+#  $(NRF5_SDK_ROOT)/components/drivers_nrf/clock/nrf_drv_clock.c \
+#  $(NRF5_SDK_ROOT)/components/drivers_nrf/common/nrf_drv_common.c \
+#  $(NRF5_SDK_ROOT)/components/drivers_nrf/gpiote/nrf_drv_gpiote.c \
+#  $(NRF5_SDK_ROOT)/components/drivers_nrf/uart/nrf_drv_uart.c \
+#  $(NRF5_SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_nvic.c \
+#  $(NRF5_SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd/nrf_soc.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/bsp/bsp.c \
+#  $(NRF5_SDK_ROOT)/components/libraries/bsp/bsp_nfc.c \
+#  $(NRF5_SDK_ROOT)/external/segger_rtt/RTT_Syscalls_GCC.c \
+#  $(NRF5_SDK_ROOT)/external/segger_rtt/SEGGER_RTT.c \
+#  $(NRF5_SDK_ROOT)/external/segger_rtt/SEGGER_RTT_printf.c \
+#  $(NRF5_SDK_ROOT)/components/toolchain/gcc/gcc_startup_nrf52.S \
+#  $(NRF5_SDK_ROOT)/components/toolchain/system_nrf52.c \
+
+# Source files for nimble library
+SRC_FILES += \
+  $(PROJ_ROOT)/nimble/src/ble_util.c \
+  $(PROJ_ROOT)/nimble/src/hci_common.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_att_clt.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_att_cmd.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_att.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_att_svr.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_eddystone.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_gap.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_gattc.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_gatts_lcl.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_gatts.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_adv.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_atomic.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_cfg.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_conn.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_dbg.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_hci_cmd.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_hci_evt.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_hci.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_hci_util.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_id.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_log.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_mbuf.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_misc.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_pvcy.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_hs_startup.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_ibeacon.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_l2cap_coc.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_l2cap.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_l2cap_sig_cmd.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_l2cap_sig.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_monitor.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_sm_alg.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_sm_cmd.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_sm_lgcy.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_sm.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_sm_sc.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_store.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_store_util.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_uuid.c \
+  $(PROJ_ROOT)/nimble/host/src/ble_uuid.c \
+  $(PROJ_ROOT)/nimble/host/services/ans/src/ble_svc_ans.c \
+  $(PROJ_ROOT)/nimble/host/services/gap/src/ble_svc_gap.c \
+  $(PROJ_ROOT)/nimble/host/services/gatt/src/ble_svc_gatt.c \
+  $(PROJ_ROOT)/nimble/host/services/ias/src/ble_svc_ias.c \
+  $(PROJ_ROOT)/nimble/host/services/lls/src/ble_svc_lls.c \
+  $(PROJ_ROOT)/nimble/host/services/tps/src/ble_svc_tps.c \
+  $(PROJ_ROOT)/nimble/host/store/ram/src/ble_store_ram.c \
+  $(PROJ_ROOT)/nimble/transport/socket/src/ble_hci_socket.c
+
+#  $(PROJ_ROOT)/nimble/transport/ram/src/ble_hci_ram.c \
+
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_sched.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_xcvr.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_whitelist.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_ctrl.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_hci.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_supp_cmd.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_adv.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_conn.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_resolv.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_conn_hci.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_rand.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_scan.c \
+#  $(PROJ_ROOT)/nimble/controller/src/ble_ll_hci_ev.c \
+#  $(PROJ_ROOT)/nimble/drivers/nrf52/src/ble_hw.c \
+#  $(PROJ_ROOT)/nimble/drivers/nrf52/src/ble_phy.c \
+
+# Source files for common crypto
+SRC_FILES += \
+  $(PROJ_ROOT)/tinycrypt/src/aes_decrypt.c \
+  $(PROJ_ROOT)/tinycrypt/src/aes_encrypt.c \
+  $(PROJ_ROOT)/tinycrypt/src/cmac_mode.c \
+  $(PROJ_ROOT)/tinycrypt/src/ecc.c \
+  $(PROJ_ROOT)/tinycrypt/src/ecc_dh.c \
+  $(PROJ_ROOT)/tinycrypt/src/utils.c \
+
+# Source files for demo app
+SRC_FILES += \
+  ./src/main.c \
+  ./src/ble_task.c \
+  ./src/nimble_port.c \
+  $(NULL)
+
+#  ./src/cmsis_nvic.c \
+#  ./src/hal_timer.c \
+
+
+# Include folders common to all targets
+INC_FOLDERS += \
+  ./ \
+  ./config \
+  $(NRF5_SDK_ROOT)/components \
+  $(NRF5_SDK_ROOT)/components/toolchain/cmsis/include \
+  $(NRF5_SDK_ROOT)/components/libraries/util \
+  $(NRF5_SDK_ROOT)/components/drivers_nrf/uart \
+  $(NRF5_SDK_ROOT)/components/libraries/bsp \
+  $(NRF5_SDK_ROOT)/components/device \
+  $(NRF5_SDK_ROOT)/components/libraries/log \
+  $(NRF5_SDK_ROOT)/components/libraries/button \
+  $(NRF5_SDK_ROOT)/components/libraries/timer \
+  $(NRF5_SDK_ROOT)/external/freertos/portable/CMSIS/nrf52 \
+  $(NRF5_SDK_ROOT)/components/drivers_nrf/gpiote \
+  $(NRF5_SDK_ROOT)/external/segger_rtt \
+  $(NRF5_SDK_ROOT)/components/drivers_nrf/nrf_soc_nosd \
+  $(NRF5_SDK_ROOT)/components/boards \
+  $(NRF5_SDK_ROOT)/components/drivers_nrf/hal \
+  $(NRF5_SDK_ROOT)/components/toolchain/gcc \
+  $(NRF5_SDK_ROOT)/components/toolchain \
+  $(NRF5_SDK_ROOT)/components/drivers_nrf/common \
+  $(NRF5_SDK_ROOT)/components/drivers_nrf/clock \
+  $(NRF5_SDK_ROOT)/external/freertos/portable/GCC/nrf52 \
+  $(NRF5_SDK_ROOT)/components/libraries/log/src \
+  ./include \
+  $(PROJ_ROOT)/porting/common/include \
+  $(PROJ_ROOT)/nimble/include \
+  $(PROJ_ROOT)/nimble/host/include \
+  $(PROJ_ROOT)/nimble/host/mesh/include \
+  $(PROJ_ROOT)/nimble/host/services/ans/include \
+  $(PROJ_ROOT)/nimble/host/services/gap/include \
+  $(PROJ_ROOT)/nimble/host/services/gatt/include \
+  $(PROJ_ROOT)/nimble/host/services/ias/include \
+  $(PROJ_ROOT)/nimble/host/services/lls/include \
+  $(PROJ_ROOT)/nimble/host/services/tps/include \
+  $(PROJ_ROOT)/nimble/host/store/ram/include \
+  $(PROJ_ROOT)/nimble/controller/include \
+  $(PROJ_ROOT)/nimble/transport/ram/include \
+  $(PROJ_ROOT)/nimble/transport/socket/include \
+  $(PROJ_ROOT)/nimble/drivers/nrf52/include \
+  $(PROJ_ROOT)/tinycrypt/include \
+
+#  $(NRF5_SDK_ROOT)/external/freertos/source/include \
+#  $(NRF5_SDK_ROOT)/external/freertos/config \
+
+# Libraries common to all targets
+LIB_FILES += \
+
+# C flags common to all targets
+#CFLAGS += -D_POSIX_C_SOURCE=199309L   # minimum for siginfo
+#CFLAGS += -D_POSIX_C_SOURCE=200112L   # minimum for timedlock
+#CFLAGS += -D_POSIX_C_SOURCE=200809L   # minimum for mutexattr
+#CFLAGS += -D_XOPEN_SOURCE=700         # minimum for mutexattr
+CFLAGS += -D_GNU_SOURCE                # Allows use of full pthread API
+CFLAGS += -DCONFIG_GPIO_AS_PINRESET
+CFLAGS +=  -Wall -Werror -Og -g3
+
+# keep every function in separate section, this allows linker to discard unused ones
+CFLAGS += -ffunction-sections -fdata-sections -fno-strict-aliasing
+CFLAGS += -fno-builtin --short-enums
+
+# C++ flags common to all targets
+CXXFLAGS += \
+
+# Assembler flags common to all targets
+ASMFLAGS += -x assembler-with-cpp
+ASMFLAGS += -DNRF52_PAN_12
+ASMFLAGS += -DNRF52_PAN_15
+ASMFLAGS += -DNRF52_PAN_58
+ASMFLAGS += -DFREERTOS
+ASMFLAGS += -DNRF52_PAN_20
+ASMFLAGS += -DNRF52_PAN_54
+ASMFLAGS += -DNRF52
+ASMFLAGS += -DNRF52_PAN_51
+ASMFLAGS += -DNRF52_PAN_36
+ASMFLAGS += -DCONFIG_GPIO_AS_PINRESET
+ASMFLAGS += -DNRF52_PAN_64
+ASMFLAGS += -DNRF52_PAN_55
+ASMFLAGS += -DBOARD_PCA10040
+ASMFLAGS += -DNRF52_PAN_31
+ASMFLAGS += -DNRF52832
+
+# Linker flags
+LDFLAGS += -lpthread -lrt -lstdc++
+
+#LDFLAGS += -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
+#LDFLAGS += -mthumb -mabi=aapcs -L $(TEMPLATE_PATH) -T$(LINKER_SCRIPT)
+#LDFLAGS += -mcpu=cortex-m4
+#LDFLAGS += -mfloat-abi=hard -mfpu=fpv4-sp-d16
+# let linker to dump unused sections
+#LDFLAGS += -Wl,--gc-sections
+# use newlib in nano version
+#LDFLAGS += --specs=nano.specs -lc -lnosys
+
+.PHONY: $(TARGETS) default all clean help flash
+
+# Default target - first one defined
+default: $(TARGETS)
+
+# Print all targets that can be built
+help:
+	@echo following targets are available:
+	@echo 	nrf52832_xxaa
+
+TEMPLATE_PATH := $(NRF5_SDK_ROOT)/components/toolchain/gcc
+
+include Makefile.common
+
+$(foreach target, $(TARGETS), $(call define_target, $(target)))
+
+# Flash the program
+flash: $(OUTPUT_DIRECTORY)/nrf52832_xxaa.hex
+	@echo Flashing: $<
+	nrfjprog --program $< -f nrf52 --sectorerase
+	nrfjprog --reset -f nrf52
+
+erase:
+	nrfjprog --eraseall -f nrf52
diff --git a/porting/linux/Makefile.common b/porting/linux/Makefile.common
new file mode 100644
index 00000000..70708349
--- /dev/null
+++ b/porting/linux/Makefile.common
@@ -0,0 +1,177 @@
+# Copyright (c) 2016 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.
+
+GNU_PREFIX       ?=
+GNU_INSTALL_ROOT ?= /usr
+
+PLATFORM_SUFFIX := $(if $(filter Windows%,$(OS)),windows,posix)
+TOOLCHAIN_CONFIG_FILE := $(TEMPLATE_PATH)/Makefile.$(PLATFORM_SUFFIX)
+#include $(TOOLCHAIN_CONFIG_FILE)
+
+# Toolchain commands
+CC      := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)gcc"
+CXX     := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)c++"
+AS      := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)as"
+AR      := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)ar" -r
+LD      := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)ld"
+NM      := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)nm"
+OBJDUMP := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)objdump"
+OBJCOPY := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)objcopy"
+SIZE    := "$(GNU_INSTALL_ROOT)/bin/$(GNU_PREFIX)size"
+$(if $(shell $(CC) --version),,$(info Cannot find: $(CC).) \
+  $(info Please set values in: "$(abspath $(TOOLCHAIN_CONFIG_FILE))") \
+  $(info according to the actual configuration of your system.) \
+  $(error Cannot continue))
+
+# Use ccache on linux if available
+CCACHE := $(if $(filter Windows%,$(OS)),, \
+               $(if $(wildcard /usr/bin/ccache),ccache))
+CC     := $(CCACHE) $(CC)
+
+MK := mkdir
+RM := rm -rf
+
+# echo suspend
+ifeq ($(VERBOSE),1)
+  NO_ECHO :=
+else
+  NO_ECHO := @
+endif
+
+# $1 type of item
+# $2 path to check
+define ensure_exists
+$(if $(wildcard $(2)),, $(warning Cannot find $(1): $(2)))
+endef
+
+# $1 object file
+# $2 source file
+define bind_obj_with_src
+$(eval $(1) := $(2))
+endef
+
+# $1 object file
+# $2 target name
+define bind_obj_with_target
+$(eval $(1)T := $(2))
+endef
+
+# $1 target name
+# $2 source file name
+# Note: this additional .o for .s-files is a workaround for issues with make 4.1
+#       from MinGW (it does nothing to remake .s.o files when a rule for .S.o
+#       files is defined as well).
+define get_object_file_name
+$(OUTPUT_DIRECTORY)/$(strip $(1))_$(patsubst %.s,%.s.o,$(notdir $(2))).o
+endef
+
+# $1 target name
+# $2 list of source files
+define get_object_files
+$(foreach src_file, $(2), \
+  $(call ensure_exists,source file, $(src_file)) \
+  $(eval obj_file := $(call get_object_file_name, $(1), $(src_file))) \
+  $(eval DEPENDENCIES += $(obj_file:.o=.d)) \
+  $(call bind_obj_with_src, $(obj_file), $(src_file)) \
+  $(call bind_obj_with_target, $(obj_file), $(1)) \
+  $(eval $(obj_file): Makefile) \
+  $(obj_file))
+endef
+
+# $1 variable name
+# $2 target name
+define target_specific
+$($(addsuffix _$(strip $(2)), $(1)))
+endef
+
+# $1 target name
+# $2 link target name
+define prepare_build
+$(eval DEPENDENCIES :=) \
+$(eval $(2): \
+  $(call get_object_files, $(1), $(SRC_FILES) \
+    $(call target_specific, SRC_FILES, $(1)))) \
+$(eval -include $(DEPENDENCIES)) \
+$(eval INC_PATHS_$(strip $(1)) := \
+  $(foreach folder, $(INC_FOLDERS) $(call target_specific, INC_FOLDERS, $(1)), \
+    $(call ensure_exists,include folder, $(folder)) \
+    -I"$(folder)"))
+endef
+
+INC_PATHS = $(call target_specific, INC_PATHS, $($@T))
+
+# $1 target name
+define define_target
+$(eval OUTPUT_FILE := $(OUTPUT_DIRECTORY)/$(strip $(1))) \
+$(eval $(1): $(OUTPUT_FILE).out $(OUTPUT_FILE).hex $(OUTPUT_FILE).bin) \
+$(call prepare_build, $(1), $(OUTPUT_FILE).out)
+endef
+
+# $1 target name
+# $2 library file name
+define define_library
+$(eval $(1) := $(2)) \
+$(call prepare_build, $(1), $(1))
+endef
+
+.PHONY: $(TARGETS) default all clean help flash
+
+all: $(TARGETS)
+
+clean:
+	$(RM) $(OUTPUT_DIRECTORY)
+
+# Create build directories
+$(OUTPUT_DIRECTORY):
+	$(MK) $@
+
+# Create objects from C source files
+$(OUTPUT_DIRECTORY)/%.c.o: | $(OUTPUT_DIRECTORY)
+	@echo Compiling file: $(notdir $($@))
+	$(NO_ECHO)$(CC) -MP -MD -std=c99 $(CFLAGS) $(INC_PATHS) -c -o $@ "$($@)"
+
+# Create objects from C++ source files
+$(OUTPUT_DIRECTORY)/%.cc.o: | $(OUTPUT_DIRECTORY)
+	@echo Compiling file: $(notdir $($@))
+	$(NO_ECHO)$(CXX) -MP -MD $(CFLAGS) $(CXXFLAGS) $(INC_PATHS) -c -o $@ "$($@)"
+
+# Create objects from C++ source files
+$(OUTPUT_DIRECTORY)/%.cpp.o: | $(OUTPUT_DIRECTORY)
+	@echo Compiling file: $(notdir $($@))
+	$(NO_ECHO)$(CXX) -MP -MD $(CFLAGS) $(CXXFLAGS) $(INC_PATHS) -c -o $@ "$($@)"
+
+# Create objects from assembly files
+$(OUTPUT_DIRECTORY)/%.S.o \
+$(OUTPUT_DIRECTORY)/%.s.o.o: | $(OUTPUT_DIRECTORY)
+	@echo Assembling file: $(notdir $($@))
+	$(NO_ECHO)$(CC) -MP -MD -std=c99 $(ASMFLAGS) $(INC_PATHS) -c -o $@ "$($@)"
+
+export FILE_LIST
+DUMP_FILE_LIST := \
+  "$(MAKE)" -s --no-print-directory -f $(TEMPLATE_PATH)/file_list.mk
+# Link object files
+%.out:
+	+ $(eval FILE_LIST := $^ $(LIB_FILES))
+	+ $(NO_ECHO)$(DUMP_FILE_LIST) > $(@:.out=.in)
+	+ @echo Linking target: $@
+	+ $(NO_ECHO)$(CC) -Wl,-Map=$(@:.out=.map) @$(@:.out=.in) $(LDFLAGS) -lm -o $@
+	+ -@echo ''
+	+ $(NO_ECHO)$(SIZE) $@
+	+ -@echo ''
+
+# Create binary .bin file from the .out file
+%.bin: %.out
+	@echo Preparing: $@
+	$(NO_ECHO)$(OBJCOPY) -O binary $< $@
+
+# Create binary .hex file from the .out file
+%.hex: %.out
+	@echo Preparing: $@
+	$(NO_ECHO)$(OBJCOPY) -O ihex $< $@
diff --git a/porting/linux/config/sdk_config.h b/porting/linux/config/sdk_config.h
new file mode 100644
index 00000000..ecf097f5
--- /dev/null
+++ b/porting/linux/config/sdk_config.h
@@ -0,0 +1,698 @@
+
+
+#ifndef SDK_CONFIG_H
+#define SDK_CONFIG_H
+// <<< Use Configuration Wizard in Context Menu >>>\n
+#ifdef USE_APP_CONFIG
+#include "app_config.h"
+#endif
+// <h> nRF_Drivers
+
+//==========================================================
+// <e> CLOCK_ENABLED - nrf_drv_clock - CLOCK peripheral driver
+//==========================================================
+#ifndef CLOCK_ENABLED
+#define CLOCK_ENABLED 1
+#endif
+#if  CLOCK_ENABLED
+// <o> CLOCK_CONFIG_XTAL_FREQ  - HF XTAL Frequency
+
+// <0=> Default (64 MHz)
+
+#ifndef CLOCK_CONFIG_XTAL_FREQ
+#define CLOCK_CONFIG_XTAL_FREQ 0
+#endif
+
+// <o> CLOCK_CONFIG_LF_SRC  - LF Clock Source
+
+// <0=> RC
+// <1=> XTAL
+// <2=> Synth
+
+#ifndef CLOCK_CONFIG_LF_SRC
+#define CLOCK_CONFIG_LF_SRC 1
+#endif
+
+// <o> CLOCK_CONFIG_IRQ_PRIORITY  - Interrupt priority
+
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef CLOCK_CONFIG_IRQ_PRIORITY
+#define CLOCK_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> CLOCK_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef CLOCK_CONFIG_LOG_ENABLED
+#define CLOCK_CONFIG_LOG_ENABLED 0
+#endif
+#if  CLOCK_CONFIG_LOG_ENABLED
+// <o> CLOCK_CONFIG_LOG_LEVEL  - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef CLOCK_CONFIG_LOG_LEVEL
+#define CLOCK_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> CLOCK_CONFIG_INFO_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef CLOCK_CONFIG_INFO_COLOR
+#define CLOCK_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> CLOCK_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef CLOCK_CONFIG_DEBUG_COLOR
+#define CLOCK_CONFIG_DEBUG_COLOR 0
+#endif
+
+#endif //CLOCK_CONFIG_LOG_ENABLED
+// </e>
+
+#endif //CLOCK_ENABLED
+// </e>
+
+// <e> GPIOTE_ENABLED - nrf_drv_gpiote - GPIOTE peripheral driver
+//==========================================================
+#ifndef GPIOTE_ENABLED
+#define GPIOTE_ENABLED 1
+#endif
+#if  GPIOTE_ENABLED
+// <o> GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS - Number of lower power input pins
+#ifndef GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS
+#define GPIOTE_CONFIG_NUM_OF_LOW_POWER_EVENTS 4
+#endif
+
+// <o> GPIOTE_CONFIG_IRQ_PRIORITY  - Interrupt priority
+
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef GPIOTE_CONFIG_IRQ_PRIORITY
+#define GPIOTE_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <e> GPIOTE_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef GPIOTE_CONFIG_LOG_ENABLED
+#define GPIOTE_CONFIG_LOG_ENABLED 0
+#endif
+#if  GPIOTE_CONFIG_LOG_ENABLED
+// <o> GPIOTE_CONFIG_LOG_LEVEL  - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef GPIOTE_CONFIG_LOG_LEVEL
+#define GPIOTE_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> GPIOTE_CONFIG_INFO_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef GPIOTE_CONFIG_INFO_COLOR
+#define GPIOTE_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> GPIOTE_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef GPIOTE_CONFIG_DEBUG_COLOR
+#define GPIOTE_CONFIG_DEBUG_COLOR 0
+#endif
+
+#endif //GPIOTE_CONFIG_LOG_ENABLED
+// </e>
+
+#endif //GPIOTE_ENABLED
+// </e>
+
+// <e> PERIPHERAL_RESOURCE_SHARING_ENABLED - nrf_drv_common - Peripheral drivers common module
+//==========================================================
+#ifndef PERIPHERAL_RESOURCE_SHARING_ENABLED
+#define PERIPHERAL_RESOURCE_SHARING_ENABLED 0
+#endif
+#if  PERIPHERAL_RESOURCE_SHARING_ENABLED
+// <e> COMMON_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef COMMON_CONFIG_LOG_ENABLED
+#define COMMON_CONFIG_LOG_ENABLED 0
+#endif
+#if  COMMON_CONFIG_LOG_ENABLED
+// <o> COMMON_CONFIG_LOG_LEVEL  - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef COMMON_CONFIG_LOG_LEVEL
+#define COMMON_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> COMMON_CONFIG_INFO_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef COMMON_CONFIG_INFO_COLOR
+#define COMMON_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> COMMON_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef COMMON_CONFIG_DEBUG_COLOR
+#define COMMON_CONFIG_DEBUG_COLOR 0
+#endif
+
+#endif //COMMON_CONFIG_LOG_ENABLED
+// </e>
+
+#endif //PERIPHERAL_RESOURCE_SHARING_ENABLED
+// </e>
+
+// <e> UART_ENABLED - nrf_drv_uart - UART/UARTE peripheral driver
+//==========================================================
+#ifndef UART_ENABLED
+#define UART_ENABLED 1
+#endif
+#if  UART_ENABLED
+// <o> UART_DEFAULT_CONFIG_HWFC  - Hardware Flow Control
+
+// <0=> Disabled
+// <1=> Enabled
+
+#ifndef UART_DEFAULT_CONFIG_HWFC
+#define UART_DEFAULT_CONFIG_HWFC 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_PARITY  - Parity
+
+// <0=> Excluded
+// <14=> Included
+
+#ifndef UART_DEFAULT_CONFIG_PARITY
+#define UART_DEFAULT_CONFIG_PARITY 0
+#endif
+
+// <o> UART_DEFAULT_CONFIG_BAUDRATE  - Default Baudrate
+
+// <323584=> 1200 baud
+// <643072=> 2400 baud
+// <1290240=> 4800 baud
+// <2576384=> 9600 baud
+// <3862528=> 14400 baud
+// <5152768=> 19200 baud
+// <7716864=> 28800 baud
+// <10289152=> 38400 baud
+// <15400960=> 57600 baud
+// <20615168=> 76800 baud
+// <30801920=> 115200 baud
+// <61865984=> 230400 baud
+// <67108864=> 250000 baud
+// <121634816=> 460800 baud
+// <251658240=> 921600 baud
+// <268435456=> 57600 baud
+
+#ifndef UART_DEFAULT_CONFIG_BAUDRATE
+#define UART_DEFAULT_CONFIG_BAUDRATE 30801920
+#endif
+
+// <o> UART_DEFAULT_CONFIG_IRQ_PRIORITY  - Interrupt priority
+
+
+// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
+// <0=> 0 (highest)
+// <1=> 1
+// <2=> 2
+// <3=> 3
+// <4=> 4
+// <5=> 5
+// <6=> 6
+// <7=> 7
+
+#ifndef UART_DEFAULT_CONFIG_IRQ_PRIORITY
+#define UART_DEFAULT_CONFIG_IRQ_PRIORITY 7
+#endif
+
+// <q> UART_EASY_DMA_SUPPORT  - Driver supporting EasyDMA
+
+
+#ifndef UART_EASY_DMA_SUPPORT
+#define UART_EASY_DMA_SUPPORT 1
+#endif
+
+// <q> UART_LEGACY_SUPPORT  - Driver supporting Legacy mode
+
+
+#ifndef UART_LEGACY_SUPPORT
+#define UART_LEGACY_SUPPORT 1
+#endif
+
+// <e> UART0_ENABLED - Enable UART0 instance
+//==========================================================
+#ifndef UART0_ENABLED
+#define UART0_ENABLED 1
+#endif
+#if  UART0_ENABLED
+// <q> UART0_CONFIG_USE_EASY_DMA  - Default setting for using EasyDMA
+
+
+#ifndef UART0_CONFIG_USE_EASY_DMA
+#define UART0_CONFIG_USE_EASY_DMA 1
+#endif
+
+#endif //UART0_ENABLED
+// </e>
+
+// <e> UART_CONFIG_LOG_ENABLED - Enables logging in the module.
+//==========================================================
+#ifndef UART_CONFIG_LOG_ENABLED
+#define UART_CONFIG_LOG_ENABLED 0
+#endif
+#if  UART_CONFIG_LOG_ENABLED
+// <o> UART_CONFIG_LOG_LEVEL  - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef UART_CONFIG_LOG_LEVEL
+#define UART_CONFIG_LOG_LEVEL 3
+#endif
+
+// <o> UART_CONFIG_INFO_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef UART_CONFIG_INFO_COLOR
+#define UART_CONFIG_INFO_COLOR 0
+#endif
+
+// <o> UART_CONFIG_DEBUG_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef UART_CONFIG_DEBUG_COLOR
+#define UART_CONFIG_DEBUG_COLOR 0
+#endif
+
+#endif //UART_CONFIG_LOG_ENABLED
+// </e>
+
+#endif //UART_ENABLED
+// </e>
+
+// </h>
+//==========================================================
+
+// <h> nRF_Libraries
+
+//==========================================================
+// <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
+//==========================================================
+#ifndef APP_TIMER_ENABLED
+#define APP_TIMER_ENABLED 1
+#endif
+#if  APP_TIMER_ENABLED
+// <q> APP_TIMER_WITH_PROFILER  - Enable app_timer profiling
+
+
+#ifndef APP_TIMER_WITH_PROFILER
+#define APP_TIMER_WITH_PROFILER 0
+#endif
+
+// <q> APP_TIMER_KEEPS_RTC_ACTIVE  - Enable RTC always on
+
+
+// <i> If option is enabled RTC is kept running even if there is no active timers.
+// <i> This option can be used when app_timer is used for timestamping.
+
+#ifndef APP_TIMER_KEEPS_RTC_ACTIVE
+#define APP_TIMER_KEEPS_RTC_ACTIVE 0
+#endif
+
+#endif //APP_TIMER_ENABLED
+// </e>
+
+// <q> BUTTON_ENABLED  - app_button - buttons handling module
+
+
+#ifndef BUTTON_ENABLED
+#define BUTTON_ENABLED 1
+#endif
+
+// </h>
+//==========================================================
+
+// <h> nRF_Log
+
+//==========================================================
+// <e> NRF_LOG_ENABLED - nrf_log - Logging
+//==========================================================
+#ifndef NRF_LOG_ENABLED
+#define NRF_LOG_ENABLED 0
+#endif
+#if  NRF_LOG_ENABLED
+// <e> NRF_LOG_USES_COLORS - If enabled then ANSI escape code for colors is prefixed to every string
+//==========================================================
+#ifndef NRF_LOG_USES_COLORS
+#define NRF_LOG_USES_COLORS 0
+#endif
+#if  NRF_LOG_USES_COLORS
+// <o> NRF_LOG_COLOR_DEFAULT  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRF_LOG_COLOR_DEFAULT
+#define NRF_LOG_COLOR_DEFAULT 0
+#endif
+
+// <o> NRF_LOG_ERROR_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRF_LOG_ERROR_COLOR
+#define NRF_LOG_ERROR_COLOR 0
+#endif
+
+// <o> NRF_LOG_WARNING_COLOR  - ANSI escape code prefix.
+
+// <0=> Default
+// <1=> Black
+// <2=> Red
+// <3=> Green
+// <4=> Yellow
+// <5=> Blue
+// <6=> Magenta
+// <7=> Cyan
+// <8=> White
+
+#ifndef NRF_LOG_WARNING_COLOR
+#define NRF_LOG_WARNING_COLOR 0
+#endif
+
+#endif //NRF_LOG_USES_COLORS
+// </e>
+
+// <o> NRF_LOG_DEFAULT_LEVEL  - Default Severity level
+
+// <0=> Off
+// <1=> Error
+// <2=> Warning
+// <3=> Info
+// <4=> Debug
+
+#ifndef NRF_LOG_DEFAULT_LEVEL
+#define NRF_LOG_DEFAULT_LEVEL 3
+#endif
+
+// <e> NRF_LOG_DEFERRED - Enable deffered logger.
+
+// <i> Log data is buffered and can be processed in idle.
+//==========================================================
+#ifndef NRF_LOG_DEFERRED
+#define NRF_LOG_DEFERRED 1
+#endif
+#if  NRF_LOG_DEFERRED
+// <o> NRF_LOG_DEFERRED_BUFSIZE - Size of the buffer for logs in words.
+// <i> Must be power of 2
+
+#ifndef NRF_LOG_DEFERRED_BUFSIZE
+#define NRF_LOG_DEFERRED_BUFSIZE 256
+#endif
+
+#endif //NRF_LOG_DEFERRED
+// </e>
+
+// <q> NRF_LOG_USES_TIMESTAMP  - Enable timestamping
+
+
+// <i> Function for getting the timestamp is provided by the user
+
+#ifndef NRF_LOG_USES_TIMESTAMP
+#define NRF_LOG_USES_TIMESTAMP 0
+#endif
+
+#endif //NRF_LOG_ENABLED
+// </e>
+
+// <h> nrf_log_backend - Logging sink
+
+//==========================================================
+// <o> NRF_LOG_BACKEND_MAX_STRING_LENGTH - Buffer for storing single output string
+// <i> Logger backend RAM usage is determined by this value.
+
+#ifndef NRF_LOG_BACKEND_MAX_STRING_LENGTH
+#define NRF_LOG_BACKEND_MAX_STRING_LENGTH 256
+#endif
+
+// <o> NRF_LOG_TIMESTAMP_DIGITS - Number of digits for timestamp
+// <i> If higher resolution timestamp source is used it might be needed to increase that
+
+#ifndef NRF_LOG_TIMESTAMP_DIGITS
+#define NRF_LOG_TIMESTAMP_DIGITS 8
+#endif
+
+// <e> NRF_LOG_BACKEND_SERIAL_USES_UART - If enabled data is printed over UART
+//==========================================================
+#ifndef NRF_LOG_BACKEND_SERIAL_USES_UART
+#define NRF_LOG_BACKEND_SERIAL_USES_UART 1
+#endif
+#if  NRF_LOG_BACKEND_SERIAL_USES_UART
+// <o> NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE  - Default Baudrate
+
+// <323584=> 1200 baud
+// <643072=> 2400 baud
+// <1290240=> 4800 baud
+// <2576384=> 9600 baud
+// <3862528=> 14400 baud
+// <5152768=> 19200 baud
+// <7716864=> 28800 baud
+// <10289152=> 38400 baud
+// <15400960=> 57600 baud
+// <20615168=> 76800 baud
+// <30801920=> 115200 baud
+// <61865984=> 230400 baud
+// <67108864=> 250000 baud
+// <121634816=> 460800 baud
+// <251658240=> 921600 baud
+// <268435456=> 57600 baud
+
+#ifndef NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE
+#define NRF_LOG_BACKEND_SERIAL_UART_BAUDRATE 30801920
+#endif
+
+// <o> NRF_LOG_BACKEND_SERIAL_UART_TX_PIN - UART TX pin
+#ifndef NRF_LOG_BACKEND_SERIAL_UART_TX_PIN
+#define NRF_LOG_BACKEND_SERIAL_UART_TX_PIN 6
+#endif
+
+// <o> NRF_LOG_BACKEND_SERIAL_UART_RX_PIN - UART RX pin
+#ifndef NRF_LOG_BACKEND_SERIAL_UART_RX_PIN
+#define NRF_LOG_BACKEND_SERIAL_UART_RX_PIN 8
+#endif
+
+// <o> NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN - UART RTS pin
+#ifndef NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN
+#define NRF_LOG_BACKEND_SERIAL_UART_RTS_PIN 5
+#endif
+
+// <o> NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN - UART CTS pin
+#ifndef NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN
+#define NRF_LOG_BACKEND_SERIAL_UART_CTS_PIN 7
+#endif
+
+// <o> NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL  - Hardware Flow Control
+
+// <0=> Disabled
+// <1=> Enabled
+
+#ifndef NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL
+#define NRF_LOG_BACKEND_SERIAL_UART_FLOW_CONTROL 0
+#endif
+
+// <o> NRF_LOG_BACKEND_UART_INSTANCE  - UART instance used
+
+// <0=> 0
+
+#ifndef NRF_LOG_BACKEND_UART_INSTANCE
+#define NRF_LOG_BACKEND_UART_INSTANCE 0
+#endif
+
+#endif //NRF_LOG_BACKEND_SERIAL_USES_UART
+// </e>
+
+// <e> NRF_LOG_BACKEND_SERIAL_USES_RTT - If enabled data is printed using RTT
+//==========================================================
+#ifndef NRF_LOG_BACKEND_SERIAL_USES_RTT
+#define NRF_LOG_BACKEND_SERIAL_USES_RTT 0
+#endif
+#if  NRF_LOG_BACKEND_SERIAL_USES_RTT
+// <o> NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE - RTT output buffer size.
+// <i> Should be equal or bigger than \ref NRF_LOG_BACKEND_MAX_STRING_LENGTH.
+// <i> This value is used in Segger RTT configuration to set the buffer size
+// <i> if it is bigger than default RTT buffer size.
+
+#ifndef NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE
+#define NRF_LOG_BACKEND_RTT_OUTPUT_BUFFER_SIZE 512
+#endif
+
+#endif //NRF_LOG_BACKEND_SERIAL_USES_RTT
+// </e>
+
+// </h>
+//==========================================================
+
+// </h>
+//==========================================================
+
+// <h> nRF_Segger_RTT
+
+//==========================================================
+// <h> segger_rtt - SEGGER RTT
+
+//==========================================================
+// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_UP - Size of upstream buffer.
+#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_UP
+#define SEGGER_RTT_CONFIG_BUFFER_SIZE_UP 64
+#endif
+
+// <o> SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS - Size of upstream buffer.
+#ifndef SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS
+#define SEGGER_RTT_CONFIG_MAX_NUM_UP_BUFFERS 2
+#endif
+
+// <o> SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN - Size of upstream buffer.
+#ifndef SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN
+#define SEGGER_RTT_CONFIG_BUFFER_SIZE_DOWN 16
+#endif
+
+// <o> SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS - Size of upstream buffer.
+#ifndef SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS
+#define SEGGER_RTT_CONFIG_MAX_NUM_DOWN_BUFFERS 2
+#endif
+
+// </h>
+//==========================================================
+
+// </h>
+//==========================================================
+
+// <<< end of configuration section >>>
+#endif //SDK_CONFIG_H
diff --git a/porting/linux/include/syscfg/syscfg.h b/porting/linux/include/syscfg/syscfg.h
new file mode 100644
index 00000000..b0238e89
--- /dev/null
+++ b/porting/linux/include/syscfg/syscfg.h
@@ -0,0 +1,988 @@
+/**
+ * This file was generated by Apache Newt version: 1.2.0-dev
+ */
+
+#ifndef H_MYNEWT_SYSCFG_
+#define H_MYNEWT_SYSCFG_
+
+/**
+ * This macro exists to ensure code includes this header when needed.  If code
+ * checks the existence of a setting directly via ifdef without including this
+ * header, the setting macro will silently evaluate to 0.  In contrast, an
+ * attempt to use these macros without including this header will result in a
+ * compiler error.
+ */
+#define MYNEWT_VAL(x)                           MYNEWT_VAL_ ## x
+
+
+
+/*** compiler/arm-none-eabi-m4 */
+#ifndef MYNEWT_VAL_HARDFLOAT
+#define MYNEWT_VAL_HARDFLOAT (0)
+#endif
+
+/*** hw/bsp/nrf52840pdk */
+#ifndef MYNEWT_VAL_BSP_NRF52840
+#define MYNEWT_VAL_BSP_NRF52840 (1)
+#endif
+
+#ifndef MYNEWT_VAL_TIMER_0
+#define MYNEWT_VAL_TIMER_0 (1)
+#endif
+
+#ifndef MYNEWT_VAL_TIMER_1
+#define MYNEWT_VAL_TIMER_1 (0)
+#endif
+
+#ifndef MYNEWT_VAL_TIMER_2
+#define MYNEWT_VAL_TIMER_2 (0)
+#endif
+
+#ifndef MYNEWT_VAL_TIMER_3
+#define MYNEWT_VAL_TIMER_3 (0)
+#endif
+
+#ifndef MYNEWT_VAL_TIMER_4
+#define MYNEWT_VAL_TIMER_4 (0)
+#endif
+
+#ifndef MYNEWT_VAL_TIMER_5
+#define MYNEWT_VAL_TIMER_5 (1)
+#endif
+
+#ifndef MYNEWT_VAL_UART_0
+#define MYNEWT_VAL_UART_0 (1)
+#endif
+
+#ifndef MYNEWT_VAL_UART_0_PIN_CTS
+#define MYNEWT_VAL_UART_0_PIN_CTS (7)
+#endif
+
+#ifndef MYNEWT_VAL_UART_0_PIN_RTS
+#define MYNEWT_VAL_UART_0_PIN_RTS (5)
+#endif
+
+#ifndef MYNEWT_VAL_UART_0_PIN_RX
+#define MYNEWT_VAL_UART_0_PIN_RX (8)
+#endif
+
+#ifndef MYNEWT_VAL_UART_0_PIN_TX
+#define MYNEWT_VAL_UART_0_PIN_TX (6)
+#endif
+
+#ifndef MYNEWT_VAL_UART_1
+#define MYNEWT_VAL_UART_1 (0)
+#endif
+
+#ifndef MYNEWT_VAL_UART_1_PIN_RX
+#define MYNEWT_VAL_UART_1_PIN_RX (-1)
+#endif
+
+#ifndef MYNEWT_VAL_UART_1_PIN_TX
+#define MYNEWT_VAL_UART_1_PIN_TX (-1)
+#endif
+
+/*** hw/drivers/nimble/nrf52 */
+#ifndef MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN
+#define MYNEWT_VAL_BLE_PHY_CODED_RX_IFS_EXTRA_MARGIN (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN
+#define MYNEWT_VAL_BLE_PHY_DBG_TIME_ADDRESS_END_PIN (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN
+#define MYNEWT_VAL_BLE_PHY_DBG_TIME_TXRXEN_READY_PIN (-1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN
+#define MYNEWT_VAL_BLE_PHY_DBG_TIME_WFR_PIN (-1)
+#endif
+
+/*** hw/mcu/nordic/nrf52xxx */
+#ifndef MYNEWT_VAL_I2C_0
+#define MYNEWT_VAL_I2C_0 (0)
+#endif
+
+#ifndef MYNEWT_VAL_I2C_1
+#define MYNEWT_VAL_I2C_1 (0)
+#endif
+
+/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */
+#ifndef MYNEWT_VAL_MCU_DCDC_ENABLED
+#define MYNEWT_VAL_MCU_DCDC_ENABLED (1)
+#endif
+
+#ifndef MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE
+#define MYNEWT_VAL_MCU_FLASH_MIN_WRITE_SIZE (1)
+#endif
+
+#ifndef MYNEWT_VAL_SPI_0_MASTER
+#define MYNEWT_VAL_SPI_0_MASTER (0)
+#endif
+
+#ifndef MYNEWT_VAL_SPI_0_SLAVE
+#define MYNEWT_VAL_SPI_0_SLAVE (0)
+#endif
+
+#ifndef MYNEWT_VAL_SPI_1_MASTER
+#define MYNEWT_VAL_SPI_1_MASTER (0)
+#endif
+
+#ifndef MYNEWT_VAL_SPI_1_SLAVE
+#define MYNEWT_VAL_SPI_1_SLAVE (0)
+#endif
+
+/* Overridden by hw/bsp/nrf52840pdk (defined by hw/mcu/nordic/nrf52xxx) */
+#ifndef MYNEWT_VAL_XTAL_32768
+#define MYNEWT_VAL_XTAL_32768 (1)
+#endif
+
+#ifndef MYNEWT_VAL_XTAL_32768_SYNTH
+#define MYNEWT_VAL_XTAL_32768_SYNTH (0)
+#endif
+
+#ifndef MYNEWT_VAL_XTAL_RC
+#define MYNEWT_VAL_XTAL_RC (0)
+#endif
+
+/*** kernel/os */
+#ifndef MYNEWT_VAL_FLOAT_USER
+#define MYNEWT_VAL_FLOAT_USER (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_1_BLOCK_COUNT
+#define MYNEWT_VAL_MSYS_1_BLOCK_COUNT (12)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_1_BLOCK_SIZE
+#define MYNEWT_VAL_MSYS_1_BLOCK_SIZE (292)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_2_BLOCK_COUNT
+#define MYNEWT_VAL_MSYS_2_BLOCK_COUNT (0)
+#endif
+
+#ifndef MYNEWT_VAL_MSYS_2_BLOCK_SIZE
+#define MYNEWT_VAL_MSYS_2_BLOCK_SIZE (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CLI
+#define MYNEWT_VAL_OS_CLI (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_COREDUMP
+#define MYNEWT_VAL_OS_COREDUMP (0)
+#endif
+
+/* Overridden by hw/bsp/nrf52840pdk (defined by kernel/os) */
+#ifndef MYNEWT_VAL_OS_CPUTIME_FREQ
+#define MYNEWT_VAL_OS_CPUTIME_FREQ (32768)
+#endif
+
+/* Overridden by hw/bsp/nrf52840pdk (defined by kernel/os) */
+#ifndef MYNEWT_VAL_OS_CPUTIME_TIMER_NUM
+#define MYNEWT_VAL_OS_CPUTIME_TIMER_NUM (5)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_CHECK
+#define MYNEWT_VAL_OS_CTX_SW_STACK_CHECK (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_CTX_SW_STACK_GUARD
+#define MYNEWT_VAL_OS_CTX_SW_STACK_GUARD (4)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MAIN_STACK_SIZE
+#define MYNEWT_VAL_OS_MAIN_STACK_SIZE (1024)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MAIN_TASK_PRIO
+#define MYNEWT_VAL_OS_MAIN_TASK_PRIO (127)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MEMPOOL_CHECK
+#define MYNEWT_VAL_OS_MEMPOOL_CHECK (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_MEMPOOL_POISON
+#define MYNEWT_VAL_OS_MEMPOOL_POISON (0)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SCHEDULING
+#define MYNEWT_VAL_OS_SCHEDULING (1)
+#endif
+
+#ifndef MYNEWT_VAL_OS_SYSVIEW
+#define MYNEWT_VAL_OS_SYSVIEW (0)
+#endif
+
+#ifndef MYNEWT_VAL_SANITY_INTERVAL
+#define MYNEWT_VAL_SANITY_INTERVAL (15000)
+#endif
+
+#ifndef MYNEWT_VAL_WATCHDOG_INTERVAL
+#define MYNEWT_VAL_WATCHDOG_INTERVAL (30000)
+#endif
+
+/*** libc/baselibc */
+#ifndef MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE
+#define MYNEWT_VAL_BASELIBC_ASSERT_FILE_LINE (0)
+#endif
+
+#ifndef MYNEWT_VAL_BASELIBC_PRESENT
+#define MYNEWT_VAL_BASELIBC_PRESENT (1)
+#endif
+
+/*** net/nimble */
+#ifndef MYNEWT_VAL_BLE_EXT_ADV
+#define MYNEWT_VAL_BLE_EXT_ADV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE
+#define MYNEWT_VAL_BLE_EXT_ADV_MAX_SIZE (31)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MAX_CONNECTIONS
+#define MYNEWT_VAL_BLE_MAX_CONNECTIONS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES
+#define MYNEWT_VAL_BLE_MULTI_ADV_INSTANCES (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_BROADCASTER
+#define MYNEWT_VAL_BLE_ROLE_BROADCASTER (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_CENTRAL
+#define MYNEWT_VAL_BLE_ROLE_CENTRAL (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_OBSERVER
+#define MYNEWT_VAL_BLE_ROLE_OBSERVER (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ROLE_PERIPHERAL
+#define MYNEWT_VAL_BLE_ROLE_PERIPHERAL (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_WHITELIST
+#define MYNEWT_VAL_BLE_WHITELIST (1)
+#endif
+
+/*** net/nimble/controller */
+#ifndef MYNEWT_VAL_BLE_DEVICE
+#define MYNEWT_VAL_BLE_DEVICE (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR
+#define MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR ((uint8_t[6]){0x66, 0x55, 0x44, 0x33, 0x22, 0x11})
+#endif
+
+/* Overridden by net/nimble/controller (defined by net/nimble/controller) */
+#ifndef MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE
+#define MYNEWT_VAL_BLE_HW_WHITELIST_ENABLE (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS
+#define MYNEWT_VAL_BLE_LL_ADD_STRICT_SCHED_PERIODS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_CONN_PARAM_REQ (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_DATA_LEN_EXT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_EXT_SCAN_FILT
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_EXT_SCAN_FILT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_2M_PHY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CODED_PHY (0)
+#endif
+
+/* Overridden by net/nimble/controller (defined by net/nimble/controller) */
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_CSA2 (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_PING (MYNEWT_VAL_BLE_LL_CFG_FEAT_LE_ENCRYPTION)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_EXT_ADV (MYNEWT_VAL_BLE_EXT_ADV)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_LL_PRIVACY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG
+#define MYNEWT_VAL_BLE_LL_CFG_FEAT_SLAVE_INIT_FEAT_XCHG (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES
+#define MYNEWT_VAL_BLE_LL_CONN_INIT_MAX_TX_BYTES (27)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET
+#define MYNEWT_VAL_BLE_LL_CONN_INIT_MIN_WIN_OFFSET (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS
+#define MYNEWT_VAL_BLE_LL_CONN_INIT_SLOTS (4)
+#endif
+
+/* Overridden by net/nimble/controller (defined by net/nimble/controller) */
+#ifndef MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT
+#define MYNEWT_VAL_BLE_LL_EXT_ADV_AUX_PTR_CNT (5)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_MASTER_SCA
+#define MYNEWT_VAL_BLE_LL_MASTER_SCA (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE
+#define MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE (251)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_MFRG_ID
+#define MYNEWT_VAL_BLE_LL_MFRG_ID (0xFFFF)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS
+#define MYNEWT_VAL_BLE_LL_NUM_SCAN_DUP_ADVS (8)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS
+#define MYNEWT_VAL_BLE_LL_NUM_SCAN_RSP_ADVS (8)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_OUR_SCA
+#define MYNEWT_VAL_BLE_LL_OUR_SCA (60)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_PRIO
+#define MYNEWT_VAL_BLE_LL_PRIO (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE
+#define MYNEWT_VAL_BLE_LL_RESOLV_LIST_SIZE (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_RNG_BUFSIZE
+#define MYNEWT_VAL_BLE_LL_RNG_BUFSIZE (32)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING
+#define MYNEWT_VAL_BLE_LL_STRICT_CONN_SCHEDULING (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES
+#define MYNEWT_VAL_BLE_LL_SUPP_MAX_RX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES
+#define MYNEWT_VAL_BLE_LL_SUPP_MAX_TX_BYTES (MYNEWT_VAL_BLE_LL_MAX_PKT_SIZE)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_TX_PWR_DBM
+#define MYNEWT_VAL_BLE_LL_TX_PWR_DBM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD
+#define MYNEWT_VAL_BLE_LL_USECS_PER_PERIOD (3250)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LL_WHITELIST_SIZE
+#define MYNEWT_VAL_BLE_LL_WHITELIST_SIZE (8)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_LP_CLOCK
+#define MYNEWT_VAL_BLE_LP_CLOCK (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE
+#define MYNEWT_VAL_BLE_NUM_COMP_PKT_RATE (((2000 * OS_TICKS_PER_SEC) / 1000))
+#endif
+
+#ifndef MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR
+#define MYNEWT_VAL_BLE_PUBLIC_DEV_ADDR ((uint8_t[6]){0xff, 0xaa, 0xff, 0xc0, 0xde, 0xc0})
+#endif
+
+/* Overridden by hw/bsp/nrf52840pdk (defined by net/nimble/controller) */
+#ifndef MYNEWT_VAL_BLE_XTAL_SETTLE_TIME
+#define MYNEWT_VAL_BLE_XTAL_SETTLE_TIME (1500)
+#endif
+
+/*** net/nimble/host */
+#ifndef MYNEWT_VAL_BLE_ATT_PREFERRED_MTU
+#define MYNEWT_VAL_BLE_ATT_PREFERRED_MTU (256)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO
+#define MYNEWT_VAL_BLE_ATT_SVR_FIND_INFO (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE
+#define MYNEWT_VAL_BLE_ATT_SVR_FIND_TYPE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_INDICATE
+#define MYNEWT_VAL_BLE_ATT_SVR_INDICATE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES
+#define MYNEWT_VAL_BLE_ATT_SVR_MAX_PREP_ENTRIES (64)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_NOTIFY
+#define MYNEWT_VAL_BLE_ATT_SVR_NOTIFY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE
+#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO
+#define MYNEWT_VAL_BLE_ATT_SVR_QUEUED_WRITE_TMO (30000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ
+#define MYNEWT_VAL_BLE_ATT_SVR_READ (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_BLOB (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_GROUP_TYPE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_MULT
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_MULT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE
+#define MYNEWT_VAL_BLE_ATT_SVR_READ_TYPE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE
+#define MYNEWT_VAL_BLE_ATT_SVR_SIGNED_WRITE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE
+#define MYNEWT_VAL_BLE_ATT_SVR_WRITE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP
+#define MYNEWT_VAL_BLE_ATT_SVR_WRITE_NO_RSP (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_CHRS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_DSCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS
+#define MYNEWT_VAL_BLE_GATT_DISC_ALL_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID
+#define MYNEWT_VAL_BLE_GATT_DISC_CHR_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID
+#define MYNEWT_VAL_BLE_GATT_DISC_SVC_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS
+#define MYNEWT_VAL_BLE_GATT_FIND_INC_SVCS (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_INDICATE
+#define MYNEWT_VAL_BLE_GATT_INDICATE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_MAX_PROCS
+#define MYNEWT_VAL_BLE_GATT_MAX_PROCS (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_NOTIFY
+#define MYNEWT_VAL_BLE_GATT_NOTIFY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ
+#define MYNEWT_VAL_BLE_GATT_READ (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_LONG
+#define MYNEWT_VAL_BLE_GATT_READ_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS
+#define MYNEWT_VAL_BLE_GATT_READ_MAX_ATTRS (8)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_MULT
+#define MYNEWT_VAL_BLE_GATT_READ_MULT (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_READ_UUID
+#define MYNEWT_VAL_BLE_GATT_READ_UUID (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_RESUME_RATE
+#define MYNEWT_VAL_BLE_GATT_RESUME_RATE (1000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_SIGNED_WRITE
+#define MYNEWT_VAL_BLE_GATT_SIGNED_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE
+#define MYNEWT_VAL_BLE_GATT_WRITE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_LONG
+#define MYNEWT_VAL_BLE_GATT_WRITE_LONG (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS
+#define MYNEWT_VAL_BLE_GATT_WRITE_MAX_ATTRS (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP
+#define MYNEWT_VAL_BLE_GATT_WRITE_NO_RSP (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE
+#define MYNEWT_VAL_BLE_GATT_WRITE_RELIABLE (MYNEWT_VAL_BLE_ROLE_CENTRAL)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HOST
+#define MYNEWT_VAL_BLE_HOST (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_DEBUG
+#define MYNEWT_VAL_BLE_HS_DEBUG (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS
+#define MYNEWT_VAL_BLE_HS_PHONY_HCI_ACKS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HS_REQUIRE_OS
+#define MYNEWT_VAL_BLE_HS_REQUIRE_OS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM
+#define MYNEWT_VAL_BLE_L2CAP_COC_MAX_NUM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS
+#define MYNEWT_VAL_BLE_L2CAP_JOIN_RX_FRAGS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_MAX_CHANS
+#define MYNEWT_VAL_BLE_L2CAP_MAX_CHANS (3*MYNEWT_VAL_BLE_MAX_CONNECTIONS)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT
+#define MYNEWT_VAL_BLE_L2CAP_RX_FRAG_TIMEOUT (30000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS
+#define MYNEWT_VAL_BLE_L2CAP_SIG_MAX_PROCS (1)
+#endif
+
+/* Overridden by apps/bleall (defined by net/nimble/host) */
+#ifndef MYNEWT_VAL_BLE_MESH
+#define MYNEWT_VAL_BLE_MESH (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE
+#define MYNEWT_VAL_BLE_MONITOR_CONSOLE_BUFFER_SIZE (128)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT
+#define MYNEWT_VAL_BLE_MONITOR_RTT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFERED (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_NAME ("monitor")
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE
+#define MYNEWT_VAL_BLE_MONITOR_RTT_BUFFER_SIZE (256)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART
+#define MYNEWT_VAL_BLE_MONITOR_UART (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE
+#define MYNEWT_VAL_BLE_MONITOR_UART_BAUDRATE (1000000)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE
+#define MYNEWT_VAL_BLE_MONITOR_UART_BUFFER_SIZE (64)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MONITOR_UART_DEV
+#define MYNEWT_VAL_BLE_MONITOR_UART_DEV ("uart0")
+#endif
+
+#ifndef MYNEWT_VAL_BLE_RPA_TIMEOUT
+#define MYNEWT_VAL_BLE_RPA_TIMEOUT (300)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_BONDING
+#define MYNEWT_VAL_BLE_SM_BONDING (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_IO_CAP
+#define MYNEWT_VAL_BLE_SM_IO_CAP (BLE_HS_IO_NO_INPUT_OUTPUT)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_KEYPRESS
+#define MYNEWT_VAL_BLE_SM_KEYPRESS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_LEGACY
+#define MYNEWT_VAL_BLE_SM_LEGACY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_MAX_PROCS
+#define MYNEWT_VAL_BLE_SM_MAX_PROCS (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_MITM
+#define MYNEWT_VAL_BLE_SM_MITM (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG
+#define MYNEWT_VAL_BLE_SM_OOB_DATA_FLAG (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_OUR_KEY_DIST
+#define MYNEWT_VAL_BLE_SM_OUR_KEY_DIST (0)
+#endif
+
+/* Overridden by net/nimble/host (defined by net/nimble/host) */
+#ifndef MYNEWT_VAL_BLE_SM_SC
+#define MYNEWT_VAL_BLE_SM_SC (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST
+#define MYNEWT_VAL_BLE_SM_THEIR_KEY_DIST (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_STORE_MAX_BONDS
+#define MYNEWT_VAL_BLE_STORE_MAX_BONDS (3)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_STORE_MAX_CCCDS
+#define MYNEWT_VAL_BLE_STORE_MAX_CCCDS (8)
+#endif
+
+/*** net/nimble/host/mesh */
+#ifndef MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT
+#define MYNEWT_VAL_BLE_MESH_ADV_BUF_COUNT (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO
+#define MYNEWT_VAL_BLE_MESH_ADV_TASK_PRIO (9)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT
+#define MYNEWT_VAL_BLE_MESH_APP_KEY_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_CRPL
+#define MYNEWT_VAL_BLE_MESH_CRPL (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG
+#define MYNEWT_VAL_BLE_MESH_DEBUG (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS
+#define MYNEWT_VAL_BLE_MESH_DEBUG_ACCESS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_ADV
+#define MYNEWT_VAL_BLE_MESH_DEBUG_ADV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_BEACON
+#define MYNEWT_VAL_BLE_MESH_DEBUG_BEACON (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_CRYPTO
+#define MYNEWT_VAL_BLE_MESH_DEBUG_CRYPTO (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_FRIEND
+#define MYNEWT_VAL_BLE_MESH_DEBUG_FRIEND (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_LOW_POWER
+#define MYNEWT_VAL_BLE_MESH_DEBUG_LOW_POWER (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_MODEL
+#define MYNEWT_VAL_BLE_MESH_DEBUG_MODEL (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_NET
+#define MYNEWT_VAL_BLE_MESH_DEBUG_NET (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_PROV
+#define MYNEWT_VAL_BLE_MESH_DEBUG_PROV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_PROXY
+#define MYNEWT_VAL_BLE_MESH_DEBUG_PROXY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEBUG_TRANS
+#define MYNEWT_VAL_BLE_MESH_DEBUG_TRANS (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_DEV_UUID
+#define MYNEWT_VAL_BLE_MESH_DEV_UUID (((uint8_t[16]){0x11, 0x22, 0}))
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_FRIEND
+#define MYNEWT_VAL_BLE_MESH_FRIEND (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT
+#define MYNEWT_VAL_BLE_MESH_FRIEND_LPN_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE
+#define MYNEWT_VAL_BLE_MESH_FRIEND_QUEUE_SIZE (16)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN
+#define MYNEWT_VAL_BLE_MESH_FRIEND_RECV_WIN (255)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE
+#define MYNEWT_VAL_BLE_MESH_FRIEND_SUB_LIST_SIZE (16)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_GATT_PROXY
+#define MYNEWT_VAL_BLE_MESH_GATT_PROXY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST
+#define MYNEWT_VAL_BLE_MESH_IV_UPDATE_TEST (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LABEL_COUNT
+#define MYNEWT_VAL_BLE_MESH_LABEL_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LOW_POWER
+#define MYNEWT_VAL_BLE_MESH_LOW_POWER (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_GROUPS
+#define MYNEWT_VAL_BLE_MESH_LPN_GROUPS (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE
+#define MYNEWT_VAL_BLE_MESH_LPN_MIN_QUEUE_SIZE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT
+#define MYNEWT_VAL_BLE_MESH_LPN_POLL_TIMEOUT (100)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY
+#define MYNEWT_VAL_BLE_MESH_LPN_RECV_DELAY (20)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR
+#define MYNEWT_VAL_BLE_MESH_LPN_RECV_WIN_FACTOR (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR
+#define MYNEWT_VAL_BLE_MESH_LPN_RSSI_FACTOR (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY
+#define MYNEWT_VAL_BLE_MESH_LPN_SCAN_LATENCY (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT
+#define MYNEWT_VAL_BLE_MESH_MODEL_GROUP_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT
+#define MYNEWT_VAL_BLE_MESH_MODEL_KEY_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE
+#define MYNEWT_VAL_BLE_MESH_MSG_CACHE_SIZE (10)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_PB_ADV
+#define MYNEWT_VAL_BLE_MESH_PB_ADV (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_PB_GATT
+#define MYNEWT_VAL_BLE_MESH_PB_GATT (1)
+#endif
+
+/* Overridden by net/nimble/host/mesh (defined by net/nimble/host/mesh) */
+#ifndef MYNEWT_VAL_BLE_MESH_PROV
+#define MYNEWT_VAL_BLE_MESH_PROV (1)
+#endif
+
+/* Overridden by net/nimble/host/mesh (defined by net/nimble/host/mesh) */
+#ifndef MYNEWT_VAL_BLE_MESH_PROXY
+#define MYNEWT_VAL_BLE_MESH_PROXY (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE
+#define MYNEWT_VAL_BLE_MESH_PROXY_FILTER_SIZE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_RELAY
+#define MYNEWT_VAL_BLE_MESH_RELAY (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_RX_SDU_MAX
+#define MYNEWT_VAL_BLE_MESH_RX_SDU_MAX (384)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT
+#define MYNEWT_VAL_BLE_MESH_RX_SEG_MSG_COUNT (2)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_SUBNET_COUNT
+#define MYNEWT_VAL_BLE_MESH_SUBNET_COUNT (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT
+#define MYNEWT_VAL_BLE_MESH_TX_SEG_MSG_COUNT (4)
+#endif
+
+/*** net/nimble/host/services/ans */
+#ifndef MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT
+#define MYNEWT_VAL_BLE_SVC_ANS_NEW_ALERT_CAT (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT
+#define MYNEWT_VAL_BLE_SVC_ANS_UNR_ALERT_CAT (0)
+#endif
+
+/*** net/nimble/transport/socket */
+#ifndef MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE
+#define MYNEWT_VAL_BLE_SOCK_USE_LINUX_BLUE (1)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_LINUX_DEV
+#define MYNEWT_VAL_BLE_SOCK_LINUX_DEV (0)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_STACK_SIZE
+#define MYNEWT_VAL_BLE_SOCK_STACK_SIZE (1028)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_SOCK_TASK_PRIO
+#define MYNEWT_VAL_BLE_SOCK_TASK_PRIO (1)
+#endif
+
+/*** net/nimble/transport/ram */
+#ifndef MYNEWT_VAL_BLE_ACL_BUF_COUNT
+#define MYNEWT_VAL_BLE_ACL_BUF_COUNT (4)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_ACL_BUF_SIZE
+#define MYNEWT_VAL_BLE_ACL_BUF_SIZE (255)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE
+#define MYNEWT_VAL_BLE_HCI_EVT_BUF_SIZE (70)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT
+#define MYNEWT_VAL_BLE_HCI_EVT_HI_BUF_COUNT (2)
+#endif
+
+#ifndef MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT
+#define MYNEWT_VAL_BLE_HCI_EVT_LO_BUF_COUNT (8)
+#endif
+
+/*** sys/console/stub */
+#ifndef MYNEWT_VAL_CONSOLE_UART_BAUD
+#define MYNEWT_VAL_CONSOLE_UART_BAUD (115200)
+#endif
+
+#ifndef MYNEWT_VAL_CONSOLE_UART_DEV
+#define MYNEWT_VAL_CONSOLE_UART_DEV ("uart0")
+#endif
+
+#ifndef MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL
+#define MYNEWT_VAL_CONSOLE_UART_FLOW_CONTROL (UART_FLOW_CTL_NONE)
+#endif
+
+/*** sys/flash_map */
+#ifndef MYNEWT_VAL_FLASH_MAP_MAX_AREAS
+#define MYNEWT_VAL_FLASH_MAP_MAX_AREAS (10)
+#endif
+
+/*** sys/log/stub */
+#ifndef MYNEWT_VAL_LOG_CONSOLE
+#define MYNEWT_VAL_LOG_CONSOLE (1)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_FCB
+#define MYNEWT_VAL_LOG_FCB (0)
+#endif
+
+#ifndef MYNEWT_VAL_LOG_LEVEL
+#define MYNEWT_VAL_LOG_LEVEL (255)
+#endif
+
+/*** sys/sysinit */
+#ifndef MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT
+#define MYNEWT_VAL_SYSINIT_CONSTRAIN_INIT (1)
+#endif
+
+#ifndef MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE
+#define MYNEWT_VAL_SYSINIT_PANIC_FILE_LINE (0)
+#endif
+
+#ifndef MYNEWT_VAL_SYSINIT_PANIC_MESSAGE
+#define MYNEWT_VAL_SYSINIT_PANIC_MESSAGE (0)
+#endif
+
+#endif
diff --git a/porting/linux/os/os_arch.h b/porting/linux/os/os_arch.h
new file mode 100644
index 00000000..ca54cb33
--- /dev/null
+++ b/porting/linux/os/os_arch.h
@@ -0,0 +1,48 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _OS_ARCH_H
+#define _OS_ARCH_H
+
+#include <stdint.h>
+#include "os/os_atomic.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int os_sr_t;
+typedef int os_stack_t;
+
+#define OS_TICKS_PER_SEC   (1000)
+
+#define OS_ALIGNMENT       (sizeof(uintptr_t))
+#define OS_STACK_ALIGNMENT (16)
+
+#define OS_STACK_ALIGN(__nmemb)					\
+	    (OS_ALIGN(((__nmemb) * 16), OS_STACK_ALIGNMENT))
+
+#define OS_ENTER_CRITICAL(unused) do { (void)unused; os_atomic_begin(); } while (0)
+#define OS_EXIT_CRITICAL(unused) do { (void)unused; os_atomic_end(); } while (0)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_ARCH_H */
diff --git a/porting/linux/os/os_atomic.c b/porting/linux/os/os_atomic.c
new file mode 100644
index 00000000..ff221357
--- /dev/null
+++ b/porting/linux/os/os_atomic.c
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <stdint.h>
+#include <pthread.h>
+
+pthread_mutex_t s_mutex = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+pthread_cond_t s_cond = PTHREAD_COND_INITIALIZER;
+
+void os_atomic_begin()
+{
+    pthread_mutex_lock(&s_mutex);
+}
+
+void os_atomic_end()
+{
+    pthread_mutex_unlock(&s_mutex);
+    pthread_cond_signal(&s_cond);
+}
diff --git a/porting/linux/os/os_atomic.h b/porting/linux/os/os_atomic.h
new file mode 100644
index 00000000..5eaa1b11
--- /dev/null
+++ b/porting/linux/os/os_atomic.h
@@ -0,0 +1,34 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _OS_ATOMIC_H
+#define _OS_ATOMIC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void os_atomic_begin();
+void os_atomic_end();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_ATOMIC_H */
diff --git a/porting/linux/os/os_callout.c b/porting/linux/os/os_callout.c
new file mode 100644
index 00000000..636f51fe
--- /dev/null
+++ b/porting/linux/os/os_callout.c
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include "os/os.h"
+
+#include <time.h>
+#include <signal.h>
+
+
+static void
+os_callout_timer_cb(union sigval sv)
+{
+    struct os_callout *c = (struct os_callout *)sv.sival_ptr;
+    assert(c);
+
+    if (c->c_evq) {
+        os_eventq_put(c->c_evq, &c->c_ev);
+    } else {
+        c->c_ev.ev_cb(&c->c_ev);
+    }
+}
+
+
+void
+os_callout_init(struct os_callout *c, struct os_eventq *evq,
+                os_event_fn *ev_cb, void *ev_arg)
+{
+    struct sigevent         event;
+
+    // Initialize the callout.
+    memset(c, 0, sizeof(*c));
+    c->c_ev.ev_cb = ev_cb;
+    c->c_ev.ev_arg = ev_arg;
+    c->c_evq = evq;
+
+    event.sigev_notify = SIGEV_THREAD;
+    event.sigev_value.sival_ptr = c;     // put callout obj in signal args
+    event.sigev_notify_function = os_callout_timer_cb;
+    event.sigev_notify_attributes = NULL;
+
+    timer_create(CLOCK_REALTIME, &event, &c->c_timer);
+}
+
+int
+os_callout_inited(struct os_callout *c)
+{
+    return (c->c_timer != NULL);
+}
+
+int
+os_callout_reset(struct os_callout *c, int32_t ticks)
+{
+    struct itimerspec       its;
+
+    if (ticks < 0) {
+        return OS_EINVAL;
+    }
+
+    if (ticks == 0) {
+        ticks = 1;
+    }
+
+    c->c_ticks = os_time_get() + ticks;
+
+    its.it_interval.tv_sec = 0;
+    its.it_interval.tv_nsec = 0;                     // one shot
+    its.it_value.tv_sec = (ticks / 1000);
+    its.it_value.tv_nsec = (ticks % 1000) * 1000000; // expiration
+    timer_settime(c->c_timer, 0, &its, NULL);
+
+    return OS_OK;
+}
+
+int
+os_callout_queued(struct os_callout *c)
+{
+    struct itimerspec its;
+    timer_gettime(c->c_timer, &its);
+
+    return ((its.it_value.tv_sec > 0) ||
+            (its.it_value.tv_nsec > 0));
+}
+
+void
+os_callout_stop(struct os_callout *c)
+{
+    if (!os_callout_inited(c)) return;
+
+    struct itimerspec its;
+    its.it_interval.tv_sec = 0;
+    its.it_interval.tv_nsec = 0;
+    its.it_value.tv_sec = 0;
+    its.it_value.tv_nsec = 0;
+    timer_settime(c->c_timer, 0, &its, NULL);
+}
diff --git a/porting/linux/os/os_callout.h b/porting/linux/os/os_callout.h
new file mode 100644
index 00000000..61a54afb
--- /dev/null
+++ b/porting/linux/os/os_callout.h
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _OS_CALLOUT_H
+#define _OS_CALLOUT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "os/os_eventq.h"
+
+#include <time.h>
+#include <signal.h>
+
+struct os_callout {
+    struct os_event c_ev;
+    struct os_eventq *c_evq;
+    uint32_t c_ticks;
+    timer_t c_timer;
+};
+
+void os_callout_init(struct os_callout *cf, struct os_eventq *evq,
+                     os_event_fn *ev_cb, void *ev_arg);
+int os_callout_reset(struct os_callout *, int32_t);
+int os_callout_queued(struct os_callout *c);
+void os_callout_stop(struct os_callout *c);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_CALLOUT_H */
diff --git a/porting/linux/os/os_eventq.cc b/porting/linux/os/os_eventq.cc
new file mode 100644
index 00000000..f87759dd
--- /dev/null
+++ b/porting/linux/os/os_eventq.cc
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "os/os.h"
+
+#include "wqueue.h"
+
+extern "C" {
+
+typedef wqueue<os_event *> wqueue_t;
+
+static struct os_eventq dflt_evq;
+
+struct os_eventq *
+os_eventq_dflt_get(void)
+{
+    if (!dflt_evq.q)
+    {
+        dflt_evq.q = new wqueue_t();
+    }
+
+    return &dflt_evq;
+}
+
+void
+os_eventq_init(struct os_eventq *evq)
+{
+    evq->q = new wqueue_t();
+}
+
+int
+os_eventq_inited(const struct os_eventq *evq)
+{
+    return (evq->q != NULL);
+}
+
+void
+os_eventq_put(struct os_eventq *evq, struct os_event *ev)
+{
+    wqueue_t *q = static_cast<wqueue_t *>(evq->q);
+
+    if (OS_EVENT_QUEUED(ev))
+    {
+        return;
+    }
+
+    ev->ev_queued = 1;
+    q->put(ev);          //    ret = xQueueSendToBack(evq->q, &ev, 0);
+}
+
+struct os_event *
+os_eventq_get(struct os_eventq *evq)
+{
+    struct os_event *ev;
+    wqueue_t *q = static_cast<wqueue_t *>(evq->q);
+
+    ev = q->get();
+    ev->ev_queued = 0;
+
+    return ev;
+}
+
+/*
+====================================================
+                NOT IMPLEMENTED
+====================================================
+
+struct os_event *
+os_eventq_get_no_wait(struct os_eventq *evq)
+{
+    assert(1);  // Not implemented
+    return os_eventq_get(evq);
+}
+
+void
+os_eventq_remove(struct os_eventq *evq, struct os_event *ev)
+{
+    assert(1);  // Not implemented
+}
+
+====================================================
+*/
+
+void
+os_eventq_run(struct os_eventq *evq)
+{
+    struct os_event *ev;
+
+    ev = os_eventq_get(evq);
+    assert(ev->ev_cb != NULL);
+
+    ev->ev_cb(ev);
+}
+
+}
diff --git a/porting/linux/os/os_eventq.h b/porting/linux/os/os_eventq.h
new file mode 100644
index 00000000..8d1c0e19
--- /dev/null
+++ b/porting/linux/os/os_eventq.h
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _OS_EVENTQ_H
+#define _OS_EVENTQ_H
+
+#include <inttypes.h>
+#include "os/os_time.h"
+#include "os/queue.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct os_event;
+typedef void os_event_fn(struct os_event *ev);
+
+struct os_event {
+    uint8_t ev_queued;
+    os_event_fn *ev_cb;
+    void *ev_arg;
+};
+
+#define OS_EVENT_QUEUED(__ev) ((__ev)->ev_queued)
+
+struct os_eventq {
+    void *q;
+};
+
+void os_eventq_init(struct os_eventq *);
+int os_eventq_inited(const struct os_eventq *evq);
+void os_eventq_put(struct os_eventq *, struct os_event *);
+struct os_event *os_eventq_get_no_wait(struct os_eventq *evq);
+struct os_event *os_eventq_get(struct os_eventq *);
+void os_eventq_run(struct os_eventq *evq);
+struct os_event *os_eventq_poll(struct os_eventq **, int, os_time_t);
+void os_eventq_remove(struct os_eventq *, struct os_event *);
+struct os_eventq *os_eventq_dflt_get(void);
+
+/* [DEPRECATED] */
+void os_eventq_designate(struct os_eventq **dst, struct os_eventq *val,
+                         struct os_event *start_ev);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_EVENTQ_H */
diff --git a/porting/linux/os/os_mutex.c b/porting/linux/os/os_mutex.c
new file mode 100644
index 00000000..6896ef99
--- /dev/null
+++ b/porting/linux/os/os_mutex.c
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "os/os.h"
+
+#include <pthread.h>
+
+os_error_t
+os_mutex_init(struct os_mutex *mu)
+{
+    if (!mu) {
+        return OS_INVALID_PARM;
+    }
+
+    pthread_mutexattr_t muAttr;
+    pthread_mutexattr_settype(&muAttr, PTHREAD_MUTEX_RECURSIVE_NP);
+    pthread_mutex_init(&mu->lock, &muAttr);
+
+    return OS_OK;
+}
+
+os_error_t
+os_mutex_release(struct os_mutex *mu)
+{
+    if (!mu) return OS_INVALID_PARM;
+
+    if (pthread_mutex_unlock(&mu->lock)) {
+        return OS_BAD_MUTEX;
+    }
+
+    return OS_OK;
+}
+
+os_error_t
+os_mutex_pend(struct os_mutex *mu, uint32_t timeout)
+{
+    if (!mu) return OS_INVALID_PARM;
+
+    assert(&mu->lock);
+
+    struct timespec wait;
+    wait.tv_sec  = timeout / 1000;
+    wait.tv_nsec = (timeout % 1000) * 1000000;
+
+    if (pthread_mutex_timedlock(&mu->lock, &wait)) {
+        return OS_TIMEOUT;
+    }
+
+    return OS_OK;
+}
diff --git a/porting/linux/os/os_mutex.h b/porting/linux/os/os_mutex.h
new file mode 100644
index 00000000..01b7d1d8
--- /dev/null
+++ b/porting/linux/os/os_mutex.h
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _OS_MUTEX_H_
+#define _OS_MUTEX_H_
+
+#include "os/os.h"
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct os_mutex
+{
+    pthread_mutex_t lock;
+};
+
+os_error_t os_mutex_init(struct os_mutex *mu);
+
+os_error_t os_mutex_release(struct os_mutex *mu);
+
+os_error_t os_mutex_pend(struct os_mutex *mu, uint32_t timeout);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _OS_MUTEX_H_ */
diff --git a/porting/linux/os/os_sched.c b/porting/linux/os/os_sched.c
new file mode 100644
index 00000000..dde219f7
--- /dev/null
+++ b/porting/linux/os/os_sched.c
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "os/os.h"
+
+/*
+static inline bool in_isr()
+{
+    return false;
+}
+*/
+
+int
+os_started(void)
+{
+    return true;
+}
+
+
+struct os_task *
+os_sched_get_current_task(void)
+{
+  // TODO: make API pass-by-reference
+  // task->handle = pthread_self();
+  // task->name = ?
+    return NULL;
+}
+
diff --git a/porting/linux/os/os_sem.c b/porting/linux/os/os_sem.c
new file mode 100644
index 00000000..81c3ae98
--- /dev/null
+++ b/porting/linux/os/os_sem.c
@@ -0,0 +1,95 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "os/os.h"
+
+#include <errno.h>
+#include <pthread.h>
+#include <semaphore.h>
+
+
+os_error_t
+os_sem_init(struct os_sem *sem, uint16_t tokens)
+{
+    if (!sem)
+    {
+        return OS_INVALID_PARM;
+    }
+
+    sem_init(&sem->lock, 0, tokens);
+
+    return OS_OK;
+}
+
+os_error_t
+os_sem_release(struct os_sem *sem)
+{
+    int err;
+
+    if (!sem)
+    {
+        return OS_INVALID_PARM;
+    }
+
+    err = sem_post(&sem->lock);
+
+    return (err) ? OS_ERROR : OS_OK;
+}
+
+os_error_t
+os_sem_pend(struct os_sem *sem, uint32_t timeout)
+{
+    if (!sem) return OS_INVALID_PARM;
+
+    int err = 0;
+    struct timespec wait;
+    err = clock_gettime(CLOCK_REALTIME, &wait);
+    if (err) return OS_ERROR;
+
+    wait.tv_sec  += timeout / 1000;
+    wait.tv_nsec += (timeout % 1000) * 1000000;
+
+    if (timeout == OS_WAIT_FOREVER)
+    {
+        err = sem_wait(&sem->lock);
+    }
+    else
+    {
+        if (sem_timedwait(&sem->lock, &wait))
+        {
+	    assert(errno == ETIMEDOUT);
+	    return OS_TIMEOUT;
+	}
+    }
+
+    return (err) ? OS_ERROR : OS_OK;
+}
+
+uint16_t
+os_sem_get_count(struct os_sem *sem)
+{
+    int count;
+    assert(sem);
+    assert(&sem->lock);
+    sem_getvalue(&sem->lock, &count);
+    return count;
+}
diff --git a/porting/linux/os/os_sem.h b/porting/linux/os/os_sem.h
new file mode 100644
index 00000000..df1d791c
--- /dev/null
+++ b/porting/linux/os/os_sem.h
@@ -0,0 +1,26 @@
+#ifndef _OS_SEM_H_
+#define _OS_SEM_H_
+
+#include "os/os_error.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <semaphore.h>
+
+struct os_sem
+{
+    sem_t lock;
+};
+
+os_error_t os_sem_init(struct os_sem *sem, uint16_t tokens);
+os_error_t os_sem_release(struct os_sem *sem);
+os_error_t os_sem_pend(struct os_sem *sem, uint32_t timeout);
+uint16_t os_sem_get_count(struct os_sem *sem);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _OS_SEM_H_ */
diff --git a/porting/linux/os/os_task.c b/porting/linux/os/os_task.c
new file mode 100644
index 00000000..7c0ce1e8
--- /dev/null
+++ b/porting/linux/os/os_task.c
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "os/os.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Initialize a task.
+ *
+ * This function initializes the task structure pointed to by t,
+ * clearing and setting it's stack pointer, provides sane defaults
+ * and sets the task as ready to run, and inserts it into the operating
+ * system scheduler.
+ *
+ * @param t The task to initialize
+ * @param name The name of the task to initialize
+ * @param func The task function to call
+ * @param arg The argument to pass to this task function
+ * @param prio The priority at which to run this task
+ * @param sanity_itvl The time at which this task should check in with the
+ *                    sanity task.  OS_WAIT_FOREVER means never check in
+ *                    here.
+ * @param stack_bottom A pointer to the bottom of a task's stack
+ * @param stack_size The overall size of the task's stack.
+ *
+ * @return 0 on success, non-zero on failure.
+ */
+int
+os_task_init(struct os_task *t, const char *name, os_task_func_t func,
+        void *arg, uint8_t prio, os_time_t sanity_itvl,
+        os_stack_t *stack_bottom, uint16_t stack_size)
+{
+    int err;
+    if ((t == NULL) || (func == NULL)) {
+        return OS_INVALID_PARM;
+    }
+
+    pthread_attr_t attr;
+    struct sched_param param;
+    err = pthread_attr_init(&attr);
+    if (err) return err;
+    err = pthread_attr_getschedparam (&attr, &param);
+    if (err) return err;
+    err = pthread_attr_setschedpolicy(&attr, SCHED_RR);
+    if (err) return err;
+    param.sched_priority = prio;
+    err = pthread_attr_setschedparam (&attr, &param);
+    if (err) return err;
+
+    t->name = name;
+    err = pthread_create(&t->handle, &attr, (void *) func, arg);
+
+    return err;
+}
+
+/*
+ * Removes specified task
+ * XXX
+ * NOTE: This interface is currently experimental and not ready for common use
+ */
+int
+os_task_remove(struct os_task *t)
+{
+    return pthread_cancel(t->handle);
+}
+
+/**
+ * Return the number of tasks initialized.
+ *
+ * @return number of tasks initialized
+ */
+uint8_t
+os_task_count(void)
+{
+    return 0;
+}
+
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/porting/linux/os/os_task.h b/porting/linux/os/os_task.h
new file mode 100644
index 00000000..9d8a0a65
--- /dev/null
+++ b/porting/linux/os/os_task.h
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _OS_TASK_H
+#define _OS_TASK_H
+
+#include "os/os.h"
+
+#include <pthread.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* The highest and lowest task priorities */
+#define OS_TASK_PRI_HIGHEST (sched_get_priority_max(SCHED_RR))
+#define OS_TASK_PRI_LOWEST  (sched_get_priority_min(SCHED_RR))
+
+/* Task states */
+typedef enum os_task_state {
+    OS_TASK_READY = 1,
+    OS_TASK_SLEEP = 2,
+} os_task_state_t;
+
+/* Task flags */
+#define OS_TASK_FLAG_NO_TIMEOUT     (0x01U)
+#define OS_TASK_FLAG_SEM_WAIT       (0x02U)
+#define OS_TASK_FLAG_MUTEX_WAIT     (0x04U)
+#define OS_TASK_FLAG_EVQ_WAIT       (0x08U)
+
+typedef void (*os_task_func_t)(void *);
+
+// #define OS_TASK_MAX_NAME_LEN (32)
+
+struct os_task {
+    pthread_t              handle;
+    const char*            name;
+};
+
+int os_task_init(struct os_task *t, const char *name, os_task_func_t func,
+		 void *arg, uint8_t prio, os_time_t sanity_itvl,
+		 os_stack_t *stack_bottom, uint16_t stack_size);
+
+int os_task_remove(struct os_task *t);
+
+uint8_t os_task_count(void);
+
+  /*
+struct os_task_info {
+    uint8_t oti_prio;
+    uint8_t oti_taskid;
+    uint8_t oti_state;
+    uint16_t oti_stkusage;
+    uint16_t oti_stksize;
+    uint32_t oti_cswcnt;
+    uint32_t oti_runtime;
+    os_time_t oti_last_checkin;
+    os_time_t oti_next_checkin;
+
+    char oti_name[OS_TASK_MAX_NAME_LEN];
+};
+
+struct os_task *os_task_info_get_next(const struct os_task *,
+        struct os_task_info *);
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _OS_TASK_H */
diff --git a/porting/linux/os/os_time.c b/porting/linux/os/os_time.c
new file mode 100644
index 00000000..4c7772a6
--- /dev/null
+++ b/porting/linux/os/os_time.c
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdint.h>
+#include <string.h>
+#include "os/os.h"
+
+#include <time.h>
+
+/**
+ * Return ticks [ms] since system start as uint32_t.
+ */
+os_time_t
+os_time_get(void)
+{
+    struct timespec now;
+    if (clock_gettime(CLOCK_MONOTONIC, &now)) return 0;
+    return now.tv_sec * 1000.0 + now.tv_nsec / 1000000.0;
+}
+
+int
+os_time_ms_to_ticks(uint32_t ms, uint32_t *out_ticks)
+{
+    *out_ticks = ms;
+
+    return OS_OK;
+}
diff --git a/porting/linux/os/wqueue.h b/porting/linux/os/wqueue.h
new file mode 100644
index 00000000..8eb23b79
--- /dev/null
+++ b/porting/linux/os/wqueue.h
@@ -0,0 +1,76 @@
+/*
+   wqueue.h
+   Worker thread queue based on the Standard C++ library list
+   template class.
+   ------------------------------------------
+   Copyright (c) 2013 Vic Hargrave
+   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.
+*/
+
+// https://vichargrave.github.io/articles/2013-01/multithreaded-work-queue-in-cpp
+// https://github.com/vichargrave/wqueue/blob/master/wqueue.h
+
+
+#ifndef __wqueue_h__
+#define __wqueue_h__
+
+#include <pthread.h>
+#include <list>
+
+using namespace std;
+
+template <typename T> class wqueue
+{
+    list<T>         m_queue;
+    pthread_mutex_t m_mutex;
+    pthread_cond_t  m_condv;
+
+public:
+    wqueue()
+    {
+        pthread_mutexattr_t attr;
+        pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+        pthread_mutex_init(&m_mutex, &attr);
+        pthread_cond_init(&m_condv, NULL);
+    }
+
+    ~wqueue() {
+        pthread_mutex_destroy(&m_mutex);
+        pthread_cond_destroy(&m_condv);
+    }
+
+    void put(T item) {
+        pthread_mutex_lock(&m_mutex);
+        m_queue.push_back(item);
+        pthread_cond_signal(&m_condv);
+        pthread_mutex_unlock(&m_mutex);
+    }
+
+    T get() {
+        pthread_mutex_lock(&m_mutex);
+        while (m_queue.size() == 0) {
+            pthread_cond_wait(&m_condv, &m_mutex);
+        }
+        T item = m_queue.front();
+        m_queue.pop_front();
+        pthread_mutex_unlock(&m_mutex);
+        return item;
+    }
+
+    int size() {
+        pthread_mutex_lock(&m_mutex);
+        int size = m_queue.size();
+        pthread_mutex_unlock(&m_mutex);
+        return size;
+    }
+};
+
+#endif
diff --git a/porting/linux/src/ble_task.c b/porting/linux/src/ble_task.c
new file mode 100644
index 00000000..1b24de52
--- /dev/null
+++ b/porting/linux/src/ble_task.c
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <assert.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "nimble_port.h"
+#include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+#include "services/ias/ble_svc_ias.h"
+
+static const char gap_name[] = "nimble test";
+
+static struct os_task task_h;
+
+static void start_advertise(void);
+
+static int
+ias_event_cb(uint8_t alert_level)
+{
+  /*
+    switch (alert_level) {
+    case BLE_SVC_IAS_ALERT_LEVEL_NO_ALERT:
+        xTimerStop(led_tmr_h, portMAX_DELAY);
+        bsp_board_leds_off();
+        break;
+    case BLE_SVC_IAS_ALERT_LEVEL_MILD_ALERT:
+        bsp_board_led_on(BSP_BOARD_LED_0);
+        bsp_board_led_off(BSP_BOARD_LED_1);
+        bsp_board_led_off(BSP_BOARD_LED_2);
+        bsp_board_led_on(BSP_BOARD_LED_3);
+        xTimerStart(led_tmr_h, portMAX_DELAY);
+        break;
+    case BLE_SVC_IAS_ALERT_LEVEL_HIGH_ALERT:
+        bsp_board_leds_on();
+        xTimerStart(led_tmr_h, portMAX_DELAY);
+        break;
+    }
+  */
+
+    return 0;
+}
+
+static void
+put_ad(uint8_t ad_type, uint8_t ad_len, const void *ad, uint8_t *buf,
+       uint8_t *len)
+{
+    buf[(*len)++] = ad_len + 1;
+    buf[(*len)++] = ad_type;
+
+    memcpy(&buf[*len], ad, ad_len);
+
+    *len += ad_len;
+}
+
+static void
+update_ad(void)
+{
+    uint8_t ad[BLE_HS_ADV_MAX_SZ];
+    uint8_t ad_len = 0;
+    uint8_t ad_flags = BLE_HS_ADV_F_DISC_GEN | BLE_HS_ADV_F_BREDR_UNSUP;
+    uint16_t ad_uuid = htole16(BLE_SVC_IAS_UUID16);
+
+    put_ad(BLE_HS_ADV_TYPE_FLAGS, 1, &ad_flags, ad, &ad_len);
+    put_ad(BLE_HS_ADV_TYPE_COMP_NAME, sizeof(gap_name), gap_name, ad, &ad_len);
+    put_ad(BLE_HS_ADV_TYPE_COMP_UUIDS16, sizeof(ad_uuid), &ad_uuid, ad, &ad_len);
+
+    ble_gap_adv_set_data(ad, ad_len);
+}
+
+static int
+gap_event_cb(struct ble_gap_event *event, void *arg)
+{
+    switch (event->type) {
+    case BLE_GAP_EVENT_CONNECT:
+        if (event->connect.status) {
+            start_advertise();
+        }
+        break;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        start_advertise();
+        break;
+    }
+
+    return 0;
+}
+
+static void
+start_advertise(void)
+{
+    struct ble_gap_adv_params advp;
+    int rc;
+
+    update_ad();
+
+    memset(&advp, 0, sizeof advp);
+    advp.conn_mode = BLE_GAP_CONN_MODE_UND;
+    advp.disc_mode = BLE_GAP_DISC_MODE_GEN;
+    rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
+                           &advp, gap_event_cb, NULL);
+    assert(rc == 0);
+}
+
+static void
+on_sync_cb(void)
+{
+    start_advertise();
+}
+
+static void
+dflt_task(void *param)
+{
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
+
+void start_nimble(void)
+{
+    /* Execute sysinit port */
+    nimble_port_sysinit();
+
+    /* Configure Nimble host */
+    ble_hs_cfg.sync_cb = on_sync_cb;
+
+    ble_svc_gap_device_name_set(gap_name);
+    ble_svc_ias_set_cb(ias_event_cb);
+
+    /* Create task which handles default event queue */
+    os_task_init(&task_h, "dflt", dflt_task,
+		 NULL, 1, 0, NULL, 400);
+}
diff --git a/porting/linux/src/main.c b/porting/linux/src/main.c
new file mode 100644
index 00000000..802cd712
--- /dev/null
+++ b/porting/linux/src/main.c
@@ -0,0 +1,45 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <stdbool.h>
+#include <stdint.h>
+
+#include <pthread.h>
+
+int main(void)
+{
+    void start_nimble(void);
+    start_nimble();
+
+    // os_sched_start();
+
+    /* Start FreeRTOS scheduler. */
+    //vTaskStartScheduler();
+
+    int ret = 0;
+    pthread_exit(&ret);
+
+    while (true)
+    {
+        pthread_yield();
+        // FreeRTOS should not be here...
+	    // FreeRTOS goes back to the start of stack
+        // in vTaskStartScheduler function.
+    }
+}
diff --git a/porting/linux/src/nimble_port.c b/porting/linux/src/nimble_port.c
new file mode 100644
index 00000000..358a6272
--- /dev/null
+++ b/porting/linux/src/nimble_port.c
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 <stddef.h>
+#include "os/os.h"
+#include "sysinit/sysinit.h"
+#include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+#include "services/gatt/ble_svc_gatt.h"
+#include "services/ans/ble_svc_ans.h"
+#include "services/ias/ble_svc_ias.h"
+#include "services/lls/ble_svc_lls.h"
+#include "services/tps/ble_svc_tps.h"
+// #include "controller/ble_ll.h"
+
+void
+nimble_port_sysinit(void)
+{
+    void os_msys_init(void);
+    //void ble_hci_ram_pkg_init(void);
+    void ble_hci_sock_init(void);
+    void ble_store_ram_init(void);
+
+    sysinit_start();
+    os_msys_init();
+    ble_hci_sock_init();
+    //ble_hci_ram_pkg_init();
+    ble_hs_init();
+    //ble_ll_init();
+    ble_svc_gap_init();
+    ble_svc_gatt_init();
+    ble_svc_ans_init();
+    ble_svc_ias_init();
+    ble_svc_lls_init();
+    ble_svc_tps_init();
+    ble_store_ram_init();
+    sysinit_end();
+}
diff --git a/tests/unit/porting/os/Makefile b/tests/unit/porting/os/Makefile
new file mode 100644
index 00000000..2abd09d6
--- /dev/null
+++ b/tests/unit/porting/os/Makefile
@@ -0,0 +1,112 @@
+# Makefile
+
+PROJ_ROOT = ../../../..
+
+### ===== Toolchain =====
+
+CROSS_COMPILE =
+CC  = ccache $(CROSS_COMPILE)gcc
+CPP = ccache $(CROSS_COMPILE)g++
+LD  = $(CROSS_COMPILE)gcc
+AR  = $(CROSS_COMPILE)ar
+
+### ===== Compiler Flags =====
+
+INCLUDES = \
+    -I.    \
+    -I$(PROJ_ROOT)/porting/linux          \
+    -I$(PROJ_ROOT)/porting/linux/include  \
+    -I$(PROJ_ROOT)/porting/common/include \
+    $(NULL)
+
+DEFINES =
+
+CFLAGS =                   \
+    $(INCLUDES) $(DEFINES) \
+    -g                     \
+    -D_GNU_SOURCE          \
+    $(NULL)
+
+#    -D_XOPEN_SOURCE=700    \
+
+LIBS = -lrt -lpthread -lstdc++
+
+LDFLAGS =
+
+### ===== Sources =====
+
+OSAL_PATH = $(PROJ_ROOT)/porting/linux/os
+
+SRCS  = $(shell find $(OSAL_PATH) -maxdepth 1 -name '*.c')
+SRCS += $(shell find $(OSAL_PATH) -maxdepth 1 -name '*.cc')
+SRCS += $(PROJ_ROOT)/porting/common/src/os/os_mempool.c
+
+OBJS  = $(patsubst %.c, %.o,$(filter %.c,  $(SRCS)))
+OBJS += $(patsubst %.cc,%.o,$(filter %.cc, $(SRCS)))
+
+TEST_SRCS  = $(shell find . -maxdepth 1 -name '*.c')
+TEST_SRCS += $(shell find . -maxdepth 1 -name '*.cc')
+
+TEST_OBJS  = $(patsubst %.c, %.o,$(filter %.c,  $(SRCS)))
+TEST_OBJS += $(patsubst %.cc,%.o,$(filter %.cc, $(SRCS)))
+
+### ===== Rules =====
+
+all: depend              \
+     test_os_mempool     \
+     test_os_task        \
+     test_os_eventq      \
+     test_os_callout     \
+     test_os_sem         \
+     $(NULL)
+
+test_os_mempool: test_os_mempool.o $(OBJS)
+	$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+test_os_task: test_os_task.o $(OBJS)
+	$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+test_os_eventq: test_os_eventq.o $(OBJS)
+	$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+test_os_callout: test_os_callout.o $(OBJS)
+	$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+test_os_sem: test_os_sem.o $(OBJS)
+	$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+test_sem: test_sem.o
+	$(LD) -o $@ $^ $(LDFLAGS) $(LIBS)
+
+test: all
+	./test_os_mempool
+	./test_os_task
+	./test_os_eventq
+	./test_os_callout
+	./test_os_sem
+
+show_objs:
+	@echo $(OBJS)
+
+### ===== Clean =====
+clean:
+	@echo "Cleaning artifacts."
+	rm *~ .depend $(OBJS)
+
+### ===== Dependencies =====
+### Rebuild if headers change
+depend: .depend
+
+.depend: $(SRCS) $(TEST_SRCS)
+	@echo "Building dependencies."
+	rm -f ./.depend
+	$(CC) $(CFLAGS) -MM $^ > ./.depend;
+
+include .depend
+
+### Generic rules based on extension
+%.o: %.c
+	$(CC) -c $(CFLAGS) $< -o $@
+
+%.o: %.cc
+	$(CPP) -c $(CFLAGS) $< -o $@
diff --git a/tests/unit/porting/os/test_os_callout.c b/tests/unit/porting/os/test_os_callout.c
new file mode 100644
index 00000000..f8cbe834
--- /dev/null
+++ b/tests/unit/porting/os/test_os_callout.c
@@ -0,0 +1,114 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+  Unit tests for the os_callout api:
+
+  void os_callout_init(struct os_callout *cf, struct os_eventq *evq,
+                       os_event_fn *ev_cb, void *ev_arg);
+  int os_callout_reset(struct os_callout *, int32_t);
+  int os_callout_queued(struct os_callout *c);
+  void os_callout_stop(struct os_callout *c);
+*/
+
+#include "test_util.h"
+#include "os/os.h"
+
+#define TEST_ARGS_VALUE  (55)
+#define TEST_INTERVAL    (100)
+
+static bool              s_tests_running = true;
+static struct os_task    s_task;
+static struct os_callout s_callout;
+static int               s_callout_args = TEST_ARGS_VALUE;
+
+static struct os_eventq  s_eventq;
+
+
+void on_callout(struct os_event *ev)
+{
+    VerifyOrQuit(ev->ev_arg == &s_callout_args,
+		 "callout: wrong args passed");
+
+    VerifyOrQuit(*(int*)ev->ev_arg == TEST_ARGS_VALUE,
+		 "callout: args corrupted");
+
+    s_tests_running = false;
+}
+
+/**
+ * os_callout_init(struct os_callout *c, struct os_eventq *evq,
+ *                 os_event_fn *ev_cb, void *ev_arg)
+ */
+int test_init()
+{
+    os_callout_init(&s_callout,
+		    &s_eventq,
+		    on_callout,
+		    &s_callout_args);
+    return PASS;
+}
+
+int test_queued()
+{
+  //VerifyOrQuit(os_callout_queued(&s_callout),
+  //	 "callout: not queued when expected");
+    return PASS;
+}
+
+int test_reset()
+{
+    return os_callout_reset(&s_callout, TEST_INTERVAL);
+}
+
+int test_stop()
+{
+    return PASS;
+}
+
+
+/**
+ * os_callout_init(struct os_callout *c, struct os_eventq *evq,
+ *                 os_event_fn *ev_cb, void *ev_arg)
+ */
+void test_task_run(void *args)
+{
+    SuccessOrQuit(test_init(),   "callout_init failed");
+    SuccessOrQuit(test_queued(), "callout_queued failed");
+    SuccessOrQuit(test_reset(),  "callout_reset failed");
+
+    while (s_tests_running)
+    {
+        os_eventq_run(&s_eventq);
+    }
+
+    printf("All tests passed\n");
+    exit(PASS);
+}
+
+int main(void)
+{
+    os_eventq_init(&s_eventq);
+
+    SuccessOrQuit(os_task_init(&s_task, "s_task", test_task_run,
+			       NULL, 1, 0, NULL, 0),
+		  "task: error initializing");
+
+    while (1) {}
+}
diff --git a/tests/unit/porting/os/test_os_mempool.c b/tests/unit/porting/os/test_os_mempool.c
new file mode 100644
index 00000000..a4eda46f
--- /dev/null
+++ b/tests/unit/porting/os/test_os_mempool.c
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "test_util.h"
+#include "os/os.h"
+
+#define    TEST_MEMPOOL_BLOCKS       4
+#define    TEST_MEMPOOL_BLOCK_SIZE   128
+
+static struct os_mempool s_mempool;
+
+static os_membuf_t s_mempool_mem[OS_MEMPOOL_SIZE(TEST_MEMPOOL_BLOCKS,
+						 TEST_MEMPOOL_BLOCK_SIZE)];
+
+static void *s_memblock[TEST_MEMPOOL_BLOCKS];
+
+/**
+ * Unit test for initializing a mempool.
+ *
+ * os_error_t os_mempool_init(struct os_mempool *mp, int blocks,
+ *                            int block_size, void *membuf, char *name);
+ *
+ */
+int test_init()
+{
+    int err;
+    err = os_mempool_init(NULL,
+			  TEST_MEMPOOL_BLOCKS,
+			  TEST_MEMPOOL_BLOCK_SIZE,
+			  NULL,
+			  "Null mempool");
+    VerifyOrQuit(err, "os_mempool_init accepted NULL parameters.");
+
+    err = os_mempool_init(&s_mempool,
+			  TEST_MEMPOOL_BLOCKS,
+			  TEST_MEMPOOL_BLOCK_SIZE,
+			  s_mempool_mem,
+			  "s_mempool");
+    return err;
+}
+
+/**
+ * Test integrity check of a mempool.
+ *
+ * bool os_mempool_is_sane(const struct os_mempool *mp);
+ */
+int test_is_sane()
+{
+    return (os_mempool_is_sane(&s_mempool)) ? PASS : FAIL;
+}
+
+/**
+ * Test getting a memory block from the pool, putting it back,
+ * and checking if it is still valid.
+ *
+ * void *os_memblock_get(struct os_mempool *mp);
+ *
+ * os_error_t os_memblock_put(struct os_mempool *mp, void *block_addr);
+ *
+ * int os_memblock_from(const struct os_mempool *mp, const void *block_addr);
+ */
+int test_stress()
+{
+    int loops = 3;
+    while(loops--)
+    {
+        for (int i = 0; i < 4; i++)
+	{
+	    s_memblock[i] = os_memblock_get(&s_mempool);
+	    VerifyOrQuit(os_memblock_from(&s_mempool, s_memblock[i]),
+			 "os_memblock_get return invalid block.");
+	}
+
+
+        for (int i = 0; i < 4; i++)
+	{
+ 	    SuccessOrQuit(os_memblock_put(&s_mempool, s_memblock[i]),
+			"os_memblock_put refused to take valid block.");
+	    //VerifyOrQuit(!os_memblock_from(&s_mempool, s_memblock[i]),
+	    //		 "Block still valid after os_memblock_put.");
+	}
+
+    }
+    return PASS;
+}
+
+int main(void)
+{
+    SuccessOrQuit(test_init(),    "Failed: os_mempool_init");
+    SuccessOrQuit(test_is_sane(), "Failed: os_mempool_is_sane");
+    SuccessOrQuit(test_stress(),  "Failed: os_mempool stree test");
+    SuccessOrQuit(test_is_sane(), "Failed: os_mempool_is_sane");
+    printf("All tests passed\n");
+    return PASS;
+}
diff --git a/tests/unit/porting/os/test_os_sem.c b/tests/unit/porting/os/test_os_sem.c
new file mode 100644
index 00000000..77ce9a4e
--- /dev/null
+++ b/tests/unit/porting/os/test_os_sem.c
@@ -0,0 +1,150 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.
+ */
+
+/**
+  Unit tests for the Semaphore api (os_sem):
+
+  os_error_t os_sem_init(struct os_sem *sem, uint16_t tokens);
+  os_error_t os_sem_release(struct os_sem *sem);
+  os_error_t os_sem_pend(struct os_sem *sem, uint32_t timeout);
+  uint16_t os_sem_get_count(struct os_sem *sem);
+*/
+
+#include "test_util.h"
+#include "os/os.h"
+
+#define TEST_ITERATIONS   10
+
+#define TASK1_PRIO        1
+#define TASK2_PRIO        1
+
+#define TASK1_STACK_SIZE  1028
+#define TASK2_STACK_SIZE  1028
+
+static struct os_task    task1;
+static struct os_task    task2;
+
+static os_stack_t task1_stack[TASK1_STACK_SIZE];
+static os_stack_t task2_stack[TASK2_STACK_SIZE];
+
+struct os_sem task1_sem;
+struct os_sem task2_sem;
+
+/* Task 1 handler function */
+void
+task1_handler(void *arg)
+{
+    for (int i = 0; i < TEST_ITERATIONS; i++)
+    {
+	/* Release semaphore to task 2 */
+        SuccessOrQuit(os_sem_release(&task1_sem),
+		      "os_sem_release: error releasing task2_sem.");
+
+	/* Wait for semaphore from task 2 */
+        SuccessOrQuit(os_sem_pend(&task2_sem, OS_TIMEOUT_NEVER),
+		      "os_sem_pend: error waiting for task2_sem.");
+    }
+
+    printf("All tests passed\n");
+    exit(PASS);
+}
+
+/* Task 2 handler function */
+void
+task2_handler(void *arg)
+{
+    while(1)
+    {
+        /* Wait for semaphore from task1 */
+        SuccessOrQuit(os_sem_pend(&task1_sem, OS_TIMEOUT_NEVER),
+		      "os_sem_pend: error waiting for task1_sem.");
+
+	/* Release task2 semaphore */
+        SuccessOrQuit(os_sem_release(&task2_sem),
+		      "os_sem_release: error releasing task1_sem.");
+    }
+}
+
+
+/* Initialize task 1 exposed data objects */
+void
+task1_init(void)
+{
+    /* Initialize task1 semaphore */
+    SuccessOrQuit(os_sem_init(&task1_sem, 0),
+		  "os_sem_init: task1 returned error.");
+}
+
+/* Initialize task 2 exposed data objects */
+void
+task2_init(void)
+{
+    /* Initialize task1 semaphore */
+    SuccessOrQuit(os_sem_init(&task2_sem, 0),
+		  "os_sem_init: task2 returned error.");
+}
+
+/**
+ * init_app_tasks
+ *
+ * This function performs initializations that are required before tasks run.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static int
+init_app_tasks(void)
+{
+    /*
+     * Call task specific initialization functions to initialize any shared objects
+     * before initializing the tasks with the OS.
+     */
+    task1_init();
+    task2_init();
+
+    /*
+     * Initialize tasks 1 and 2 with the OS.
+     */
+    os_task_init(&task1, "task1", task1_handler, NULL, TASK1_PRIO,
+		 OS_WAIT_FOREVER, task1_stack, TASK1_STACK_SIZE);
+
+    os_task_init(&task2, "task2", task2_handler, NULL, TASK2_PRIO,
+		 OS_WAIT_FOREVER, task2_stack, TASK2_STACK_SIZE);
+
+    return 0;
+}
+
+/**
+ * main
+ *
+ * The main function for the application. This function initializes the system and packages,
+ * calls the application specific task initialization function, then waits and dispatches
+ * events from the OS default event queue in an infinite loop.
+ */
+int
+main(int argc, char **arg)
+{
+    /* Initialize application specific tasks */
+    init_app_tasks();
+
+    while (1)
+    {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* main never returns */
+}
diff --git a/tests/unit/porting/os/test_os_task.c b/tests/unit/porting/os/test_os_task.c
new file mode 100644
index 00000000..da59accf
--- /dev/null
+++ b/tests/unit/porting/os/test_os_task.c
@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 "test_util.h"
+#include "os/os_mempool.h"
+
+#include <pthread.h>
+
+#define TASK0_ARG     55
+#define TASK1_ARG     66
+
+static struct os_task s_task[2];
+static int            s_task_arg[2] =
+{
+    TASK0_ARG, TASK1_ARG
+};
+
+
+void task0_run(void *args)
+{
+    int i = 10000;
+    VerifyOrQuit(args == &s_task_arg[0], "Wrong args passed to task0");
+
+    while (i--)
+    {
+    }
+}
+
+void task1_run(void *args)
+{
+    int i = 10000;
+    VerifyOrQuit(args == &s_task_arg[1], "Wrong args passed to task0");
+
+    while (i--)
+    {
+    }
+
+    printf("All tests passed\n");
+    exit(PASS);
+}
+
+/**
+ * Unit test for initializing a task.
+ *
+ * int os_task_init(struct os_task *t, const char *name, os_task_func_t func,
+ *                  void *arg, uint8_t prio, os_time_t sanity_itvl,
+ *                  os_stack_t *stack_bottom, uint16_t stack_size)
+ *
+ */
+int test_init()
+{
+    int err;
+    err = os_task_init(NULL,
+		       "Null task",
+		       NULL, NULL, 1, 0, NULL, 0);
+    VerifyOrQuit(err, "os_task_init accepted NULL parameters.");
+
+    err = os_task_init(&s_task[0],
+		       "s_task[0]",
+		       task0_run, &s_task_arg[0], 1, 0, NULL, 0);
+    SuccessOrQuit(err, "os_task_init failed.");
+
+    err = os_task_init(&s_task[1],
+		       "s_task[1]",
+		       task1_run, &s_task_arg[1], 1, 0, NULL, 0);
+
+    return err;
+}
+
+int main(void)
+{
+    int ret = PASS;
+    SuccessOrQuit(test_init(),    "Failed: os_task_init");
+
+    pthread_exit(&ret);
+
+    return ret;
+}
diff --git a/tests/unit/porting/os/test_util.h b/tests/unit/porting/os/test_util.h
new file mode 100644
index 00000000..89af1a07
--- /dev/null
+++ b/tests/unit/porting/os/test_util.h
@@ -0,0 +1,55 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 _TEST_UTIL_H_
+#define _TEST_UTIL_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdio.h>
+
+#define PASS    (0)
+#define FAIL    (-1)
+
+#define SuccessOrQuit(ERR, MSG)						      \
+  do {                                                                        \
+    if ((ERR))                                                                \
+    {                                                                         \
+      fprintf(stderr, "\nFAILED %s:%d - %s\n", __FUNCTION__, __LINE__, MSG);  \
+      exit(-1);                                                               \
+    }                                                                         \
+  } while (false)
+
+#define VerifyOrQuit(TST, MSG)                                                \
+  do {                                                                        \
+    if (!(TST))                                                               \
+    {                                                                         \
+      fprintf(stderr, "\nFAILED %s:%d - %s\n", __FUNCTION__, __LINE__, MSG);  \
+      exit(-1);                                                               \
+    }                                                                         \
+  } while (false)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* _TEST_UTIL_H_ */


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services