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 2019/01/11 23:47:57 UTC

[GitHub] minchingho-pax closed pull request #1596: Pkf 443

minchingho-pax closed pull request #1596: Pkf 443
URL: https://github.com/apache/mynewt-core/pull/1596
 
 
   

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/.gitignore b/.gitignore
index 4d2aacee69..86f93128e2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,7 +34,16 @@ tags
 docs/html
 docs/latex
 cscope.*
+*.tags
+stlink.log
+openocd.log
+*.pem
 
 # Prevent accidental checkins of personal targets.  If you need to commit a
 # target, specify the -f option for "git add".
 targets
+
+# Generated directories - pubkey sources, coverity data, etc
+/keys/
+/repos/
+/cov-int/
diff --git a/.mailmap b/.mailmap
new file mode 100644
index 0000000000..b0d2c86703
--- /dev/null
+++ b/.mailmap
@@ -0,0 +1,28 @@
+Aditi Hilbert <ad...@runtime.io>			<ad...@runtime.io>
+Alfred Schilken <al...@schilken.de>			<al...@schilken.de>
+Brian Giori <br...@gmail.com>			<bg...@users.noreply.github.com>
+Christopher Collins <cc...@apache.org>		<cc...@gmail.com>
+Christopher Collins <cc...@apache.org>		<cc...@iori.nightmare-heaven.no-ip.biz>
+David G. Simmons <sa...@mac.com>			<da...@users.noreply.github.com>
+Fabio Utzig <ut...@utzig.org>				<ut...@apache.org>
+Francois Berder <fb...@outlook.fr>			<fb...@outlook.fr>
+Gordon Klaus <go...@gmail.com>			<go...@telenordigital.com>
+Jacob Rosenthal <ja...@gmail.com>		<ja...@gmail.com>
+Jacob Rosenthal <ja...@gmail.com>		<ja...@localhost.localdomain>
+Julian Ingram <ju...@imgtec.com>		<ju...@imgtec.com>
+Julian Ingram <ju...@imgtec.com>		<jj...@gmail.com>
+Julian Ingram <ju...@imgtec.com>		<IM...@users.noreply.github.com>
+Marko Kiiskila <ma...@runtime.io>			<ma...@runtime.io>
+Marko Kiiskila <ma...@runtime.io>			<ma...@Markos-MacBook-Pro-2.local>
+Neel Natu <ne...@nahannisys.com>				<ne...@neels-Air.attlocal.net>
+Neel Natu <ne...@nahannisys.com>				<ne...@neels-MacBook-Air.local>
+Peter Snyder <pe...@apache.org>			<gi...@peterfs.com>
+Sterling Hughes <st...@apache.org>			<st...@apache.org>
+Sterling Hughes <st...@apache.org>			<st...@micosa.net>
+Sterling Hughes <st...@apache.org>			<st...@runtime.io>
+Sterling Hughes <st...@apache.org>			<st...@users.noreply.github.com>
+Szymon Janc <sz...@codecoup.pl>			<sz...@gmail.com>
+Vipul Rahane <vi...@apache.org>			<vi...@runtime.io>
+Vipul Rahane <vi...@apache.org>			<vr...@gmail.com>
+William San Filippo <wi...@runtime.io>			<wi...@micosa.io>
+William San Filippo <wi...@runtime.io>			<wi...@runtime.io>
diff --git a/.rat-excludes b/.rat-excludes
index 8143f67761..2438a7a6e1 100644
--- a/.rat-excludes
+++ b/.rat-excludes
@@ -10,13 +10,14 @@ tags
 RELEASE_NOTES.md
 repository.yml
 .gitignore
-pts-gap.txt
-pts-gatt.txt
-pts-l2cap.txt
-pts-sm.txt
-90359-20161220-172100175.tpg
-90359-20161220-172113981.pts
 00readme.txt
+uncrustify.cfg
+README.md
+.mailmap
+version.txt
+
+# unit tests executables
+bin
 
 # CRC16 - BSD License.
 crc16.*
@@ -85,6 +86,35 @@ uicr_config.h
 iar_startup_nrf51.s
 iar_startup_nrf52.s
 
+# Nordic BLE400 SDK - BSD License
+ble400_no_boot.ld
+split-ble400.ld
+
+# Nordic nRF52 Thingy SDK - BSD License
+nrf52-thingy_no_boot.ld
+split-nrf52-thingy.ld
+
+# RedBear Blend2 SDK - BSD License
+rb-blend2_no_boot.ld
+split-rb-blend2.ld
+
+# Telenor ee02 SDK - BSD License
+split-telee02.ld
+telee02_no_boot.ld
+
+# VBLUno51 board - BSD License
+split-vbluno51.ld
+vbluno51_no_boot.ld
+
+# VBLUno52 board - BSD License
+split-vbluno52.ld
+vbluno52_no_boot.ld
+
+# STM32 HAL - BSD License
+stm32_driver_mod_i2c_v1.c
+stm32_driver_mod_i2c_v2.c
+stm32_driver_mod_spi.c
+
 # STM32CubeF4  - BSD License.
 stm32f4xx_hal_conf.h
 system_stm32f4xx.c
@@ -183,8 +213,20 @@ core_cmInstr.h
 cmsis_nvic.c
 cmsis_nvic.h
 HAL_CM0.s
+HAL_CM3.s
 HAL_CM4.s
 SVC_Table.s
+arm_common_tables.h
+arm_const_structs.h
+arm_math.h
+cmsis_armcc.h
+cmsis_armcc_V6.h
+cmsis_gcc.h
+core_cm7.h
+core_cmSimd.h
+core_sc000.h
+core_sc300.h
+HAL_CM7.s
 
 # microjson - BSD License.
 MSJSON_COPYING
@@ -234,7 +276,7 @@ unicode.c
 split-nrf52840pdk.ld
 nrf52840pdk_no_boot.ld
 
-#Freescale Semiconductor License
+# Freescale Semiconductor License
 boot-mkw41z512.ld
 mkw41z512.ld
 no-boot-mkw41z512.ld
@@ -245,7 +287,140 @@ system_MKW41Z4.h
 MKW41Z4_features.h
 system_MKW41Z4.c
 
-#Imagination Technologies License
+# Imagination Technologies - BSD License
+mips-hal
 ctx.S
 excpt_isr.S
 uhi32.ld
+abiflags.S
+
+# Cygnus Support - MIT like License
+gcc_startup_mips.S
+
+# HiFive1 - Apache License 2.0
+sifive
+
+# MQTT - Eclipse Public License
+mqtt
+
+# CMSIS Cortex-M7, STM32f7 - BSD License.
+STM32F7xx
+STM32F7xx_HAL_Driver
+
+# LORA - BSD License
+lora
+
+# loraping - BSD License (main.c only)
+loraping
+
+# SEGGER Sysview - BSD License
+sysview
+
+# SEGGER RTT - BSD License
+rtt
+
+# Adafruit TSL2561 Sensor - BSD License
+tsl2561
+
+# pic32mx470f512h - BSD License
+pic32mx470f512h
+
+# Sensorhub board - BSD License
+startup_STM32F427xx.s
+
+# STM32F7 Discovery BSP - BSD License
+stm32f7xx_hal_conf.h
+system_stm32f7xx.c
+startup_stm32f746xx.s
+
+# STM32F3 Discovery BSP - BSD License
+startup_stm32f303xc.s
+
+# STM32F429 BSP - BSD License
+startup_STM32F429x.s
+
+# STM32L152C BSP - BSD License
+stm32l1xx_hal_conf.h
+system_stm32l1xx.c
+startup_stm32l152xc.s
+
+# NUCLEO-F767 BSP - BSD License
+startup_stm32f767xx.s
+
+# Microchip PIC32 SDK - BSD License
+p32mz2048efg100.h
+pic32_init_cache.S
+pic32_init_tlb_ebi_sqi.S
+cache-err-exception.S
+cp0defs.h
+simple-tlb-refill-exception.S
+crt0.S
+
+# Calliope SDK - BSD Licence
+split-calliope_mini.ld
+
+# Bluetooth Mesh - Apache 2.0 License
+mesh
+
+# pic32mx470_6lp_clicker BSP - one BSD licensed file (other are Apache):
+# /hw/bsp/pic32mx470_6lp_clicker/src/sbrk.c
+pic32mx470_6lp_clicker
+
+# pic32mz2048_wi-fire BSP - one BSD licensed file (other are Apache):
+# ./hw/bsp/pic32mz2048_wi-fire/src/sbrk.c
+pic32mz2048_wi-fire
+
+# SDK for Apollo2 - MIT/BSD/Apache License
+# hw/bsp/apollo2_evb/src/arch/cortex_m4/gcc_startup.s
+apollo2_evb
+
+# BSP for Apollo2 - BSD License
+AmbiqSuite
+apollo2.h
+system_apollo2.h
+system_apollo2.c
+apollo_nvic.h
+
+# Apollo2 linker script - MIT License
+apollo2.ld
+
+# CMSIS Cortex-M4, STM32f3 - BSD License.
+STM32F3xx
+STM32F3xx_HAL_Driver
+
+# Nucleo-F303K8, Nucleo-F303RE - BSD License.
+system_stm32f3xx.c
+startup_stm32f303x8.s
+startup_stm32f303xe.s
+stm32f3xx_hal_conf.h
+
+# Ignore documentation folder
+docs
+
+# nrfX - BSD License
+nrfx
+nrfx_glue.h
+
+# cmsis-core - Apache License
+cmsis-core
+
+# stm32l1xx - BSD License
+stm32l1xx
+
+# stm32f1xx - BSD License
+stm32f1xx
+
+# ARC - BSD License
+arc
+embarc_emsk
+
+# DWM1001 - BSD Licence
+dwm1001-dev_no_boot.ld
+split-dwm1001-dev.ld
+
+# olimex-p103 - BSD and APL 2.0 License
+olimex-p103
+
+# puckjs - BSD License
+puckjs_no_boot.ld
+split_puckjs.ld
diff --git a/DISCLAIMER b/DISCLAIMER
deleted file mode 100644
index 1600825bb7..0000000000
--- a/DISCLAIMER
+++ /dev/null
@@ -1,8 +0,0 @@
-Apache Mynewt is an effort undergoing incubation at The Apache Software
-Foundation (ASF), sponsored by the Incubator PMC.  Incubation is
-required of all newly accepted projects until a further review indicates
-that the infrastructure, communications, and decision making process
-have stabilized in a manner consistent with other successful ASF
-projects. While incubation status is not necessarily a reflection of the
-completeness or stability of the code, it does indicate that the project
-has yet to be fully endorsed by the ASF.
diff --git a/LICENSE b/LICENSE
index 0473ed5867..8d8a09b181 100644
--- a/LICENSE
+++ b/LICENSE
@@ -260,21 +260,16 @@ This product bundles additional files from CMSIS-CORE, but these files are
 missing licensing information.  The BSD license was subsequently added to
 these files in later releases.  These files are:
     * hw/cmsis-core/src/cmsis_nvic.c
-    * hw/bsp/ada_feather_nrf52/include/bsp/cmsis_nvic.h
-    * hw/bsp/arduino_primo_nrf52/include/bsp/cmsis_nvic.h
-    * hw/bsp/bbc_microbit/include/bsp/cmsis_nvic.h
-    * hw/bsp/bmd200/include/bsp/cmsis_nvic.h
-    * hw/bsp/bmd300eval/include/bsp/cmsis_nvic.h
-    * hw/bsp/nrf51-arduino_101/include/bsp/cmsis_nvic.h
-    * hw/bsp/nrf51-blenano/include/bsp/cmsis_nvic.h
-    * hw/bsp/nrf51dk/include/bsp/cmsis_nvic.h
-    * hw/bsp/nrf51dk-16kbram/include/bsp/cmsis_nvic.h
-    * hw/bsp/nrf52840pdk/include/bsp/cmsis_nvic.h
-    * hw/bsp/nrf52dk/include/bsp/cmsis_nvic.h
-    * hw/bsp/nucleo-f401re/include/bsp/cmsis_nvic.h
-    * hw/bsp/olimex_stm32-e407_devboard/include/bsp/cmsis_nvic.h
-    * hw/bsp/rb-nano2/include/bsp/cmsis_nvic.h
-    * hw/bsp/stm32f4discovery/include/bsp/cmsis_nvic.h
+    * hw/mcu/ambiq/apollo2/include/mcu/cmsis_nvic.h
+    * hw/mcu/nordic/nrf51xxx/include/mcu/cmsis_nvic.h
+    * hw/mcu/nordic/nrf52xxx/include/mcu/cmsis_nvic.h
+    * hw/mcu/nxp/MK64F12/include/mcu/cmsis_nvic.h
+    * hw/mcu/nxp/mkw41z/include/mcu/cmsis_nvic.h
+    * hw/mcu/stm/stm32f1xx/include/mcu/cmsis_nvic.h
+    * hw/mcu/stm/stm32f3xx/include/mcu/cmsis_nvic.h
+    * hw/mcu/stm/stm32f4xx/include/mcu/cmsis_nvic.h
+    * hw/mcu/stm/stm32f7xx/include/mcu/cmsis_nvic.h
+    * hw/mcu/stm/stm32l1xx/include/mcu/cmsis_nvic.h
 
 This product bundles parts of STM32CubeF4 1.5, which is available under the
 "3-clause BSD" license.  Bundled files are:
@@ -296,32 +291,27 @@ This product bundles parts of STM32CubeF7, which is available under the
     * hw/bsp/stm32f767-nucleo/src/system_stm32f7xx.c
     * hw/bsp/stm32f767-nucleo/src/arch/cortex_m7/startup_stm32f767xx.s
 
-This product bundles parts of mbed, which is available under the
+This product bundles parts of STM32CubeF3, which is available under the
 "3-clause BSD" license.  Bundled files are:
-    * hw/mcu/nordic/nrf51xxx/include/mcu/cortex_m0.h
-    * hw/mcu/nordic/nrf52xxx/include/mcu/cortex_m4.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/compiler_abstraction.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf51.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52840.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf51_to_nrf52.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf51_to_nrf52840.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52_to_nrf52840.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf51_bitfields.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52_bitfields.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52840_bitfields.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52840_peripherals.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf51_deprecated.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf51.c
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf51.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf51422.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf51422.c
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf52.c
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf52.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf52840.c
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/toolchain/system_nrf52840.h
-    * hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/device/nrf52_name_change.h
+    * hw/mcu/stm/stm32f3xx/src/ext
+    * hw/bsp/stm32f3discovery
+
+This product bundles parts of stm32l1xx, which is available under the
+"3-clause BSD" license.  Bundled files are:
+    * hw/bsp/stm32l152discovery/src/system_stm32l1xx.c
+    * hw/bsp/stm32l152discovery/include/bsp/stm32l1xx_hal_conf.h
+    * hw/bsp/stm32l152discovery/src/system_stm32l1xx.c
+    * hw/mcu/stm/stm32l1xx/src/ext/
+
+This product bundles parts of stm32f1xx, which is available under the
+"3-clause BSD" license.  Bundled files are:
+    * hw/bsp/olimex-p103/include/bsp/stm32f1xx_hal_conf.h
+    * hw/bsp/olimex-p103/src/system_stm32f1xx.c
+    * hw/mcu/stm/stm32f1xx/src/ext/
+
+This product bundles parts of nrfx, which is available under the
+"3-clause BSD" license.  For detalils see:
+    * hw/mcu/nordic/src/ext/nrfx/LICENSE
 
 This product bundles FATFS, which is available under a
 "1-clause BSD" style license.  Bundled files are:
@@ -342,6 +332,7 @@ This product bundles part of linker scripts Nordic Semiconductor nRF5 devices, w
     * hw/bsp/nrf52dk/nrf52dk_no_boot.ld
     * hw/mcu/nordic/nrf51xxx/nrf51.ld
     * hw/mcu/nordic/nrf52xxx/nrf52.ld
+    * hw/mcu/ambiq/apollo2/apollo2.ld
 
 This product bundles part of NXP/FreeScale SDK, which is available
 under the "3-clause BSD" license. Bundled files are:
@@ -374,3 +365,80 @@ This product bundles tinycrypt, which is available under the "3-clause BSD"
 license. For details, and bundled files see:
     * crypto/tinycrypt/LICENSE
     * crypto/tinycrypt
+
+This product bundles parts of the Generic SX1276 driver from Semtech, which
+is available under the "3-clause BSD" license. For details, see:
+    * apps/loraping/src/main.c
+    * hw/drivers/lora/sx1276/LICENSE.txt
+
+This product bundles parts of SEGGER RTT, which is available under the
+"3-clause BSD" license. For details, see:
+    * hw/drivers/rtt
+
+This products bundle Adafruit's tsl2561 driver, which is available under the
+"3-clause BSD" license. For details, see:
+    * hw/drivers/sensors/tsl2561
+
+This products bundles Amiq Micro Apollo 2, which is available under the
+"3-clause BSD" license. Bundled files are:
+    * hw/mcu/ambiq/apollo2/include/mcu/apollo2.h
+    * hw/mcu/ambiq/apollo2/include/mcu/system_apollo2.h
+
+This product bundles processor headers for PIC32 by Microchip Technology
+Inc., which is available under the "3-clause BSD" license. Bundled files are:
+    * hw/mcu/microchip/pic32mx470f512h/include/mcu/p32mx470f512h.h
+    * hw/mcu/microchip/pic32mx470f512h/include/mcu/ppic32mx.h
+
+This product bundles MIPS processor low-level macros by Imagination
+Technologies Limited, which is available under the "3-clause BSD" license.
+Bundled files are included inside:
+    * hw/mips-hal/src/arch/mips
+
+This product bundles parts of LoRaWAN endpoint stack by Semtech, which is
+available under the "3-clause BSD" license. For details, see:
+    * net/lora/node/LICENSE.txt
+
+This product bundles Eclipse Paho's MQTT by IBM Corp. which is available
+under the Eclipse Public License 1.0. For details see:
+    * net/mqtt/eclipse/LICENSE.txt
+
+This product bundles SEGGER SystemView, which is available under the
+"3-clause BSD" license. For details, see:
+    * sys/sysview/vendor
+
+This product bundles normalizer.css, affix.js and scrollspy.js by Twitter
+which are available under the MIT license. Bundled files are:
+    * docs/_static/css/bootstrap-3.0.3.min.css
+    * docs/themes/mynewt/static/js/affix.js
+    * docs/themes/mynewt/static/js/scrollspy.js
+
+This product bundles tinycbor by Intel Corporation, which is available under
+the MIT license. For details see:
+    * encoding/tinycbor/include/tinycbor
+
+This product bundles FontAwesome by Dave Gandy, which is available under the
+SIL Open Font License 1.1. Bundled files are:
+    * docs/themes/mynewt/static/fonts/fontawesome-webfont.eot
+    * docs/themes/mynewt/static/fonts/fontawesome-webfont.svg
+    * docs/themes/mynewt/static/fonts/fontawesome-webfont.ttf
+    * docs/themes/mynewt/static/fonts/fontawesome-webfont.woff
+    * docs/themes/mynewt/static/fonts/FontAwesome.otf
+
+This product bundles Inconsolata by Raph Levien, which is available under the
+SIL Open Font License 1.1. Bundled files are:
+    * docs/themes/mynewt/static/fonts/Inconsolata-Bold.ttf
+    * docs/themes/mynewt/static/fonts/Inconsolata-Regular.ttf
+
+This product bundles Lato by Łukasz Dziedzic, which is available under the
+SIL Open Font License 1.1. Bundled files are:
+    * docs/themes/mynewt/static/fonts/Lato-Bold.ttf
+    * docs/themes/mynewt/static/fonts/Lato-Regular.ttf
+
+This product bundles RobotSlab by Christian Robertson, which is available
+under the Apache License v2.0. Bundled files are:
+    * docs/themes/mynewt/static/fonts/RobotoSlab-Bold.ttf
+    * docs/themes/mynewt/static/fonts/RobotoSlab-Regular.ttf
+
+This product bundles part of embARC BSP SDK by Synopsys, which is available
+under the "3-clause BSD" license. Bundled files are:
+    * hw/mcu/arc/src/ext/sdk
diff --git a/NOTICE b/NOTICE
index 8648ba987c..4ba7354179 100644
--- a/NOTICE
+++ b/NOTICE
@@ -1,4 +1,4 @@
-Apache Mynewt (incubating)
+Apache Mynewt
 Copyright 2015-2017 The Apache Software Foundation
 
 This product includes software developed at
diff --git a/README.md b/README.md
index 44f6b74e08..39b646166f 100644
--- a/README.md
+++ b/README.md
@@ -32,10 +32,13 @@ It currently supports the following hardware platforms:
 * nRF52 DK from Nordic Semiconductor (Cortex-M4)
 * RuuviTag Sensor beacon platform (Nordic nRF52832 based)
 * nRF51 DK from Nordic Semiconductor (Cortex-M0)
+* VBLUno51 from VNG IoT Lab (Nordic nRF51822 SoC based)
+* VBLUno52 from VNG IoT Lab (Nordic nRF52832 SoC based, Cortex-M4)
 * BLE Nano from RedBear (Nordic nRF51822 SoC based)
 * BLE Nano2 and Blend2 from RedBear (Nordic nRF52832 SoC based)
 * BMD-300-EVAL-ES from Rigado (Cortex-M4)
 * BMD-200 from Rigado (Cortex-M0)
+* Adafruit Feather nRF52 Pro
 * STM32F4DISCOVERY from ST Micro (Cortex-M4)
 * STM32-E407 from Olimex (Cortex-M4)
 * Arduino Zero (Cortex-M0)
@@ -44,23 +47,33 @@ It currently supports the following hardware platforms:
 * Arduino MKR1000 (Cortex-M0)
 * Arduino Primo NRF52 (Cortex-M4)
 * NUCLEO-F401RE (Cortex-M4)
+* NUCLEO-F767ZI (Cortex-M7)
+* Discovery kit for STM32F7 Series (Cortex-M7)
 * FRDM-K64F from NXP (Cortex-M4)
 * BBC micro:bit (Nordic nrf51822; Cortex-M0)
+* SiFive HiFive1 (RISC-V Instruction Set Architecture)
+* NINA-B1 BLE module from u-blox (Cortex-M4)
+* 6LoWPAN clicker from MikroElectronika (PIC32MX470 microcontroller)
+* chipKIT Wi-FIRE (PIC32MZ microcontroller)
+* Creator Ci40 module (dual MIPS interAptiv CPU)
+* EE-02 board with Semtech Sx1276 chip from Telenor (Cortex-M4) 
 
 Apache Mynewt uses the
-[Newt](https://www.github.com/apache/incubator-mynewt-newt) build and package
+[Newt](https://www.github.com/apache/mynewt-newt) build and package
 management system, which allows you to compose your OS and choose only the
 components you need.
 
 This repository contains the core packages of the Apache Mynewt OS, including:
 
 * A Pre-emptive, Real Time OS Kernel
-* A open-source Bluetooth 4.2 stack (both Host & Controller), NimBLE, that
+* A open-source Bluetooth 5.0 stack (both Host & Controller), NimBLE, that
 completely replaces the proprietary SoftDevice on Nordic chipsets.
+<span style="color:red">**NOTE** NimBLE sources were moved to separate [repository](https://github.com/apache/mynewt-nimble).</span>
     - Support for 251 byte packet size
     - Support for all 4 roles concurrently - Broadcaster, Observer, Peripheral and Central
     - Support for up to 32 simultaneous connections.
     - Legacy and SC (secure connections) SMP support (pairing and bonding).
+    - Advertising Extensions.
 * A flash filesystem, NFFS, which is designed for tiny (128KB->16MB) flashes.
 * FatFS
 * Flash Circular Buffer
@@ -75,50 +88,37 @@ completely replaces the proprietary SoftDevice on Nordic chipsets.
 For more information on the Mynewt OS, please visit our website [here](https://mynewt.apache.org/).
 If you'd like to get started, visit the [Quick Start Guide](http://mynewt.apache.org/quick-start/).
 
-## Roadmap
-
-Mynewt is being actively developed.  Some of the features we're currently working on:
-
-* Deep sleep: Mynewt OS will coordinate peripherals and processor to put the
-  processor to sleep when all tasks are idle.
-* Sensor API
-* IP Stack
-* Support for different boards and microcontroller architectures, we're working
-  on:
-    - ESP8266
-    - Arduino Uno
-    - Arduino Mega
-
 ## Browsing
 
 If you are browsing around the source tree, and want to see some of the
 major functional chunks, here are a few pointers:
 
-- kernel: Contains the core of the RTOS ([kernel/os](https://github.com/apache/incubator-mynewt-core/tree/master/kernel/os))
+- kernel: Contains the core of the RTOS ([kernel/os](https://github.com/apache/mynewt-core/tree/master/kernel/os))
 
 - sys: Contains a number of helper libraries for building applications.  Including a
-console ([sys/console](https://github.com/apache/incubator-mynewt-core/tree/master/sys/console))),
-shell ([sys/shell](https://github.com/apache/incubator-mynewt-core/tree/master/sys/shell)))
+console ([sys/console](https://github.com/apache/mynewt-core/tree/master/sys/console))),
+shell ([sys/shell](https://github.com/apache/mynewt-core/tree/master/sys/shell)))
 
-- mgmt: Contains the management libraries for newtmgr [mgmt/newtmgr](https://github.com/apache/incubator-mynewt-core/tree/master/sys/newtmgr)), which supports software upgrade and remote fetching of logs and statistics.
+- mgmt: Contains the management libraries for newtmgr [mgmt/newtmgr](https://github.com/apache/mynewt-core/tree/master/sys/newtmgr)), which supports software upgrade and remote fetching of logs and statistics.
 
 - net: Contains the networking packages.  Highlights of the net directory are the NimBLE and IP packages.
-[Nimble](https://github.com/apache/incubator-mynewt-core/tree/master/net/nimble)
+[Nimble](https://github.com/apache/mynewt-nimble)
 is a full Bluetooth host and controller implementation, that is written
-from the ground up for the Apache Mynewt Operating System.
-[ip](https://github.com/apache/incubator-mynewt-core/tree/master/net/ip) is a port of LWIP, a complete IPv4 and IPv6 implementation.
+from the ground up for the Apache Mynewt Operating System (due to code moved to
+separate repo this folder contains only compatibility package files).
+[ip](https://github.com/apache/mynewt-core/tree/master/net/ip) is a port of LWIP, a complete IPv4 and IPv6 implementation.
 
 - hw: Contains the HW specific support packages.  Board Support Packages
-are located in [hw/bsp](https://github.com/apache/incubator-mynewt-core/tree/master/hw/bsp),
+are located in [hw/bsp](https://github.com/apache/mynewt-core/tree/master/hw/bsp),
 and the MCU specific definitions they rely on are located in
-[hw/mcu](https://github.com/apache/incubator-mynewt-core/tree/master/hw/mcu).
+[hw/mcu](https://github.com/apache/mynewt-core/tree/master/hw/mcu).
 There is a HAL (Hardware Abstraction Layer) stored in
-[hw/hal](https://github.com/apache/incubator-mynewt-core/tree/master/hw/hal), even
-though the implementation of various HALs are stored in the MCU specific definitions.  Finally, drivers can be found in [hw/drivers](https://github.com/apache/incubator-mynewt-core/tree/master/hw/drivers).  Drivers provide a higher-level interface to the hardware than the HAL, and may require the Mynewt operating system to function.
+[hw/hal](https://github.com/apache/mynewt-core/tree/master/hw/hal), even
+though the implementation of various HALs are stored in the MCU specific definitions.  Finally, drivers can be found in [hw/drivers](https://github.com/apache/mynewt-core/tree/master/hw/drivers).  Drivers provide a higher-level interface to the hardware than the HAL, and may require the Mynewt operating system to function.
 
-- fs: Contains the FS package ([fs/fs](https://github.com/apache/incubator-mynewt-core/tree/master/fs/fs))
+- fs: Contains the FS package ([fs/fs](https://github.com/apache/mynewt-core/tree/master/fs/fs))
 which is the high-level Apache Mynewt file system API.   A specific implementation of that FS, is
-[NFFS](https://github.com/apache/incubator-mynewt-core/tree/master/fs/nffs) (Newtron
+[NFFS](https://github.com/apache/mynewt-core/tree/master/fs/nffs) (Newtron
 Flash File System.)  The Newtron file system is a FS that has been built from
 the ground-up in Apache Mynewt, designed to be optimized for small
 (64KB-32MB) flashes.
@@ -130,28 +130,27 @@ In addition to some of the core packages, there are also some sample
 applications that show how to instantiate the Apache Mynewt system.  These
 sample applications are located in the `apps/` directory.  They include:
 
-* [boot](https://github.com/apache/incubator-mynewt-core/tree/master/apps/boot):
+* [boot](https://github.com/apache/mynewt-core/tree/master/apps/boot):
   Project to build the bootloader for test platforms.
-* [blinky](https://github.com/apache/incubator-mynewt-core/tree/master/apps/blinky): The
+* [blinky](https://github.com/apache/mynewt-core/tree/master/apps/blinky): The
   minimal packages to build the OS, and blink a LED!
-* [slinky](https://github.com/apache/incubator-mynewt-core/tree/master/apps/slinky): A
+* [slinky](https://github.com/apache/mynewt-core/tree/master/apps/slinky): A
   slightly more complex project that includes the console and shell libraries.
-* [blecent](https://github.com/apache/incubator-mynewt-core/tree/master/apps/blecent): A basic central device with no user interface.  This
+* [blecent](https://github.com/apache/mynewt-core/tree/master/apps/blecent): A basic central device with no user interface.  This
 application scans for a peripheral that supports the alert notification
 service (ANS).  Upon discovering such a peripheral, blecent connects and
 performs a characteristic read, characteristic write, and notification subscription.
-* [blehci](https://github.com/apache/incubator-mynewt-core/tree/master/apps/blehci): Implements a BLE controller-only application.  A separate
+* [blehci](https://github.com/apache/mynewt-core/tree/master/apps/blehci): Implements a BLE controller-only application.  A separate
 host-only implementation, such as Linux's BlueZ, can interface with this
 application via HCI over UART.
-* [bleprph](https://github.com/apache/incubator-mynewt-core/tree/master/apps/bleprph): An
+* [bleprph](https://github.com/apache/mynewt-core/tree/master/apps/bleprph): An
   implementation of a minimal BLE peripheral.
-* [bletiny](https://github.com/apache/incubator-mynewt-core/tree/master/apps/bletiny): A
-  stripped down interface to the Apache Mynewt Bluetooth stack.
-* [bleuart](https://github.com/apache/incubator-mynewt-core/tree/master/apps/bleuart):
+* [btshell](https://github.com/apache/mynewt-core/tree/master/apps/btshell): Shell interface to the Apache Mynewt Bluetooth stack.
+* [bleuart](https://github.com/apache/mynewt-core/tree/master/apps/bleuart):
 Implements a simple BLE peripheral that supports the Nordic
 UART / Serial Port Emulation service
 (https://developer.nordicsemi.com/nRF5_SDK/nRF51_SDK_v8.x.x/doc/8.0.0/s110/html/a00072.html).
-* [test](https://github.com/apache/incubator-mynewt-core/tree/master/apps/test): Test
+* [test](https://github.com/apache/mynewt-core/tree/master/apps/test): Test
   project which can be compiled either with the simulator, or on a per-architecture basis.
   Test will run all the package's unit tests.
 
@@ -159,7 +158,7 @@ UART / Serial Port Emulation service
 
 If you are having trouble using or contributing to Apache Mynewt, or just want to talk
 to a human about what you're working on, you can contact us via the
-[developers mailing list](mailto:dev@mynewt.incubator.apache.org).
+[developers mailing list](mailto:dev@mynewt.apache.org).
 
 Although not a formal channel, you can also find a number of core developers
 on the #mynewt channel on Freenode.
@@ -181,7 +180,7 @@ website, located [here](https://mynewt.apache.org/community).
 
 Apache Mynewt welcomes pull request via Github.  Discussions are done on Github,
 but depending on the topic, can also be relayed to the official Apache Mynewt
-developer mailing list dev@mynewt.incubator.apache.org.
+developer mailing list dev@mynewt.apache.org.
 
 If you are suggesting a new feature, please email the developer list directly,
 with a description of the feature you are planning to work on.
@@ -192,15 +191,16 @@ pushed through https://git.apache.org/.
 ## Filing Bugs
 
 Bugs can be filed on the
-[Apache Mynewt Bug Tracker](https://issues.apache.org/jira/browse/MYNEWT).
+[Apache Mynewt Issues](https://github.com/apache/mynewt-core/issues).
+Please label the issue as a "Bug".
 
 Where possible, please include a self-contained reproduction case!
 
 ## Feature Requests
 
 Feature requests should also be filed on the
-[Apache Mynewt Bug Tracker](https://issues.apache.org/jira/browse/MYNEWT).
-Please introduce it as a ticket type "Wish."
+[Apache Mynewt Bug Tracker](https://github.com/apache/mynewt-core/issues).
+Please label the issue as a "Feature" or "Enhancement" depending on the scope.
 
 ## Writing Tests
 
@@ -212,10 +212,7 @@ code coverage is a win for every Apache Mynewt user.
 Contributing to documentation (in addition to writing tests), is a great way
 to get involved with the Apache Mynewt project.
 
-Pull requests to the apache-mynewt-site repository on Github are the best
-way to submit documentation.  For more information on contributing to the
-documentation, the [FAQ](https://mynewt.apache.org/faq/answers/) has some
-more information.
+The Mynewt core OS documentation is found in [/docs](/docs).
 
 # License
 
diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md
index c5d38f937e..ff27eafc3d 100644
--- a/RELEASE_NOTES.md
+++ b/RELEASE_NOTES.md
@@ -1,19 +1,17 @@
 # RELEASE NOTES
 
-22 Nov 2016 - Apache Mynewt v1.0.0, beta 1
+04 June 2018 - Apache Mynewt v1.4.0
 
 For full release notes, please visit the
 [Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes).
 
-This is the fifth source release of Apache Mynewt Core.  For more
+This is the seventh source release of Apache Mynewt Core. For more
 information on Apache Mynewt, please visit the
 [Apache Mynewt Website](https://mynewt.apache.org/).
 
-As a beta release of Apache Mynewt, the normal caveat applies: APIs and
-commands are subject to change.  However, Apache Mynewt continues to stabilize
-with each release, and we believe this release is a further step forward.
-People who are interested in playing around, and trying Mynewt, are encouraged
-to download and begin to evaluate it.
+Apache Mynewt continues to stabilize with each release, and we believe this
+release is a further step forward. People who are interested in playing around,
+and trying Mynewt, are encouraged to download and begin to evaluate it.
 
 A full roadmap for Apache Mynewt is available on the [website](http://mynewt.apache.org/about/).
 In addition, a detailed view of what is being worked on, and all open feature
@@ -24,4 +22,4 @@ More information is available in the [README](/README.md) file in this directory
 
 If building an Operating System for Microcontrollers sounds fun to you, get in
 touch by sending a mail to the [Apache Mynewt Developer's
-list](mailto:dev@mynewt.incubator.apache.org).
+list](mailto:dev@mynewt.apache.org).
diff --git a/apps/blecent/pkg.yml b/apps/blecent/pkg.yml
deleted file mode 100644
index c885f9623d..0000000000
--- a/apps/blecent/pkg.yml
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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.
-#
-pkg.name: apps/blecent
-pkg.type: app
-pkg.description: Simple BLE central application.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps: 
-    - kernel/os 
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/host/services/gap
-    - net/nimble/host/services/gatt
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/full
diff --git a/apps/blecent/src/blecent.h b/apps/blecent/src/blecent.h
deleted file mode 100644
index 2dfa85b739..0000000000
--- a/apps/blecent/src/blecent.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * 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 H_BLECENT_
-#define H_BLECENT_
-
-#include "os/queue.h"
-#include "log/log.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ble_hs_adv_fields;
-struct ble_gap_conn_desc;
-struct ble_hs_cfg;
-union ble_store_value;
-union ble_store_key;
-
-extern struct log blecent_log;
-
-/* blecent uses the first "peruser" log module. */
-#define BLECENT_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
-
-/* Convenience macro for logging to the blecent module. */
-#define BLECENT_LOG(lvl, ...) \
-    LOG_ ## lvl(&blecent_log, BLECENT_LOG_MODULE, __VA_ARGS__)
-
-#define BLECENT_SVC_ALERT_UUID              0x1811
-#define BLECENT_CHR_SUP_NEW_ALERT_CAT_UUID  0x2A47
-#define BLECENT_CHR_NEW_ALERT               0x2A46
-#define BLECENT_CHR_SUP_UNR_ALERT_CAT_UUID  0x2A48
-#define BLECENT_CHR_UNR_ALERT_STAT_UUID     0x2A45
-#define BLECENT_CHR_ALERT_NOT_CTRL_PT       0x2A44
-
-/** GATT server. */
-void gatt_svr_register(void);
-void gatt_svr_init_cfg(struct ble_hs_cfg *cfg);
-
-
-/** Misc. */
-void print_bytes(const uint8_t *bytes, int len);
-void print_mbuf(const struct os_mbuf *om);
-char *addr_str(const void *addr);
-void print_uuid(const ble_uuid_t *uuid);
-void print_conn_desc(const struct ble_gap_conn_desc *desc);
-void print_adv_fields(const struct ble_hs_adv_fields *fields);
-
-/** Peer. */
-struct peer_dsc {
-    SLIST_ENTRY(peer_dsc) next;
-    struct ble_gatt_dsc dsc;
-};
-SLIST_HEAD(peer_dsc_list, peer_dsc);
-
-struct peer_chr {
-    SLIST_ENTRY(peer_chr) next;
-    struct ble_gatt_chr chr;
-
-    struct peer_dsc_list dscs;
-};
-SLIST_HEAD(peer_chr_list, peer_chr);
-
-struct peer_svc {
-    SLIST_ENTRY(peer_svc) next;
-    struct ble_gatt_svc svc;
-
-    struct peer_chr_list chrs;
-};
-SLIST_HEAD(peer_svc_list, peer_svc);
-
-struct peer;
-typedef void peer_disc_fn(const struct peer *peer, int status, void *arg);
-
-struct peer {
-    SLIST_ENTRY(peer) next;
-
-    uint16_t conn_handle;
-
-    /** List of discovered GATT services. */
-    struct peer_svc_list svcs;
-
-    /** Keeps track of where we are in the service discovery process. */
-    uint16_t disc_prev_chr_val;
-    struct peer_svc *cur_svc;
-
-    /** Callback that gets executed when service discovery completes. */
-    peer_disc_fn *disc_cb;
-    void *disc_cb_arg;
-};
-
-int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb,
-                  void *disc_cb_arg);
-const struct peer_dsc *
-peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
-                   const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid);
-const struct peer_chr *
-peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
-                   const ble_uuid_t *chr_uuid);
-const struct peer_svc *
-peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid);
-int peer_delete(uint16_t conn_handle);
-int peer_add(uint16_t conn_handle);
-int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/blecent/src/main.c b/apps/blecent/src/main.c
deleted file mode 100755
index a1dfa62b1a..0000000000
--- a/apps/blecent/src/main.c
+++ /dev/null
@@ -1,498 +0,0 @@
-/*
- * 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 <string.h>
-#include "syscfg/syscfg.h"
-#include "sysinit/sysinit.h"
-#include "bsp/bsp.h"
-#include "os/os.h"
-
-/* BLE */
-#include "nimble/ble.h"
-#include "controller/ble_ll.h"
-#include "host/ble_hs.h"
-
-/* RAM HCI transport. */
-#include "transport/ram/ble_hci_ram.h"
-
-/* Mandatory services. */
-#include "services/gap/ble_svc_gap.h"
-#include "services/gatt/ble_svc_gatt.h"
-
-/* Application-specified header. */
-#include "blecent.h"
-
-/** Log data. */
-struct log blecent_log;
-
-static int blecent_gap_event(struct ble_gap_event *event, void *arg);
-
-/**
- * Application callback.  Called when the read of the ANS Supported New Alert
- * Category characteristic has completed.
- */
-static int
-blecent_on_read(uint16_t conn_handle,
-                const struct ble_gatt_error *error,
-                struct ble_gatt_attr *attr,
-                void *arg)
-{
-    BLECENT_LOG(INFO, "Read complete; status=%d conn_handle=%d", error->status,
-                conn_handle);
-    if (error->status == 0) {
-        BLECENT_LOG(INFO, " attr_handle=%d value=", attr->handle);
-        print_mbuf(attr->om);
-    }
-    BLECENT_LOG(INFO, "\n");
-
-    return 0;
-}
-
-/**
- * Application callback.  Called when the write to the ANS Alert Notification
- * Control Point characteristic has completed.
- */
-static int
-blecent_on_write(uint16_t conn_handle,
-                 const struct ble_gatt_error *error,
-                 struct ble_gatt_attr *attr,
-                 void *arg)
-{
-    BLECENT_LOG(INFO, "Write complete; status=%d conn_handle=%d "
-                      "attr_handle=%d\n",
-                error->status, conn_handle, attr->handle);
-
-    return 0;
-}
-
-/**
- * Application callback.  Called when the attempt to subscribe to notifications
- * for the ANS Unread Alert Status characteristic has completed.
- */
-static int
-blecent_on_subscribe(uint16_t conn_handle,
-                     const struct ble_gatt_error *error,
-                     struct ble_gatt_attr *attr,
-                     void *arg)
-{
-    BLECENT_LOG(INFO, "Subscribe complete; status=%d conn_handle=%d "
-                      "attr_handle=%d\n",
-                error->status, conn_handle, attr->handle);
-
-    return 0;
-}
-
-/**
- * Performs three concurrent GATT operations against the specified peer:
- * 1. Reads the ANS Supported New Alert Category characteristic.
- * 2. Writes the ANS Alert Notification Control Point characteristic.
- * 3. Subscribes to notifications for the ANS Unread Alert Status
- *    characteristic.
- *
- * If the peer does not support a required service, characteristic, or
- * descriptor, then the peer lied when it claimed support for the alert
- * notification service!  When this happens, or if a GATT procedure fails,
- * this function immediately terminates the connection.
- */
-static void
-blecent_read_write_subscribe(const struct peer *peer)
-{
-    const struct peer_chr *chr;
-    const struct peer_dsc *dsc;
-    uint8_t value[2];
-    int rc;
-
-    /* Read the supported-new-alert-category characteristic. */
-    chr = peer_chr_find_uuid(peer,
-                             BLE_UUID16_DECLARE(BLECENT_SVC_ALERT_UUID),
-                             BLE_UUID16_DECLARE(BLECENT_CHR_SUP_NEW_ALERT_CAT_UUID));
-    if (chr == NULL) {
-        BLECENT_LOG(ERROR, "Error: Peer doesn't support the Supported New "
-                           "Alert Category characteristic\n");
-        goto err;
-    }
-
-    rc = ble_gattc_read(peer->conn_handle, chr->chr.val_handle,
-                        blecent_on_read, NULL);
-    if (rc != 0) {
-        BLECENT_LOG(ERROR, "Error: Failed to read characteristic; rc=%d\n",
-                    rc);
-        goto err;
-    }
-
-    /* Write two bytes (99, 100) to the alert-notification-control-point
-     * characteristic.
-     */
-    chr = peer_chr_find_uuid(peer,
-                             BLE_UUID16_DECLARE(BLECENT_SVC_ALERT_UUID),
-                             BLE_UUID16_DECLARE(BLECENT_CHR_ALERT_NOT_CTRL_PT));
-    if (chr == NULL) {
-        BLECENT_LOG(ERROR, "Error: Peer doesn't support the Alert "
-                           "Notification Control Point characteristic\n");
-        goto err;
-    }
-
-    value[0] = 99;
-    value[1] = 100;
-    rc = ble_gattc_write_flat(peer->conn_handle, chr->chr.val_handle,
-                              value, sizeof value, blecent_on_write, NULL);
-    if (rc != 0) {
-        BLECENT_LOG(ERROR, "Error: Failed to write characteristic; rc=%d\n",
-                    rc);
-    }
-
-    /* Subscribe to notifications for the Unread Alert Status characteristic.
-     * A central enables notifications by writing two bytes (1, 0) to the
-     * characteristic's client-characteristic-configuration-descriptor (CCCD).
-     */
-    dsc = peer_dsc_find_uuid(peer,
-                             BLE_UUID16_DECLARE(BLECENT_SVC_ALERT_UUID),
-                             BLE_UUID16_DECLARE(BLECENT_CHR_UNR_ALERT_STAT_UUID),
-                             BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
-    if (dsc == NULL) {
-        BLECENT_LOG(ERROR, "Error: Peer lacks a CCCD for the Unread Alert "
-                           "Status characteristic\n");
-        goto err;
-    }
-
-    value[0] = 1;
-    value[1] = 0;
-    rc = ble_gattc_write_flat(peer->conn_handle, dsc->dsc.handle,
-                              value, sizeof value, blecent_on_subscribe, NULL);
-    if (rc != 0) {
-        BLECENT_LOG(ERROR, "Error: Failed to subscribe to characteristic; "
-                           "rc=%d\n", rc);
-        goto err;
-    }
-
-    return;
-
-err:
-    /* Terminate the connection. */
-    ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-}
-
-/**
- * Called when service discovery of the specified peer has completed.
- */
-static void
-blecent_on_disc_complete(const struct peer *peer, int status, void *arg)
-{
-
-    if (status != 0) {
-        /* Service discovery failed.  Terminate the connection. */
-        BLECENT_LOG(ERROR, "Error: Service discovery failed; status=%d "
-                           "conn_handle=%d\n", status, peer->conn_handle);
-        ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
-        return;
-    }
-
-    /* Service discovery has completed successfully.  Now we have a complete
-     * list of services, characteristics, and descriptors that the peer
-     * supports.
-     */
-    BLECENT_LOG(ERROR, "Service discovery complete; status=%d "
-                       "conn_handle=%d\n", status, peer->conn_handle);
-
-    /* Now perform three concurrent GATT procedures against the peer: read,
-     * write, and subscribe to notifications.
-     */
-    blecent_read_write_subscribe(peer);
-}
-
-/**
- * Initiates the GAP general discovery procedure.
- */
-static void
-blecent_scan(void)
-{
-    struct ble_gap_disc_params disc_params;
-    int rc;
-
-    /* Tell the controller to filter duplicates; we don't want to process
-     * repeated advertisements from the same device.
-     */
-    disc_params.filter_duplicates = 1;
-
-    /**
-     * Perform a passive scan.  I.e., don't send follow-up scan requests to
-     * each advertiser.
-     */
-    disc_params.passive = 1;
-
-    /* Use defaults for the rest of the parameters. */
-    disc_params.itvl = 0;
-    disc_params.window = 0;
-    disc_params.filter_policy = 0;
-    disc_params.limited = 0;
-
-    rc = ble_gap_disc(BLE_OWN_ADDR_PUBLIC, BLE_HS_FOREVER, &disc_params,
-                      blecent_gap_event, NULL);
-    if (rc != 0) {
-        BLECENT_LOG(ERROR, "Error initiating GAP discovery procedure; rc=%d\n",
-                    rc);
-    }
-}
-
-/**
- * Indicates whether we should tre to connect to the sender of the specified
- * advertisement.  The function returns a positive result if the device
- * advertises connectability and support for the Alert Notification service.
- */
-static int
-blecent_should_connect(const struct ble_gap_disc_desc *disc)
-{
-    struct ble_hs_adv_fields fields;
-    int rc;
-    int i;
-
-    /* The device has to be advertising connectability. */
-    if (disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_ADV_IND &&
-        disc->event_type != BLE_HCI_ADV_RPT_EVTYPE_DIR_IND) {
-
-        return 0;
-    }
-
-    rc = ble_hs_adv_parse_fields(&fields, disc->data, disc->length_data);
-    if (rc != 0) {
-        return rc;
-    }
-
-    /* The device has to advertise support for the Alert Notification
-     * service (0x1811).
-     */
-    for (i = 0; i < fields.num_uuids16; i++) {
-        if (ble_uuid_u16(&fields.uuids16[i].u) == BLECENT_SVC_ALERT_UUID) {
-            return 1;
-        }
-    }
-
-    return 0;
-}
-
-/**
- * Connects to the sender of the specified advertisement of it looks
- * interesting.  A device is "interesting" if it advertises connectability and
- * support for the Alert Notification service.
- */
-static void
-blecent_connect_if_interesting(const struct ble_gap_disc_desc *disc)
-{
-    int rc;
-
-    /* Don't do anything if we don't care about this advertiser. */
-    if (!blecent_should_connect(disc)) {
-        return;
-    }
-
-    /* Scanning must be stopped before a connection can be initiated. */
-    rc = ble_gap_disc_cancel();
-    if (rc != 0) {
-        BLECENT_LOG(DEBUG, "Failed to cancel scan; rc=%d\n", rc);
-        return;
-    }
-
-    /* Try to connect the the advertiser.  Allow 30 seconds (30000 ms) for
-     * timeout.
-     */
-    rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, &disc->addr, 30000, NULL,
-                         blecent_gap_event, NULL);
-    if (rc != 0) {
-        BLECENT_LOG(ERROR, "Error: Failed to connect to device; addr_type=%d "
-                           "addr=%s\n", disc->addr.type,
-                           addr_str(disc->addr.val));
-        return;
-    }
-}
-
-/**
- * The nimble host executes this callback when a GAP event occurs.  The
- * application associates a GAP event callback with each connection that is
- * established.  blecent uses the same callback for all connections.
- *
- * @param event                 The event being signalled.
- * @param arg                   Application-specified argument; unused by
- *                                  blecent.
- *
- * @return                      0 if the application successfully handled the
- *                                  event; nonzero on failure.  The semantics
- *                                  of the return code is specific to the
- *                                  particular GAP event being signalled.
- */
-static int
-blecent_gap_event(struct ble_gap_event *event, void *arg)
-{
-    struct ble_gap_conn_desc desc;
-    struct ble_hs_adv_fields fields;
-    int rc;
-
-    switch (event->type) {
-    case BLE_GAP_EVENT_DISC:
-        rc = ble_hs_adv_parse_fields(&fields, event->disc.data,
-                                     event->disc.length_data);
-        if (rc != 0) {
-            return 0;
-        }
-
-        /* An advertisment report was received during GAP discovery. */
-        print_adv_fields(&fields);
-
-        /* Try to connect to the advertiser if it looks interesting. */
-        blecent_connect_if_interesting(&event->disc);
-        return 0;
-
-    case BLE_GAP_EVENT_CONNECT:
-        /* A new connection was established or a connection attempt failed. */
-        if (event->connect.status == 0) {
-            /* Connection successfully established. */
-            BLECENT_LOG(INFO, "Connection established ");
-
-            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-            assert(rc == 0);
-            print_conn_desc(&desc);
-            BLECENT_LOG(INFO, "\n");
-
-            /* Remember peer. */
-            rc = peer_add(event->connect.conn_handle);
-            if (rc != 0) {
-                BLECENT_LOG(ERROR, "Failed to add peer; rc=%d\n", rc);
-                return 0;
-            }
-
-            /* Perform service discovery. */
-            rc = peer_disc_all(event->connect.conn_handle,
-                               blecent_on_disc_complete, NULL);
-            if (rc != 0) {
-                BLECENT_LOG(ERROR, "Failed to discover services; rc=%d\n", rc);
-                return 0;
-            }
-        } else {
-            /* Connection attempt failed; resume scanning. */
-            BLECENT_LOG(ERROR, "Error: Connection failed; status=%d\n",
-                        event->connect.status);
-            blecent_scan();
-        }
-
-        return 0;
-
-    case BLE_GAP_EVENT_DISCONNECT:
-        /* Connection terminated. */
-        BLECENT_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason);
-        print_conn_desc(&event->disconnect.conn);
-        BLECENT_LOG(INFO, "\n");
-
-        /* Forget about peer. */
-        peer_delete(event->disconnect.conn.conn_handle);
-
-        /* Resume scanning. */
-        blecent_scan();
-        return 0;
-
-    case BLE_GAP_EVENT_ENC_CHANGE:
-        /* Encryption has been enabled or disabled for this connection. */
-        BLECENT_LOG(INFO, "encryption change event; status=%d ",
-                    event->enc_change.status);
-        rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
-        assert(rc == 0);
-        print_conn_desc(&desc);
-        return 0;
-
-    case BLE_GAP_EVENT_NOTIFY_RX:
-        /* Peer sent us a notification or indication. */
-        BLECENT_LOG(INFO, "received %s; conn_handle=%d attr_handle=%d "
-                          "attr_len=%d\n",
-                    event->notify_rx.indication ?
-                        "indication" :
-                        "notification",
-                    event->notify_rx.conn_handle,
-                    event->notify_rx.attr_handle,
-                    OS_MBUF_PKTLEN(event->notify_rx.om));
-
-        /* Attribute data is contained in event->notify_rx.attr_data. */
-        return 0;
-
-    case BLE_GAP_EVENT_MTU:
-        BLECENT_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
-                    event->mtu.conn_handle,
-                    event->mtu.channel_id,
-                    event->mtu.value);
-        return 0;
-
-    default:
-        return 0;
-    }
-}
-
-static void
-blecent_on_reset(int reason)
-{
-    BLECENT_LOG(ERROR, "Resetting state; reason=%d\n", reason);
-}
-
-static void
-blecent_on_sync(void)
-{
-    /* Begin scanning for a peripheral to connect to. */
-    blecent_scan();
-}
-
-/**
- * main
- *
- * All application logic and NimBLE host work is performed in default task.
- *
- * @return int NOTE: this function should never return!
- */
-int
-main(void)
-{
-    int rc;
-
-    /* Set initial BLE device address. */
-    memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}, 6);
-
-    /* Initialize OS */
-    sysinit();
-
-    /* Initialize the blecent log. */
-    log_register("blecent", &blecent_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
-    /* Configure the host. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-    ble_hs_cfg.reset_cb = blecent_on_reset;
-    ble_hs_cfg.sync_cb = blecent_on_sync;
-
-    /* Initialize data structures to track connected peers. */
-    rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 64, 64);
-    assert(rc == 0);
-
-    /* Set the default device name. */
-    rc = ble_svc_gap_device_name_set("nimble-blecent");
-    assert(rc == 0);
-
-    /* os start should never return. If it does, this should be an error */
-    while (1) {
-        os_eventq_run(os_eventq_dflt_get());
-    }
-
-    return 0;
-}
diff --git a/apps/blecent/src/misc.c b/apps/blecent/src/misc.c
deleted file mode 100644
index eb4af0cc18..0000000000
--- a/apps/blecent/src/misc.c
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * 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 <string.h>
-#include "host/ble_hs.h"
-#include "host/ble_uuid.h"
-#include "blecent.h"
-
-/**
- * Utility function to log an array of bytes.
- */
-void
-print_bytes(const uint8_t *bytes, int len)
-{
-    int i;
-
-    for (i = 0; i < len; i++) {
-        BLECENT_LOG(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
-    }
-}
-
-void
-print_mbuf(const struct os_mbuf *om)
-{
-    int colon;
-
-    colon = 0;
-    while (om != NULL) {
-        if (colon) {
-            BLECENT_LOG(DEBUG, ":");
-        } else {
-            colon = 1;
-        }
-        print_bytes(om->om_data, om->om_len);
-        om = SLIST_NEXT(om, om_next);
-    }
-}
-
-char *
-addr_str(const void *addr)
-{
-    static char buf[6 * 2 + 5 + 1];
-    const uint8_t *u8p;
-
-    u8p = addr;
-    sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
-            u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
-
-    return buf;
-}
-
-void
-print_uuid(const ble_uuid_t *uuid)
-{
-    char buf[BLE_UUID_STR_LEN];
-
-    BLECENT_LOG(DEBUG, "%s", ble_uuid_to_str(uuid, buf));
-}
-
-/**
- * Logs information about a connection to the console.
- */
-void
-print_conn_desc(const struct ble_gap_conn_desc *desc)
-{
-    BLECENT_LOG(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ",
-                desc->conn_handle, desc->our_ota_addr.type,
-                addr_str(desc->our_ota_addr.val));
-    BLECENT_LOG(DEBUG, "our_id_addr_type=%d our_id_addr=%s ",
-                desc->our_id_addr.type, addr_str(desc->our_id_addr.val));
-    BLECENT_LOG(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ",
-                desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val));
-    BLECENT_LOG(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ",
-                desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val));
-    BLECENT_LOG(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d "
-                "encrypted=%d authenticated=%d bonded=%d",
-                desc->conn_itvl, desc->conn_latency,
-                desc->supervision_timeout,
-                desc->sec_state.encrypted,
-                desc->sec_state.authenticated,
-                desc->sec_state.bonded);
-}
-
-
-void
-print_adv_fields(const struct ble_hs_adv_fields *fields)
-{
-    char s[BLE_HS_ADV_MAX_SZ];
-    const uint8_t *u8p;
-    int i;
-
-    if (fields->flags != 0) {
-        BLECENT_LOG(DEBUG, "    flags=0x%02x\n", fields->flags);
-    }
-
-    if (fields->uuids16 != NULL) {
-        BLECENT_LOG(DEBUG, "    uuids16(%scomplete)=",
-                    fields->uuids16_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids16; i++) {
-            print_uuid(&fields->uuids16[i].u);
-            BLECENT_LOG(DEBUG, " ");
-        }
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->uuids32 != NULL) {
-        BLECENT_LOG(DEBUG, "    uuids32(%scomplete)=",
-                    fields->uuids32_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids32; i++) {
-            print_uuid(&fields->uuids32[i].u);
-            BLECENT_LOG(DEBUG, " ");
-        }
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->uuids128 != NULL) {
-        BLECENT_LOG(DEBUG, "    uuids128(%scomplete)=",
-                    fields->uuids128_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids128; i++) {
-            print_uuid(&fields->uuids128[i].u);
-            BLECENT_LOG(DEBUG, " ");
-        }
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->name != NULL) {
-        assert(fields->name_len < sizeof s - 1);
-        memcpy(s, fields->name, fields->name_len);
-        s[fields->name_len] = '\0';
-        BLECENT_LOG(DEBUG, "    name(%scomplete)=%s\n",
-                    fields->name_is_complete ? "" : "in", s);
-    }
-
-    if (fields->tx_pwr_lvl_is_present) {
-        BLECENT_LOG(DEBUG, "    tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
-    }
-
-    if (fields->slave_itvl_range != NULL) {
-        BLECENT_LOG(DEBUG, "    slave_itvl_range=");
-        print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->svc_data_uuid16 != NULL) {
-        BLECENT_LOG(DEBUG, "    svc_data_uuid16=");
-        print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len);
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->public_tgt_addr != NULL) {
-        BLECENT_LOG(DEBUG, "    public_tgt_addr=");
-        u8p = fields->public_tgt_addr;
-        for (i = 0; i < fields->num_public_tgt_addrs; i++) {
-            BLECENT_LOG(DEBUG, "public_tgt_addr=%s ", addr_str(u8p));
-            u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
-        }
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->appearance_is_present) {
-        BLECENT_LOG(DEBUG, "    appearance=0x%04x\n", fields->appearance);
-    }
-
-    if (fields->adv_itvl_is_present) {
-        BLECENT_LOG(DEBUG, "    adv_itvl=0x%04x\n", fields->adv_itvl);
-    }
-
-    if (fields->svc_data_uuid32 != NULL) {
-        BLECENT_LOG(DEBUG, "    svc_data_uuid32=");
-        print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len);
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->svc_data_uuid128 != NULL) {
-        BLECENT_LOG(DEBUG, "    svc_data_uuid128=");
-        print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len);
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->uri != NULL) {
-        BLECENT_LOG(DEBUG, "    uri=");
-        print_bytes(fields->uri, fields->uri_len);
-        BLECENT_LOG(DEBUG, "\n");
-    }
-
-    if (fields->mfg_data != NULL) {
-        BLECENT_LOG(DEBUG, "    mfg_data=");
-        print_bytes(fields->mfg_data, fields->mfg_data_len);
-        BLECENT_LOG(DEBUG, "\n");
-    }
-}
diff --git a/apps/blecent/src/peer.c b/apps/blecent/src/peer.c
deleted file mode 100644
index 05ec8a0050..0000000000
--- a/apps/blecent/src/peer.c
+++ /dev/null
@@ -1,807 +0,0 @@
-/*
- * 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 <string.h>
-#include "host/ble_hs.h"
-#include "blecent.h"
-
-static void *peer_svc_mem;
-static struct os_mempool peer_svc_pool;
-
-static void *peer_chr_mem;
-static struct os_mempool peer_chr_pool;
-
-static void *peer_dsc_mem;
-static struct os_mempool peer_dsc_pool;
-
-static void *peer_mem;
-static struct os_mempool peer_pool;
-static SLIST_HEAD(, peer) peers;
-
-static struct peer_svc *
-peer_svc_find_range(struct peer *peer, uint16_t attr_handle);
-static struct peer_svc *
-peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
-              struct peer_svc **out_prev);
-int
-peer_svc_is_empty(const struct peer_svc *svc);
-
-uint16_t
-chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr);
-int
-chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr);
-static struct peer_chr *
-peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle,
-              struct peer_chr **out_prev);
-static void
-peer_disc_chrs(struct peer *peer);
-
-static int
-peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
-                uint16_t chr_def_handle, const struct ble_gatt_dsc *dsc,
-                void *arg);
-
-static struct peer *
-peer_find(uint16_t conn_handle)
-{
-    struct peer *peer;
-
-    SLIST_FOREACH(peer, &peers, next) {
-        if (peer->conn_handle == conn_handle) {
-            return peer;
-        }
-    }
-
-    return NULL;
-}
-
-static void
-peer_disc_complete(struct peer *peer, int rc)
-{
-    peer->disc_prev_chr_val = 0;
-
-    /* Notify caller that discovery has completed. */
-    if (peer->disc_cb != NULL) {
-        peer->disc_cb(peer, rc, peer->disc_cb_arg);
-    }
-}
-
-static struct peer_dsc *
-peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle)
-{
-    struct peer_dsc *prev;
-    struct peer_dsc *dsc;
-
-    prev = NULL;
-    SLIST_FOREACH(dsc, &chr->dscs, next) {
-        if (dsc->dsc.handle >= dsc_handle) {
-            break;
-        }
-
-        prev = dsc;
-    }
-
-    return prev;
-}
-
-static struct peer_dsc *
-peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle,
-              struct peer_dsc **out_prev)
-{
-    struct peer_dsc *prev;
-    struct peer_dsc *dsc;
-
-    prev = peer_dsc_find_prev(chr, dsc_handle);
-    if (prev == NULL) {
-        dsc = SLIST_FIRST(&chr->dscs);
-    } else {
-        dsc = SLIST_NEXT(prev, next);
-    }
-
-    if (dsc != NULL && dsc->dsc.handle != dsc_handle) {
-        dsc = NULL;
-    }
-
-    if (out_prev != NULL) {
-        *out_prev = prev;
-    }
-    return dsc;
-}
-
-static int
-peer_dsc_add(struct peer *peer, uint16_t chr_val_handle,
-             const struct ble_gatt_dsc *gatt_dsc)
-{
-    struct peer_dsc *prev;
-    struct peer_dsc *dsc;
-    struct peer_svc *svc;
-    struct peer_chr *chr;
-
-    svc = peer_svc_find_range(peer, chr_val_handle);
-    if (svc == NULL) {
-        /* Can't find service for discovered descriptor; this shouldn't
-         * happen.
-         */
-        assert(0);
-        return BLE_HS_EUNKNOWN;
-    }
-
-    chr = peer_chr_find(svc, chr_val_handle, NULL);
-    if (chr == NULL) {
-        /* Can't find characteristic for discovered descriptor; this shouldn't
-         * happen.
-         */
-        assert(0);
-        return BLE_HS_EUNKNOWN;
-    }
-
-    dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev);
-    if (dsc != NULL) {
-        /* Descriptor already discovered. */
-        return 0;
-    }
-
-    dsc = os_memblock_get(&peer_dsc_pool);
-    if (dsc == NULL) {
-        /* Out of memory. */
-        return BLE_HS_ENOMEM;
-    }
-    memset(dsc, 0, sizeof *dsc);
-
-    dsc->dsc = *gatt_dsc;
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&chr->dscs, dsc, next);
-    } else {
-        SLIST_NEXT(prev, next) = dsc;
-    }
-
-    return 0;
-}
-
-static void
-peer_disc_dscs(struct peer *peer)
-{
-    struct peer_chr *chr;
-    struct peer_svc *svc;
-    int rc;
-
-    /* Search through the list of discovered characteristics for the first
-     * characteristic that contains undiscovered descriptors.  Then, discover
-     * all descriptors belonging to that characteristic.
-     */
-    SLIST_FOREACH(svc, &peer->svcs, next) {
-        SLIST_FOREACH(chr, &svc->chrs, next) {
-            if (!chr_is_empty(svc, chr) &&
-                SLIST_EMPTY(&chr->dscs) &&
-                peer->disc_prev_chr_val <= chr->chr.def_handle) {
-
-                rc = ble_gattc_disc_all_dscs(peer->conn_handle,
-                                             chr->chr.val_handle,
-                                             chr_end_handle(svc, chr),
-                                             peer_dsc_disced, peer);
-                if (rc != 0) {
-                    peer_disc_complete(peer, rc);
-                }
-
-                peer->disc_prev_chr_val = chr->chr.val_handle;
-                return;
-            }
-        }
-    }
-
-    /* All descriptors discovered. */
-    peer_disc_complete(peer, 0);
-}
-
-static int
-peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
-                uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
-                void *arg)
-{
-    struct peer *peer;
-    int rc;
-
-    peer = arg;
-    assert(peer->conn_handle == conn_handle);
-
-    switch (error->status) {
-    case 0:
-        rc = peer_dsc_add(peer, chr_val_handle, dsc);
-        break;
-
-    case BLE_HS_EDONE:
-        /* All descriptors in this characteristic discovered; start discovering
-         * descriptors in the next characteristic.
-         */
-        if (peer->disc_prev_chr_val > 0) {
-            peer_disc_dscs(peer);
-        }
-        rc = 0;
-        break;
-
-    default:
-        /* Error; abort discovery. */
-        rc = error->status;
-        break;
-    }
-
-    if (rc != 0) {
-        /* Error; abort discovery. */
-        peer_disc_complete(peer, rc);
-    }
-
-    return rc;
-}
-
-uint16_t
-chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr)
-{
-    const struct peer_chr *next_chr;
-
-    next_chr = SLIST_NEXT(chr, next);
-    if (next_chr != NULL) {
-        return next_chr->chr.def_handle - 1;
-    } else {
-        return svc->svc.end_handle;
-    }
-}
-
-int
-chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr)
-{
-    return chr_end_handle(svc, chr) <= chr->chr.val_handle;
-}
-
-static struct peer_chr *
-peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle)
-{
-    struct peer_chr *prev;
-    struct peer_chr *chr;
-
-    prev = NULL;
-    SLIST_FOREACH(chr, &svc->chrs, next) {
-        if (chr->chr.val_handle >= chr_val_handle) {
-            break;
-        }
-
-        prev = chr;
-    }
-
-    return prev;
-}
-
-static struct peer_chr *
-peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle,
-              struct peer_chr **out_prev)
-{
-    struct peer_chr *prev;
-    struct peer_chr *chr;
-
-    prev = peer_chr_find_prev(svc, chr_val_handle);
-    if (prev == NULL) {
-        chr = SLIST_FIRST(&svc->chrs);
-    } else {
-        chr = SLIST_NEXT(prev, next);
-    }
-
-    if (chr != NULL && chr->chr.val_handle != chr_val_handle) {
-        chr = NULL;
-    }
-
-    if (out_prev != NULL) {
-        *out_prev = prev;
-    }
-    return chr;
-}
-
-static void
-peer_chr_delete(struct peer_chr *chr)
-{
-    struct peer_dsc *dsc;
-
-    while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) {
-        SLIST_REMOVE_HEAD(&chr->dscs, next);
-        os_memblock_put(&peer_dsc_pool, dsc);
-    }
-
-    os_memblock_put(&peer_chr_pool, chr);
-}
-
-static int
-peer_chr_add(struct peer *peer,  uint16_t svc_start_handle,
-             const struct ble_gatt_chr *gatt_chr)
-{
-    struct peer_chr *prev;
-    struct peer_chr *chr;
-    struct peer_svc *svc;
-
-    svc = peer_svc_find(peer, svc_start_handle, NULL);
-    if (svc == NULL) {
-        /* Can't find service for discovered characteristic; this shouldn't
-         * happen.
-         */
-        assert(0);
-        return BLE_HS_EUNKNOWN;
-    }
-
-    chr = peer_chr_find(svc, gatt_chr->def_handle, &prev);
-    if (chr != NULL) {
-        /* Characteristic already discovered. */
-        return 0;
-    }
-
-    chr = os_memblock_get(&peer_chr_pool);
-    if (chr == NULL) {
-        /* Out of memory. */
-        return BLE_HS_ENOMEM;
-    }
-    memset(chr, 0, sizeof *chr);
-
-    chr->chr = *gatt_chr;
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&svc->chrs, chr, next);
-    } else {
-        SLIST_NEXT(prev, next) = chr;
-    }
-
-    return 0;
-}
-
-static int
-peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
-                const struct ble_gatt_chr *chr, void *arg)
-{
-    struct peer *peer;
-    int rc;
-
-    peer = arg;
-    assert(peer->conn_handle == conn_handle);
-
-    switch (error->status) {
-    case 0:
-        rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr);
-        break;
-
-    case BLE_HS_EDONE:
-        /* All characteristics in this service discovered; start discovering
-         * characteristics in the next service.
-         */
-        if (peer->disc_prev_chr_val > 0) {
-             peer_disc_chrs(peer);
-        }
-        rc = 0;
-        break;
-
-    default:
-        rc = error->status;
-        break;
-    }
-
-    if (rc != 0) {
-        /* Error; abort discovery. */
-        peer_disc_complete(peer, rc);
-    }
-
-    return rc;
-}
-
-static void
-peer_disc_chrs(struct peer *peer)
-{
-    struct peer_svc *svc;
-    int rc;
-
-    /* Search through the list of discovered service for the first service that
-     * contains undiscovered characteristics.  Then, discover all
-     * characteristics belonging to that service.
-     */
-    SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) {
-            peer->cur_svc = svc;
-            rc = ble_gattc_disc_all_chrs(peer->conn_handle,
-                                         svc->svc.start_handle,
-                                         svc->svc.end_handle,
-                                         peer_chr_disced, peer);
-            if (rc != 0) {
-                peer_disc_complete(peer, rc);
-            }
-            return;
-        }
-    }
-
-    /* All characteristics discovered. */
-    peer_disc_dscs(peer);
-}
-
-int
-peer_svc_is_empty(const struct peer_svc *svc)
-{
-    return svc->svc.end_handle < svc->svc.start_handle;
-}
-
-static struct peer_svc *
-peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle)
-{
-    struct peer_svc *prev;
-    struct peer_svc *svc;
-
-    prev = NULL;
-    SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (svc->svc.start_handle >= svc_start_handle) {
-            break;
-        }
-
-        prev = svc;
-    }
-
-    return prev;
-}
-
-static struct peer_svc *
-peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
-              struct peer_svc **out_prev)
-{
-    struct peer_svc *prev;
-    struct peer_svc *svc;
-
-    prev = peer_svc_find_prev(peer, svc_start_handle);
-    if (prev == NULL) {
-        svc = SLIST_FIRST(&peer->svcs);
-    } else {
-        svc = SLIST_NEXT(prev, next);
-    }
-
-    if (svc != NULL && svc->svc.start_handle != svc_start_handle) {
-        svc = NULL;
-    }
-
-    if (out_prev != NULL) {
-        *out_prev = prev;
-    }
-    return svc;
-}
-
-static struct peer_svc *
-peer_svc_find_range(struct peer *peer, uint16_t attr_handle)
-{
-    struct peer_svc *svc;
-
-    SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (svc->svc.start_handle <= attr_handle &&
-            svc->svc.end_handle >= attr_handle) {
-
-            return svc;
-        }
-    }
-
-    return NULL;
-}
-
-const struct peer_svc *
-peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid)
-{
-    const struct peer_svc *svc;
-
-    SLIST_FOREACH(svc, &peer->svcs, next) {
-        if (ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) {
-            return svc;
-        }
-    }
-
-    return NULL;
-}
-
-const struct peer_chr *
-peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
-                   const ble_uuid_t *chr_uuid)
-{
-    const struct peer_svc *svc;
-    const struct peer_chr *chr;
-
-    svc = peer_svc_find_uuid(peer, svc_uuid);
-    if (svc == NULL) {
-        return NULL;
-    }
-
-    SLIST_FOREACH(chr, &svc->chrs, next) {
-        if (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) {
-            return chr;
-        }
-    }
-
-    return NULL;
-}
-
-const struct peer_dsc *
-peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
-                   const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid)
-{
-    const struct peer_chr *chr;
-    const struct peer_dsc *dsc;
-
-    chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid);
-    if (chr == NULL) {
-        return NULL;
-    }
-
-    SLIST_FOREACH(dsc, &chr->dscs, next) {
-        if (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) {
-            return dsc;
-        }
-    }
-
-    return NULL;
-}
-
-static int
-peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc)
-{
-    struct peer_svc *prev;
-    struct peer_svc *svc;
-
-    svc = peer_svc_find(peer, gatt_svc->start_handle, &prev);
-    if (svc != NULL) {
-        /* Service already discovered. */
-        return 0;
-    }
-
-    svc = os_memblock_get(&peer_svc_pool);
-    if (svc == NULL) {
-        /* Out of memory. */
-        return BLE_HS_ENOMEM;
-    }
-    memset(svc, 0, sizeof *svc);
-
-    svc->svc = *gatt_svc;
-    SLIST_INIT(&svc->chrs);
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&peer->svcs, svc, next);
-    } else {
-        SLIST_INSERT_AFTER(prev, svc, next);
-    }
-
-    return 0;
-}
-
-static void
-peer_svc_delete(struct peer_svc *svc)
-{
-    struct peer_chr *chr;
-
-    while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) {
-        SLIST_REMOVE_HEAD(&svc->chrs, next);
-        peer_chr_delete(chr);
-    }
-
-    os_memblock_put(&peer_svc_pool, svc);
-}
-
-static int
-peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
-                const struct ble_gatt_svc *service, void *arg)
-{
-    struct peer *peer;
-    int rc;
-
-    peer = arg;
-    assert(peer->conn_handle == conn_handle);
-
-    switch (error->status) {
-    case 0:
-        rc = peer_svc_add(peer, service);
-        break;
-
-    case BLE_HS_EDONE:
-        /* All services discovered; start discovering characteristics. */
-        if (peer->disc_prev_chr_val > 0) {
-            peer_disc_chrs(peer);
-        }
-        rc = 0;
-        break;
-
-    default:
-        rc = error->status;
-        break;
-    }
-
-    if (rc != 0) {
-        /* Error; abort discovery. */
-        peer_disc_complete(peer, rc);
-    }
-
-    return rc;
-}
-
-
-int
-peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg)
-{
-    struct peer_svc *svc;
-    struct peer *peer;
-    int rc;
-
-    peer = peer_find(conn_handle);
-    if (peer == NULL) {
-        return BLE_HS_ENOTCONN;
-    }
-
-    /* Undiscover everything first. */
-    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
-        SLIST_REMOVE_HEAD(&peer->svcs, next);
-        peer_svc_delete(svc);
-    }
-
-    peer->disc_prev_chr_val = 1;
-    peer->disc_cb = disc_cb;
-    peer->disc_cb_arg = disc_cb_arg;
-
-    rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-int
-peer_delete(uint16_t conn_handle)
-{
-    struct peer_svc *svc;
-    struct peer *peer;
-    int rc;
-
-    peer = peer_find(conn_handle);
-    if (peer == NULL) {
-        return BLE_HS_ENOTCONN;
-    }
-
-    SLIST_REMOVE(&peers, peer, peer, next);
-
-    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
-        SLIST_REMOVE_HEAD(&peer->svcs, next);
-        peer_svc_delete(svc);
-    }
-
-    rc = os_memblock_put(&peer_pool, peer);
-    if (rc != 0) {
-        return BLE_HS_EOS;
-    }
-
-    return 0;
-}
-
-int
-peer_add(uint16_t conn_handle)
-{
-    struct peer *peer;
-
-    /* Make sure the connection handle is unique. */
-    peer = peer_find(conn_handle);
-    if (peer != NULL) {
-        return BLE_HS_EALREADY;
-    }
-
-    peer = os_memblock_get(&peer_pool);
-    if (peer == NULL) {
-        /* Out of memory. */
-        return BLE_HS_ENOMEM;
-    }
-
-    memset(peer, 0, sizeof *peer);
-    peer->conn_handle = conn_handle;
-
-    SLIST_INSERT_HEAD(&peers, peer, next);
-
-    return 0;
-}
-
-static void
-peer_free_mem(void)
-{
-    free(peer_mem);
-    peer_mem = NULL;
-
-    free(peer_svc_mem);
-    peer_svc_mem = NULL;
-
-    free(peer_chr_mem);
-    peer_chr_mem = NULL;
-
-    free(peer_dsc_mem);
-    peer_dsc_mem = NULL;
-}
-
-int
-peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs)
-{
-    int rc;
-
-    /* Free memory first in case this function gets called more than once. */
-    peer_free_mem();
-
-    peer_mem = malloc(
-        OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer)));
-    if (peer_mem == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto err;
-    }
-
-    rc = os_mempool_init(&peer_pool, max_peers,
-                         sizeof (struct peer), peer_mem,
-                         "peer_pool");
-    if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
-    }
-
-    peer_svc_mem = malloc(
-        OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc)));
-    if (peer_svc_mem == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto err;
-    }
-
-    rc = os_mempool_init(&peer_svc_pool, max_svcs,
-                         sizeof (struct peer_svc), peer_svc_mem,
-                         "peer_svc_pool");
-    if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
-    }
-
-    peer_chr_mem = malloc(
-        OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr)));
-    if (peer_chr_mem == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto err;
-    }
-
-    rc = os_mempool_init(&peer_chr_pool, max_chrs,
-                         sizeof (struct peer_chr), peer_chr_mem,
-                         "peer_chr_pool");
-    if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
-    }
-
-    peer_dsc_mem = malloc(
-        OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc)));
-    if (peer_dsc_mem == NULL) {
-        rc = BLE_HS_ENOMEM;
-        goto err;
-    }
-
-    rc = os_mempool_init(&peer_dsc_pool, max_dscs,
-                         sizeof (struct peer_dsc), peer_dsc_mem,
-                         "peer_dsc_pool");
-    if (rc != 0) {
-        rc = BLE_HS_EOS;
-        goto err;
-    }
-
-    return 0;
-
-err:
-    peer_free_mem();
-    return rc;
-}
diff --git a/apps/blecent/syscfg.yml b/apps/blecent/syscfg.yml
deleted file mode 100644
index f20064551e..0000000000
--- a/apps/blecent/syscfg.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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.
-#
-
-# Package: apps/blecent
-
-syscfg.vals:
-    # DEBUG logging is a bit noisy; use INFO.
-    LOG_LEVEL: 1
-
-    # Default task settings
-    OS_MAIN_STACK_SIZE: 336
diff --git a/apps/blehci/pkg.yml b/apps/blehci/pkg.yml
deleted file mode 100644
index 18ee5dcbd6..0000000000
--- a/apps/blehci/pkg.yml
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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.
-#
-pkg.name: apps/blehci
-pkg.type: app
-pkg.description: BLE controller application exposing HCI over UART
-pkg.author: "Johan Hedberg <jo...@intel.com>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps:
-    - sys/console/stub
-    - sys/stats/full
-    - kernel/os
-    - net/nimble/controller
-    - net/nimble/transport/uart
diff --git a/apps/blehci/src/main.c b/apps/blehci/src/main.c
deleted file mode 100755
index 04f4e880db..0000000000
--- a/apps/blehci/src/main.c
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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 "sysinit/sysinit.h"
-#include "os/os.h"
-
-int
-main(void)
-{
-    /* Initialize OS */
-    sysinit();
-
-    while (1) {
-        os_eventq_run(os_eventq_dflt_get());
-    }
-    return 0;
-}
diff --git a/apps/blehci/syscfg.yml b/apps/blehci/syscfg.yml
deleted file mode 100644
index 89f1013809..0000000000
--- a/apps/blehci/syscfg.yml
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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.
-#
-
-# Package: apps/blehci
-
-syscfg.vals:
-    # Default task settings
-    OS_MAIN_STACK_SIZE: 64
diff --git a/apps/bleprph/pkg.yml b/apps/bleprph/pkg.yml
deleted file mode 100644
index 2bc97bd988..0000000000
--- a/apps/bleprph/pkg.yml
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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.
-#
-pkg.name: apps/bleprph
-pkg.type: app
-pkg.description: Simple BLE peripheral application.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps: 
-    - boot/split
-    - kernel/os 
-    - mgmt/imgmgr
-    - mgmt/newtmgr
-    - mgmt/newtmgr/transport/ble
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/host/services/ans
-    - net/nimble/host/services/gap
-    - net/nimble/host/services/gatt
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/full
-    - sys/sysinit
-    - sys/id
diff --git a/apps/bleprph/src/bleprph.h b/apps/bleprph/src/bleprph.h
deleted file mode 100644
index afcbb72e22..0000000000
--- a/apps/bleprph/src/bleprph.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * 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 H_BLEPRPH_
-#define H_BLEPRPH_
-
-#include "log/log.h"
-#include "nimble/ble.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ble_hs_cfg;
-struct ble_gatt_register_ctxt;
-
-extern struct log bleprph_log;
-
-/* bleprph uses the first "peruser" log module. */
-#define BLEPRPH_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
-
-/* Convenience macro for logging to the bleprph module. */
-#define BLEPRPH_LOG(lvl, ...) \
-    LOG_ ## lvl(&bleprph_log, BLEPRPH_LOG_MODULE, __VA_ARGS__)
-
-/** GATT server. */
-#define GATT_SVR_SVC_ALERT_UUID               0x1811
-#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
-#define GATT_SVR_CHR_NEW_ALERT                0x2A46
-#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
-#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
-#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
-
-void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
-int gatt_svr_init(void);
-
-/** Misc. */
-void print_bytes(const uint8_t *bytes, int len);
-void print_addr(const void *addr);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/bleprph/src/gatt_svr.c b/apps/bleprph/src/gatt_svr.c
deleted file mode 100644
index 7025aaf354..0000000000
--- a/apps/bleprph/src/gatt_svr.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- * 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 <string.h>
-#include "bsp/bsp.h"
-#include "host/ble_hs.h"
-#include "host/ble_uuid.h"
-#include "bleprph.h"
-
-/**
- * The vendor specific security test service consists of two characteristics:
- *     o random-number-generator: generates a random 32-bit number each time
- *       it is read.  This characteristic can only be read over an encrypted
- *       connection.
- *     o static-value: a single-byte characteristic that can always be read,
- *       but can only be written over an encrypted connection.
- */
-
-/* 59462f12-9543-9999-12c8-58b459a2712d */
-static const ble_uuid128_t gatt_svr_svc_sec_test_uuid =
-    BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12,
-                     0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df6 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid =
-        BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
-                         0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df7 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid =
-        BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
-                         0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-static uint8_t gatt_svr_sec_test_static_val;
-
-static int
-gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt,
-                             void *arg);
-
-static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
-    {
-        /*** Service: Security test. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = &gatt_svr_svc_sec_test_uuid.u,
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            /*** Characteristic: Random number generator. */
-            .uuid = &gatt_svr_chr_sec_test_rand_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
-        }, {
-            /*** Characteristic: Static value. */
-            .uuid = &gatt_svr_chr_sec_test_static_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ |
-                     BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
-        0, /* No more services. */
-    },
-};
-
-static int
-gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
-                   void *dst, uint16_t *len)
-{
-    uint16_t om_len;
-    int rc;
-
-    om_len = OS_MBUF_PKTLEN(om);
-    if (om_len < min_len || om_len > max_len) {
-        return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-    }
-
-    rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
-    if (rc != 0) {
-        return BLE_ATT_ERR_UNLIKELY;
-    }
-
-    return 0;
-}
-
-static int
-gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt,
-                             void *arg)
-{
-    const ble_uuid_t *uuid;
-    int rand_num;
-    int rc;
-
-    uuid = ctxt->chr->uuid;
-
-    /* Determine which characteristic is being accessed by examining its
-     * 128-bit UUID.
-     */
-
-    if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) {
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-
-        /* Respond with a 32-bit random number. */
-        rand_num = rand();
-        rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-    }
-
-    if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) {
-        switch (ctxt->op) {
-        case BLE_GATT_ACCESS_OP_READ_CHR:
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val,
-                                sizeof gatt_svr_sec_test_static_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-        case BLE_GATT_ACCESS_OP_WRITE_CHR:
-            rc = gatt_svr_chr_write(ctxt->om,
-                                    sizeof gatt_svr_sec_test_static_val,
-                                    sizeof gatt_svr_sec_test_static_val,
-                                    &gatt_svr_sec_test_static_val, NULL);
-            return rc;
-
-        default:
-            assert(0);
-            return BLE_ATT_ERR_UNLIKELY;
-        }
-    }
-
-    /* Unknown characteristic; the nimble stack should not have called this
-     * function.
-     */
-    assert(0);
-    return BLE_ATT_ERR_UNLIKELY;
-}
-
-void
-gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
-{
-    char buf[BLE_UUID_STR_LEN];
-
-    switch (ctxt->op) {
-    case BLE_GATT_REGISTER_OP_SVC:
-        BLEPRPH_LOG(DEBUG, "registered service %s with handle=%d\n",
-                    ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
-                    ctxt->svc.handle);
-        break;
-
-    case BLE_GATT_REGISTER_OP_CHR:
-        BLEPRPH_LOG(DEBUG, "registering characteristic %s with "
-                           "def_handle=%d val_handle=%d\n",
-                    ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
-                    ctxt->chr.def_handle,
-                    ctxt->chr.val_handle);
-        break;
-
-    case BLE_GATT_REGISTER_OP_DSC:
-        BLEPRPH_LOG(DEBUG, "registering descriptor %s with handle=%d\n",
-                    ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
-                    ctxt->dsc.handle);
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-}
-
-int
-gatt_svr_init(void)
-{
-    int rc;
-
-    rc = ble_gatts_count_cfg(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = ble_gatts_add_svcs(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
diff --git a/apps/bleprph/src/main.c b/apps/bleprph/src/main.c
deleted file mode 100755
index 1f45fa9052..0000000000
--- a/apps/bleprph/src/main.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * 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 <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include "sysinit/sysinit.h"
-#include "bsp/bsp.h"
-#include "os/os.h"
-#include "bsp/bsp.h"
-#include "hal/hal_gpio.h"
-#include "console/console.h"
-#include "hal/hal_system.h"
-#include "config/config.h"
-#include "split/split.h"
-
-/* BLE */
-#include "nimble/ble.h"
-#include "host/ble_hs.h"
-#include "services/gap/ble_svc_gap.h"
-
-/* Application-specified header. */
-#include "bleprph.h"
-
-/** Log data. */
-struct log bleprph_log;
-
-static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
-
-/**
- * Logs information about a connection to the console.
- */
-static void
-bleprph_print_conn_desc(struct ble_gap_conn_desc *desc)
-{
-    BLEPRPH_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
-                desc->conn_handle, desc->our_ota_addr.type);
-    print_addr(desc->our_ota_addr.val);
-    BLEPRPH_LOG(INFO, " our_id_addr_type=%d our_id_addr=",
-                desc->our_id_addr.type);
-    print_addr(desc->our_id_addr.val);
-    BLEPRPH_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
-                desc->peer_ota_addr.type);
-    print_addr(desc->peer_ota_addr.val);
-    BLEPRPH_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=",
-                desc->peer_id_addr.type);
-    print_addr(desc->peer_id_addr.val);
-    BLEPRPH_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
-                "encrypted=%d authenticated=%d bonded=%d\n",
-                desc->conn_itvl, desc->conn_latency,
-                desc->supervision_timeout,
-                desc->sec_state.encrypted,
-                desc->sec_state.authenticated,
-                desc->sec_state.bonded);
-}
-
-/**
- * Enables advertising with the following parameters:
- *     o General discoverable mode.
- *     o Undirected connectable mode.
- */
-static void
-bleprph_advertise(void)
-{
-    struct ble_gap_adv_params adv_params;
-    struct ble_hs_adv_fields fields;
-    const char *name;
-    int rc;
-
-    /**
-     *  Set the advertisement data included in our advertisements:
-     *     o Flags (indicates advertisement type and other general info).
-     *     o Advertising tx power.
-     *     o Device name.
-     *     o 16-bit service UUIDs (alert notifications).
-     */
-
-    memset(&fields, 0, sizeof fields);
-
-    /* Advertise two flags:
-     *     o Discoverability in forthcoming advertisement (general)
-     *     o BLE-only (BR/EDR unsupported).
-     */
-    fields.flags = BLE_HS_ADV_F_DISC_GEN |
-                   BLE_HS_ADV_F_BREDR_UNSUP;
-
-    /* Indicate that the TX power level field should be included; have the
-     * stack fill this value automatically.  This is done by assiging the
-     * special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
-     */
-    fields.tx_pwr_lvl_is_present = 1;
-    fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
-
-    name = ble_svc_gap_device_name();
-    fields.name = (uint8_t *)name;
-    fields.name_len = strlen(name);
-    fields.name_is_complete = 1;
-
-    fields.uuids16 = (ble_uuid16_t[]){
-        BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID)
-    };
-    fields.num_uuids16 = 1;
-    fields.uuids16_is_complete = 1;
-
-    rc = ble_gap_adv_set_fields(&fields);
-    if (rc != 0) {
-        BLEPRPH_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc);
-        return;
-    }
-
-    /* Begin advertising. */
-    memset(&adv_params, 0, sizeof adv_params);
-    adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
-    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
-    rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
-                           &adv_params, bleprph_gap_event, NULL);
-    if (rc != 0) {
-        BLEPRPH_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc);
-        return;
-    }
-}
-
-/**
- * The nimble host executes this callback when a GAP event occurs.  The
- * application associates a GAP event callback with each connection that forms.
- * bleprph uses the same callback for all connections.
- *
- * @param event                 The type of event being signalled.
- * @param ctxt                  Various information pertaining to the event.
- * @param arg                   Application-specified argument; unuesd by
- *                                  bleprph.
- *
- * @return                      0 if the application successfully handled the
- *                                  event; nonzero on failure.  The semantics
- *                                  of the return code is specific to the
- *                                  particular GAP event being signalled.
- */
-static int
-bleprph_gap_event(struct ble_gap_event *event, void *arg)
-{
-    struct ble_gap_conn_desc desc;
-    int rc;
-
-    switch (event->type) {
-    case BLE_GAP_EVENT_CONNECT:
-        /* A new connection was established or a connection attempt failed. */
-        BLEPRPH_LOG(INFO, "connection %s; status=%d ",
-                       event->connect.status == 0 ? "established" : "failed",
-                       event->connect.status);
-        if (event->connect.status == 0) {
-            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-            assert(rc == 0);
-            bleprph_print_conn_desc(&desc);
-        }
-        BLEPRPH_LOG(INFO, "\n");
-
-        if (event->connect.status != 0) {
-            /* Connection failed; resume advertising. */
-            bleprph_advertise();
-        }
-        return 0;
-
-    case BLE_GAP_EVENT_DISCONNECT:
-        BLEPRPH_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason);
-        bleprph_print_conn_desc(&event->disconnect.conn);
-        BLEPRPH_LOG(INFO, "\n");
-
-        /* Connection terminated; resume advertising. */
-        bleprph_advertise();
-        return 0;
-
-    case BLE_GAP_EVENT_CONN_UPDATE:
-        /* The central has updated the connection parameters. */
-        BLEPRPH_LOG(INFO, "connection updated; status=%d ",
-                    event->conn_update.status);
-        rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-        assert(rc == 0);
-        bleprph_print_conn_desc(&desc);
-        BLEPRPH_LOG(INFO, "\n");
-        return 0;
-
-    case BLE_GAP_EVENT_ENC_CHANGE:
-        /* Encryption has been enabled or disabled for this connection. */
-        BLEPRPH_LOG(INFO, "encryption change event; status=%d ",
-                    event->enc_change.status);
-        rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-        assert(rc == 0);
-        bleprph_print_conn_desc(&desc);
-        BLEPRPH_LOG(INFO, "\n");
-        return 0;
-
-    case BLE_GAP_EVENT_SUBSCRIBE:
-        BLEPRPH_LOG(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
-                          "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
-                    event->subscribe.conn_handle,
-                    event->subscribe.attr_handle,
-                    event->subscribe.reason,
-                    event->subscribe.prev_notify,
-                    event->subscribe.cur_notify,
-                    event->subscribe.prev_indicate,
-                    event->subscribe.cur_indicate);
-        return 0;
-
-    case BLE_GAP_EVENT_MTU:
-        BLEPRPH_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
-                    event->mtu.conn_handle,
-                    event->mtu.channel_id,
-                    event->mtu.value);
-        return 0;
-    }
-
-    return 0;
-}
-
-static void
-bleprph_on_reset(int reason)
-{
-    BLEPRPH_LOG(ERROR, "Resetting state; reason=%d\n", reason);
-}
-
-static void
-bleprph_on_sync(void)
-{
-    /* Begin advertising. */
-    bleprph_advertise();
-}
-
-/**
- * main
- *
- * The main task for the project. This function initializes the packages,
- * then starts serving events from default event queue.
- *
- * @return int NOTE: this function should never return!
- */
-int
-main(void)
-{
-    int rc;
-
-    /* Set initial BLE device address. */
-    memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}, 6);
-
-    /* Initialize OS */
-    sysinit();
-
-    /* Initialize the bleprph log. */
-    log_register("bleprph", &bleprph_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
-    /* Initialize the NimBLE host configuration. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-    ble_hs_cfg.reset_cb = bleprph_on_reset;
-    ble_hs_cfg.sync_cb = bleprph_on_sync;
-    ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
-
-    rc = gatt_svr_init();
-    assert(rc == 0);
-
-    /* Set the default device name. */
-    rc = ble_svc_gap_device_name_set("nimble-bleprph");
-    assert(rc == 0);
-
-    conf_load();
-
-    /* If this app is acting as the loader in a split image setup, jump into
-     * the second stage application instead of starting the OS.
-     */
-#if MYNEWT_VAL(SPLIT_LOADER)
-    {
-        void *entry;
-        rc = split_app_go(&entry, true);
-        if (rc == 0) {
-            hal_system_start(entry);
-        }
-    }
-#endif
-
-    /*
-     * As the last thing, process events from default event queue.
-     */
-    while (1) {
-        os_eventq_run(os_eventq_dflt_get());
-    }
-    return 0;
-}
diff --git a/apps/bleprph/src/misc.c b/apps/bleprph/src/misc.c
deleted file mode 100644
index 8ec785e511..0000000000
--- a/apps/bleprph/src/misc.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * 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 "bleprph.h"
-
-/**
- * Utility function to log an array of bytes.
- */
-void
-print_bytes(const uint8_t *bytes, int len)
-{
-    int i;
-
-    for (i = 0; i < len; i++) {
-        BLEPRPH_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
-    }
-}
-
-void
-print_addr(const void *addr)
-{
-    const uint8_t *u8p;
-
-    u8p = addr;
-    BLEPRPH_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
-                u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
-}
diff --git a/apps/bleprph/syscfg.yml b/apps/bleprph/syscfg.yml
deleted file mode 100644
index 9bc5db545b..0000000000
--- a/apps/bleprph/syscfg.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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.
-#
-
-# Package: apps/bleprph
-
-syscfg.vals:
-    # Use INFO log level to reduce code size.  DEBUG is too large for nRF51.
-    LOG_LEVEL: 1
-
-    # Disable central and observer roles.
-    BLE_ROLE_BROADCASTER: 1
-    BLE_ROLE_CENTRAL: 0
-    BLE_ROLE_OBSERVER: 0
-    BLE_ROLE_PERIPHERAL: 1
-
-    # Disable unused eddystone feature.
-    BLE_EDDYSTONE: 0
-
-    # Log reboot messages to a flash circular buffer.
-    REBOOT_LOG_FCB: 1
-    LOG_FCB: 1
-    CONFIG_FCB: 1
-
-    # Enable newtmgr commands.
-    STATS_NEWTMGR: 1
-    LOG_NEWTMGR: 1
-
-    # Enable Config.
-    CONFIG_NEWTMGR: 1
-
-    # OS main/default task
-    OS_MAIN_STACK_SIZE: 428
diff --git a/apps/bleprph_oic/pkg.yml b/apps/bleprph_oic/pkg.yml
index 9e311373ff..bd7470ff17 100644
--- a/apps/bleprph_oic/pkg.yml
+++ b/apps/bleprph_oic/pkg.yml
@@ -18,22 +18,24 @@
 pkg.name: apps/bleprph_oic
 pkg.type: app
 pkg.description: Simple BLE peripheral application.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
 
 pkg.deps: 
-    - kernel/os 
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/host/services/gap
-    - net/nimble/host/services/gatt
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/stub
-    - mgmt/oicmgr
-    - sys/sysinit
-    - sys/shell
-    - sys/id
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/nimble/controller"
+    - "@apache-mynewt-core/net/nimble/host"
+    - "@apache-mynewt-core/net/nimble/host/services/gap"
+    - "@apache-mynewt-core/net/nimble/host/services/gatt"
+    - "@apache-mynewt-core/net/nimble/host/store/ram"
+    - "@apache-mynewt-core/net/nimble/transport/ram"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/mgmt/oicmgr"
+    - "@apache-mynewt-core/sys/sysinit"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/id"
diff --git a/apps/bleprph_oic/src/bleprph.h b/apps/bleprph_oic/src/bleprph.h
index 2e3f024737..d14b53a97a 100644
--- a/apps/bleprph_oic/src/bleprph.h
+++ b/apps/bleprph_oic/src/bleprph.h
@@ -20,7 +20,8 @@
 #ifndef H_BLEPRPH_
 #define H_BLEPRPH_
 
-#include "log/log.h"
+#include "os/mynewt.h"
+#include "modlog/modlog.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -30,13 +31,6 @@ struct ble_gatt_register_ctxt;
 
 extern struct log bleprph_log;
 
-/* bleprph uses the first "peruser" log module. */
-#define BLEPRPH_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
-
-/* Convenience macro for logging to the bleprph module. */
-#define BLEPRPH_LOG(lvl, ...) \
-    LOG_ ## lvl(&bleprph_log, BLEPRPH_LOG_MODULE, __VA_ARGS__)
-
 /** GATT server. */
 #define GATT_SVR_SVC_ALERT_UUID               0x1811
 #define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
diff --git a/apps/bleprph_oic/src/gatt_svr.c b/apps/bleprph_oic/src/gatt_svr.c
index 659a9c1e5a..03791d3eba 100644
--- a/apps/bleprph_oic/src/gatt_svr.c
+++ b/apps/bleprph_oic/src/gatt_svr.c
@@ -24,240 +24,6 @@
 #include "host/ble_hs.h"
 #include "bleprph.h"
 
-/**
- * The vendor specific security test service consists of two characteristics:
- *     o random-number-generator: generates a random 32-bit number each time
- *       it is read.  This characteristic can only be read over an encrypted
- *       connection.
- *     o static-value: a single-byte characteristic that can always be read,
- *       but can only be written over an encrypted connection.
- */
-
-/* 59462f12-9543-9999-12c8-58b459a2712d */
-static const ble_uuid128_t gatt_svr_svc_sec_test_uuid =
-    BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12, \
-                     0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df6 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid =
-    BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, \
-                     0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df7 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid =
-    BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0, \
-                     0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-static uint8_t gatt_svr_sec_test_static_val;
-
-static int
-gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt,
-                          void *arg);
-
-static int
-gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt,
-                             void *arg);
-
-static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
-    {
-        /*** Alert Notification Service. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = BLE_UUID16_DECLARE(GATT_SVR_SVC_ALERT_UUID),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_NEW_ALERT),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_NOTIFY,
-        }, {
-            .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_READ,
-        }, {
-            .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_UNR_ALERT_STAT_UUID),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_NOTIFY,
-        }, {
-            .uuid = BLE_UUID16_DECLARE(GATT_SVR_CHR_ALERT_NOT_CTRL_PT),
-            .access_cb = gatt_svr_chr_access_alert,
-            .flags = BLE_GATT_CHR_F_WRITE,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
-        /*** Service: Security test. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = &gatt_svr_svc_sec_test_uuid.u,
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            /*** Characteristic: Random number generator. */
-            .uuid = &gatt_svr_chr_sec_test_rand_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
-        }, {
-            /*** Characteristic: Static value. */
-            .uuid = &gatt_svr_chr_sec_test_static_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ |
-                     BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
-        0, /* No more services. */
-    },
-};
-
-static int
-gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
-                   void *dst, uint16_t *len)
-{
-    uint16_t om_len;
-    int rc;
-
-    om_len = OS_MBUF_PKTLEN(om);
-    if (om_len < min_len || om_len > max_len) {
-        return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-    }
-
-    rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
-    if (rc != 0) {
-        return BLE_ATT_ERR_UNLIKELY;
-    }
-
-    return 0;
-}
-
-#define GATT_SVR_NEW_ALERT_VAL_MAX_LEN    64
-
-static const uint8_t gatt_svr_new_alert_cat = 0x01; /* Simple alert. */
-static uint8_t gatt_svr_new_alert_val[GATT_SVR_NEW_ALERT_VAL_MAX_LEN];
-static uint16_t gatt_svr_new_alert_val_len;
-static const uint8_t gatt_svr_unr_alert_cat = 0x01; /* Simple alert. */
-static uint16_t gatt_svr_unr_alert_stat;
-static uint16_t gatt_svr_alert_not_ctrl_pt;
-
-static int
-gatt_svr_chr_access_alert(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt,
-                          void *arg)
-{
-    uint16_t uuid16;
-    int rc;
-
-    uuid16 = ble_uuid_u16(ctxt->chr->uuid);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_cat,
-                            sizeof gatt_svr_new_alert_cat);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case GATT_SVR_CHR_NEW_ALERT:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om, 0,
-                                    sizeof gatt_svr_new_alert_val,
-                                    gatt_svr_new_alert_val,
-                                    &gatt_svr_new_alert_val_len);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_new_alert_val,
-                                sizeof gatt_svr_new_alert_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_cat,
-                            sizeof gatt_svr_unr_alert_cat);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case GATT_SVR_CHR_UNR_ALERT_STAT_UUID:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om, 2, 2, &gatt_svr_unr_alert_stat,
-                                    NULL);
-            return rc;
-        } else {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_unr_alert_stat,
-                                sizeof gatt_svr_unr_alert_stat);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case GATT_SVR_CHR_ALERT_NOT_CTRL_PT:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om, 2, 2,
-                                    &gatt_svr_alert_not_ctrl_pt, NULL);
-        } else {
-            rc = BLE_ATT_ERR_UNLIKELY;
-        }
-        return rc;
-
-    default:
-        assert(0);
-        return BLE_ATT_ERR_UNLIKELY;
-    }
-}
-
-static int
-gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt,
-                             void *arg)
-{
-    const ble_uuid_t *uuid;
-    int rand_num;
-    int rc;
-
-    uuid = ctxt->chr->uuid;
-
-    /* Determine which characteristic is being accessed by examining its
-     * 128-bit UUID.
-     */
-
-    if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) {
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-
-        /* Respond with a 32-bit random number. */
-        rand_num = rand();
-        rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-    }
-
-    if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0) {
-        switch (ctxt->op) {
-        case BLE_GATT_ACCESS_OP_READ_CHR:
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val,
-                                sizeof gatt_svr_sec_test_static_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-        case BLE_GATT_ACCESS_OP_WRITE_CHR:
-            rc = gatt_svr_chr_write(ctxt->om,
-                                    sizeof gatt_svr_sec_test_static_val,
-                                    sizeof gatt_svr_sec_test_static_val,
-                                    &gatt_svr_sec_test_static_val, NULL);
-            return rc;
-
-        default:
-            assert(0);
-            return BLE_ATT_ERR_UNLIKELY;
-        }
-    }
-
-    /* Unknown characteristic; the nimble stack should not have called this
-     * function.
-     */
-    assert(0);
-    return BLE_ATT_ERR_UNLIKELY;
-}
-
 void
 gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
 {
@@ -265,13 +31,13 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
 
     switch (ctxt->op) {
     case BLE_GATT_REGISTER_OP_SVC:
-        BLEPRPH_LOG(DEBUG, "registered service %s with handle=%d\n",
+        MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
                     ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
                     ctxt->svc.handle);
         break;
 
     case BLE_GATT_REGISTER_OP_CHR:
-        BLEPRPH_LOG(DEBUG, "registering characteristic %s with "
+        MODLOG_DFLT(DEBUG, "registering characteristic %s with "
                            "def_handle=%d val_handle=%d\n",
                     ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
                     ctxt->chr.def_handle,
@@ -279,7 +45,7 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
         break;
 
     case BLE_GATT_REGISTER_OP_DSC:
-        BLEPRPH_LOG(DEBUG, "registering descriptor %s with handle=%d\n",
+        MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
                     ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
                     ctxt->dsc.handle);
         break;
@@ -289,21 +55,3 @@ gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
         break;
     }
 }
-
-int
-gatt_svr_init(void)
-{
-    int rc;
-
-    rc = ble_gatts_count_cfg(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = ble_gatts_add_svcs(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
diff --git a/apps/bleprph_oic/src/main.c b/apps/bleprph_oic/src/main.c
old mode 100755
new mode 100644
index 0418ba7e61..fa6268459a
--- a/apps/bleprph_oic/src/main.c
+++ b/apps/bleprph_oic/src/main.c
@@ -21,9 +21,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
-#include <sysinit/sysinit.h>
-#include <bsp/bsp.h>
-#include <os/os.h>
+#include "os/mynewt.h"
 #include <bsp/bsp.h>
 #include <hal/hal_gpio.h>
 #include <console/console.h>
@@ -31,7 +29,6 @@
 
 #include <oic/oc_api.h>
 #include <oic/oc_gatt.h>
-#include <oic/oc_log.h>
 #include <cborattr/cborattr.h>
 
 /* BLE */
@@ -42,10 +39,6 @@
 /* Application-specified header. */
 #include "bleprph.h"
 
-
-/** Log data. */
-struct log bleprph_log;
-
 static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
 
 /**
@@ -54,19 +47,19 @@ static int bleprph_gap_event(struct ble_gap_event *event, void *arg);
 static void
 bleprph_print_conn_desc(struct ble_gap_conn_desc *desc)
 {
-    BLEPRPH_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
+    MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
                 desc->conn_handle, desc->our_ota_addr.type);
     print_addr(desc->our_ota_addr.val);
-    BLEPRPH_LOG(INFO, " our_id_addr_type=%d our_id_addr=",
+    MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
                 desc->our_id_addr.type);
     print_addr(desc->our_id_addr.val);
-    BLEPRPH_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
+    MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
                 desc->peer_ota_addr.type);
     print_addr(desc->peer_ota_addr.val);
-    BLEPRPH_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=",
+    MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
                 desc->peer_id_addr.type);
     print_addr(desc->peer_id_addr.val);
-    BLEPRPH_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
+    MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
                 "encrypted=%d authenticated=%d bonded=%d\n",
                 desc->conn_itvl, desc->conn_latency,
                 desc->supervision_timeout,
@@ -93,7 +86,7 @@ bleprph_advertise(void)
      *     o Flags (indicates advertisement type and other general info).
      *     o Advertising tx power.
      *     o Device name.
-     *     o 16-bit service UUIDs (alert notifications).
+     *     o service UUID.
      */
 
     memset(&fields, 0, sizeof fields);
@@ -117,15 +110,25 @@ bleprph_advertise(void)
     fields.name_len = strlen(name);
     fields.name_is_complete = 1;
 
+#if MYNEWT_VAL(ADVERTISE_128BIT_UUID)
+    /* Advertise the 128-bit CoAP-over-BLE service UUID in the scan response. */
     fields.uuids128 = (ble_uuid128_t []) {
-        BLE_UUID128_INIT(OC_GATT_SERVICE_UUID)
+        BLE_UUID128_INIT(OC_GATT_UNSEC_SVC_UUID)
     };
     fields.num_uuids128 = 1;
     fields.uuids128_is_complete = 1;
-
+#endif
+#if MYNEWT_VAL(ADVERTISE_16BIT_UUID)
+    /* Advertise the 16-bit CoAP-over-BLE service UUID in the scan response. */
+    fields.uuids16 = (ble_uuid16_t[]) {
+        BLE_UUID16_INIT(OC_GATT_SEC_SVC_UUID)
+    };
+    fields.num_uuids16 = 1;
+    fields.uuids16_is_complete = 1;
+#endif
     rc = ble_gap_adv_set_fields(&fields);
     if (rc != 0) {
-        BLEPRPH_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc);
+        MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
         return;
     }
 
@@ -136,7 +139,7 @@ bleprph_advertise(void)
     rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
                            &adv_params, bleprph_gap_event, NULL);
     if (rc != 0) {
-        BLEPRPH_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
         return;
     }
 }
@@ -165,15 +168,15 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
     switch (event->type) {
     case BLE_GAP_EVENT_CONNECT:
         /* A new connection was established or a connection attempt failed. */
-        BLEPRPH_LOG(INFO, "connection %s; status=%d ",
-                       event->connect.status == 0 ? "established" : "failed",
-                       event->connect.status);
+        MODLOG_DFLT(INFO, "connection %s; status=%d ",
+                    event->connect.status == 0 ? "established" : "failed",
+                    event->connect.status);
         if (event->connect.status == 0) {
             rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
             assert(rc == 0);
             bleprph_print_conn_desc(&desc);
         }
-        BLEPRPH_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
 
         if (event->connect.status != 0) {
             /* Connection failed; resume advertising. */
@@ -184,9 +187,9 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
         return 0;
 
     case BLE_GAP_EVENT_DISCONNECT:
-        BLEPRPH_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
         bleprph_print_conn_desc(&event->disconnect.conn);
-        BLEPRPH_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
 
         oc_ble_coap_conn_del(event->disconnect.conn.conn_handle);
 
@@ -196,26 +199,32 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
 
     case BLE_GAP_EVENT_CONN_UPDATE:
         /* The central has updated the connection parameters. */
-        BLEPRPH_LOG(INFO, "connection updated; status=%d ",
+        MODLOG_DFLT(INFO, "connection updated; status=%d ",
                     event->conn_update.status);
         rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
         assert(rc == 0);
         bleprph_print_conn_desc(&desc);
-        BLEPRPH_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        MODLOG_DFLT(INFO, "advertise complete; reason=%d\n",
+                    event->adv_complete.reason);
+        bleprph_advertise();
         return 0;
 
     case BLE_GAP_EVENT_ENC_CHANGE:
         /* Encryption has been enabled or disabled for this connection. */
-        BLEPRPH_LOG(INFO, "encryption change event; status=%d ",
+        MODLOG_DFLT(INFO, "encryption change event; status=%d ",
                     event->enc_change.status);
         rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
         assert(rc == 0);
         bleprph_print_conn_desc(&desc);
-        BLEPRPH_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
         return 0;
 
     case BLE_GAP_EVENT_SUBSCRIBE:
-        BLEPRPH_LOG(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
+        MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
                           "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
                     event->subscribe.conn_handle,
                     event->subscribe.attr_handle,
@@ -227,11 +236,27 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
         return 0;
 
     case BLE_GAP_EVENT_MTU:
-        BLEPRPH_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
+        MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
                     event->mtu.conn_handle,
                     event->mtu.channel_id,
                     event->mtu.value);
         return 0;
+
+    case BLE_GAP_EVENT_REPEAT_PAIRING:
+        /* We already have a bond with the peer, but it is attempting to
+         * establish a new secure link.  This app sacrifices security for
+         * convenience: just throw away the old bond and accept the new link.
+         */
+
+        /* Delete the old bond. */
+        rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
+        assert(rc == 0);
+        ble_store_util_delete_peer(&desc.peer_id_addr);
+
+        /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
+         * continue with the pairing operation.
+         */
+        return BLE_GAP_REPEAT_PAIRING_RETRY;
     }
 
     return 0;
@@ -240,7 +265,7 @@ bleprph_gap_event(struct ble_gap_event *event, void *arg)
 static void
 bleprph_on_reset(int reason)
 {
-    BLEPRPH_LOG(ERROR, "Resetting state; reason=%d\n", reason);
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
 }
 
 static void
@@ -253,19 +278,19 @@ bleprph_on_sync(void)
 static void
 app_get_light(oc_request_t *request, oc_interface_mask_t interface)
 {
-    bool state;
+    bool value;
 
     if (hal_gpio_read(LED_BLINK_PIN)) {
-        state = true;
+        value = true;
     } else {
-        state = false;
+        value = false;
     }
     oc_rep_start_root_object();
     switch (interface) {
     case OC_IF_BASELINE:
         oc_process_baseline_interface(request->resource);
-    case OC_IF_RW:
-        oc_rep_set_boolean(root, state, state);
+    case OC_IF_A:
+        oc_rep_set_boolean(root, value, value);
         break;
     default:
         break;
@@ -277,15 +302,15 @@ app_get_light(oc_request_t *request, oc_interface_mask_t interface)
 static void
 app_set_light(oc_request_t *request, oc_interface_mask_t interface)
 {
-    bool state;
+    bool value;
     int len;
     uint16_t data_off;
     struct os_mbuf *m;
     struct cbor_attr_t attrs[] = {
         [0] = {
-            .attribute = "state",
+            .attribute = "value",
             .type = CborAttrBooleanType,
-            .addr.boolean = &state,
+            .addr.boolean = &value,
             .dflt.boolean = false
         },
         [1] = {
@@ -296,7 +321,7 @@ app_set_light(oc_request_t *request, oc_interface_mask_t interface)
     if (cbor_read_mbuf_attrs(m, data_off, len, attrs)) {
         oc_send_response(request, OC_STATUS_BAD_REQUEST);
     } else {
-        hal_gpio_write(LED_BLINK_PIN, state == true);
+        hal_gpio_write(LED_BLINK_PIN, value == true);
         oc_send_response(request, OC_STATUS_CHANGED);
     }
 }
@@ -311,14 +336,15 @@ omgr_app_init(void)
                   NULL);
 
     res = oc_new_resource("/light/1", 1, 0);
-    oc_resource_bind_resource_type(res, "oic.r.light");
-    oc_resource_bind_resource_interface(res, OC_IF_RW);
-    oc_resource_set_default_interface(res, OC_IF_RW);
+    oc_resource_bind_resource_type(res, "oic.r.switch.binary");
+    oc_resource_bind_resource_interface(res, OC_IF_A);
+    oc_resource_set_default_interface(res, OC_IF_A);
 
     oc_resource_set_discoverable(res);
     oc_resource_set_periodic_observable(res, 1);
     oc_resource_set_request_handler(res, OC_GET, app_get_light);
     oc_resource_set_request_handler(res, OC_PUT, app_set_light);
+    oc_resource_set_request_handler(res, OC_POST, app_set_light);
     oc_add_resource(res);
 
 }
@@ -346,25 +372,17 @@ main(void)
     /* Initialize OS */
     sysinit();
 
-    /* Initialize the bleprph log. */
-    log_register("bleprph", &bleprph_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
-    /* Initialize the NimBLE host configuration. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
     /* Initialize the OIC  */
-    log_register("oic", &oc_log, &log_console_handler, NULL, LOG_SYSLEVEL);
     oc_main_init((oc_handler_t *)&omgr_oc_handler);
     oc_ble_coap_gatt_srv_init();
 
     ble_hs_cfg.reset_cb = bleprph_on_reset;
     ble_hs_cfg.sync_cb = bleprph_on_sync;
     ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
+    ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
 
     /* Set the default device name. */
-    rc = ble_svc_gap_device_name_set("pi");
+    rc = ble_svc_gap_device_name_set("c5");
     assert(rc == 0);
 
     /* Our light resource */
diff --git a/apps/bleprph_oic/src/misc.c b/apps/bleprph_oic/src/misc.c
index 8ec785e511..6ed205ec84 100644
--- a/apps/bleprph_oic/src/misc.c
+++ b/apps/bleprph_oic/src/misc.c
@@ -28,7 +28,7 @@ print_bytes(const uint8_t *bytes, int len)
     int i;
 
     for (i = 0; i < len; i++) {
-        BLEPRPH_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
+        MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
     }
 }
 
@@ -38,6 +38,6 @@ print_addr(const void *addr)
     const uint8_t *u8p;
 
     u8p = addr;
-    BLEPRPH_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
-                u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
+    MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
+             u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
 }
diff --git a/apps/bleprph_oic/syscfg.yml b/apps/bleprph_oic/syscfg.yml
index 8f120fd258..bfa3b2ae01 100644
--- a/apps/bleprph_oic/syscfg.yml
+++ b/apps/bleprph_oic/syscfg.yml
@@ -16,6 +16,14 @@
 # under the License.
 #
 
+syscfg.defs:
+    ADVERTISE_16BIT_UUID:
+        description: 'Advertise Runtime 16 bit service UUID'
+        value: 1
+    ADVERTISE_128BIT_UUID:
+        description: 'Advertise Iotivity 128 bit service UUID'
+        value: 0
+
 syscfg.vals:
     # Use INFO log level to reduce code size.  DEBUG is too large for nRF51.
     LOG_LEVEL: 0
@@ -35,9 +43,6 @@ syscfg.vals:
     BLE_LL_CFG_FEAT_LE_ENCRYPTION: 0
     BLE_LL_CFG_FEAT_LL_PRIVACY: 0
 
-    # Disable unused eddystone feature.
-    BLE_EDDYSTONE: 0
-
     # Log reboot messages to a flash circular buffer.
     REBOOT_LOG_FCB: 1
     LOG_FCB: 1
@@ -60,4 +65,9 @@ syscfg.vals:
     STATS_NAMES: 1
 
     # Default task settings
-    OS_MAIN_STACK_SIZE: 336
+    OS_MAIN_STACK_SIZE: 568
+
+    # Lots of smaller mbufs are required for newtmgr-over-OIC using typical BLE
+    # ATT MTU values.
+    MSYS_1_BLOCK_COUNT: 20
+    MSYS_1_BLOCK_SIZE: 150
diff --git a/apps/blesplit/pkg.yml b/apps/blesplit/pkg.yml
index 534bd40ba6..5e93ab089f 100644
--- a/apps/blesplit/pkg.yml
+++ b/apps/blesplit/pkg.yml
@@ -20,25 +20,28 @@
 pkg.name: apps/blesplit
 pkg.type: app
 pkg.description: "Example BLE application which runs as a split app."
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
 
 pkg.deps:
-    - boot/split
-    - boot/split_app
-    - kernel/os
-    - mgmt/imgmgr
-    - mgmt/newtmgr
-    - mgmt/newtmgr/transport/ble
-    - net/nimble/host
-    - net/nimble/host/services/ans
-    - net/nimble/host/services/gap
-    - net/nimble/host/services/gatt
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
-    - sys/console/full
-    - sys/id
-    - sys/log/full
-    - sys/shell
-    - sys/stats/full
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/boot/split"
+    - "@apache-mynewt-core/boot/split_app"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/ble"
+    - "@apache-mynewt-core/net/nimble/host"
+    - "@apache-mynewt-core/net/nimble/host/util"
+    - "@apache-mynewt-core/net/nimble/host/services/ans"
+    - "@apache-mynewt-core/net/nimble/host/services/gap"
+    - "@apache-mynewt-core/net/nimble/host/services/gatt"
+    - "@apache-mynewt-core/net/nimble/host/store/ram"
+    - "@apache-mynewt-core/net/nimble/transport/ram"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/id"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
diff --git a/apps/blesplit/src/blesplit.h b/apps/blesplit/src/blesplit.h
index 8a04e3eda7..6b17c9beec 100644
--- a/apps/blesplit/src/blesplit.h
+++ b/apps/blesplit/src/blesplit.h
@@ -20,7 +20,8 @@
 #ifndef H_BLESPLIT_
 #define H_BLESPLIT_
 
-#include "log/log.h"
+#include "os/mynewt.h"
+#include "modlog/modlog.h"
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -28,15 +29,6 @@ extern "C" {
 struct ble_hs_cfg;
 struct ble_gatt_register_ctxt;
 
-extern struct log blesplit_log;
-
-/* blesplit uses the first "peruser" log module. */
-#define BLESPLIT_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
-
-/* Convenience macro for logging to the blesplit module. */
-#define BLESPLIT_LOG(lvl, ...) \
-    LOG_ ## lvl(&blesplit_log, BLESPLIT_LOG_MODULE, __VA_ARGS__)
-
 /** GATT server. */
 #define GATT_SVR_SVC_ALERT_UUID               0x1811
 #define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
diff --git a/apps/blesplit/src/main.c b/apps/blesplit/src/main.c
old mode 100755
new mode 100644
index 8c349c1530..b4d8caa355
--- a/apps/blesplit/src/main.c
+++ b/apps/blesplit/src/main.c
@@ -21,9 +21,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
-#include "sysinit/sysinit.h"
-#include "bsp/bsp.h"
-#include "os/os.h"
+#include "os/mynewt.h"
 #include "bsp/bsp.h"
 #include "hal/hal_gpio.h"
 #include "console/console.h"
@@ -34,14 +32,12 @@
 /* BLE */
 #include "nimble/ble.h"
 #include "host/ble_hs.h"
+#include "host/util/util.h"
 #include "services/gap/ble_svc_gap.h"
 
 /* Application-specified header. */
 #include "blesplit.h"
 
-/** Log data. */
-struct log blesplit_log;
-
 static int blesplit_gap_event(struct ble_gap_event *event, void *arg);
 
 /**
@@ -50,19 +46,19 @@ static int blesplit_gap_event(struct ble_gap_event *event, void *arg);
 static void
 blesplit_print_conn_desc(struct ble_gap_conn_desc *desc)
 {
-    BLESPLIT_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
+    MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
                 desc->conn_handle, desc->our_ota_addr.type);
     print_addr(desc->our_ota_addr.val);
-    BLESPLIT_LOG(INFO, " our_id_addr_type=%d our_id_addr=",
+    MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
                 desc->our_id_addr.type);
     print_addr(desc->our_id_addr.val);
-    BLESPLIT_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
+    MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
                 desc->peer_ota_addr.type);
     print_addr(desc->peer_ota_addr.val);
-    BLESPLIT_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=",
+    MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
                 desc->peer_id_addr.type);
     print_addr(desc->peer_id_addr.val);
-    BLESPLIT_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
+    MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
                  "encrypted=%d authenticated=%d bonded=%d\n",
                  desc->conn_itvl, desc->conn_latency,
                  desc->supervision_timeout,
@@ -79,11 +75,19 @@ blesplit_print_conn_desc(struct ble_gap_conn_desc *desc)
 static void
 blesplit_advertise(void)
 {
+    uint8_t own_addr_type;
     struct ble_gap_adv_params adv_params;
     struct ble_hs_adv_fields fields;
     const char *name;
     int rc;
 
+    /* Figure out address to use while advertising (no privacy for now) */
+    rc = ble_hs_id_infer_auto(0, &own_addr_type);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "error determining address type; rc=%d\n", rc);
+        return;
+    }
+
     /**
      *  Set the advertisement data included in our advertisements:
      *     o Flags (indicates advertisement type and other general info).
@@ -121,7 +125,7 @@ blesplit_advertise(void)
 
     rc = ble_gap_adv_set_fields(&fields);
     if (rc != 0) {
-        BLESPLIT_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc);
+        MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
         return;
     }
 
@@ -129,10 +133,10 @@ blesplit_advertise(void)
     memset(&adv_params, 0, sizeof adv_params);
     adv_params.conn_mode = BLE_GAP_CONN_MODE_UND;
     adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
-    rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
+    rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER,
                            &adv_params, blesplit_gap_event, NULL);
     if (rc != 0) {
-        BLESPLIT_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
         return;
     }
 }
@@ -161,15 +165,15 @@ blesplit_gap_event(struct ble_gap_event *event, void *arg)
     switch (event->type) {
     case BLE_GAP_EVENT_CONNECT:
         /* A new connection was established or a connection attempt failed. */
-        BLESPLIT_LOG(INFO, "connection %s; status=%d ",
-                       event->connect.status == 0 ? "established" : "failed",
-                       event->connect.status);
+        MODLOG_DFLT(INFO, "connection %s; status=%d ",
+                    event->connect.status == 0 ? "established" : "failed",
+                    event->connect.status);
         if (event->connect.status == 0) {
             rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
             assert(rc == 0);
             blesplit_print_conn_desc(&desc);
         }
-        BLESPLIT_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
 
         if (event->connect.status != 0) {
             /* Connection failed; resume advertising. */
@@ -178,9 +182,9 @@ blesplit_gap_event(struct ble_gap_event *event, void *arg)
         return 0;
 
     case BLE_GAP_EVENT_DISCONNECT:
-        BLESPLIT_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
         blesplit_print_conn_desc(&event->disconnect.conn);
-        BLESPLIT_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
 
         /* Connection terminated; resume advertising. */
         blesplit_advertise();
@@ -188,26 +192,33 @@ blesplit_gap_event(struct ble_gap_event *event, void *arg)
 
     case BLE_GAP_EVENT_CONN_UPDATE:
         /* The central has updated the connection parameters. */
-        BLESPLIT_LOG(INFO, "connection updated; status=%d ",
+        MODLOG_DFLT(INFO, "connection updated; status=%d ",
                     event->conn_update.status);
         rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
         assert(rc == 0);
         blesplit_print_conn_desc(&desc);
-        BLESPLIT_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        MODLOG_DFLT(INFO, "advertise complete; reason=%d\n",
+                    event->adv_complete.reason);
+        blesplit_advertise();
         return 0;
 
     case BLE_GAP_EVENT_ENC_CHANGE:
         /* Encryption has been enabled or disabled for this connection. */
-        BLESPLIT_LOG(INFO, "encryption change event; status=%d ",
+        MODLOG_DFLT(INFO, "encryption change event; status=%d ",
                     event->enc_change.status);
         rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
         assert(rc == 0);
         blesplit_print_conn_desc(&desc);
-        BLESPLIT_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
         return 0;
 
     case BLE_GAP_EVENT_SUBSCRIBE:
-        BLESPLIT_LOG(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
+        MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
                           "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
                     event->subscribe.conn_handle,
                     event->subscribe.attr_handle,
@@ -219,11 +230,27 @@ blesplit_gap_event(struct ble_gap_event *event, void *arg)
         return 0;
 
     case BLE_GAP_EVENT_MTU:
-        BLESPLIT_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
+        MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
                     event->mtu.conn_handle,
                     event->mtu.channel_id,
                     event->mtu.value);
         return 0;
+
+    case BLE_GAP_EVENT_REPEAT_PAIRING:
+        /* We already have a bond with the peer, but it is attempting to
+         * establish a new secure link.  This app sacrifices security for
+         * convenience: just throw away the old bond and accept the new link.
+         */
+
+        /* Delete the old bond. */
+        rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
+        assert(rc == 0);
+        ble_store_util_delete_peer(&desc.peer_id_addr);
+
+        /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
+         * continue with the pairing operation.
+         */
+        return BLE_GAP_REPEAT_PAIRING_RETRY;
     }
 
     return 0;
@@ -232,12 +259,18 @@ blesplit_gap_event(struct ble_gap_event *event, void *arg)
 static void
 blesplit_on_reset(int reason)
 {
-    BLESPLIT_LOG(ERROR, "Resetting state; reason=%d\n", reason);
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
 }
 
 static void
 blesplit_on_sync(void)
 {
+    int rc;
+
+    /* Make sure we have proper identity address set (public preferred) */
+    rc = ble_hs_util_ensure_addr(0);
+    assert(rc == 0);
+
     /* Begin advertising. */
     blesplit_advertise();
 }
@@ -258,25 +291,15 @@ main(void)
     /* Initialize OS */
     sysinit();
 
-    /* Set initial BLE device address. */
-    memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0x0a, 0x0a, 0x0a, 0x0a, 0x0a}, 6);
-
-    /* Initialize the blesplit log. */
-    log_register("blesplit", &blesplit_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
     /* Initialize the NimBLE host configuration. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
     ble_hs_cfg.reset_cb = blesplit_on_reset;
     ble_hs_cfg.sync_cb = blesplit_on_sync;
+    ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
 
     /* Set the default device name. */
     rc = ble_svc_gap_device_name_set("nimble-blesplit");
     assert(rc == 0);
 
-    conf_load();
-
     /*
      * As the last thing, process events from default event queue.
      */
diff --git a/apps/blesplit/src/misc.c b/apps/blesplit/src/misc.c
index 43f62ae6bd..3c11d916ff 100644
--- a/apps/blesplit/src/misc.c
+++ b/apps/blesplit/src/misc.c
@@ -28,7 +28,7 @@ print_bytes(const uint8_t *bytes, int len)
     int i;
 
     for (i = 0; i < len; i++) {
-        BLESPLIT_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
+        MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
     }
 }
 
@@ -38,6 +38,6 @@ print_addr(const void *addr)
     const uint8_t *u8p;
 
     u8p = addr;
-    BLESPLIT_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
-                 u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
+    MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
+             u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
 }
diff --git a/apps/blesplit/syscfg.yml b/apps/blesplit/syscfg.yml
index a377246fb4..8e5ca9ec7f 100644
--- a/apps/blesplit/syscfg.yml
+++ b/apps/blesplit/syscfg.yml
@@ -28,9 +28,6 @@ syscfg.vals:
     BLE_ROLE_OBSERVER: 0
     BLE_ROLE_PERIPHERAL: 1
 
-    # Disable unused eddystone feature.
-    BLE_EDDYSTONE: 0
-
     # Log reboot messages to a flash circular buffer.
     REBOOT_LOG_FCB: 1
     LOG_FCB: 1
@@ -44,4 +41,4 @@ syscfg.vals:
     CONFIG_NEWTMGR: 1
 
     # OS main/default task
-    OS_MAIN_STACK_SIZE: 428
+    OS_MAIN_STACK_SIZE: 468
diff --git a/apps/bletest/pkg.yml b/apps/bletest/pkg.yml
deleted file mode 100644
index 929480d8b3..0000000000
--- a/apps/bletest/pkg.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-#
-# 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.
-#
-
-pkg.name: apps/bletest
-pkg.type: app
-pkg.description: Test project for the nimble BLE controller.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps:
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/transport/ram
-    - kernel/os
-    - sys/console/full
-    - sys/shell
-    - sys/config
-    - sys/log/full
-    - sys/stats/full
-pkg.cflags: -DBLETEST
diff --git a/apps/bletest/src/bletest_hci.c b/apps/bletest/src/bletest_hci.c
deleted file mode 100755
index 86d2293565..0000000000
--- a/apps/bletest/src/bletest_hci.c
+++ /dev/null
@@ -1,785 +0,0 @@
-/*
- * 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 <string.h>
-#include "os/os.h"
-#include "bsp/bsp.h"
-#include "syscfg/syscfg.h"
-
-/* BLE */
-#include "nimble/ble.h"
-#include "nimble/ble_hci_trans.h"
-#include "nimble/hci_common.h"
-#include "nimble/hci_vendor.h"
-#include "host/ble_hs.h"
-#include "controller/ble_ll.h"
-#include "controller/ble_ll_hci.h"
-#include "controller/ble_ll_conn.h"
-#include "controller/ble_ll_scan.h"
-#include "controller/ble_ll_adv.h"
-
-/* XXX: An app should not include private headers from a library.  The bletest
- * app uses some of nimble's internal details for logging.
- */
-#include "../src/ble_hs_priv.h"
-#include "bletest_priv.h"
-
-extern uint16_t g_bletest_ltk_reply_handle;
-
-void
-bletest_send_conn_update(uint16_t handle)
-{
-    int rc;
-    struct hci_conn_update hcu;
-
-    hcu.conn_latency = 4;
-    hcu.supervision_timeout = 2000;
-    hcu.conn_itvl_min = 1000;
-    hcu.conn_itvl_max = 1000;
-    hcu.handle = handle;
-    hcu.min_ce_len = 4;
-    hcu.max_ce_len = 4;
-
-    rc = ble_hs_hci_cmd_le_conn_update(&hcu);
-    assert(rc == 0);
-}
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-void
-bletest_ltk_req_reply(uint16_t handle)
-{
-    g_bletest_ltk_reply_handle |= (1 << (handle-1));
-}
-
-int
-bletest_send_ltk_req_neg_reply(uint16_t handle)
-{
-    int rc;
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + sizeof(uint16_t)];
-    uint16_t ack_conn_handle;
-    uint8_t rsplen;
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_LT_KEY_REQ_NEG_REPLY,
-                       sizeof(uint16_t), dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    put_le16(dst, handle);
-    rc = ble_hs_hci_cmd_tx(buf, &ack_conn_handle, 2, &rsplen);
-    if (rc == 0) {
-        if (rsplen != 2) {
-            rc = -1;
-        }
-    }
-
-    return rc;
-}
-
-int
-bletest_send_ltk_req_reply(uint16_t handle)
-{
-    struct hci_lt_key_req_reply hkr;
-    uint16_t ack_conn_handle;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LT_KEY_REQ_REPLY_LEN];
-    uint8_t ack_params_len;
-    int rc;
-
-    hkr.conn_handle = handle;
-    swap_buf(hkr.long_term_key, (uint8_t *)g_bletest_LTK, 16);
-
-    ble_hs_hci_cmd_build_le_lt_key_req_reply(&hkr, buf, sizeof buf);
-    rc = ble_hs_hci_cmd_tx(buf, &ack_conn_handle, sizeof ack_conn_handle,
-                        &ack_params_len);
-    if (rc != 0) {
-        return rc;
-    }
-    if (ack_params_len != BLE_HCI_LT_KEY_REQ_REPLY_ACK_PARAM_LEN - 1) {
-        return -1;
-    }
-
-    ack_conn_handle = TOFROMLE16(ack_conn_handle);
-    if (ack_conn_handle != handle) {
-        return -1;
-    }
-    return 0;
-}
-#endif
-
-int
-bletest_hci_reset_ctlr(void)
-{
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_CTLR_BASEBAND, BLE_HCI_OCF_CB_RESET,
-                             0, buf);
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-
-int
-bletest_hci_rd_bd_addr(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_DEV_ADDR_LEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_BD_ADDR, 0,
-                       buf);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_DEV_ADDR_LEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_DEV_ADDR_LEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-
-    return rc;
-}
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-int
-bletest_hci_le_encrypt(uint8_t *key, uint8_t *pt)
-{
-    int rc;
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_ENCRYPT_LEN];
-    uint8_t rspbuf[16];
-    uint8_t rsplen;
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_ENCRYPT,
-                       BLE_HCI_LE_ENCRYPT_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    swap_buf(dst, key, BLE_ENC_BLOCK_SIZE);
-    swap_buf(dst + BLE_ENC_BLOCK_SIZE, pt, BLE_ENC_BLOCK_SIZE);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, 16, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != 16) {
-        return BLE_HS_ECONTROLLER;
-    }
-    return rc;
-}
-#endif
-
-int
-bletest_hci_le_set_datalen(uint16_t handle, uint16_t txoctets, uint16_t txtime)
-{
-    int rc;
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_DATALEN_LEN];
-    uint8_t rspbuf[2];
-    uint8_t rsplen;
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_DATA_LEN,
-                       BLE_HCI_SET_DATALEN_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    put_le16(dst, handle);
-    put_le16(dst + 2, txoctets);
-    put_le16(dst + 4, txtime);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, 2, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != 2) {
-        return BLE_HS_ECONTROLLER;
-    }
-
-    return rc;
-}
-
-int
-bletest_hci_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_WR_SUGG_DATALEN_LEN];
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_WR_SUGG_DEF_DATA_LEN,
-                       BLE_HCI_WR_SUGG_DATALEN_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    put_le16(dst, txoctets);
-    put_le16(dst + 2, txtime);
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-
-int
-bletest_hci_le_rd_sugg_datalen(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_SUGG_DATALEN_RSPLEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUGG_DEF_DATA_LEN, 0,
-                       buf);
-
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_SUGG_DATALEN_RSPLEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_SUGG_DATALEN_RSPLEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-
-    return 0;
-}
-
-int
-bletest_hci_rd_local_version(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_LOC_VER_INFO_RSPLEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOCAL_VER, 0,
-                       buf);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_LOC_VER_INFO_RSPLEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_LOC_VER_INFO_RSPLEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-    return rc;
-}
-
-int
-bletest_hci_rd_local_feat(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_FEAT,
-                       0, buf);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_LOC_SUPP_FEAT_RSPLEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-    return rc;
-}
-
-int
-bletest_hci_rd_local_supp_cmd(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_INFO_PARAMS, BLE_HCI_OCF_IP_RD_LOC_SUPP_CMD,
-                       0, buf);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_LOC_SUPP_CMD_RSPLEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-    return rc;
-}
-
-/**
- * Read supported states
- *
- * OGF = 0x08 (LE)
- * OCF = 0x001C
- *
- * @return int
- */
-int
-bletest_hci_le_read_supp_states(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_SUPP_STATES_RSPLEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_SUPP_STATES, 0, buf);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_SUPP_STATES_RSPLEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_SUPP_STATES_RSPLEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-    return rc;
-}
-
-int
-bletest_hci_le_rd_max_datalen(void)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_MAX_DATALEN_RSPLEN];
-    uint8_t rsplen;
-
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_MAX_DATA_LEN, 0, buf);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_MAX_DATALEN_RSPLEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_MAX_DATALEN_RSPLEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-    return rc;
-}
-
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-int
-bletest_hci_le_set_multi_adv_data(uint8_t *data, uint8_t len, uint8_t instance)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_DATA_LEN];
-
-    if (instance >= BLE_LL_ADV_INSTANCES) {
-        return -1;
-    }
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
-                             BLE_HCI_MULTI_ADV_DATA_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    if (((data == NULL) && (len != 0)) || (len > BLE_HCI_MAX_ADV_DATA_LEN)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    memset(dst, 0, BLE_HCI_MULTI_ADV_DATA_LEN);
-    dst[0] = BLE_HCI_MULTI_ADV_DATA;
-    dst[1] = len;
-    memcpy(dst + 2, data, len);
-    dst[33] = instance;
-
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-#else
-int
-bletest_hci_le_set_adv_data(uint8_t *data, uint8_t len)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_DATA_LEN];
-
-    rc = ble_hs_hci_cmd_build_le_set_adv_data(data, len, buf, sizeof buf);
-    assert(rc == 0);
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-#endif
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-int
-bletest_hci_le_start_encrypt(struct hci_start_encrypt *cmd)
-{
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_LE_START_ENCRYPT_LEN];
-
-    ble_hs_hci_cmd_build_le_start_encrypt(cmd, buf, sizeof buf);
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-#endif
-
-int
-bletest_hci_le_read_rem_used_feat(uint16_t handle)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CONN_RD_REM_FEAT_LEN];
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_REM_FEAT,
-                       BLE_HCI_CONN_RD_REM_FEAT_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    put_le16(dst, handle);
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-int
-bletest_hci_le_set_multi_adv_params(struct hci_multi_adv_params *adv,
-                                    uint8_t instance)
-{
-    uint8_t *dst;
-    uint16_t itvl;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_PARAMS_LEN];
-
-    if (instance >= BLE_LL_ADV_INSTANCES) {
-        return -1;
-    }
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
-                             BLE_HCI_MULTI_ADV_PARAMS_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    /* Make sure parameters are valid */
-    if ((adv->adv_itvl_min > adv->adv_itvl_max) ||
-        (adv->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) ||
-        (adv->peer_addr_type > BLE_HCI_ADV_PEER_ADDR_MAX) ||
-        (adv->adv_filter_policy > BLE_HCI_ADV_FILT_MAX) ||
-        (adv->adv_type > BLE_HCI_ADV_TYPE_MAX) ||
-        (adv->adv_channel_map == 0) ||
-        ((adv->adv_channel_map & 0xF8) != 0)) {
-        /* These parameters are not valid */
-        return -1;
-    }
-
-    /* Make sure interval is valid for advertising type. */
-    if ((adv->adv_type == BLE_HCI_ADV_TYPE_ADV_NONCONN_IND) ||
-        (adv->adv_type == BLE_HCI_ADV_TYPE_ADV_SCAN_IND)) {
-        itvl = BLE_HCI_ADV_ITVL_NONCONN_MIN;
-    } else {
-        itvl = BLE_HCI_ADV_ITVL_MIN;
-    }
-
-    /* Do not check if high duty-cycle directed */
-    if (adv->adv_type != BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
-        if ((adv->adv_itvl_min < itvl) ||
-            (adv->adv_itvl_min > BLE_HCI_ADV_ITVL_MAX)) {
-            return -1;
-        }
-    }
-
-    dst[0] = BLE_HCI_MULTI_ADV_PARAMS;
-    put_le16(dst + 1, adv->adv_itvl_min);
-    put_le16(dst + 3, adv->adv_itvl_max);
-    dst[5] = adv->adv_type;
-    dst[6] = adv->own_addr_type;
-    memcpy(dst + 7, adv->own_addr, BLE_DEV_ADDR_LEN);
-    dst[13] = adv->peer_addr_type;
-    memcpy(dst + 14, adv->peer_addr, BLE_DEV_ADDR_LEN);
-    dst[20] = adv->adv_channel_map;
-    dst[21] = adv->adv_filter_policy;
-    dst[22] = instance;
-    dst[23] = adv->adv_tx_pwr;
-
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-#else
-int
-bletest_hci_le_set_adv_params(struct hci_adv_params *adv)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_PARAM_LEN];
-
-    rc = ble_hs_hci_cmd_build_le_set_adv_params(adv, buf, sizeof buf);
-    if (!rc) {
-        rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    }
-    return rc;
-}
-#endif
-
-int
-bletest_hci_le_set_rand_addr(uint8_t *addr)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_RAND_ADDR_LEN];
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_RAND_ADDR,
-                       BLE_DEV_ADDR_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    memcpy(dst, addr, BLE_DEV_ADDR_LEN);
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-int
-bletest_hci_le_set_multi_rand_addr(uint8_t *addr, uint8_t instance)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_SET_RAND_ADDR_LEN];
-
-    if (instance >= BLE_LL_ADV_INSTANCES) {
-        return -1;
-    }
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
-                       BLE_HCI_MULTI_ADV_SET_RAND_ADDR_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    dst[0] = BLE_HCI_MULTI_ADV_SET_RAND_ADDR;
-    memcpy(dst + 1, addr, BLE_DEV_ADDR_LEN);
-    dst[7] = instance;
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-#endif
-
-int
-bletest_hci_rd_rem_version(uint16_t handle)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + sizeof(uint16_t)];
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LINK_CTRL, BLE_HCI_OCF_RD_REM_VER_INFO,
-                       sizeof(uint16_t), dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    put_le16(dst, handle);
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-
-int
-bletest_hci_le_set_host_chan_class(uint8_t *chanmap)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_HOST_CHAN_CLASS_LEN];
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS,
-                       BLE_HCI_SET_HOST_CHAN_CLASS_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    memcpy(dst, chanmap, BLE_HCI_SET_HOST_CHAN_CLASS_LEN);
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-
-int
-bletest_hci_le_rd_chanmap(uint16_t handle)
-{
-    int rc;
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_RD_CHANMAP_LEN];
-    uint8_t rspbuf[BLE_HCI_RD_CHANMAP_RSP_LEN];
-    uint8_t rsplen;
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_RD_CHAN_MAP,
-                       BLE_HCI_RD_CHANMAP_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    put_le16(dst, handle);
-    rc = ble_hs_hci_cmd_tx(buf, rspbuf, BLE_HCI_RD_CHANMAP_RSP_LEN, &rsplen);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (rsplen != BLE_HCI_RD_CHANMAP_RSP_LEN) {
-        return BLE_HS_ECONTROLLER;
-    }
-
-    return rc;
-}
-
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-int
-bletest_hci_le_set_multi_adv_enable(uint8_t enable, uint8_t instance)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_ENABLE_LEN];
-
-    if (instance >= BLE_LL_ADV_INSTANCES) {
-        return -1;
-    }
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
-                             BLE_HCI_MULTI_ADV_ENABLE_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    dst[0] = BLE_HCI_MULTI_ADV_ENABLE;
-    dst[1] = enable;
-    dst[2] = instance;
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-#else
-int
-bletest_hci_le_set_adv_enable(uint8_t enable)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADV_ENABLE_LEN];
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_LE, BLE_HCI_OCF_LE_SET_ADV_ENABLE,
-                       BLE_HCI_SET_ADV_ENABLE_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    dst[0] = enable;
-    return ble_hs_hci_cmd_tx(buf, NULL, 0, NULL);
-}
-#endif
-
-int
-bletest_hci_le_set_event_mask(uint64_t event_mask)
-{
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_LE_EVENT_MASK_LEN];
-
-    ble_hs_hci_cmd_build_le_set_event_mask(event_mask, buf, sizeof buf);
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-
-int
-bletest_hci_set_event_mask(uint64_t event_mask)
-{
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_EVENT_MASK_LEN];
-
-    ble_hs_hci_cmd_build_set_event_mask(event_mask, buf, sizeof buf);
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-int
-bletest_hci_le_set_multi_scan_rsp_data(uint8_t *data, uint8_t len,
-                                       uint8_t instance)
-{
-    uint8_t *dst;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_MULTI_ADV_SCAN_RSP_DATA_LEN];
-
-    if (instance >= BLE_LL_ADV_INSTANCES) {
-        return -1;
-    }
-
-    dst = buf;
-    ble_hs_hci_cmd_write_hdr(BLE_HCI_OGF_VENDOR, BLE_HCI_OCF_MULTI_ADV,
-                             BLE_HCI_MULTI_ADV_SCAN_RSP_DATA_LEN, dst);
-    dst += BLE_HCI_CMD_HDR_LEN;
-
-    if (((data == NULL) && (len != 0)) || (len>BLE_HCI_MAX_SCAN_RSP_DATA_LEN)) {
-        return BLE_ERR_INV_HCI_CMD_PARMS;
-    }
-
-    memset(dst, 0, BLE_HCI_MULTI_ADV_SCAN_RSP_DATA_LEN);
-    dst[0] = BLE_HCI_MULTI_ADV_SCAN_RSP_DATA;
-    dst[1] = len;
-    memcpy(dst + 2, data, len);
-    dst[33] = instance;
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-#else
-int
-bletest_hci_le_set_scan_rsp_data(uint8_t *data, uint8_t len)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_RSP_DATA_LEN];
-
-    rc = ble_hs_hci_cmd_build_le_set_scan_rsp_data(data, len, buf, sizeof buf);
-    assert(rc == 0);
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-#endif
-
-int
-bletest_hci_cmd_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
-                                   uint16_t scan_window, uint8_t own_addr_type,
-                                   uint8_t filter_policy) {
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
-
-    rc = ble_hs_hci_cmd_build_le_set_scan_params(scan_type, scan_itvl,
-                                               scan_window, own_addr_type,
-                                               filter_policy, buf, sizeof buf);
-    if (!rc) {
-        rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    }
-    return rc;
-}
-
-int
-bletest_hci_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
-
-    rc = ble_hs_hci_cmd_build_le_add_to_whitelist(addr, addr_type, buf,
-                                                sizeof buf);
-    if (!rc) {
-        rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    }
-    return rc;
-}
-
-int
-bletest_hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dups)
-{
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_ENABLE_LEN];
-
-    ble_hs_hci_cmd_build_le_set_scan_enable(enable, filter_dups, buf, sizeof buf);
-    return ble_hs_hci_cmd_tx_empty_ack(buf);
-}
-
-int
-bletest_hci_le_create_connection(struct hci_create_conn *hcc)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_CREATE_CONN_LEN];
-
-    rc = ble_hs_hci_cmd_build_le_create_connection(hcc, buf, sizeof buf);
-    if (!rc) {
-        rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    }
-    return rc;
-}
-
-int
-bletest_hci_le_add_resolv_list(uint8_t *local_irk, uint8_t *peer_irk,
-                               uint8_t *peer_ident_addr, uint8_t addr_type)
-{
-    int rc;
-    struct hci_add_dev_to_resolving_list padd;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_ADD_TO_RESOLV_LIST_LEN];
-
-    padd.addr_type = addr_type;
-    memcpy(padd.addr, peer_ident_addr, BLE_DEV_ADDR_LEN);
-    swap_buf(padd.local_irk, local_irk, 16);
-    swap_buf(padd.peer_irk, peer_irk, 16);
-    rc = ble_hs_hci_cmd_build_add_to_resolv_list(&padd, buf, sizeof buf);
-    if (!rc) {
-        rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    }
-    return rc;
-}
-
-int
-bletest_hci_le_enable_resolv_list(uint8_t enable)
-{
-    int rc;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_ADDR_RESOL_ENA_LEN];
-
-
-    rc = ble_hs_hci_cmd_build_set_addr_res_en(enable, buf, sizeof buf);
-    if (!rc) {
-        rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    }
-    return rc;
-}
-
diff --git a/apps/bletest/src/bletest_priv.h b/apps/bletest/src/bletest_priv.h
deleted file mode 100644
index 7ecc8df9fe..0000000000
--- a/apps/bletest/src/bletest_priv.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * 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 H_BLETEST_PRIV_
-#define H_BLETEST_PRIV_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void bletest_send_conn_update(uint16_t handle);
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-void bletest_ltk_req_reply(uint16_t handle);
-int bletest_send_ltk_req_neg_reply(uint16_t handle);
-int bletest_send_ltk_req_reply(uint16_t handle);
-int bletest_hci_le_start_encrypt(struct hci_start_encrypt *cmd);
-int bletest_hci_le_encrypt(uint8_t *key, uint8_t *pt);
-#endif
-
-int bletest_hci_reset_ctlr(void);
-int bletest_hci_rd_bd_addr(void);
-int bletest_hci_le_set_datalen(uint16_t handle, uint16_t txoctets,
-                               uint16_t txtime);
-int bletest_hci_le_write_sugg_datalen(uint16_t txoctets, uint16_t txtime);
-int bletest_hci_le_rd_sugg_datalen(void);
-int bletest_hci_rd_local_version(void);
-int bletest_hci_rd_local_feat(void);
-int bletest_hci_rd_local_supp_cmd(void);
-int bletest_hci_le_read_supp_states(void);
-int bletest_hci_le_rd_max_datalen(void);
-int bletest_hci_le_read_rem_used_feat(uint16_t handle);
-int bletest_hci_le_set_rand_addr(uint8_t *addr);
-int bletest_hci_rd_rem_version(uint16_t handle);
-int bletest_hci_le_set_host_chan_class(uint8_t *chanmap);
-int bletest_hci_le_rd_chanmap(uint16_t handle);
-int bletest_hci_le_set_event_mask(uint64_t event_mask);
-int bletest_hci_set_event_mask(uint64_t event_mask);
-int bletest_hci_le_add_to_whitelist(uint8_t *addr, uint8_t addr_type);
-int bletest_hci_le_set_scan_enable(uint8_t enable, uint8_t filter_dups);
-int bletest_hci_le_create_connection(struct hci_create_conn *hcc);
-int bletest_hci_le_set_scan_params(uint8_t scan_type, uint16_t scan_itvl,
-                                   uint16_t scan_window, uint8_t own_addr_type,
-                                   uint8_t filter_policy);
-int bletest_hci_le_add_resolv_list(uint8_t *local_irk, uint8_t *peer_irk,
-                                   uint8_t *peer_ident_addr, uint8_t addr_type);
-int bletest_hci_le_enable_resolv_list(uint8_t enable);
-
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-int bletest_hci_le_set_multi_rand_addr(uint8_t *addr, uint8_t instance);
-int bletest_hci_le_set_multi_adv_data(uint8_t *data, uint8_t len,
-                                      uint8_t instance);
-int bletest_hci_le_set_multi_adv_params(struct hci_multi_adv_params *adv,
-                                        uint8_t instance);
-int bletest_hci_le_set_multi_adv_enable(uint8_t enable, uint8_t instance);
-int bletest_hci_le_set_multi_scan_rsp_data(uint8_t *data, uint8_t len,
-                                           uint8_t instance);
-#else
-int bletest_hci_le_set_adv_data(uint8_t *data, uint8_t len);
-int bletest_hci_le_set_adv_params(struct hci_adv_params *adv);
-int bletest_hci_le_set_adv_enable(uint8_t enable);
-int bletest_hci_le_set_scan_rsp_data(uint8_t *data, uint8_t len);
-#endif
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif  /* H_BLETEST_PRIV_*/
diff --git a/apps/bletest/src/main.c b/apps/bletest/src/main.c
deleted file mode 100755
index e2519eb4c1..0000000000
--- a/apps/bletest/src/main.c
+++ /dev/null
@@ -1,1329 +0,0 @@
-/*
- * 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 <string.h>
-#include "sysinit/sysinit.h"
-#include "syscfg/syscfg.h"
-#include "os/os.h"
-#include "bsp/bsp.h"
-#include "hal/hal_bsp.h"
-#include "hal/hal_gpio.h"
-#include "hal/hal_flash.h"
-#include "console/console.h"
-#include "shell/shell.h"
-#include "stats/stats.h"
-#include "flash_map/flash_map.h"
-
-/* BLE */
-#include "nimble/ble.h"
-#include "nimble/ble_hci_trans.h"
-#include "nimble/hci_common.h"
-#include "nimble/hci_vendor.h"
-#include "host/ble_hs.h"
-#include "controller/ble_ll.h"
-#include "controller/ble_ll_hci.h"
-#include "controller/ble_ll_conn.h"
-#include "controller/ble_ll_scan.h"
-#include "controller/ble_ll_adv.h"
-
-/* RAM HCI transport. */
-#include "transport/ram/ble_hci_ram.h"
-
-/* XXX: An app should not include private headers from a library.  The bletest
- * app uses some of nimble's internal details for logging.
- */
-#include "../src/ble_hs_priv.h"
-#include "bletest_priv.h"
-
-#define BLETEST_TASK_PRIO               5
-
-/* For LED toggling */
-int g_led_pin;
-
-/* A buffer for host advertising data */
-uint8_t g_host_adv_data[BLE_HCI_MAX_ADV_DATA_LEN];
-uint8_t g_host_adv_len;
-
-/* Some application configurations */
-#define BLETEST_ROLE_NONE               (0)
-#define BLETEST_ROLE_ADVERTISER         (1)
-#define BLETEST_ROLE_SCANNER            (2)
-#define BLETEST_ROLE_INITIATOR          (3)
-
-#if MYNEWT_VAL(BLETEST_ROLE) == BLETEST_ROLE_ADVERTISER
-#define BLETEST_CFG_ROLE                BLETEST_ROLE_ADVERTISER
-#endif
-#if MYNEWT_VAL(BLETEST_ROLE) == BLETEST_ROLE_SCANNER
-#define BLETEST_CFG_ROLE                BLETEST_ROLE_SCANNER
-#endif
-#if MYNEWT_VAL(BLETEST_ROLE) == BLETEST_ROLE_INITIATOR
-#define BLETEST_CFG_ROLE                BLETEST_ROLE_INITIATOR
-#endif
-
-#ifndef BLETEST_CFG_ROLE
-#error "No role defined! Must define a valid role in syscfg.yml in apps/bletest"
-#endif
-
-/* Advertiser config */
-#define BLETEST_CFG_ADV_OWN_ADDR_TYPE   (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
-#define BLETEST_CFG_ADV_PEER_ADDR_TYPE  (BLE_HCI_ADV_PEER_ADDR_PUBLIC)
-#define BLETEST_CFG_ADV_ITVL            (60000 / BLE_HCI_ADV_ITVL)
-#define BLETEST_CFG_ADV_TYPE            BLE_HCI_ADV_TYPE_ADV_IND
-#define BLETEST_CFG_ADV_FILT_POLICY     (BLE_HCI_ADV_FILT_NONE)
-#define BLETEST_CFG_ADV_ADDR_RES_EN     (0)
-
-/* Multi-adv config */
-/*
- * Number of advertising instances to start up, not including the default
- * instance. The default instance is used to connect. If this number is greater
- * than the number of available advertising instances, we only use the number
- * of available advertising instances (defined by the configuration setting:
- * BLE_MULTI_ADV_INSTANCES.
- */
-#define BLETEST_CFG_ADV_TEST_INSTANCES     (8)
-
-struct bletest_multi_adv_interval
-{
-    uint8_t adv_type;
-    /*
-     * Note: if own addr type greater than 1, we use own addr field; otherwise
-     * we use the set multi random address call to set the random address
-     */
-    uint8_t adv_own_addr_type;
-    uint16_t adv_itvl;
-};
-
-/*
- * NOTE: currently, these are all NONCONN_IND. Thus, must be 100 msecs or
- * greater
- */
-const struct bletest_multi_adv_interval
-bletest_multi_adv_instances[BLETEST_CFG_ADV_TEST_INSTANCES] = {
-    {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
-     BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-     (100000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_SCAN_IND,
-     BLE_HCI_ADV_OWN_ADDR_RANDOM,
-     (110000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
-     BLE_HCI_ADV_OWN_ADDR_RANDOM,
-     (120000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
-     BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-     (130000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_SCAN_IND,
-     BLE_HCI_ADV_OWN_ADDR_MAX + 1,
-     (140000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
-     BLE_HCI_ADV_OWN_ADDR_MAX + 1,
-     (150000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_NONCONN_IND,
-     BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-     (160000 / BLE_HCI_ADV_ITVL)},
-
-    {BLE_HCI_ADV_TYPE_ADV_SCAN_IND,
-     BLE_HCI_ADV_OWN_ADDR_PUBLIC,
-     (170000 / BLE_HCI_ADV_ITVL)}
-};
-
-/*
- * Determines if own address contains random address or set through the
- * multi-adv set random address command
- */
-#define BLETEST_CFG_MULTI_ADV_RANDOM_OWN    (0)
-
-/* Scan config */
-#define BLETEST_CFG_SCAN_ITVL           (700000 / BLE_HCI_SCAN_ITVL)
-#define BLETEST_CFG_SCAN_WINDOW         (700000 / BLE_HCI_SCAN_ITVL)
-#define BLETEST_CFG_SCAN_TYPE           (BLE_HCI_SCAN_TYPE_PASSIVE)
-#define BLETEST_CFG_SCAN_OWN_ADDR_TYPE  (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
-#define BLETEST_CFG_SCAN_FILT_POLICY    (BLE_HCI_SCAN_FILT_NO_WL)
-#define BLETEST_CFG_FILT_DUP_ADV        (1)
-
-/* Connection config */
-#define BLETEST_CFG_CONN_ITVL           (128)  /* in 1.25 msec increments */
-#define BLETEST_CFG_SLAVE_LATENCY       (0)
-#define BLETEST_CFG_INIT_FILTER_POLICY  (BLE_HCI_CONN_FILT_NO_WL)
-#define BLETEST_CFG_CONN_SPVN_TMO       (1000)  /* 10 msec increments */
-#define BLETEST_CFG_MIN_CE_LEN          (6)
-#define BLETEST_CFG_MAX_CE_LEN          (BLETEST_CFG_CONN_ITVL)
-#define BLETEST_CFG_CONN_PEER_ADDR_TYPE (BLE_HCI_CONN_PEER_ADDR_PUBLIC)
-#define BLETEST_CFG_CONN_OWN_ADDR_TYPE  (BLE_HCI_ADV_OWN_ADDR_PUBLIC)
-#define BLETEST_CFG_CONCURRENT_CONNS    (1)
-
-/* Test packet config */
-#define BLETEST_CFG_RAND_PKT_SIZE       (1)
-#define BLETEST_CFG_SUGG_DEF_TXOCTETS   (251)
-#define BLETEST_CFG_SUGG_DEF_TXTIME     \
-    BLE_TX_DUR_USECS_M(BLETEST_CFG_SUGG_DEF_TXOCTETS + 4)
-
-/* Test configurations. One of these should be set to 1 */
-#if !defined(BLETEST_CONCURRENT_CONN_TEST) && !defined(BLETEST_THROUGHPUT_TEST)
-    #define BLETEST_CONCURRENT_CONN_TEST    (1)
-#endif
-
-/* BLETEST variables */
-#undef BLETEST_ADV_PKT_NUM
-#define BLETEST_MAX_PKT_SIZE            (247)
-#define BLETEST_PKT_SIZE                (247)
-#define BLETEST_STACK_SIZE              (256)
-uint32_t g_next_os_time;
-int g_bletest_state;
-struct os_eventq g_bletest_evq;
-struct os_callout g_bletest_timer;
-struct os_task bletest_task;
-bssnz_t os_stack_t bletest_stack[BLETEST_STACK_SIZE];
-uint32_t g_bletest_conn_end;
-int g_bletest_start_update;
-uint32_t g_bletest_conn_upd_time;
-uint8_t g_bletest_current_conns;
-uint8_t g_bletest_cur_peer_addr[BLE_DEV_ADDR_LEN];
-uint8_t g_last_handle_used;
-uint8_t g_bletest_led_state;
-uint32_t g_bletest_led_rate;
-uint32_t g_bletest_next_led_time;
-uint16_t g_bletest_handle;
-uint16_t g_bletest_completed_pkts;
-uint16_t g_bletest_outstanding_pkts;
-uint16_t g_bletest_ltk_reply_handle;
-uint32_t g_bletest_hw_id[4];
-struct hci_create_conn g_cc;
-
-/* --- For LE encryption testing --- */
-/* Key: 0x4C68384139F574D836BCF34E9DFB01BF */
-const uint8_t g_ble_ll_encrypt_test_key[16] =
-{
-    0x4c, 0x68, 0x38, 0x41, 0x39, 0xf5, 0x74, 0xd8,
-    0x36, 0xbc, 0xf3, 0x4e, 0x9d, 0xfb, 0x01, 0xbf
-};
-
-/* Plaint text: 0x0213243546576879acbdcedfe0f10213 */
-const uint8_t g_ble_ll_encrypt_test_plain_text[16] =
-{
-    0x02, 0x13, 0x24, 0x35, 0x46, 0x57, 0x68, 0x79,
-    0xac, 0xbd, 0xce, 0xdf, 0xe0, 0xf1, 0x02, 0x13
-};
-
-/* Encrypted data: 0x99ad1b5226a37e3e058e3b8e27c2c666 */
-const uint8_t g_ble_ll_encrypt_test_encrypted_data[16] =
-{
-    0x99, 0xad, 0x1b, 0x52, 0x26, 0xa3, 0x7e, 0x3e,
-    0x05, 0x8e, 0x3b, 0x8e, 0x27, 0xc2, 0xc6, 0x66
-};
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-uint8_t g_bletest_adv_irk[16] = {
-    0xec, 0x02, 0x34, 0xa3, 0x57, 0xc8, 0xad, 0x05,
-    0x34, 0x10, 0x10, 0xa6, 0x0a, 0x39, 0x7d, 0x9b
-};
-
-uint8_t g_bletest_init_irk[16] = {
-    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
-    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10
-};
-#endif
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-/* LTK 0x4C68384139F574D836BCF34E9DFB01BF */
-const uint8_t g_bletest_LTK[16] =
-{
-    0x4C,0x68,0x38,0x41,0x39,0xF5,0x74,0xD8,
-    0x36,0xBC,0xF3,0x4E,0x9D,0xFB,0x01,0xBF
-};
-uint16_t g_bletest_EDIV = 0x2474;
-uint64_t g_bletest_RAND = 0xABCDEF1234567890;
-uint64_t g_bletest_SKDm = 0xACBDCEDFE0F10213;
-uint64_t g_bletest_SKDs = 0x0213243546576879;
-uint32_t g_bletest_IVm = 0xBADCAB24;
-uint32_t g_bletest_IVs = 0xDEAFBABE;
-#endif
-
-#if (BLETEST_THROUGHPUT_TEST == 1)
-void
-bletest_completed_pkt(uint16_t handle)
-{
-    os_sr_t sr;
-
-    OS_ENTER_CRITICAL(sr);
-    if (handle == g_bletest_handle) {
-        ++g_bletest_completed_pkts;
-    }
-    OS_EXIT_CRITICAL(sr);
-}
-#endif
-
-#ifdef BLETEST_ADV_PKT_NUM
-void
-bletest_inc_adv_pkt_num(void)
-{
-    int rc;
-    uint8_t *dptr;
-    uint8_t digit;
-
-    if (g_host_adv_len != 0) {
-        dptr = &g_host_adv_data[18];
-        while (dptr >= &g_host_adv_data[13]) {
-            digit = *dptr;
-            ++digit;
-            if (digit == 58) {
-                digit = 48;
-                *dptr = digit;
-                --dptr;
-            } else {
-                *dptr = digit;
-                break;
-            }
-        }
-
-        rc = bletest_hci_le_set_adv_data(g_host_adv_data, g_host_adv_len);
-        assert(rc == 0);
-    }
-}
-#endif
-
-/**
- * Sets the advertising data to be sent in advertising pdu's which contain
- * advertising data.
- *
- * @param dptr
- * @return uint8_t
- */
-uint8_t
-bletest_set_adv_data(uint8_t *dptr, uint8_t *addr)
-{
-    uint8_t len;
-
-    /* Place flags in first */
-    dptr[0] = 0x02;
-    dptr[1] = 0x01;     /* Flags identifier */
-    dptr[2] = 0x06;
-    dptr += 3;
-    len = 3;
-
-    /*  Add HID service */
-    dptr[0] = 0x03;
-    dptr[1] = 0x03;
-    dptr[2] = 0x12;
-    dptr[3] = 0x18;
-    dptr += 4;
-    len += 4;
-
-    /* Add local name */
-    dptr[0] = 12;   /* Length of this data, not including the length */
-    dptr[1] = 0x09;
-    dptr[2] = 'r';
-    dptr[3] = 'u';
-    dptr[4] = 'n';
-    dptr[5] = 't';
-    dptr[6] = 'i';
-    dptr[7] = 'm';
-    dptr[8] = 'e';
-    dptr[9] = '-';
-    dptr[10] = '0';
-    dptr[11] = '0';
-    dptr[12] = '7';
-    dptr += 13;
-    len += 13;
-
-    /* Add local device address */
-    dptr[0] = 0x08;
-    dptr[1] = 0x1B;
-    dptr[2] = 0x00;
-    memcpy(dptr + 3, addr, BLE_DEV_ADDR_LEN);
-    len += 9;
-
-    g_host_adv_len = len;
-
-    return len;
-}
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-void
-bletest_init_adv_instances(void)
-{
-    uint8_t i;
-    int rc;
-    uint8_t *addr;
-    uint8_t adv_len;
-    uint8_t inst_allowed;
-    uint8_t rand_addr[BLE_DEV_ADDR_LEN];
-    struct hci_multi_adv_params adv;
-
-    inst_allowed = MYNEWT_VAL(BLE_MULTI_ADV_INSTANCES);
-    if (inst_allowed > BLETEST_CFG_ADV_TEST_INSTANCES) {
-        inst_allowed = BLETEST_CFG_ADV_TEST_INSTANCES;
-    }
-
-    /* Start up all the instances */
-    for (i = 1; i <= inst_allowed; ++i) {
-        memset(&adv, 0, sizeof(struct hci_multi_adv_params));
-
-        adv.own_addr_type = bletest_multi_adv_instances[i-1].adv_own_addr_type;
-        if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_PUBLIC) {
-            addr = g_dev_addr;
-        } else {
-            memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN);
-            rand_addr[5] |= 0xc0;
-            rand_addr[0] = i;
-            /*
-             * NOTE: we overload own address type with a special case
-             * to denote if we use own address or call to set multi random
-             * address.
-             */
-            if (adv.own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-                rc = bletest_hci_le_set_multi_rand_addr(rand_addr, i);
-                assert(rc == 0);
-                addr = rand_addr;
-            } else {
-                adv.own_addr_type = BLE_HCI_ADV_OWN_ADDR_RANDOM;
-                addr = rand_addr;
-                memcpy(adv.own_addr, addr, BLE_DEV_ADDR_LEN);
-            }
-        }
-
-        adv.adv_type = bletest_multi_adv_instances[i - 1].adv_type;
-        adv.adv_channel_map = 0x07;
-        adv.adv_filter_policy = BLE_HCI_ADV_FILT_NONE;
-        adv.peer_addr_type = BLE_HCI_ADV_PEER_ADDR_PUBLIC;
-        adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr);
-
-        adv.adv_itvl_min = bletest_multi_adv_instances[i - 1].adv_itvl;
-        adv.adv_itvl_max = bletest_multi_adv_instances[i - 1].adv_itvl;
-        adv.adv_tx_pwr = -1 * i;
-
-        /* Set the advertising parameters */
-        rc = bletest_hci_le_set_multi_adv_params(&adv, i);
-        assert(rc == 0);
-
-        /* Set advertising data */
-        if (adv_len != 0) {
-            rc = bletest_hci_le_set_multi_adv_data(&g_host_adv_data[0], adv_len,
-                                                   i);
-            assert(rc == 0);
-
-            /* Set scan response data */
-            rc = bletest_hci_le_set_multi_scan_rsp_data(&g_host_adv_data[0],
-                                                        adv_len, i);
-            assert(rc == 0);
-        }
-
-        /* Set the advertising parameters */
-        rc = bletest_hci_le_set_multi_adv_enable(1, i);
-        assert(rc == 0);
-    }
-}
-
-void
-bletest_init_advertising(uint8_t instance, int8_t txpwr)
-{
-    int rc;
-    int set_peer_addr;
-    uint8_t adv_len;
-    uint8_t *addr;
-    uint8_t rand_addr[BLE_DEV_ADDR_LEN];
-    struct hci_multi_adv_params adv;
-
-    /* Make sure it is a valid instance */
-    assert(instance < BLE_LL_ADV_INSTANCES);
-
-    /* Just zero out advertising */
-    set_peer_addr = 0;
-    memset(&adv, 0, sizeof(struct hci_multi_adv_params));
-
-    /* If we are using a random address, we need to set it */
-    adv.own_addr_type = BLETEST_CFG_ADV_OWN_ADDR_TYPE;
-    if (adv.own_addr_type & 1) {
-        memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN);
-        rand_addr[5] |= 0xc0;
-        if (BLETEST_CFG_MULTI_ADV_RANDOM_OWN == 1) {
-            addr = rand_addr;
-            memcpy(adv.own_addr, addr, BLE_DEV_ADDR_LEN);
-        } else {
-            rc = bletest_hci_le_set_multi_rand_addr(rand_addr, instance);
-            assert(rc == 0);
-            addr = rand_addr;
-        }
-    } else {
-        addr = g_dev_addr;
-    }
-
-    /* Set advertising parameters */
-    adv.adv_type = BLETEST_CFG_ADV_TYPE;
-    adv.adv_channel_map = 0x07;
-    adv.adv_filter_policy = BLETEST_CFG_ADV_FILT_POLICY;
-    if ((adv.adv_filter_policy & 1) || (BLETEST_CFG_ADV_ADDR_RES_EN == 1)) {
-        set_peer_addr = 1;
-    }
-    adv.peer_addr_type = BLETEST_CFG_ADV_PEER_ADDR_TYPE;
-    if ((adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
-        (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
-        set_peer_addr = 1;
-        adv_len = 0;
-    } else {
-        adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr);
-    }
-
-    /* Not allowed for multi-adv command */
-    if (adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-        assert(0);
-    }
-
-    if (set_peer_addr) {
-        memcpy(adv.peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN);
-        if (adv.peer_addr_type == BLE_HCI_ADV_PEER_ADDR_RANDOM) {
-            adv.peer_addr[5] |= 0xc0;
-        }
-    }
-
-    console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n",
-                   adv.peer_addr[0], adv.peer_addr[1], adv.peer_addr[2],
-                   adv.peer_addr[3], adv.peer_addr[4], adv.peer_addr[5]);
-
-    if (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
-        adv.adv_itvl_min = 0;
-        adv.adv_itvl_max = 0;
-    } else {
-        adv.adv_itvl_min = BLETEST_CFG_ADV_ITVL;
-        adv.adv_itvl_max = BLETEST_CFG_ADV_ITVL; /* Advertising interval */
-    }
-
-    adv.adv_tx_pwr = txpwr;
-
-    /* Set the advertising parameters */
-    rc = bletest_hci_le_set_multi_adv_params(&adv, instance);
-    assert(rc == 0);
-
-    /* Set advertising data */
-    if (adv_len != 0) {
-        rc = bletest_hci_le_set_multi_adv_data(&g_host_adv_data[0], adv_len,
-                                               instance);
-        assert(rc == 0);
-
-        /* Set scan response data */
-        rc = bletest_hci_le_set_multi_scan_rsp_data(&g_host_adv_data[0],adv_len,
-                                                    instance);
-        assert(rc == 0);
-    }
-}
-#else
-void
-bletest_init_advertising(void)
-{
-    int rc;
-    int set_peer_addr;
-    uint8_t adv_len;
-    uint8_t *addr;
-    uint8_t rand_addr[BLE_DEV_ADDR_LEN];
-    struct hci_adv_params adv;
-
-    /* Just zero out advertising */
-    set_peer_addr = 0;
-    memset(&adv, 0, sizeof(struct hci_adv_params));
-
-    /* If we are using a random address, we need to set it */
-    adv.own_addr_type = BLETEST_CFG_ADV_OWN_ADDR_TYPE;
-    if (adv.own_addr_type & 1) {
-        memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN);
-        rand_addr[5] |= 0xc0;
-        rc = bletest_hci_le_set_rand_addr(rand_addr);
-        assert(rc == 0);
-        addr = rand_addr;
-    } else {
-        addr = g_dev_addr;
-    }
-
-    /* Set advertising parameters */
-    adv.adv_type = BLETEST_CFG_ADV_TYPE;
-    adv.adv_channel_map = 0x07;
-    adv.adv_filter_policy = BLETEST_CFG_ADV_FILT_POLICY;
-    if ((adv.adv_filter_policy & 1) || (BLETEST_CFG_ADV_ADDR_RES_EN == 1)) {
-        set_peer_addr = 1;
-    }
-    adv.peer_addr_type = BLETEST_CFG_ADV_PEER_ADDR_TYPE;
-    if ((adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) ||
-        (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD)) {
-        set_peer_addr = 1;
-        adv_len = 0;
-    } else {
-        adv_len = bletest_set_adv_data(&g_host_adv_data[0], addr);
-    }
-
-    if (adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-        set_peer_addr = 1;
-    }
-
-    if (set_peer_addr) {
-        memcpy(adv.peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN);
-        if (adv.peer_addr_type == BLE_HCI_ADV_PEER_ADDR_RANDOM) {
-            adv.peer_addr[5] |= 0xc0;
-        }
-    }
-
-    console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n",
-                   adv.peer_addr[0], adv.peer_addr[1], adv.peer_addr[2],
-                   adv.peer_addr[3], adv.peer_addr[4], adv.peer_addr[5]);
-
-    if (adv.adv_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD) {
-        adv.adv_itvl_min = 0;
-        adv.adv_itvl_max = 0;
-    } else {
-        adv.adv_itvl_min = BLETEST_CFG_ADV_ITVL;
-        adv.adv_itvl_max = BLETEST_CFG_ADV_ITVL; /* Advertising interval */
-    }
-
-    /* Set the advertising parameters */
-    rc = bletest_hci_le_set_adv_params(&adv);
-    assert(rc == 0);
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-    if ((adv.own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) ||
-        (BLETEST_CFG_ADV_ADDR_RES_EN == 1)) {
-        rc = bletest_hci_le_add_resolv_list(g_bletest_adv_irk,
-                                            g_bletest_init_irk,
-                                            adv.peer_addr,
-                                            adv.peer_addr_type);
-        assert(rc == 0);
-
-        rc = bletest_hci_le_enable_resolv_list(1);
-        assert(rc == 0);
-    }
-#endif
-
-    /* Set advertising data */
-    if (adv_len != 0) {
-        rc = bletest_hci_le_set_adv_data(&g_host_adv_data[0], adv_len);
-        assert(rc == 0);
-
-        /* Set scan response data */
-        rc = bletest_hci_le_set_scan_rsp_data(&g_host_adv_data[0], adv_len);
-        assert(rc == 0);
-    }
-}
-#endif  /* MULTI_ADV SUPPORT */
-#endif  /* BLETEST_ROLE_ADVERTISER */
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
-void
-bletest_init_scanner(void)
-{
-    int rc;
-    uint8_t own_addr_type;
-    uint8_t buf[BLE_HCI_CMD_HDR_LEN + BLE_HCI_SET_SCAN_PARAM_LEN];
-    uint8_t add_whitelist;
-
-    own_addr_type = BLETEST_CFG_SCAN_OWN_ADDR_TYPE;
-    rc = ble_hs_hci_cmd_build_le_set_scan_params(BLETEST_CFG_SCAN_TYPE,
-                                               BLETEST_CFG_SCAN_ITVL,
-                                               BLETEST_CFG_SCAN_WINDOW,
-                                               own_addr_type,
-                                               BLETEST_CFG_SCAN_FILT_POLICY,
-                                               buf, sizeof buf);
-    assert(rc == 0);
-    rc = ble_hs_hci_cmd_tx_empty_ack(buf);
-    if (rc == 0) {
-        add_whitelist = BLETEST_CFG_SCAN_FILT_POLICY;
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-        if (own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-            rc = bletest_hci_le_add_resolv_list(g_bletest_init_irk,
-                                                g_bletest_adv_irk,
-                                                g_bletest_cur_peer_addr,
-                                                BLETEST_CFG_ADV_PEER_ADDR_TYPE);
-            assert(rc == 0);
-
-            rc = bletest_hci_le_enable_resolv_list(1);
-            assert(rc == 0);
-        }
-#endif
-        if (add_whitelist & 1) {
-            rc = bletest_hci_le_add_to_whitelist(g_bletest_cur_peer_addr,
-                                                 BLE_ADDR_RANDOM);
-            assert(rc == 0);
-        }
-    }
-}
-
-void
-bletest_execute_scanner(void)
-{
-    int rc;
-
-    /* Enable scanning */
-    if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-        if (g_bletest_state) {
-            rc = bletest_hci_le_set_scan_enable(0, BLETEST_CFG_FILT_DUP_ADV);
-            assert(rc == 0);
-            g_bletest_state = 0;
-        } else {
-            rc = bletest_hci_le_set_scan_enable(1, BLETEST_CFG_FILT_DUP_ADV);
-            assert(rc == 0);
-            g_bletest_state = 1;
-        }
-        g_next_os_time += (OS_TICKS_PER_SEC * 60);
-    }
-}
-#endif
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR)
-void
-bletest_init_initiator(void)
-{
-    int rc;
-    uint8_t rand_addr[BLE_DEV_ADDR_LEN];
-    struct hci_create_conn *hcc;
-
-    /* Enable initiating */
-    hcc = &g_cc;
-    hcc->conn_itvl_max = BLETEST_CFG_CONN_ITVL;
-    hcc->conn_itvl_min = BLETEST_CFG_CONN_ITVL;
-    hcc->conn_latency = BLETEST_CFG_SLAVE_LATENCY;
-    hcc->filter_policy = BLETEST_CFG_INIT_FILTER_POLICY;
-    hcc->supervision_timeout = BLETEST_CFG_CONN_SPVN_TMO;
-    hcc->scan_itvl = BLETEST_CFG_SCAN_ITVL;
-    hcc->scan_window = BLETEST_CFG_SCAN_WINDOW;
-    hcc->peer_addr_type = BLETEST_CFG_CONN_PEER_ADDR_TYPE;
-    memcpy(hcc->peer_addr, g_bletest_cur_peer_addr, BLE_DEV_ADDR_LEN);
-    if (hcc->peer_addr_type == BLE_HCI_CONN_PEER_ADDR_RANDOM) {
-        hcc->peer_addr[5] |= 0xc0;
-    }
-    hcc->own_addr_type = BLETEST_CFG_CONN_OWN_ADDR_TYPE;
-    hcc->min_ce_len = BLETEST_CFG_MIN_CE_LEN;
-    hcc->max_ce_len = BLETEST_CFG_MAX_CE_LEN;
-
-    console_printf("Trying to connect to %x.%x.%x.%x.%x.%x\n",
-                   hcc->peer_addr[0], hcc->peer_addr[1], hcc->peer_addr[2],
-                   hcc->peer_addr[3], hcc->peer_addr[4], hcc->peer_addr[5]);
-
-    /* If we are using a random address, we need to set it */
-    if (hcc->own_addr_type == BLE_HCI_ADV_OWN_ADDR_RANDOM) {
-        memcpy(rand_addr, g_dev_addr, BLE_DEV_ADDR_LEN);
-        rand_addr[5] |= 0xc0;
-        rc = bletest_hci_le_set_rand_addr(rand_addr);
-        assert(rc == 0);
-    }
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-        if ((hcc->peer_addr_type > BLE_HCI_CONN_PEER_ADDR_RANDOM) ||
-            (hcc->own_addr_type > BLE_HCI_ADV_OWN_ADDR_RANDOM)) {
-            rc = bletest_hci_le_add_resolv_list(g_bletest_init_irk,
-                                                g_bletest_adv_irk,
-                                                g_bletest_cur_peer_addr,
-                                                BLETEST_CFG_ADV_PEER_ADDR_TYPE);
-            assert(rc == 0);
-
-            rc = bletest_hci_le_enable_resolv_list(1);
-            assert(rc == 0);
-        }
-#endif
-
-    bletest_hci_le_create_connection(hcc);
-}
-
-void
-bletest_execute_initiator(void)
-{
-    int i;
-    int rc;
-    int8_t rssi;
-    uint16_t handle;
-    uint8_t new_chan_map[5];
-
-    /*
-     * Determine if there is an active connection for the current handle
-     * we are trying to create. If so, start looking for the next one
-     */
-    if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
-        handle = g_bletest_current_conns + 1;
-        if (ble_ll_conn_find_active_conn(handle)) {
-            /* Set LED to slower blink rate */
-            g_bletest_led_rate = OS_TICKS_PER_SEC;
-
-            /* Ask for version information */
-            rc = bletest_hci_rd_rem_version(handle);
-
-            /* Ask for remote used features */
-            rc = bletest_hci_le_read_rem_used_feat(handle);
-
-            /* Scanning better be stopped! */
-            assert(ble_ll_scan_enabled() == 0);
-
-            /* Add to current connections */
-            if (!rc) {
-                ++g_bletest_current_conns;
-
-                /* Move to next connection */
-                if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
-                    /* restart initiating */
-                    g_bletest_cur_peer_addr[5] += 1;
-                    g_dev_addr[5] += 1;
-                    bletest_init_initiator();
-                }
-            }
-        } else {
-            if (ble_ll_scan_enabled() == 0) {
-                bletest_hci_le_create_connection(&g_cc);
-            }
-        }
-    } else {
-        if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-            if ((g_bletest_state == 1) || (g_bletest_state == 3)) {
-                for (i = 0; i < g_bletest_current_conns; ++i) {
-                    if (ble_ll_conn_find_active_conn(i + 1)) {
-                        bletest_hci_le_rd_chanmap(i+1);
-                    }
-                }
-            } else if (g_bletest_state == 2) {
-                new_chan_map[0] = 0;
-                new_chan_map[1] = 0x3;
-                new_chan_map[2] = 0;
-                new_chan_map[3] = 0x1F;
-                new_chan_map[4] = 0;
-                bletest_hci_le_set_host_chan_class(new_chan_map);
-            } else if (g_bletest_state == 4) {
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-                struct hci_start_encrypt hsle;
-                for (i = 0; i < g_bletest_current_conns; ++i) {
-                    if (ble_ll_conn_find_active_conn(i + 1)) {
-                        hsle.connection_handle = i + 1;
-                        hsle.encrypted_diversifier = g_bletest_EDIV;
-                        hsle.random_number = g_bletest_RAND;
-                        swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
-                                 16);
-                        bletest_hci_le_start_encrypt(&hsle);
-                    }
-                }
-#endif
-            } else if (g_bletest_state == 8) {
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-                struct hci_start_encrypt hsle;
-                for (i = 0; i < g_bletest_current_conns; ++i) {
-                    if (ble_ll_conn_find_active_conn(i + 1)) {
-                        hsle.connection_handle = i + 1;
-                        hsle.encrypted_diversifier = g_bletest_EDIV;
-                        hsle.random_number = ~g_bletest_RAND;
-                        swap_buf(hsle.long_term_key, (uint8_t *)g_bletest_LTK,
-                                 16);
-                        bletest_hci_le_start_encrypt(&hsle);
-                    }
-                }
-#endif
-            } else {
-                for (i = 0; i < g_bletest_current_conns; ++i) {
-                    if (ble_ll_conn_find_active_conn(i + 1)) {
-                        ble_hs_hci_util_read_rssi(i+1, &rssi);
-                    }
-                }
-            }
-
-            ++g_bletest_state;
-            if (g_bletest_state > 9) {
-                g_bletest_state = 9;
-            }
-            g_next_os_time = os_time_get() + OS_TICKS_PER_SEC * 3;
-        }
-    }
-}
-#endif
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-/*
- * Test wrapper to get packets. Only get a packet if we have more than half
- * left
- */
-static struct os_mbuf *
-bletest_get_packet(void)
-{
-    struct os_mbuf *om;
-
-    om = NULL;
-    if (os_msys_num_free() >= 5) {
-        om = os_msys_get_pkthdr(0, sizeof(struct ble_mbuf_hdr));
-    }
-    return om;
-}
-
-static struct os_mbuf *
-bletest_send_packet(uint16_t handle)
-{
-    int j;
-    uint8_t val;
-    struct os_mbuf *om;
-    uint16_t pktlen;
-
-    om = bletest_get_packet();
-    if (om) {
-        /* set payload length */
-#if BLETEST_THROUGHPUT_TEST
-        pktlen = BLETEST_PKT_SIZE;
-#else
-#if (BLETEST_CFG_RAND_PKT_SIZE == 1)
-        pktlen = rand() % (BLETEST_MAX_PKT_SIZE + 1);
-#else
-        pktlen = BLETEST_PKT_SIZE;
-#endif
-#endif
-
-        /* Put the HCI header in the mbuf */
-        put_le16(om->om_data, handle);
-        put_le16(om->om_data + 2, pktlen + 4);
-
-        /* Place L2CAP header in packet */
-        put_le16(om->om_data + 4, pktlen);
-        om->om_data[6] = 0;
-        om->om_data[7] = 0;
-        om->om_len = 8;
-        OS_MBUF_PKTHDR(om)->omp_len = 8;
-
-        /* Fill with incrementing pattern (starting from 1) */
-        for (j = 0; j < pktlen; ++j) {
-            val = j + 1;
-            os_mbuf_append(om, &val, 1);
-        }
-
-        /* Transmit it */
-        ble_hci_trans_hs_acl_tx(om);
-    }
-
-    return om;
-}
-
-static void
-bletest_execute_advertiser(void)
-{
-    int i;
-#if (BLETEST_CONCURRENT_CONN_TEST == 1)
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-    uint16_t mask;
-    uint16_t reply_handle;
-#endif
-#endif
-    int rc;
-    uint16_t handle;
-    struct os_mbuf *om;
-#if (BLETEST_THROUGHPUT_TEST == 1)
-    os_sr_t sr;
-    uint16_t completed_pkts;
-#endif
-
-    /* See if we should start advertising again */
-    if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
-        handle = g_bletest_current_conns + 1;
-        if (ble_ll_conn_find_active_conn(handle)) {
-            /* Set LED to slower blink rate */
-            g_bletest_led_rate = OS_TICKS_PER_SEC;
-
-#if (BLETEST_THROUGHPUT_TEST == 1)
-            /* Set next os time to 10 seconds after 1st connection */
-            if (g_next_os_time == 0) {
-                g_next_os_time = os_time_get() + (10 * OS_TICKS_PER_SEC);
-                g_bletest_handle = handle;
-            }
-#endif
-
-            /* advertising better be stopped! */
-            assert(ble_ll_adv_enabled() == 0);
-
-            /* Send the remote used features command */
-            rc = bletest_hci_le_read_rem_used_feat(handle);
-            if (rc) {
-                return;
-            }
-
-            /* Send the remote read version command */
-            rc = bletest_hci_rd_rem_version(handle);
-            if (rc) {
-                return;
-            }
-
-            /* set conn update time */
-            g_bletest_conn_upd_time = os_time_get() + (OS_TICKS_PER_SEC * 5);
-            g_bletest_start_update = 1;
-
-            /* Add to current connections */
-            ++g_bletest_current_conns;
-
-            /* Move to next connection */
-            if (g_bletest_current_conns < BLETEST_CFG_CONCURRENT_CONNS) {
-                /* restart initiating */
-                g_bletest_cur_peer_addr[5] += 1;
-                g_dev_addr[5] += 1;
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-                bletest_init_advertising(0,0);
-                bletest_hci_le_set_multi_adv_enable(1, 0);
-#else
-                bletest_init_advertising();
-                bletest_hci_le_set_adv_enable(1);
-#endif
-            }
-        } else {
-            /* If we failed to start advertising we should keep trying */
-            if (ble_ll_adv_enabled() == 0) {
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-                bletest_hci_le_set_multi_adv_enable(1, 0);
-#else
-                bletest_hci_le_set_adv_enable(1);
-#endif
-            }
-        }
-    }
-#if 0
-    if (g_bletest_start_update) {
-        if ((int32_t)(os_time_get() - g_bletest_conn_upd_time) >= 0) {
-            bletest_send_conn_update(1);
-            g_bletest_start_update = 0;
-        }
-    }
-#endif
-
-#if (BLETEST_CONCURRENT_CONN_TEST == 1)
-    /* See if it is time to hand a data packet to the connection */
-    if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-        /* Do we need to send a LTK reply? */
-        mask = 1;
-        reply_handle = 1;
-        while (g_bletest_ltk_reply_handle && mask) {
-            if (g_bletest_ltk_reply_handle & mask) {
-                bletest_send_ltk_req_reply(reply_handle);
-                //bletest_send_ltk_req_neg_reply(reply_handle);
-                g_bletest_ltk_reply_handle &= ~mask;
-            }
-            ++reply_handle;
-            mask <<= 1;
-        }
-#endif
-        if (g_bletest_current_conns) {
-            for (i = 0; i < g_bletest_current_conns; ++i) {
-                if ((g_last_handle_used == 0) ||
-                    (g_last_handle_used > g_bletest_current_conns)) {
-                    g_last_handle_used = 1;
-                }
-                handle = g_last_handle_used;
-                if (ble_ll_conn_find_active_conn(handle)) {
-                    om = bletest_send_packet(handle);
-                    if (om) {
-                        /* Increment last handle used */
-                        ++g_last_handle_used;
-                    }
-                } else {
-                    ++g_last_handle_used;
-                }
-            }
-        }
-        g_next_os_time = os_time_get() + OS_TICKS_PER_SEC;
-    }
-#endif
-
-#if (BLETEST_THROUGHPUT_TEST == 1)
-    /* Nothing to do if no connections */
-    if (!g_bletest_current_conns) {
-        return;
-    }
-
-    /* See if it is time to start throughput testing */
-    if ((int32_t)(os_time_get() - g_next_os_time) >= 0) {
-        /* Keep window full */
-        OS_ENTER_CRITICAL(sr);
-        completed_pkts = g_bletest_completed_pkts;
-        g_bletest_completed_pkts = 0;
-        OS_EXIT_CRITICAL(sr);
-
-        assert(g_bletest_outstanding_pkts >= completed_pkts);
-        g_bletest_outstanding_pkts -= completed_pkts;
-
-        while (g_bletest_outstanding_pkts < 20) {
-            om = bletest_send_packet(g_bletest_handle);
-            if (om) {
-                ++g_bletest_outstanding_pkts;
-            }
-        }
-    }
-#endif /* XXX: throughput test */
-}
-#endif /* XXX: BLETEST_ROLE_ADVERTISER */
-
-/**
- * Main bletest function. Called by the task timer every 50 msecs.
- *
- */
-void
-bletest_execute(void)
-{
-    /* Toggle LED at set rate */
-    if ((int32_t)(os_time_get() - g_bletest_next_led_time) >= 0) {
-        hal_gpio_toggle(LED_BLINK_PIN);
-        g_bletest_next_led_time = os_time_get() + g_bletest_led_rate;
-    }
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-    bletest_execute_advertiser();
-#endif
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
-    bletest_execute_scanner();
-#endif
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR)
-    bletest_execute_initiator();
-#endif
-}
-
-/**
- * Callback when BLE test timer expires.
- *
- * @param arg
- */
-void
-bletest_timer_cb(struct os_event *ev)
-{
-    /* Call the bletest code */
-    bletest_execute();
-
-    /* Re-start the timer (run every 10 msecs) */
-    os_callout_reset(&g_bletest_timer, OS_TICKS_PER_SEC / 100);
-}
-
-/**
- * BLE test task
- *
- * @param arg
- */
-void
-bletest_task_handler(void *arg)
-{
-    int rc;
-    uint64_t rand64;
-    uint64_t event_mask;
-
-    /* Set LED blink rate */
-    g_bletest_led_rate = OS_TICKS_PER_SEC / 20;
-
-    /* Wait one second before starting test task */
-    os_time_delay(OS_TICKS_PER_SEC);
-
-    /* Initialize the host timer */
-    os_callout_init(&g_bletest_timer, &g_bletest_evq, bletest_timer_cb,
-                    NULL);
-
-    ble_hs_dbg_set_sync_state(BLE_HS_SYNC_STATE_GOOD);
-
-    /* Send the reset command first */
-    rc = bletest_hci_reset_ctlr();
-    assert(rc == 0);
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-    /* Initialize the advertiser */
-    console_printf("Starting BLE test task as advertiser\n");
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-    /* Start up all advertising instances except default one */
-    bletest_init_adv_instances();
-
-    /* Start advertising on instance 0 at 0 dbm */
-    bletest_init_advertising(0, 0);
-#else
-    bletest_init_advertising();
-#endif
-#endif
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_SCANNER)
-    /* Initialize the scanner */
-    console_printf("Starting BLE test task as scanner\n");
-    bletest_init_scanner();
-#endif
-
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_INITIATOR)
-    /* Initialize the scanner */
-    console_printf("Starting BLE test task as initiator\n");
-    bletest_init_initiator();
-#endif
-
-    /* Read unique HW id */
-    rc = hal_bsp_hw_id((void *)&g_bletest_hw_id[0], sizeof(g_bletest_hw_id));
-    assert(rc == 16);
-    console_printf("HW id=%04x%04x%04x%04x\n",
-                   (unsigned int)g_bletest_hw_id[0],
-                   (unsigned int)g_bletest_hw_id[1],
-                   (unsigned int)g_bletest_hw_id[2],
-                   (unsigned int)g_bletest_hw_id[3]);
-
-    /* Set the event mask we want to display */
-    event_mask = 0x7FF;
-    rc = bletest_hci_le_set_event_mask(event_mask);
-    assert(rc == 0);
-
-    /* Turn on all events */
-    event_mask = 0xffffffffffffffff;
-    rc = bletest_hci_set_event_mask(event_mask);
-    assert(rc == 0);
-
-    /* Read device address */
-    rc = bletest_hci_rd_bd_addr();
-    assert(rc == 0);
-
-    /* Read local features */
-    rc = bletest_hci_rd_local_feat();
-    assert(rc == 0);
-
-    /* Read local commands */
-    rc = bletest_hci_rd_local_supp_cmd();
-    assert(rc == 0);
-
-    /* Read version */
-    rc = bletest_hci_rd_local_version();
-    assert(rc == 0);
-
-    /* Read supported states */
-    rc = bletest_hci_le_read_supp_states();
-    assert(rc == 0);
-
-    /* Read maximum data length */
-    rc = bletest_hci_le_rd_max_datalen();
-    assert(rc == 0);
-
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT) == 1)
-    /* Read suggested data length */
-    rc = bletest_hci_le_rd_sugg_datalen();
-    assert(rc == 0);
-
-    /* write suggested default data length */
-    rc = bletest_hci_le_write_sugg_datalen(BLETEST_CFG_SUGG_DEF_TXOCTETS,
-                                           BLETEST_CFG_SUGG_DEF_TXTIME);
-    assert(rc == 0);
-
-    /* Read suggested data length */
-    rc = bletest_hci_le_rd_sugg_datalen();
-    assert(rc == 0);
-
-    /* Set data length (note: we know there is no connection; just a test) */
-    rc = bletest_hci_le_set_datalen(0x1234, BLETEST_CFG_SUGG_DEF_TXOCTETS,
-                                    BLETEST_CFG_SUGG_DEF_TXTIME);
-    assert(rc != 0);
-#endif
-
-    /* Encrypt a block */
-#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_ENCRYPTION) == 1)
-    rc = bletest_hci_le_encrypt((uint8_t *)g_ble_ll_encrypt_test_key,
-                                (uint8_t *)g_ble_ll_encrypt_test_plain_text);
-    assert(rc == 0);
-#endif
-
-    /* Get a random number */
-    rc = ble_hs_hci_util_rand(&rand64, 8);
-    assert(rc == 0);
-
-    /* Wait some time before starting */
-    os_time_delay(OS_TICKS_PER_SEC);
-
-    /* Init state */
-    g_bletest_state = 0;
-
-    /* Begin advertising if we are an advertiser */
-#if (BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER)
-#if MYNEWT_VAL(BLE_MULTI_ADV_SUPPORT)
-    rc = bletest_hci_le_set_multi_adv_enable(1, 0);
-    assert(rc == 0);
-#else
-    rc = bletest_hci_le_set_adv_enable(1);
-    assert(rc == 0);
-#endif
-#endif
-
-    bletest_timer_cb(NULL);
-
-    while (1) {
-        os_eventq_run(&g_bletest_evq);
-    }
-}
-
-/**
- * main
- *
- * The main task for the project. This function initializes the packages,
- * then starts serving events from default event queue.
- *
- * @return int NOTE: this function should never return!
- */
-int
-main(void)
-{
-    int rc;
-
-    /* Initialize OS */
-    sysinit();
-
-    /* Dummy device address */
-#if BLETEST_CFG_ROLE == BLETEST_ROLE_ADVERTISER
-    g_dev_addr[0] = 0x00;
-    g_dev_addr[1] = 0x00;
-    g_dev_addr[2] = 0x00;
-    g_dev_addr[3] = 0x88;
-    g_dev_addr[4] = 0x88;
-    g_dev_addr[5] = 0x08;
-
-    g_bletest_cur_peer_addr[0] = 0x00;
-    g_bletest_cur_peer_addr[1] = 0x00;
-    g_bletest_cur_peer_addr[2] = 0x00;
-    g_bletest_cur_peer_addr[3] = 0x99;
-    g_bletest_cur_peer_addr[4] = 0x99;
-    g_bletest_cur_peer_addr[5] = 0x09;
-#else
-    g_dev_addr[0] = 0x00;
-    g_dev_addr[1] = 0x00;
-    g_dev_addr[2] = 0x00;
-    g_dev_addr[3] = 0x99;
-    g_dev_addr[4] = 0x99;
-    g_dev_addr[5] = 0x09;
-
-    g_bletest_cur_peer_addr[0] = 0x00;
-    g_bletest_cur_peer_addr[1] = 0x00;
-    g_bletest_cur_peer_addr[2] = 0x00;
-    g_bletest_cur_peer_addr[3] = 0x88;
-    g_bletest_cur_peer_addr[4] = 0x88;
-    g_bletest_cur_peer_addr[5] = 0x08;
-#endif
-
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
-    /* Set the led pin as an output */
-    g_led_pin = LED_BLINK_PIN;
-    hal_gpio_init_out(g_led_pin, 1);
-
-    /* Initialize eventq for bletest task */
-    os_eventq_init(&g_bletest_evq);
-
-    rc = os_task_init(&bletest_task, "bletest", bletest_task_handler, NULL,
-                      BLETEST_TASK_PRIO, OS_WAIT_FOREVER, bletest_stack,
-                      BLETEST_STACK_SIZE);
-    assert(rc == 0);
-
-    while (1) {
-        os_eventq_run(os_eventq_dflt_get());
-    }
-    /* Never returns */
-
-    /* os start should never return. If it does, this should be an error */
-    assert(0);
-
-    return rc;
-}
diff --git a/apps/bletest/syscfg.yml b/apps/bletest/syscfg.yml
deleted file mode 100644
index ba44607b4a..0000000000
--- a/apps/bletest/syscfg.yml
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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.
-#
-
-# Package: apps/bletest
-syscfg.defs:
-    BLETEST_ROLE:
-        description: >
-            The role of the bletest code. Should be set to:
-                1: Advertiser
-                2: Scanner
-                3: Initiator
-        value: 1
-
-syscfg.vals:
-    MSYS_1_BLOCK_COUNT: 16
-    BLE_SM_LEGACY: 0
-
-    # Default task settings
-    OS_MAIN_STACK_SIZE: 256
diff --git a/apps/bletiny/pkg.yml b/apps/bletiny/pkg.yml
deleted file mode 100644
index 0d70a9d47d..0000000000
--- a/apps/bletiny/pkg.yml
+++ /dev/null
@@ -1,37 +0,0 @@
-# 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.
-#
-pkg.name: apps/bletiny
-pkg.type: app
-pkg.description: Shell application exposing the nimble GAP and GATT.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps: 
-    - kernel/os 
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/host/services/ans
-    - net/nimble/host/services/gap
-    - net/nimble/host/services/gatt
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/full
-    - sys/shell
diff --git a/apps/bletiny/src/bletiny.h b/apps/bletiny/src/bletiny.h
deleted file mode 100644
index 495aadb76f..0000000000
--- a/apps/bletiny/src/bletiny.h
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
- * 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 H_BLETINY_PRIV_
-#define H_BLETINY_PRIV_
-
-#include <inttypes.h>
-#include "nimble/ble.h"
-#include "nimble/nimble_opt.h"
-#include "log/log.h"
-#include "os/queue.h"
-
-#include "host/ble_gatt.h"
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct ble_gap_white_entry;
-struct ble_hs_adv_fields;
-struct ble_gap_upd_params;
-struct ble_gap_conn_params;
-struct hci_adv_params;
-struct ble_l2cap_sig_update_req;
-struct ble_l2cap_sig_update_params;
-union ble_store_value;
-union ble_store_key;
-struct ble_gap_adv_params;
-struct ble_gap_conn_desc;
-struct ble_gap_disc_params;
-
-typedef int cmd_fn(int argc, char **argv);
-struct cmd_entry {
-    char *name;
-    cmd_fn *cb;
-};
-
-struct kv_pair {
-    char *key;
-    int val;
-};
-
-struct bletiny_dsc {
-    SLIST_ENTRY(bletiny_dsc) next;
-    struct ble_gatt_dsc dsc;
-};
-SLIST_HEAD(bletiny_dsc_list, bletiny_dsc);
-
-struct bletiny_chr {
-    SLIST_ENTRY(bletiny_chr) next;
-    struct ble_gatt_chr chr;
-
-    struct bletiny_dsc_list dscs;
-};
-SLIST_HEAD(bletiny_chr_list, bletiny_chr);
-
-struct bletiny_svc {
-    SLIST_ENTRY(bletiny_svc) next;
-    struct ble_gatt_svc svc;
-    bool char_disc_sent;
-    struct bletiny_chr_list chrs;
-};
-
-SLIST_HEAD(bletiny_svc_list, bletiny_svc);
-
-struct bletiny_l2cap_coc {
-    SLIST_ENTRY(bletiny_l2cap_coc) next;
-    struct ble_l2cap_chan *chan;
-};
-
-SLIST_HEAD(bletiny_l2cap_coc_list, bletiny_l2cap_coc);
-
-struct bletiny_conn {
-    uint16_t handle;
-    struct bletiny_svc_list svcs;
-    struct bletiny_l2cap_coc_list coc_list;
-};
-
-extern struct bletiny_conn bletiny_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)];
-extern int bletiny_num_conns;
-
-extern uint16_t nm_attr_val_handle;
-
-extern struct log bletiny_log;
-
-const struct cmd_entry *parse_cmd_find(const struct cmd_entry *cmds,
-                                       char *name);
-struct kv_pair *parse_kv_find(struct kv_pair *kvs, char *name);
-int parse_arg_find_idx(const char *key);
-char *parse_arg_extract(const char *key);
-long parse_arg_long_bounds(char *name, long min, long max, int *out_status);
-long parse_arg_long_bounds_default(char *name, long min, long max,
-                                   long dflt, int *out_status);
-uint64_t parse_arg_uint64_bounds(char *name, uint64_t min,
-                                 uint64_t max, int *out_status);
-long parse_arg_long(char *name, int *staus);
-uint8_t parse_arg_bool(char *name, int *status);
-uint8_t parse_arg_bool_default(char *name, uint8_t dflt, int *out_status);
-uint8_t parse_arg_uint8(char *name, int *status);
-uint8_t parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status);
-uint16_t parse_arg_uint16(char *name, int *status);
-uint16_t parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status);
-uint32_t parse_arg_uint32(char *name, int *out_status);
-uint32_t parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status);
-uint64_t parse_arg_uint64(char *name, int *out_status);
-int parse_arg_kv(char *name, struct kv_pair *kvs, int *out_status);
-int parse_arg_kv_default(char *name, struct kv_pair *kvs, int def_val,
-                         int *out_status);
-int parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len);
-int parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len);
-int parse_arg_mac(char *name, uint8_t *dst);
-int parse_arg_uuid(char *name, ble_uuid_any_t *uuid);
-int parse_err_too_few_args(char *cmd_name);
-int parse_arg_all(int argc, char **argv);
-int cmd_init(void);
-int nm_chr_access(uint16_t conn_handle, uint16_t attr_handle,
-                  uint8_t op, struct ble_gatt_access_ctxt *ctxt,
-                  void *arg);
-int nm_rx_rsp(uint8_t *attr_val, uint16_t attr_len);
-void nm_init(void);
-void bletiny_lock(void);
-void bletiny_unlock(void);
-int bletiny_exchange_mtu(uint16_t conn_handle);
-int bletiny_disc_svcs(uint16_t conn_handle);
-int bletiny_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid);
-int bletiny_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
-                           uint16_t end_handle);
-int bletiny_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
-                               uint16_t end_handle, const ble_uuid_t *uuid);
-int bletiny_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle,
-                          uint16_t end_handle);
-int bletiny_disc_full(uint16_t conn_handle);
-int bletiny_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
-                           uint16_t end_handle);
-int bletiny_read(uint16_t conn_handle, uint16_t attr_handle);
-int bletiny_read_long(uint16_t conn_handle, uint16_t attr_handle,
-                      uint16_t offset);
-int bletiny_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
-                          uint16_t end_handle, const ble_uuid_t *uuid);
-int bletiny_read_mult(uint16_t conn_handle, uint16_t *attr_handles,
-                       int num_attr_handles);
-int bletiny_write(uint16_t conn_handle, uint16_t attr_handle,
-                  struct os_mbuf *om);
-int bletiny_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
-                         struct os_mbuf *om);
-int bletiny_write_long(uint16_t conn_handle, uint16_t attr_handle,
-                       uint16_t offset, struct os_mbuf *om);
-int bletiny_write_reliable(uint16_t conn_handle,
-                           struct ble_gatt_attr *attrs, int num_attrs);
-int bletiny_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
-                      int32_t duration_ms,
-                      const struct ble_gap_adv_params *params);
-int bletiny_adv_stop(void);
-int bletiny_conn_initiate(uint8_t own_addr_type, const ble_addr_t *peer_addr,
-                          int32_t duration_ms,
-                          struct ble_gap_conn_params *params);
-int bletiny_conn_cancel(void);
-int bletiny_term_conn(uint16_t conn_handle, uint8_t reason);
-int bletiny_wl_set(ble_addr_t *addrs, int addrs_count);
-int bletiny_scan(uint8_t own_addr_type, int32_t duration_ms,
-                 const struct ble_gap_disc_params *disc_params);
-int bletiny_scan_cancel(void);
-int bletiny_set_adv_data(struct ble_hs_adv_fields *adv_fields);
-int bletiny_update_conn(uint16_t conn_handle,
-                         struct ble_gap_upd_params *params);
-void bletiny_chrup(uint16_t attr_handle);
-int bletiny_datalen(uint16_t conn_handle, uint16_t tx_octets,
-                    uint16_t tx_time);
-int bletiny_l2cap_update(uint16_t conn_handle,
-                          struct ble_l2cap_sig_update_params *params);
-int bletiny_sec_start(uint16_t conn_handle);
-int bletiny_sec_pair(uint16_t conn_handle);
-int bletiny_sec_restart(uint16_t conn_handle, uint8_t *ltk, uint16_t ediv,
-                        uint64_t rand_val, int auth);
-int bletiny_tx_start(uint16_t handle, uint16_t len, uint16_t rate,
-                     uint16_t num);
-int bletiny_rssi(uint16_t conn_handle, int8_t *out_rssi);
-int bletiny_l2cap_create_srv(uint16_t psm);
-int bletiny_l2cap_connect(uint16_t conn, uint16_t psm);
-int bletiny_l2cap_disconnect(uint16_t conn, uint16_t idx);
-int bletiny_l2cap_send(uint16_t conn, uint16_t idx, uint16_t bytes);
-#define BLETINY_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
-#define BLETINY_LOG(lvl, ...) \
-    LOG_ ## lvl(&bletiny_log, BLETINY_LOG_MODULE, __VA_ARGS__)
-
-/** GATT server. */
-#define GATT_SVR_SVC_ALERT_UUID               0x1811
-#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
-#define GATT_SVR_CHR_NEW_ALERT                0x2A46
-#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
-#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
-#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
-
-void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
-int gatt_svr_init(void);
-
-/** Misc. */
-void print_bytes(const uint8_t *bytes, int len);
-void print_mbuf(const struct os_mbuf *om);
-void print_addr(const void *addr);
-void print_uuid(const ble_uuid_t *uuid);
-int svc_is_empty(const struct bletiny_svc *svc);
-uint16_t chr_end_handle(const struct bletiny_svc *svc,
-                        const struct bletiny_chr *chr);
-int chr_is_empty(const struct bletiny_svc *svc, const struct bletiny_chr *chr);
-void print_conn_desc(const struct ble_gap_conn_desc *desc);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/apps/bletiny/src/cmd.c b/apps/bletiny/src/cmd.c
deleted file mode 100644
index 15563a01f7..0000000000
--- a/apps/bletiny/src/cmd.c
+++ /dev/null
@@ -1,3572 +0,0 @@
-/*
- * 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 <errno.h>
-#include <string.h>
-#include "bsp/bsp.h"
-#include "console/console.h"
-#include "shell/shell.h"
-
-#include "nimble/ble.h"
-#include "nimble/nimble_opt.h"
-#include "nimble/hci_common.h"
-#include "host/ble_gap.h"
-#include "host/ble_hs_adv.h"
-#include "host/ble_sm.h"
-#include "host/ble_eddystone.h"
-#include "host/ble_hs_id.h"
-#include "services/gatt/ble_svc_gatt.h"
-#include "../src/ble_l2cap_priv.h"
-#include "../src/ble_hs_priv.h"
-
-#include "bletiny.h"
-
-#define CMD_BUF_SZ      256
-
-static int cmd_b_exec(int argc, char **argv);
-static struct shell_cmd cmd_b = {
-    .sc_cmd = "b",
-    .sc_cmd_func = cmd_b_exec
-};
-
-static bssnz_t uint8_t cmd_buf[CMD_BUF_SZ];
-
-static struct kv_pair cmd_own_addr_types[] = {
-    { "public",     BLE_OWN_ADDR_PUBLIC },
-    { "random",     BLE_OWN_ADDR_RANDOM },
-    { "rpa_pub",    BLE_OWN_ADDR_RPA_PUBLIC_DEFAULT },
-    { "rpa_rnd",    BLE_OWN_ADDR_RPA_RANDOM_DEFAULT },
-    { NULL }
-};
-
-static struct kv_pair cmd_peer_addr_types[] = {
-    { "public",     BLE_ADDR_PUBLIC },
-    { "random",     BLE_ADDR_RANDOM },
-    { "public_id",  BLE_ADDR_PUBLIC_ID },
-    { "random_id",  BLE_ADDR_RANDOM_ID },
-    { NULL }
-};
-
-static struct kv_pair cmd_addr_type[] = {
-    { "public",     BLE_ADDR_PUBLIC },
-    { "random",     BLE_ADDR_RANDOM },
-    { NULL }
-};
-
-/*****************************************************************************
- * $misc                                                                     *
- *****************************************************************************/
-
-static int
-cmd_exec(const struct cmd_entry *cmds, int argc, char **argv)
-{
-    const struct cmd_entry *cmd;
-    int rc;
-
-    if (argc <= 1) {
-        return parse_err_too_few_args(argv[0]);
-    }
-
-    cmd = parse_cmd_find(cmds, argv[1]);
-    if (cmd == NULL) {
-        console_printf("Error: unknown %s command: %s\n", argv[0], argv[1]);
-        return -1;
-    }
-
-    rc = cmd->cb(argc - 1, argv + 1);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-cmd_print_dsc(struct bletiny_dsc *dsc)
-{
-    console_printf("            dsc_handle=%d uuid=", dsc->dsc.handle);
-    print_uuid(&dsc->dsc.uuid.u);
-    console_printf("\n");
-}
-
-static void
-cmd_print_chr(struct bletiny_chr *chr)
-{
-    struct bletiny_dsc *dsc;
-
-    console_printf("        def_handle=%d val_handle=%d properties=0x%02x "
-                   "uuid=", chr->chr.def_handle, chr->chr.val_handle,
-                   chr->chr.properties);
-    print_uuid(&chr->chr.uuid.u);
-    console_printf("\n");
-
-    SLIST_FOREACH(dsc, &chr->dscs, next) {
-        cmd_print_dsc(dsc);
-    }
-}
-
-static void
-cmd_print_svc(struct bletiny_svc *svc)
-{
-    struct bletiny_chr *chr;
-
-    console_printf("    start=%d end=%d uuid=", svc->svc.start_handle,
-                   svc->svc.end_handle);
-    print_uuid(&svc->svc.uuid.u);
-    console_printf("\n");
-
-    SLIST_FOREACH(chr, &svc->chrs, next) {
-        cmd_print_chr(chr);
-    }
-}
-
-static int
-cmd_parse_conn_start_end(uint16_t *out_conn, uint16_t *out_start,
-                         uint16_t *out_end)
-{
-    int rc;
-
-    *out_conn = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        return rc;
-    }
-
-    *out_start = parse_arg_uint16("start", &rc);
-    if (rc != 0) {
-        return rc;
-    }
-
-    *out_end = parse_arg_uint16("end", &rc);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static int
-cmd_parse_eddystone_url(char *full_url, uint8_t *out_scheme, char *out_body,
-                        uint8_t *out_body_len, uint8_t *out_suffix)
-{
-    static const struct {
-        char *s;
-        uint8_t scheme;
-    } schemes[] = {
-        { "http://www.", BLE_EDDYSTONE_URL_SCHEME_HTTP_WWW },
-        { "https://www.", BLE_EDDYSTONE_URL_SCHEME_HTTPS_WWW },
-        { "http://", BLE_EDDYSTONE_URL_SCHEME_HTTP },
-        { "https://", BLE_EDDYSTONE_URL_SCHEME_HTTPS },
-    };
-
-    static const struct {
-        char *s;
-        uint8_t code;
-    } suffixes[] = {
-        { ".com/", BLE_EDDYSTONE_URL_SUFFIX_COM_SLASH },
-        { ".org/", BLE_EDDYSTONE_URL_SUFFIX_ORG_SLASH },
-        { ".edu/", BLE_EDDYSTONE_URL_SUFFIX_EDU_SLASH },
-        { ".net/", BLE_EDDYSTONE_URL_SUFFIX_NET_SLASH },
-        { ".info/", BLE_EDDYSTONE_URL_SUFFIX_INFO_SLASH },
-        { ".biz/", BLE_EDDYSTONE_URL_SUFFIX_BIZ_SLASH },
-        { ".gov/", BLE_EDDYSTONE_URL_SUFFIX_GOV_SLASH },
-        { ".com", BLE_EDDYSTONE_URL_SUFFIX_COM },
-        { ".org", BLE_EDDYSTONE_URL_SUFFIX_ORG },
-        { ".edu", BLE_EDDYSTONE_URL_SUFFIX_EDU },
-        { ".net", BLE_EDDYSTONE_URL_SUFFIX_NET },
-        { ".info", BLE_EDDYSTONE_URL_SUFFIX_INFO },
-        { ".biz", BLE_EDDYSTONE_URL_SUFFIX_BIZ },
-        { ".gov", BLE_EDDYSTONE_URL_SUFFIX_GOV },
-    };
-
-    char *prefix;
-    char *suffix;
-    int full_url_len;
-    int prefix_len;
-    int suffix_len;
-    int suffix_idx;
-    int rc;
-    int i;
-
-    full_url_len = strlen(full_url);
-
-    rc = BLE_HS_EINVAL;
-    for (i = 0; i < sizeof schemes / sizeof schemes[0]; i++) {
-        prefix = schemes[i].s;
-        prefix_len = strlen(schemes[i].s);
-
-        if (full_url_len >= prefix_len &&
-            memcmp(full_url, prefix, prefix_len) == 0) {
-
-            *out_scheme = i;
-            rc = 0;
-            break;
-        }
-    }
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = BLE_HS_EINVAL;
-    for (i = 0; i < sizeof suffixes / sizeof suffixes[0]; i++) {
-        suffix = suffixes[i].s;
-        suffix_len = strlen(suffixes[i].s);
-
-        suffix_idx = full_url_len - suffix_len;
-        if (suffix_idx >= prefix_len &&
-            memcmp(full_url + suffix_idx, suffix, suffix_len) == 0) {
-
-            *out_suffix = i;
-            rc = 0;
-            break;
-        }
-    }
-    if (rc != 0) {
-        *out_suffix = BLE_EDDYSTONE_URL_SUFFIX_NONE;
-        *out_body_len = full_url_len - prefix_len;
-    } else {
-        *out_body_len = full_url_len - prefix_len - suffix_len;
-    }
-
-    memcpy(out_body, full_url + prefix_len, *out_body_len);
-
-    return 0;
-}
-
-/*****************************************************************************
- * $advertise                                                                *
- *****************************************************************************/
-
-static struct kv_pair cmd_adv_conn_modes[] = {
-    { "non", BLE_GAP_CONN_MODE_NON },
-    { "und", BLE_GAP_CONN_MODE_UND },
-    { "dir", BLE_GAP_CONN_MODE_DIR },
-    { NULL }
-};
-
-static struct kv_pair cmd_adv_disc_modes[] = {
-    { "non", BLE_GAP_DISC_MODE_NON },
-    { "ltd", BLE_GAP_DISC_MODE_LTD },
-    { "gen", BLE_GAP_DISC_MODE_GEN },
-    { NULL }
-};
-
-static struct kv_pair cmd_adv_filt_types[] = {
-    { "none", BLE_HCI_ADV_FILT_NONE },
-    { "scan", BLE_HCI_ADV_FILT_SCAN },
-    { "conn", BLE_HCI_ADV_FILT_CONN },
-    { "both", BLE_HCI_ADV_FILT_BOTH },
-    { NULL }
-};
-
-static void
-print_enumerate_options(struct kv_pair *options)
-{
-    int i;
-    for (i = 0; options[i].key != NULL; i++) {
-        if (i != 0) {
-            console_printf("|");
-        }
-        console_printf("%s(%d)", options[i].key, options[i].val);
-    }
-}
-
-static void
-help_cmd_long_bounds(const char *cmd_name, long min, long max)
-{
-    console_printf("\t%s=<%ld-%ld>\n", cmd_name, min, max);
-}
-
-static void
-help_cmd_long_bounds_dflt(const char *cmd_name, long min, long max, long dflt)
-{
-    console_printf("\t%s=[%ld-%ld] default=%ld\n", cmd_name, min, max, dflt);
-}
-
-static void
-help_cmd_val(const char *cmd_name)
-{
-    console_printf("\t%s=<val>\n", cmd_name);
-}
-
-static void
-help_cmd_long(const char *cmd_name)
-{
-    help_cmd_val(cmd_name);
-}
-
-static void
-help_cmd_bool(const char *cmd_name)
-{
-    console_printf("\t%s=<0|1>\n", cmd_name);
-}
-
-static void
-help_cmd_bool_dflt(const char *cmd_name, bool dflt)
-{
-    console_printf("\t%s=[0|1] default=%d\n", cmd_name, dflt);
-}
-
-static void
-help_cmd_uint8(const char *cmd_name)
-{
-    help_cmd_val(cmd_name);
-}
-
-static void
-help_cmd_uint8_dflt(const char *cmd_name, uint8_t dflt)
-{
-    console_printf("\t%s=[val] default=%u\n", cmd_name, dflt);
-}
-
-static void
-help_cmd_uint16(const char *cmd_name)
-{
-    help_cmd_val(cmd_name);
-}
-
-static void
-help_cmd_uint16_dflt(const char *cmd_name, uint16_t dflt)
-{
-    console_printf("\t%s=[val] default=%u\n", cmd_name, dflt);
-}
-
-static void
-help_cmd_uint32(const char *cmd_name)
-{
-    help_cmd_val(cmd_name);
-}
-
-static void
-help_cmd_uint64(const char *cmd_name)
-{
-    help_cmd_val(cmd_name);
-}
-
-static void
-help_cmd_kv(const char *cmd_name, struct kv_pair *options)
-{
-    console_printf("\t%s=<", cmd_name);
-    print_enumerate_options(options);
-    console_printf(">\n");
-}
-
-static void
-help_cmd_kv_dflt(const char *cmd_name, struct kv_pair *options, int dflt)
-{
-    console_printf("\t%s=[", cmd_name);
-    print_enumerate_options(options);
-    console_printf("] default=%d\n", dflt);
-}
-
-static void
-help_cmd_byte_stream(const char *cmd_name)
-{
-    console_printf("\t%s=<xx:xx:xx: ...>\n", cmd_name);
-}
-
-static void
-help_cmd_byte_stream_exact_length(const char *cmd_name, int len)
-{
-    console_printf("\t%s=<xx:xx:xx: ...> len=%d\n", cmd_name, len);
-}
-
-static void
-help_cmd_uuid(const char *cmd_name)
-{
-    console_printf("\t%s=<UUID>\n", cmd_name);
-}
-
-static void
-help_cmd_extract(const char *cmd_name)
-{
-    console_printf("\t%s=<str>\n", cmd_name);
-}
-
-static void
-help_cmd_conn_start_end(void)
-{
-    console_printf("\t%s=<val> %s=<val> %s=<val>\n", "conn", "start", "end");
-}
-
-static void
-bletiny_adv_help(void)
-{
-    console_printf("Available adv commands: \n");
-    console_printf("\thelp\n");
-    console_printf("\tstop\n");
-    console_printf("Available adv params: \n");
-    help_cmd_kv_dflt("conn", cmd_adv_conn_modes, BLE_GAP_CONN_MODE_UND);
-    help_cmd_kv_dflt("disc", cmd_adv_disc_modes, BLE_GAP_DISC_MODE_GEN);
-    help_cmd_kv_dflt("peer_addr_type", cmd_peer_addr_types, BLE_ADDR_PUBLIC);
-    help_cmd_byte_stream_exact_length("peer_addr", 6);
-    help_cmd_kv_dflt("own_addr_type", cmd_own_addr_types,
-                     BLE_OWN_ADDR_PUBLIC);
-    help_cmd_long_bounds_dflt("chan_map", 0, 0xff, 0);
-    help_cmd_kv_dflt("filt", cmd_adv_filt_types, BLE_HCI_ADV_FILT_NONE);
-    help_cmd_long_bounds_dflt("itvl_min", 0, UINT16_MAX, 0);
-    help_cmd_long_bounds_dflt("itvl_max", 0, UINT16_MAX, 0);
-    help_cmd_long_bounds_dflt("hd", 0, 1, 0);
-    help_cmd_long_bounds_dflt("dur", 1, INT32_MAX, BLE_HS_FOREVER);
-}
-
-static int
-cmd_adv(int argc, char **argv)
-{
-    struct ble_gap_adv_params params;
-    int32_t duration_ms;
-    ble_addr_t peer_addr;
-    ble_addr_t *peer_addr_param = &peer_addr;
-    uint8_t own_addr_type;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_adv_help();
-        return 0;
-    }
-
-    if (argc > 1 && strcmp(argv[1], "stop") == 0) {
-        rc = bletiny_adv_stop();
-        if (rc != 0) {
-            console_printf("advertise stop fail: %d\n", rc);
-            return rc;
-        }
-
-        return 0;
-    }
-
-    params.conn_mode = parse_arg_kv_default("conn", cmd_adv_conn_modes,
-                                            BLE_GAP_CONN_MODE_UND, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_kv_dflt("conn", cmd_adv_conn_modes, BLE_GAP_CONN_MODE_UND);
-        return rc;
-    }
-
-    params.disc_mode = parse_arg_kv_default("disc", cmd_adv_disc_modes,
-                                            BLE_GAP_DISC_MODE_GEN, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'disc' parameter\n");
-        help_cmd_kv_dflt("disc", cmd_adv_disc_modes, BLE_GAP_DISC_MODE_GEN);
-        return rc;
-    }
-
-    peer_addr.type = parse_arg_kv_default(
-        "peer_addr_type", cmd_peer_addr_types, BLE_ADDR_PUBLIC, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'peer_addr_type' parameter\n");
-        help_cmd_kv_dflt("peer_addr_type", cmd_peer_addr_types,
-                         BLE_ADDR_PUBLIC);
-        return rc;
-    }
-
-    rc = parse_arg_mac("peer_addr", peer_addr.val);
-    if (rc == ENOENT) {
-        peer_addr_param = NULL;
-    } else if (rc != 0) {
-        console_printf("invalid 'peer_addr' parameter\n");
-        help_cmd_byte_stream_exact_length("peer_addr", 6);
-        return rc;
-    }
-
-    own_addr_type = parse_arg_kv_default(
-        "own_addr_type", cmd_own_addr_types, BLE_OWN_ADDR_PUBLIC, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'own_addr_type' parameter\n");
-        help_cmd_kv_dflt("own_addr_type", cmd_own_addr_types,
-                         BLE_OWN_ADDR_PUBLIC);
-        return rc;
-    }
-
-    params.channel_map = parse_arg_long_bounds_default("chan_map", 0, 0xff, 0,
-                                                       &rc);
-    if (rc != 0) {
-        console_printf("invalid 'chan_map' parameter\n");
-        help_cmd_long_bounds_dflt("chan_map", 0, 0xff, 0);
-        return rc;
-    }
-
-    params.filter_policy = parse_arg_kv_default("filt", cmd_adv_filt_types,
-                                                BLE_HCI_ADV_FILT_NONE, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'filt' parameter\n");
-        help_cmd_kv_dflt("filt", cmd_adv_filt_types, BLE_HCI_ADV_FILT_NONE);
-        return rc;
-    }
-
-    params.itvl_min = parse_arg_long_bounds_default("itvl_min", 0, UINT16_MAX,
-                                                    0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_min' parameter\n");
-        help_cmd_long_bounds_dflt("itvl_min", 0, UINT16_MAX, 0);
-        return rc;
-    }
-
-    params.itvl_max = parse_arg_long_bounds_default("itvl_max", 0, UINT16_MAX,
-                                                    0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_max' parameter\n");
-        help_cmd_long_bounds_dflt("itvl_max", 0, UINT16_MAX, 0);
-        return rc;
-    }
-
-    params.high_duty_cycle = parse_arg_long_bounds_default("hd", 0, 1, 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'hd' parameter\n");
-        help_cmd_long_bounds_dflt("hd", 0, 1, 0);
-        return rc;
-    }
-
-    duration_ms = parse_arg_long_bounds_default("dur", 1, INT32_MAX,
-                                                BLE_HS_FOREVER, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'dur' parameter\n");
-        help_cmd_long_bounds_dflt("dur", 1, INT32_MAX, BLE_HS_FOREVER);
-        return rc;
-    }
-
-    rc = bletiny_adv_start(own_addr_type, peer_addr_param, duration_ms,
-                           &params);
-    if (rc != 0) {
-        console_printf("advertise fail: %d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $connect                                                                  *
- *****************************************************************************/
-
-static void
-bletiny_conn_help(void)
-{
-    console_printf("Available conn commands: \n");
-    console_printf("\thelp\n");
-    console_printf("\tcancel\n");
-    console_printf("Available conn params: \n");
-    help_cmd_kv_dflt("peer_addr_type", cmd_peer_addr_types, BLE_ADDR_PUBLIC);
-    help_cmd_byte_stream_exact_length("peer_addr", 6);
-    help_cmd_kv_dflt("own_addr_type", cmd_own_addr_types,
-                     BLE_OWN_ADDR_PUBLIC);
-    help_cmd_uint16_dflt("scan_itvl", 0x0010);
-    help_cmd_uint16_dflt("scan_window", 0x0010);
-    help_cmd_uint16_dflt("itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN);
-    help_cmd_uint16_dflt("itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX);
-    help_cmd_uint16_dflt("latency", 0);
-    help_cmd_uint16_dflt("timeout", 0x0100);
-    help_cmd_uint16_dflt("min_ce_len", 0x0010);
-    help_cmd_uint16_dflt("max_ce_len", 0x0300);
-    help_cmd_long_bounds_dflt("dur", 1, INT32_MAX, 0);
-}
-
-static int
-cmd_conn(int argc, char **argv)
-{
-    struct ble_gap_conn_params params;
-    int32_t duration_ms;
-    ble_addr_t peer_addr;
-    ble_addr_t *peer_addr_param = &peer_addr;
-    int own_addr_type;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_conn_help();
-        return 0;
-    }
-
-    if (argc > 1 && strcmp(argv[1], "cancel") == 0) {
-        rc = bletiny_conn_cancel();
-        if (rc != 0) {
-            console_printf("connection cancel fail: %d\n", rc);
-            return rc;
-        }
-
-        return 0;
-    }
-
-    peer_addr.type = parse_arg_kv_default("peer_addr_type", cmd_peer_addr_types,
-                                          BLE_ADDR_PUBLIC, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'peer_addr_type' parameter\n");
-        help_cmd_kv_dflt("peer_addr_type", cmd_peer_addr_types,
-                         BLE_ADDR_PUBLIC);
-        return rc;
-    }
-
-    rc = parse_arg_mac("peer_addr", peer_addr.val);
-    if (rc == ENOENT) {
-        /* Allow "addr" for backwards compatibility. */
-        rc = parse_arg_mac("addr", peer_addr.val);
-    }
-
-    if (rc == ENOENT) {
-        /* With no "peer_addr" specified we'll use white list */
-        peer_addr_param = NULL;
-    } else if (rc != 0) {
-        console_printf("invalid 'peer_addr' parameter\n");
-        help_cmd_byte_stream_exact_length("peer_addr", 6);
-        return rc;
-    }
-
-    own_addr_type = parse_arg_kv_default("own_addr_type", cmd_own_addr_types,
-                                         BLE_OWN_ADDR_PUBLIC, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'own_addr_type' parameter\n");
-        help_cmd_kv_dflt("own_addr_type", cmd_own_addr_types,
-                         BLE_OWN_ADDR_PUBLIC);
-        return rc;
-    }
-
-    params.scan_itvl = parse_arg_uint16_dflt("scan_itvl", 0x0010, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'scan_itvl' parameter\n");
-        help_cmd_uint16_dflt("scan_itvl", 0x0010);
-        return rc;
-    }
-
-    params.scan_window = parse_arg_uint16_dflt("scan_window", 0x0010, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'scan_window' parameter\n");
-        help_cmd_uint16_dflt("scan_window", 0x0010);
-        return rc;
-    }
-
-    params.itvl_min = parse_arg_uint16_dflt(
-        "itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_min' parameter\n");
-        help_cmd_uint16_dflt("itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN);
-        return rc;
-    }
-
-    params.itvl_max = parse_arg_uint16_dflt(
-        "itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_max' parameter\n");
-        help_cmd_uint16_dflt("itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX);
-        return rc;
-    }
-
-    params.latency = parse_arg_uint16_dflt("latency", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'latency' parameter\n");
-        help_cmd_uint16_dflt("latency", 0);
-        return rc;
-    }
-
-    params.supervision_timeout = parse_arg_uint16_dflt("timeout", 0x0100, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'timeout' parameter\n");
-        help_cmd_uint16_dflt("timeout", 0x0100);
-        return rc;
-    }
-
-    params.min_ce_len = parse_arg_uint16_dflt("min_ce_len", 0x0010, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'min_ce_len' parameter\n");
-        help_cmd_uint16_dflt("min_ce_len", 0x0010);
-        return rc;
-    }
-
-    params.max_ce_len = parse_arg_uint16_dflt("max_ce_len", 0x0300, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'max_ce_len' parameter\n");
-        help_cmd_uint16_dflt("max_ce_len", 0x0300);
-        return rc;
-    }
-
-    duration_ms = parse_arg_long_bounds_default("dur", 1, INT32_MAX, 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'dur' parameter\n");
-        help_cmd_long_bounds_dflt("dur", 1, INT32_MAX, 0);
-        return rc;
-    }
-
-    rc = bletiny_conn_initiate(own_addr_type, peer_addr_param, duration_ms,
-                               &params);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $chrup                                                                    *
- *****************************************************************************/
-
-static void
-bletiny_chrup_help(void)
-{
-    console_printf("Available chrup commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available chrup params: \n");
-    help_cmd_long("attr");
-}
-
-static int
-cmd_chrup(int argc, char **argv)
-{
-    uint16_t attr_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_chrup_help();
-        return 0;
-    }
-
-    attr_handle = parse_arg_long("attr", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'attr' parameter\n");
-        help_cmd_long("attr");
-        return rc;
-    }
-
-    bletiny_chrup(attr_handle);
-
-    return 0;
-}
-
-/*****************************************************************************
- * $datalen                                                                  *
- *****************************************************************************/
-
-static void
-bletiny_datalen_help(void)
-{
-    console_printf("Available datalen commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available datalen params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16("octets");
-    help_cmd_uint16("time");
-}
-
-static int
-cmd_datalen(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    uint16_t tx_octets;
-    uint16_t tx_time;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_datalen_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    tx_octets = parse_arg_long("octets", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'octets' parameter\n");
-        help_cmd_long("octets");
-        return rc;
-    }
-
-    tx_time = parse_arg_long("time", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'time' parameter\n");
-        help_cmd_long("time");
-        return rc;
-    }
-
-    rc = bletiny_datalen(conn_handle, tx_octets, tx_time);
-    if (rc != 0) {
-        console_printf("error setting data length; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $discover                                                                 *
- *****************************************************************************/
-
-static void
-bletiny_disc_chr_help(void)
-{
-    console_printf("Available disc chr commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available disc chr params: \n");
-    help_cmd_conn_start_end();
-    help_cmd_uuid("uuid");
-}
-
-static int
-cmd_disc_chr(int argc, char **argv)
-{
-    uint16_t start_handle;
-    uint16_t conn_handle;
-    uint16_t end_handle;
-    ble_uuid_any_t uuid;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_disc_chr_help();
-        return 0;
-    }
-
-    rc = cmd_parse_conn_start_end(&conn_handle, &start_handle, &end_handle);
-    if (rc != 0) {
-        console_printf("invalid 'conn start end' parameter\n");
-        help_cmd_conn_start_end();
-        return rc;
-    }
-
-    rc = parse_arg_uuid("uuid", &uuid);
-    if (rc == 0) {
-        rc = bletiny_disc_chrs_by_uuid(conn_handle, start_handle, end_handle,
-                                       &uuid.u);
-    } else if (rc == ENOENT) {
-        rc = bletiny_disc_all_chrs(conn_handle, start_handle, end_handle);
-    } else  {
-        console_printf("invalid 'uuid' parameter\n");
-        help_cmd_uuid("uuid");
-        return rc;
-    }
-    if (rc != 0) {
-        console_printf("error discovering characteristics; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_disc_dsc_help(void)
-{
-    console_printf("Available disc dsc commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available disc dsc params: \n");
-    help_cmd_conn_start_end();
-}
-
-static int
-cmd_disc_dsc(int argc, char **argv)
-{
-    uint16_t start_handle;
-    uint16_t conn_handle;
-    uint16_t end_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_disc_dsc_help();
-        return 0;
-    }
-
-    rc = cmd_parse_conn_start_end(&conn_handle, &start_handle, &end_handle);
-    if (rc != 0) {
-        console_printf("invalid 'conn start end' parameter\n");
-        help_cmd_conn_start_end();
-        return rc;
-    }
-
-    rc = bletiny_disc_all_dscs(conn_handle, start_handle, end_handle);
-    if (rc != 0) {
-        console_printf("error discovering descriptors; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_disc_svc_help(void)
-{
-    console_printf("Available disc svc commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available disc svc params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uuid("uuid");
-}
-
-static int
-cmd_disc_svc(int argc, char **argv)
-{
-    ble_uuid_any_t uuid;
-    int conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_disc_svc_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    rc = parse_arg_uuid("uuid", &uuid);
-    if (rc == 0) {
-        rc = bletiny_disc_svc_by_uuid(conn_handle, &uuid.u);
-    } else if (rc == ENOENT) {
-        rc = bletiny_disc_svcs(conn_handle);
-    } else  {
-        console_printf("invalid 'uuid' parameter\n");
-        help_cmd_uuid("uuid");
-        return rc;
-    }
-
-    if (rc != 0) {
-        console_printf("error discovering services; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_disc_full_help(void)
-{
-    console_printf("Available disc full commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available disc full params: \n");
-    help_cmd_uint16("conn");
-}
-
-static int
-cmd_disc_full(int argc, char **argv)
-{
-    int conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_disc_full_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    rc = bletiny_disc_full(conn_handle);
-    if (rc != 0) {
-        console_printf("error discovering all; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static struct cmd_entry cmd_disc_entries[];
-
-static int
-cmd_disc_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available disc commands:\n");
-    for (i = 0; cmd_disc_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_disc_entries[i].name);
-    }
-    return 0;
-}
-
-static struct cmd_entry cmd_disc_entries[] = {
-    { "chr", cmd_disc_chr },
-    { "dsc", cmd_disc_dsc },
-    { "svc", cmd_disc_svc },
-    { "full", cmd_disc_full },
-    { "help", cmd_disc_help },
-    { NULL, NULL }
-};
-
-static int
-cmd_disc(int argc, char **argv)
-{
-    int rc;
-
-    rc = cmd_exec(cmd_disc_entries, argc, argv);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $find                                                                     *
- *****************************************************************************/
-
-static void
-bletiny_find_inc_svcs_help(void)
-{
-    console_printf("Available find inc svcs commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available find inc svcs params: \n");
-    help_cmd_conn_start_end();
-}
-
-static int
-cmd_find_inc_svcs(int argc, char **argv)
-{
-    uint16_t start_handle;
-    uint16_t conn_handle;
-    uint16_t end_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_find_inc_svcs_help();
-        return 0;
-    }
-
-    rc = cmd_parse_conn_start_end(&conn_handle, &start_handle, &end_handle);
-    if (rc != 0) {
-        console_printf("invalid 'conn start end' parameter\n");
-        help_cmd_conn_start_end();
-        return rc;
-    }
-
-    rc = bletiny_find_inc_svcs(conn_handle, start_handle, end_handle);
-    if (rc != 0) {
-        console_printf("error finding included services; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static const struct cmd_entry cmd_find_entries[];
-
-static int
-cmd_find_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available find commands:\n");
-    for (i = 0; cmd_find_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_find_entries[i].name);
-    }
-    return 0;
-}
-
-static const struct cmd_entry cmd_find_entries[] = {
-    { "inc_svcs", cmd_find_inc_svcs },
-    { "help", cmd_find_help },
-    { NULL, NULL }
-};
-
-static int
-cmd_find(int argc, char **argv)
-{
-    int rc;
-
-    rc = cmd_exec(cmd_find_entries, argc, argv);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $l2cap                                                                    *
- *****************************************************************************/
-
-static void
-bletiny_l2cap_update_help(void)
-{
-    console_printf("Available l2cap update commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available l2cap update params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16_dflt("itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN);
-    help_cmd_uint16_dflt("itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX);
-    help_cmd_uint16_dflt("latency", 0);
-    help_cmd_uint16_dflt("timeout", 0x0100);
-}
-
-static int
-cmd_l2cap_update(int argc, char **argv)
-{
-    struct ble_l2cap_sig_update_params params;
-    uint16_t conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_l2cap_update_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    params.itvl_min = parse_arg_uint16_dflt(
-        "itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_min' parameter\n");
-        help_cmd_uint16_dflt("itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN);
-        return rc;
-    }
-
-    params.itvl_max = parse_arg_uint16_dflt(
-        "itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_max' parameter\n");
-        help_cmd_uint16_dflt("itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX);
-        return rc;
-    }
-
-    params.slave_latency = parse_arg_uint16_dflt("latency", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'latency' parameter\n");
-        help_cmd_uint16_dflt("latency", 0);
-        return rc;
-    }
-
-    params.timeout_multiplier = parse_arg_uint16_dflt("timeout", 0x0100, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'timeout' parameter\n");
-        help_cmd_uint16_dflt("timeout", 0x0100);
-        return rc;
-    }
-
-    rc = bletiny_l2cap_update(conn_handle, &params);
-    if (rc != 0) {
-        console_printf("error txing l2cap update; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_l2cap_create_srv_help(void)
-{
-    console_printf("Available l2cap create_srv commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available l2cap create_srv params: \n");
-    help_cmd_uint16("psm");
-    help_cmd_uint16("mtu");
-}
-
-static int
-cmd_l2cap_create_srv(int argc, char **argv)
-{
-    uint16_t psm = 0;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-            bletiny_l2cap_create_srv_help();
-        return 0;
-    }
-
-    psm = parse_arg_uint16("psm", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'psm' parameter\n");
-        help_cmd_uint16("psm");
-        return rc;
-    }
-
-    rc = bletiny_l2cap_create_srv(psm);
-    if (rc) {
-        console_printf("Server create error: 0x%02x", rc);
-    }
-
-    return 0;
-}
-
-static void
-bletiny_l2cap_connect_help(void)
-{
-    console_printf("Available l2cap connect commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available l2cap connect params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16("psm");
-}
-
-static int
-cmd_l2cap_connect(int argc, char **argv)
-{
-    uint16_t conn = 0;
-    uint16_t psm = 0;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-            bletiny_l2cap_connect_help();
-        return 0;
-    }
-
-    conn = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    psm = parse_arg_uint16("psm", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'psm' parameter\n");
-        help_cmd_uint16("psm");
-        return rc;
-    }
-
-    return bletiny_l2cap_connect(conn, psm);
-}
-
-static void
-bletiny_l2cap_disconnect_help(void)
-{
-    console_printf("Available l2cap disconnect commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available l2cap disconnect params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16("idx");
-    console_printf("\n Use 'b show coc' to get those parameters \n");
-}
-
-static int
-cmd_l2cap_disconnect(int argc, char **argv)
-{
-    uint16_t conn;
-    uint16_t idx;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_l2cap_disconnect_help();
-        return 0;
-    }
-
-    conn = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    idx = parse_arg_uint16("idx", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'idx' parameter\n");
-        help_cmd_uint16("idx");
-        return rc;
-    }
-
-    return bletiny_l2cap_disconnect(conn, idx);
-}
-
-static void
-bletiny_l2cap_send_help(void)
-{
-    console_printf("Available l2cap send commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available l2cap disconnect params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16("idx");
-    help_cmd_uint16("bytes");
-    console_printf("\n Use 'b show coc' to get conn and idx parameters.\n");
-    console_printf("bytes stands for number of bytes to send .\n");
-}
-
-static int
-cmd_l2cap_send(int argc, char **argv)
-{
-    uint16_t conn;
-    uint16_t idx;
-    uint16_t bytes;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_l2cap_send_help();
-        return 0;
-    }
-    conn = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-       console_printf("invalid 'conn' parameter\n");
-       help_cmd_uint16("conn");
-       return rc;
-    }
-
-    idx = parse_arg_uint16("idx", &rc);
-    if (rc != 0) {
-       console_printf("invalid 'idx' parameter\n");
-       help_cmd_uint16("idx");
-       return rc;
-    }
-
-    bytes = parse_arg_uint16("bytes", &rc);
-    if (rc != 0) {
-       console_printf("invalid 'bytes' parameter\n");
-       help_cmd_uint16("bytes");
-       return rc;
-    }
-
-    return bletiny_l2cap_send(conn, idx, bytes);
-}
-
-static const struct cmd_entry cmd_l2cap_entries[];
-
-static int
-cmd_l2cap_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available l2cap commands:\n");
-    for (i = 0; cmd_l2cap_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_l2cap_entries[i].name);
-    }
-    return 0;
-}
-
-static const struct cmd_entry cmd_l2cap_entries[] = {
-    { "update", cmd_l2cap_update },
-    { "create_srv", cmd_l2cap_create_srv },
-    { "connect", cmd_l2cap_connect },
-    { "disconnect", cmd_l2cap_disconnect },
-    { "send", cmd_l2cap_send },
-    { "help", cmd_l2cap_help },
-    { NULL, NULL }
-};
-
-static int
-cmd_l2cap(int argc, char **argv)
-{
-    int rc;
-
-    rc = cmd_exec(cmd_l2cap_entries, argc, argv);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $mtu                                                                      *
- *****************************************************************************/
-
-static void
-bletiny_mtu_help(void)
-{
-    console_printf("Available mtu commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available mtu params: \n");
-    help_cmd_uint16("conn");
-}
-
-static int
-cmd_mtu(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_mtu_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    rc = bletiny_exchange_mtu(conn_handle);
-    if (rc != 0) {
-        console_printf("error exchanging mtu; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $read                                                                     *
- *****************************************************************************/
-
-#define CMD_READ_MAX_ATTRS  8
-
-static void
-bletiny_read_help(void)
-{
-    console_printf("Available read commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available read params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_long("long");
-    help_cmd_uint16("attr");
-    help_cmd_uuid("uuid");
-    help_cmd_uint16("start");
-    help_cmd_uint16("end");
-    help_cmd_uint16("offset");
-}
-
-static int
-cmd_read(int argc, char **argv)
-{
-    static uint16_t attr_handles[CMD_READ_MAX_ATTRS];
-    uint16_t conn_handle;
-    uint16_t start;
-    uint16_t end;
-    uint16_t offset;
-    ble_uuid_any_t uuid;
-    uint8_t num_attr_handles;
-    int is_uuid;
-    int is_long;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_read_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    is_long = parse_arg_long("long", &rc);
-    if (rc == ENOENT) {
-        is_long = 0;
-    } else if (rc != 0) {
-        console_printf("invalid 'long' parameter\n");
-        help_cmd_long("long");
-        return rc;
-    }
-
-    for (num_attr_handles = 0;
-         num_attr_handles < CMD_READ_MAX_ATTRS;
-         num_attr_handles++) {
-
-        attr_handles[num_attr_handles] = parse_arg_uint16("attr", &rc);
-        if (rc == ENOENT) {
-            break;
-        } else if (rc != 0) {
-            console_printf("invalid 'attr' parameter\n");
-            help_cmd_uint16("attr");
-            return rc;
-        }
-    }
-
-    rc = parse_arg_uuid("uuid", &uuid);
-    if (rc == ENOENT) {
-        is_uuid = 0;
-    } else if (rc == 0) {
-        is_uuid = 1;
-    } else {
-        console_printf("invalid 'uuid' parameter\n");
-        help_cmd_uuid("uuid");
-        return rc;
-    }
-
-    start = parse_arg_uint16("start", &rc);
-    if (rc == ENOENT) {
-        start = 0;
-    } else if (rc != 0) {
-        console_printf("invalid 'start' parameter\n");
-        help_cmd_uint16("start");
-        return rc;
-    }
-
-    end = parse_arg_uint16("end", &rc);
-    if (rc == ENOENT) {
-        end = 0;
-    } else if (rc != 0) {
-        console_printf("invalid 'end' parameter\n");
-        help_cmd_uint16("end");
-        return rc;
-    }
-
-    offset = parse_arg_uint16("offset", &rc);
-    if (rc == ENOENT) {
-        offset = 0;
-    } else if (rc != 0) {
-        console_printf("invalid 'offset' parameter\n");
-        help_cmd_uint16("offset");
-        return rc;
-    }
-
-    if (num_attr_handles == 1) {
-        if (is_long) {
-            rc = bletiny_read_long(conn_handle, attr_handles[0], offset);
-        } else {
-            rc = bletiny_read(conn_handle, attr_handles[0]);
-        }
-    } else if (num_attr_handles > 1) {
-        rc = bletiny_read_mult(conn_handle, attr_handles, num_attr_handles);
-    } else if (is_uuid) {
-        if (start == 0 || end == 0) {
-            rc = EINVAL;
-        } else {
-            rc = bletiny_read_by_uuid(conn_handle, start, end, &uuid.u);
-        }
-    } else {
-        rc = EINVAL;
-    }
-
-    if (rc != 0) {
-        console_printf("error reading characteristic; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $rssi                                                                     *
- *****************************************************************************/
-
-static void
-bletiny_rssi_help(void)
-{
-    console_printf("Available rssi commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available rssi params: \n");
-    help_cmd_uint16("conn");
-}
-
-static int
-cmd_rssi(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    int8_t rssi;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_rssi_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    rc = bletiny_rssi(conn_handle, &rssi);
-    if (rc != 0) {
-        console_printf("error reading rssi; rc=%d\n", rc);
-        return rc;
-    }
-
-    console_printf("conn=%d rssi=%d\n", conn_handle, rssi);
-
-    return 0;
-}
-
-/*****************************************************************************
- * $scan                                                                     *
- *****************************************************************************/
-
-static struct kv_pair cmd_scan_filt_policies[] = {
-    { "no_wl", BLE_HCI_SCAN_FILT_NO_WL },
-    { "use_wl", BLE_HCI_SCAN_FILT_USE_WL },
-    { "no_wl_inita", BLE_HCI_SCAN_FILT_NO_WL_INITA },
-    { "use_wl_inita", BLE_HCI_SCAN_FILT_USE_WL_INITA },
-    { NULL }
-};
-
-static void
-bletiny_scan_help(void)
-{
-    console_printf("Available scan commands: \n");
-    console_printf("\thelp\n");
-    console_printf("\tcancel\n");
-    console_printf("Available scan params: \n");
-    help_cmd_long_bounds_dflt("dur", 1, INT32_MAX, BLE_HS_FOREVER);
-    help_cmd_bool_dflt("ltd", 0);
-    help_cmd_bool_dflt("passive", 0);
-    help_cmd_uint16_dflt("itvl", 0);
-    help_cmd_uint16_dflt("window", 0);
-    help_cmd_kv_dflt("filt", cmd_scan_filt_policies,
-                     BLE_HCI_SCAN_FILT_NO_WL);
-    help_cmd_uint16_dflt("nodups", 0);
-    help_cmd_kv_dflt("own_addr_type", cmd_own_addr_types,
-                     BLE_OWN_ADDR_PUBLIC);
-}
-
-static int
-cmd_scan(int argc, char **argv)
-{
-    struct ble_gap_disc_params params;
-    int32_t duration_ms;
-    uint8_t own_addr_type;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_scan_help();
-        return 0;
-    }
-
-    if (argc > 1 && strcmp(argv[1], "cancel") == 0) {
-        rc = bletiny_scan_cancel();
-        if (rc != 0) {
-            console_printf("connection cancel fail: %d\n", rc);
-            return rc;
-        }
-
-        return 0;
-    }
-
-    duration_ms = parse_arg_long_bounds_default("dur", 1, INT32_MAX,
-                                                BLE_HS_FOREVER, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'dur' parameter\n");
-        help_cmd_long_bounds_dflt("dur", 1, INT32_MAX, BLE_HS_FOREVER);
-        return rc;
-    }
-
-    params.limited = parse_arg_bool_default("ltd", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'ltd' parameter\n");
-        help_cmd_bool_dflt("ltd", 0);
-        return rc;
-    }
-
-    params.passive = parse_arg_bool_default("passive", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'passive' parameter\n");
-        help_cmd_bool_dflt("passive", 0);
-        return rc;
-    }
-
-    params.itvl = parse_arg_uint16_dflt("itvl", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl' parameter\n");
-        help_cmd_uint16_dflt("itvl", 0);
-        return rc;
-    }
-
-    params.window = parse_arg_uint16_dflt("window", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'window' parameter\n");
-        help_cmd_uint16_dflt("window", 0);
-        return rc;
-    }
-
-    params.filter_policy = parse_arg_kv_default(
-        "filt", cmd_scan_filt_policies, BLE_HCI_SCAN_FILT_NO_WL, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'filt' parameter\n");
-        help_cmd_kv_dflt("filt", cmd_scan_filt_policies,
-                         BLE_HCI_SCAN_FILT_NO_WL);
-        return rc;
-    }
-
-    params.filter_duplicates = parse_arg_bool_default("nodups", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'nodups' parameter\n");
-        help_cmd_uint16_dflt("nodups", 0);
-        return rc;
-    }
-
-    own_addr_type = parse_arg_kv_default("own_addr_type", cmd_own_addr_types,
-                                         BLE_OWN_ADDR_PUBLIC, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'own_addr_type' parameter\n");
-        help_cmd_kv_dflt("own_addr_type", cmd_own_addr_types,
-                         BLE_OWN_ADDR_PUBLIC);
-        return rc;
-    }
-
-    rc = bletiny_scan(own_addr_type, duration_ms, &params);
-    if (rc != 0) {
-        console_printf("error scanning; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $show                                                                     *
- *****************************************************************************/
-
-static int
-cmd_show_addr(int argc, char **argv)
-{
-    uint8_t id_addr[6];
-    int rc;
-
-    console_printf("public_id_addr=");
-    rc = ble_hs_id_copy_addr(BLE_ADDR_PUBLIC, id_addr, NULL);
-    if (rc == 0) {
-        print_addr(id_addr);
-    } else {
-        console_printf("none");
-    }
-
-    console_printf(" random_id_addr=");
-    rc = ble_hs_id_copy_addr(BLE_ADDR_RANDOM, id_addr, NULL);
-    if (rc == 0) {
-        print_addr(id_addr);
-    } else {
-        console_printf("none");
-    }
-    console_printf("\n");
-
-    return 0;
-}
-
-static int
-cmd_show_chr(int argc, char **argv)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_svc *svc;
-    int i;
-
-    for (i = 0; i < bletiny_num_conns; i++) {
-        conn = bletiny_conns + i;
-
-        console_printf("CONNECTION: handle=%d\n", conn->handle);
-
-        SLIST_FOREACH(svc, &conn->svcs, next) {
-            cmd_print_svc(svc);
-        }
-    }
-
-    return 0;
-}
-
-static int
-cmd_show_conn(int argc, char **argv)
-{
-    struct ble_gap_conn_desc conn_desc;
-    struct bletiny_conn *conn;
-    int rc;
-    int i;
-
-    for (i = 0; i < bletiny_num_conns; i++) {
-        conn = bletiny_conns + i;
-
-        rc = ble_gap_conn_find(conn->handle, &conn_desc);
-        if (rc == 0) {
-            print_conn_desc(&conn_desc);
-        }
-    }
-
-    return 0;
-}
-
-static int
-cmd_show_coc(int argc, char **argv)
-{
-    struct bletiny_conn *conn = NULL;
-    struct bletiny_l2cap_coc *coc;
-    int i, j;
-
-    for (i = 0; i < bletiny_num_conns; i++) {
-        conn = bletiny_conns + i;
-        if (!conn) {
-            break;
-        }
-
-        if (SLIST_EMPTY(&conn->coc_list)) {
-            continue;
-        }
-
-        console_printf("conn_handle: 0x%04x\n", conn->handle);
-        j = 0;
-        SLIST_FOREACH(coc, &conn->coc_list, next) {
-            console_printf("    idx: %i, chan pointer = %p\n", j++, coc->chan);
-        }
-    }
-
-    return 0;
-}
-
-static struct cmd_entry cmd_show_entries[];
-
-static int
-cmd_show_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available show commands:\n");
-    for (i = 0; cmd_show_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_show_entries[i].name);
-    }
-    return 0;
-}
-
-static struct cmd_entry cmd_show_entries[] = {
-    { "addr", cmd_show_addr },
-    { "chr", cmd_show_chr },
-    { "conn", cmd_show_conn },
-    { "coc", cmd_show_coc },
-    { "help", cmd_show_help },
-    { NULL, NULL }
-};
-
-static int
-cmd_show(int argc, char **argv)
-{
-    int rc;
-
-    rc = cmd_exec(cmd_show_entries, argc, argv);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $sec                                                                      *
- *****************************************************************************/
-
-static void
-bletiny_sec_pair_help(void)
-{
-    console_printf("Available sec pair commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available sec pair params: \n");
-    help_cmd_uint16("conn");
-}
-
-static int
-cmd_sec_pair(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_sec_pair_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    rc = bletiny_sec_pair(conn_handle);
-    if (rc != 0) {
-        console_printf("error initiating pairing; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_sec_start_help(void)
-{
-    console_printf("Available sec start commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available sec start params: \n");
-    help_cmd_uint16("conn");
-}
-
-static int
-cmd_sec_start(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_sec_start_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    rc = bletiny_sec_start(conn_handle);
-    if (rc != 0) {
-        console_printf("error starting security; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_sec_enc_help(void)
-{
-    console_printf("Available sec enc commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available sec enc params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint64("rand");
-    help_cmd_bool("auth");
-    help_cmd_byte_stream_exact_length("ltk", 16);
-}
-
-static int
-cmd_sec_enc(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    uint16_t ediv;
-    uint64_t rand_val;
-    uint8_t ltk[16];
-    int rc;
-    int auth;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_sec_enc_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    ediv = parse_arg_uint16("ediv", &rc);
-    if (rc == ENOENT) {
-        rc = bletiny_sec_restart(conn_handle, NULL, 0, 0, 0);
-    } else {
-        rand_val = parse_arg_uint64("rand", &rc);
-        if (rc != 0) {
-            console_printf("invalid 'rand' parameter\n");
-            help_cmd_uint64("rand");
-            return rc;
-        }
-
-        auth = parse_arg_bool("auth", &rc);
-        if (rc != 0) {
-            console_printf("invalid 'auth' parameter\n");
-            help_cmd_bool("auth");
-            return rc;
-        }
-
-        rc = parse_arg_byte_stream_exact_length("ltk", ltk, 16);
-        if (rc != 0) {
-            console_printf("invalid 'ltk' parameter\n");
-            help_cmd_byte_stream_exact_length("ltk", 16);
-            return rc;
-        }
-
-        rc = bletiny_sec_restart(conn_handle, ltk, ediv, rand_val, auth);
-    }
-
-    if (rc != 0) {
-        console_printf("error initiating encryption; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static struct cmd_entry cmd_sec_entries[];
-
-static int
-cmd_sec_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available sec commands:\n");
-    for (i = 0; cmd_sec_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_sec_entries[i].name);
-    }
-    return 0;
-}
-
-static struct cmd_entry cmd_sec_entries[] = {
-    { "pair", cmd_sec_pair },
-    { "start", cmd_sec_start },
-    { "enc", cmd_sec_enc },
-    { "help", cmd_sec_help },
-    { NULL }
-};
-
-static int
-cmd_sec(int argc, char **argv)
-{
-    int rc;
-
-    rc = cmd_exec(cmd_sec_entries, argc, argv);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $set                                                                      *
- *****************************************************************************/
-
-#define CMD_ADV_DATA_MAX_UUIDS16                8
-#define CMD_ADV_DATA_MAX_UUIDS32                8
-#define CMD_ADV_DATA_MAX_UUIDS128               2
-#define CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS       8
-#define CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN    BLE_HS_ADV_MAX_FIELD_SZ
-#define CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN    BLE_HS_ADV_MAX_FIELD_SZ
-#define CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN   BLE_HS_ADV_MAX_FIELD_SZ
-#define CMD_ADV_DATA_URI_MAX_LEN                BLE_HS_ADV_MAX_FIELD_SZ
-#define CMD_ADV_DATA_MFG_DATA_MAX_LEN           BLE_HS_ADV_MAX_FIELD_SZ
-
-static void
-bletiny_set_adv_data_help(void)
-{
-    console_printf("Available set adv_data params: \n");
-    help_cmd_long_bounds("flags", 0, UINT8_MAX);
-    help_cmd_uint16("uuid16");
-    help_cmd_long("uuids16_is_complete");
-    help_cmd_uint32("uuid32");
-    help_cmd_long("uuids32_is_complete");
-    help_cmd_byte_stream_exact_length("uuid128", 16);
-    help_cmd_long("uuids128_is_complete");
-    help_cmd_long_bounds("tx_pwr_lvl", INT8_MIN, INT8_MAX);
-    help_cmd_byte_stream_exact_length("slave_itvl_range",
-                                      BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
-    help_cmd_byte_stream("svc_data_uuid16");
-    help_cmd_byte_stream_exact_length("public_tgt_addr",
-                                      BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
-    help_cmd_uint16("appearance");
-    help_cmd_extract("name");
-    help_cmd_uint16("adv_itvl");
-    help_cmd_byte_stream("svc_data_uuid32");
-    help_cmd_byte_stream("svc_data_uuid128");
-    help_cmd_byte_stream("uri");
-    help_cmd_byte_stream("mfg_data");
-}
-
-static int
-cmd_set_adv_data(void)
-{
-    static bssnz_t ble_uuid16_t uuids16[CMD_ADV_DATA_MAX_UUIDS16];
-    static bssnz_t ble_uuid32_t uuids32[CMD_ADV_DATA_MAX_UUIDS32];
-    static bssnz_t ble_uuid128_t uuids128[CMD_ADV_DATA_MAX_UUIDS128];
-    static bssnz_t uint8_t
-        public_tgt_addrs[CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS]
-                        [BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN];
-    static bssnz_t uint8_t slave_itvl_range[BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN];
-    static bssnz_t uint8_t
-        svc_data_uuid16[CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN];
-    static bssnz_t uint8_t
-        svc_data_uuid32[CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN];
-    static bssnz_t uint8_t
-        svc_data_uuid128[CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN];
-    static bssnz_t uint8_t uri[CMD_ADV_DATA_URI_MAX_LEN];
-    static bssnz_t uint8_t mfg_data[CMD_ADV_DATA_MFG_DATA_MAX_LEN];
-    struct ble_hs_adv_fields adv_fields;
-    uint32_t uuid32;
-    uint16_t uuid16;
-    uint8_t uuid128[16];
-    uint8_t public_tgt_addr[BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN];
-    uint8_t eddystone_url_body_len;
-    uint8_t eddystone_url_suffix;
-    uint8_t eddystone_url_scheme;
-    char eddystone_url_body[BLE_EDDYSTONE_URL_MAX_LEN];
-    char *eddystone_url_full;
-    int svc_data_uuid16_len;
-    int svc_data_uuid32_len;
-    int svc_data_uuid128_len;
-    int uri_len;
-    int mfg_data_len;
-    int tmp;
-    int rc;
-
-    memset(&adv_fields, 0, sizeof adv_fields);
-
-    tmp = parse_arg_long_bounds("flags", 0, UINT8_MAX, &rc);
-    if (rc == 0) {
-        adv_fields.flags = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'flags' parameter\n");
-        help_cmd_long_bounds("flags", 0, UINT8_MAX);
-        return rc;
-    }
-
-    while (1) {
-        uuid16 = parse_arg_uint16("uuid16", &rc);
-        if (rc == 0) {
-            if (adv_fields.num_uuids16 >= CMD_ADV_DATA_MAX_UUIDS16) {
-                console_printf("invalid 'uuid16' parameter\n");
-                help_cmd_uint16("uuid16");
-                return EINVAL;
-            }
-            uuids16[adv_fields.num_uuids16] = (ble_uuid16_t) BLE_UUID16_INIT(uuid16);
-            adv_fields.num_uuids16++;
-        } else if (rc == ENOENT) {
-            break;
-        } else {
-            console_printf("invalid 'uuid16' parameter\n");
-            help_cmd_uint16("uuid16");
-            return rc;
-        }
-    }
-    if (adv_fields.num_uuids16 > 0) {
-        adv_fields.uuids16 = uuids16;
-    }
-
-    tmp = parse_arg_long("uuids16_is_complete", &rc);
-    if (rc == 0) {
-        adv_fields.uuids16_is_complete = !!tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'uuids16_is_complete' parameter\n");
-        help_cmd_long("uuids16_is_complete");
-        return rc;
-    }
-
-    while (1) {
-        uuid32 = parse_arg_uint32("uuid32", &rc);
-        if (rc == 0) {
-            if (adv_fields.num_uuids32 >= CMD_ADV_DATA_MAX_UUIDS32) {
-                console_printf("invalid 'uuid32' parameter\n");
-                help_cmd_uint32("uuid32");
-                return EINVAL;
-            }
-            uuids32[adv_fields.num_uuids32] = (ble_uuid32_t) BLE_UUID32_INIT(uuid32);
-            adv_fields.num_uuids32++;
-        } else if (rc == ENOENT) {
-            break;
-        } else {
-            console_printf("invalid 'uuid32' parameter\n");
-            help_cmd_uint32("uuid32");
-            return rc;
-        }
-    }
-    if (adv_fields.num_uuids32 > 0) {
-        adv_fields.uuids32 = uuids32;
-    }
-
-    tmp = parse_arg_long("uuids32_is_complete", &rc);
-    if (rc == 0) {
-        adv_fields.uuids32_is_complete = !!tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'uuids32_is_complete' parameter\n");
-        help_cmd_long("uuids32_is_complete");
-        return rc;
-    }
-
-    while (1) {
-        rc = parse_arg_byte_stream_exact_length("uuid128", uuid128, 16);
-        if (rc == 0) {
-            if (adv_fields.num_uuids128 >= CMD_ADV_DATA_MAX_UUIDS128) {
-                console_printf("invalid 'uuid128' parameter\n");
-                help_cmd_byte_stream_exact_length("uuid128", 16);
-                return EINVAL;
-            }
-            ble_uuid_init_from_buf((ble_uuid_any_t *) &uuids128[adv_fields.num_uuids128],
-                                   uuid128, 16);
-            adv_fields.num_uuids128++;
-        } else if (rc == ENOENT) {
-            break;
-        } else {
-            console_printf("invalid 'uuid128' parameter\n");
-            help_cmd_byte_stream_exact_length("uuid128", 16);
-            return rc;
-        }
-    }
-    if (adv_fields.num_uuids128 > 0) {
-        adv_fields.uuids128 = uuids128;
-    }
-
-    tmp = parse_arg_long("uuids128_is_complete", &rc);
-    if (rc == 0) {
-        adv_fields.uuids128_is_complete = !!tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'uuids128_is_complete' parameter\n");
-        help_cmd_long("uuids128_is_complete");
-        return rc;
-    }
-
-    adv_fields.name = (uint8_t *)parse_arg_extract("name");
-    if (adv_fields.name != NULL) {
-        adv_fields.name_len = strlen((char *)adv_fields.name);
-    }
-
-    tmp = parse_arg_long_bounds("tx_pwr_lvl", INT8_MIN, INT8_MAX, &rc);
-    if (rc == 0) {
-        adv_fields.tx_pwr_lvl = tmp;
-        adv_fields.tx_pwr_lvl_is_present = 1;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'tx_pwr_lvl' parameter\n");
-        help_cmd_long_bounds("tx_pwr_lvl", INT8_MIN, INT8_MAX);
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream_exact_length("slave_itvl_range",
-                                            slave_itvl_range,
-                                            BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
-    if (rc == 0) {
-        adv_fields.slave_itvl_range = slave_itvl_range;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'slave_itvl_range' parameter\n");
-        help_cmd_byte_stream_exact_length("slave_itvl_range",
-                                          BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream("svc_data_uuid16",
-                               CMD_ADV_DATA_SVC_DATA_UUID16_MAX_LEN,
-                               svc_data_uuid16, &svc_data_uuid16_len);
-    if (rc == 0) {
-        adv_fields.svc_data_uuid16 = svc_data_uuid16;
-        adv_fields.svc_data_uuid16_len = svc_data_uuid16_len;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'svc_data_uuid16' parameter\n");
-        help_cmd_byte_stream("svc_data_uuid16");
-        return rc;
-    }
-
-    while (1) {
-        rc = parse_arg_byte_stream_exact_length(
-            "public_tgt_addr", public_tgt_addr,
-            BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
-        if (rc == 0) {
-            if (adv_fields.num_public_tgt_addrs >=
-                CMD_ADV_DATA_MAX_PUBLIC_TGT_ADDRS) {
-
-                console_printf("invalid 'public_tgt_addr' parameter\n");
-                help_cmd_byte_stream_exact_length("public_tgt_addr",
-                                          BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
-                return EINVAL;
-            }
-            memcpy(public_tgt_addrs[adv_fields.num_public_tgt_addrs],
-                   public_tgt_addr, BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
-            adv_fields.num_public_tgt_addrs++;
-        } else if (rc == ENOENT) {
-            break;
-        } else {
-            console_printf("invalid 'public_tgt_addr' parameter\n");
-            help_cmd_byte_stream_exact_length("public_tgt_addr",
-                                          BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN);
-            return rc;
-        }
-    }
-    if (adv_fields.num_public_tgt_addrs > 0) {
-        adv_fields.public_tgt_addr = (void *)public_tgt_addrs;
-    }
-
-    adv_fields.appearance = parse_arg_uint16("appearance", &rc);
-    if (rc == 0) {
-        adv_fields.appearance_is_present = 1;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'appearance' parameter\n");
-        help_cmd_uint16("appearance");
-        return rc;
-    }
-
-    adv_fields.adv_itvl = parse_arg_uint16("adv_itvl", &rc);
-    if (rc == 0) {
-        adv_fields.adv_itvl_is_present = 1;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'adv_itvl' parameter\n");
-        help_cmd_uint16("adv_itvl");
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream("svc_data_uuid32",
-                               CMD_ADV_DATA_SVC_DATA_UUID32_MAX_LEN,
-                               svc_data_uuid32, &svc_data_uuid32_len);
-    if (rc == 0) {
-        adv_fields.svc_data_uuid32 = svc_data_uuid32;
-        adv_fields.svc_data_uuid32_len = svc_data_uuid32_len;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'svc_data_uuid32' parameter\n");
-        help_cmd_byte_stream("svc_data_uuid32");
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream("svc_data_uuid128",
-                               CMD_ADV_DATA_SVC_DATA_UUID128_MAX_LEN,
-                               svc_data_uuid128, &svc_data_uuid128_len);
-    if (rc == 0) {
-        adv_fields.svc_data_uuid128 = svc_data_uuid128;
-        adv_fields.svc_data_uuid128_len = svc_data_uuid128_len;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'svc_data_uuid128' parameter\n");
-        help_cmd_byte_stream("svc_data_uuid128");
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream("uri", CMD_ADV_DATA_URI_MAX_LEN, uri, &uri_len);
-    if (rc == 0) {
-        adv_fields.uri = uri;
-        adv_fields.uri_len = uri_len;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'uri' parameter\n");
-        help_cmd_byte_stream("uri");
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream("mfg_data", CMD_ADV_DATA_MFG_DATA_MAX_LEN,
-                               mfg_data, &mfg_data_len);
-    if (rc == 0) {
-        adv_fields.mfg_data = mfg_data;
-        adv_fields.mfg_data_len = mfg_data_len;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'mfg_data' parameter\n");
-        help_cmd_byte_stream("mfg_data");
-        return rc;
-    }
-
-    eddystone_url_full = parse_arg_extract("eddystone_url");
-    if (eddystone_url_full != NULL) {
-        rc = cmd_parse_eddystone_url(eddystone_url_full, &eddystone_url_scheme,
-                                     eddystone_url_body,
-                                     &eddystone_url_body_len,
-                                     &eddystone_url_suffix);
-        if (rc != 0) {
-            return rc;
-        }
-
-        rc = ble_eddystone_set_adv_data_url(&adv_fields, eddystone_url_scheme,
-                                            eddystone_url_body,
-                                            eddystone_url_body_len,
-                                            eddystone_url_suffix);
-    } else {
-        rc = bletiny_set_adv_data(&adv_fields);
-    }
-    if (rc != 0) {
-        console_printf("error setting advertisement data; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_set_sm_data_help(void)
-{
-    console_printf("Available set sm_data params: \n");
-    help_cmd_bool("oob_flag");
-    help_cmd_bool("mitm_flag");
-    help_cmd_uint8("io_capabilities");
-    help_cmd_uint8("our_key_dist");
-    help_cmd_uint8("their_key_dist");
-    help_cmd_bool("bonding");
-    help_cmd_bool("sc");
-}
-
-static int
-cmd_set_sm_data(void)
-{
-    uint8_t tmp;
-    int good;
-    int rc;
-
-    good = 0;
-
-    tmp = parse_arg_bool("oob_flag", &rc);
-    if (rc == 0) {
-        ble_hs_cfg.sm_oob_data_flag = tmp;
-        good++;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'oob_flag' parameter\n");
-        help_cmd_bool("oob_flag");
-        return rc;
-    }
-
-    tmp = parse_arg_bool("mitm_flag", &rc);
-    if (rc == 0) {
-        good++;
-        ble_hs_cfg.sm_mitm = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'mitm_flag' parameter\n");
-        help_cmd_bool("mitm_flag");
-        return rc;
-    }
-
-    tmp = parse_arg_uint8("io_capabilities", &rc);
-    if (rc == 0) {
-        good++;
-        ble_hs_cfg.sm_io_cap = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'io_capabilities' parameter\n");
-        help_cmd_uint8("io_capabilities");
-        return rc;
-    }
-
-    tmp = parse_arg_uint8("our_key_dist", &rc);
-    if (rc == 0) {
-        good++;
-        ble_hs_cfg.sm_our_key_dist = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'our_key_dist' parameter\n");
-        help_cmd_uint8("our_key_dist");
-        return rc;
-    }
-
-    tmp = parse_arg_uint8("their_key_dist", &rc);
-    if (rc == 0) {
-        good++;
-        ble_hs_cfg.sm_their_key_dist = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'their_key_dist' parameter\n");
-        help_cmd_uint8("their_key_dist");
-        return rc;
-    }
-
-    tmp = parse_arg_bool("bonding", &rc);
-    if (rc == 0) {
-        good++;
-        ble_hs_cfg.sm_bonding = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'bonding' parameter\n");
-        help_cmd_bool("bonding");
-        return rc;
-    }
-
-    tmp = parse_arg_bool("sc", &rc);
-    if (rc == 0) {
-        good++;
-        ble_hs_cfg.sm_sc = tmp;
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'sc' parameter\n");
-        help_cmd_bool("sc");
-        return rc;
-    }
-
-    if (!good) {
-        console_printf("Error: no valid settings specified\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-static struct kv_pair cmd_set_addr_types[] = {
-    { "public",         BLE_ADDR_PUBLIC },
-    { "random",         BLE_ADDR_RANDOM },
-    { NULL }
-};
-
-static void
-bletiny_set_addr_help(void)
-{
-    console_printf("Available set addr params: \n");
-    help_cmd_kv_dflt("addr_type", cmd_set_addr_types, BLE_ADDR_PUBLIC);
-    help_cmd_byte_stream_exact_length("addr", 6);
-}
-
-static int
-cmd_set_addr(void)
-{
-    uint8_t addr[6];
-    int addr_type;
-    int rc;
-
-    addr_type = parse_arg_kv_default("addr_type", cmd_set_addr_types,
-                                     BLE_ADDR_PUBLIC, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'addr_type' parameter\n");
-        help_cmd_kv_dflt("addr_type", cmd_set_addr_types, BLE_ADDR_PUBLIC);
-        return rc;
-    }
-
-    rc = parse_arg_mac("addr", addr);
-    if (rc != 0) {
-        console_printf("invalid 'addr' parameter\n");
-        help_cmd_byte_stream_exact_length("addr", 6);
-        return rc;
-    }
-
-    switch (addr_type) {
-    case BLE_ADDR_PUBLIC:
-        /* We shouldn't be writing to the controller's address (g_dev_addr).
-         * There is no standard way to set the local public address, so this is
-         * our only option at the moment.
-         */
-        memcpy(g_dev_addr, addr, 6);
-        ble_hs_id_set_pub(g_dev_addr);
-        break;
-
-    case BLE_ADDR_RANDOM:
-        rc = ble_hs_id_set_rnd(addr);
-        if (rc != 0) {
-            return rc;
-        }
-        break;
-
-    default:
-        assert(0);
-        return BLE_HS_EUNKNOWN;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_set_help(void)
-{
-    console_printf("Available set commands: \n");
-    console_printf("\thelp\n");
-    console_printf("\tadv_data\n");
-    console_printf("\tsm_data\n");
-    console_printf("\taddr\n");
-    console_printf("Available set params: \n");
-    help_cmd_uint16("mtu");
-    help_cmd_byte_stream_exact_length("irk", 16);
-}
-
-static int
-cmd_set(int argc, char **argv)
-{
-    uint16_t mtu;
-    uint8_t irk[16];
-    int good;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_set_help();
-        bletiny_set_adv_data_help();
-        bletiny_set_sm_data_help();
-        bletiny_set_addr_help();
-        return 0;
-    }
-
-    if (argc > 1 && strcmp(argv[1], "adv_data") == 0) {
-        rc = cmd_set_adv_data();
-        return rc;
-    }
-
-    if (argc > 1 && strcmp(argv[1], "sm_data") == 0) {
-        rc = cmd_set_sm_data();
-        return rc;
-    }
-
-    good = 0;
-
-    rc = parse_arg_find_idx("addr");
-    if (rc != -1) {
-        rc = cmd_set_addr();
-        if (rc != 0) {
-            return rc;
-        }
-
-        good = 1;
-    }
-
-    mtu = parse_arg_uint16("mtu", &rc);
-    if (rc == 0) {
-        rc = ble_att_set_preferred_mtu(mtu);
-        if (rc == 0) {
-            good = 1;
-        }
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'mtu' parameter\n");
-        help_cmd_uint16("mtu");
-        return rc;
-    }
-
-    rc = parse_arg_byte_stream_exact_length("irk", irk, 16);
-    if (rc == 0) {
-        good = 1;
-        ble_hs_pvcy_set_our_irk(irk);
-    } else if (rc != ENOENT) {
-        console_printf("invalid 'irk' parameter\n");
-        help_cmd_byte_stream_exact_length("irk", 16);
-        return rc;
-    }
-
-    if (!good) {
-        console_printf("Error: no valid settings specified\n");
-        return -1;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $terminate                                                                *
- *****************************************************************************/
-
-static void
-bletiny_term_help(void)
-{
-    console_printf("Available term commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available term params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint8_dflt("reason", BLE_ERR_REM_USER_CONN_TERM);
-}
-
-static int
-cmd_term(int argc, char **argv)
-{
-    uint16_t conn_handle;
-    uint8_t reason;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_term_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    reason = parse_arg_uint8_dflt("reason", BLE_ERR_REM_USER_CONN_TERM, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'reason' parameter\n");
-        help_cmd_uint8_dflt("reason", BLE_ERR_REM_USER_CONN_TERM);
-        return rc;
-    }
-
-    rc = bletiny_term_conn(conn_handle, reason);
-    if (rc != 0) {
-        console_printf("error terminating connection; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $update connection parameters                                             *
- *****************************************************************************/
-
-static void
-bletiny_update_help(void)
-{
-    console_printf("Available update commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available update params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16_dflt("itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN);
-    help_cmd_uint16_dflt("itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX);
-    help_cmd_uint16_dflt("latency", 0);
-    help_cmd_uint16_dflt("timeout", 0x0100);
-    help_cmd_uint16_dflt("min_ce_len", 0x0010);
-    help_cmd_uint16_dflt("max_ce_len", 0x0300);
-}
-
-static int
-cmd_update(int argc, char **argv)
-{
-    struct ble_gap_upd_params params;
-    uint16_t conn_handle;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_update_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    params.itvl_min = parse_arg_uint16_dflt(
-        "itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_min' parameter\n");
-        help_cmd_uint16_dflt("itvl_min", BLE_GAP_INITIAL_CONN_ITVL_MIN);
-        return rc;
-    }
-
-    params.itvl_max = parse_arg_uint16_dflt(
-        "itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'itvl_max' parameter\n");
-        help_cmd_uint16_dflt("itvl_max", BLE_GAP_INITIAL_CONN_ITVL_MAX);
-        return rc;
-    }
-
-    params.latency = parse_arg_uint16_dflt("latency", 0, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'latency' parameter\n");
-        help_cmd_uint16_dflt("latency", 0);
-        return rc;
-    }
-
-    params.supervision_timeout = parse_arg_uint16_dflt("timeout", 0x0100, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'timeout' parameter\n");
-        help_cmd_uint16_dflt("timeout", 0x0100);
-        return rc;
-    }
-
-    params.min_ce_len = parse_arg_uint16_dflt("min_ce_len", 0x0010, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'min_ce_len' parameter\n");
-        help_cmd_uint16_dflt("min_ce_len", 0x0010);
-        return rc;
-    }
-
-    params.max_ce_len = parse_arg_uint16_dflt("max_ce_len", 0x0300, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'max_ce_len' parameter\n");
-        help_cmd_uint16_dflt("max_ce_len", 0x0300);
-        return rc;
-    }
-
-    rc = bletiny_update_conn(conn_handle, &params);
-    if (rc != 0) {
-        console_printf("error updating connection; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $white list                                                               *
- *****************************************************************************/
-
-#define CMD_WL_MAX_SZ   8
-
-static void
-bletiny_wl_help(void)
-{
-    console_printf("Available wl commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available wl params: \n");
-    console_printf("\tlist of:\n");
-    help_cmd_byte_stream_exact_length("addr", 6);
-    help_cmd_kv("addr_type", cmd_addr_type);
-}
-
-static int
-cmd_wl(int argc, char **argv)
-{
-    static ble_addr_t addrs[CMD_WL_MAX_SZ];
-    int addrs_cnt;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_wl_help();
-        return 0;
-    }
-
-    addrs_cnt = 0;
-    while (1) {
-        if (addrs_cnt >= CMD_WL_MAX_SZ) {
-            return EINVAL;
-        }
-
-        rc = parse_arg_mac("addr", addrs[addrs_cnt].val);
-        if (rc == ENOENT) {
-            break;
-        } else if (rc != 0) {
-            console_printf("invalid 'addr' parameter\n");
-            help_cmd_byte_stream_exact_length("addr", 6);
-            return rc;
-        }
-
-        addrs[addrs_cnt].type = parse_arg_kv("addr_type", cmd_addr_type, &rc);
-        if (rc != 0) {
-            console_printf("invalid 'addr' parameter\n");
-            help_cmd_kv("addr_type", cmd_addr_type);
-            return rc;
-        }
-
-        addrs_cnt++;
-    }
-
-    if (addrs_cnt == 0) {
-        return EINVAL;
-    }
-
-    bletiny_wl_set(addrs, addrs_cnt);
-
-    return 0;
-}
-
-/*****************************************************************************
- * $write                                                                    *
- *****************************************************************************/
-
-static void
-bletiny_write_help(void)
-{
-    console_printf("Available write commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available write params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_long("no_rsp");
-    help_cmd_long("long");
-    console_printf("\tlist of:\n");
-    help_cmd_long("attr");
-    help_cmd_byte_stream("value");
-    help_cmd_uint16("offset");
-}
-
-static int
-cmd_write(int argc, char **argv)
-{
-    struct ble_gatt_attr attrs[MYNEWT_VAL(BLE_GATT_WRITE_MAX_ATTRS)] = { { 0 } };
-    uint16_t attr_handle;
-    uint16_t conn_handle;
-    uint16_t offset;
-    int total_attr_len;
-    int num_attrs;
-    int attr_len;
-    int is_long;
-    int no_rsp;
-    int rc;
-    int i;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_write_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    no_rsp = parse_arg_long("no_rsp", &rc);
-    if (rc == ENOENT) {
-        no_rsp = 0;
-    } else if (rc != 0) {
-        console_printf("invalid 'no_rsp' parameter\n");
-        help_cmd_long("no_rsp");
-        return rc;
-    }
-
-    is_long = parse_arg_long("long", &rc);
-    if (rc == ENOENT) {
-        is_long = 0;
-    } else if (rc != 0) {
-        console_printf("invalid 'long' parameter\n");
-        help_cmd_long("long");
-        return rc;
-    }
-
-    total_attr_len = 0;
-    num_attrs = 0;
-    while (1) {
-        attr_handle = parse_arg_long("attr", &rc);
-        if (rc == ENOENT) {
-            break;
-        } else if (rc != 0) {
-            rc = -rc;
-            console_printf("invalid 'attr' parameter\n");
-            help_cmd_long("attr");
-            goto done;
-        }
-
-        rc = parse_arg_byte_stream("value", sizeof cmd_buf - total_attr_len,
-                                   cmd_buf + total_attr_len, &attr_len);
-        if (rc == ENOENT) {
-            break;
-        } else if (rc != 0) {
-            console_printf("invalid 'value' parameter\n");
-            help_cmd_byte_stream("value");
-            goto done;
-        }
-
-        offset = parse_arg_uint16("offset", &rc);
-        if (rc == ENOENT) {
-            offset = 0;
-        } else if (rc != 0) {
-            console_printf("invalid 'offset' parameter\n");
-            help_cmd_uint16("offset");
-            return rc;
-        }
-
-        if (num_attrs >= sizeof attrs / sizeof attrs[0]) {
-            rc = -EINVAL;
-            goto done;
-        }
-
-        attrs[num_attrs].handle = attr_handle;
-        attrs[num_attrs].offset = offset;
-        attrs[num_attrs].om = ble_hs_mbuf_from_flat(cmd_buf + total_attr_len,
-                                                    attr_len);
-        if (attrs[num_attrs].om == NULL) {
-            goto done;
-        }
-
-        total_attr_len += attr_len;
-        num_attrs++;
-    }
-
-    if (no_rsp) {
-        if (num_attrs != 1) {
-            rc = -EINVAL;
-            goto done;
-        }
-        rc = bletiny_write_no_rsp(conn_handle, attrs[0].handle, attrs[0].om);
-        attrs[0].om = NULL;
-    } else if (is_long) {
-        if (num_attrs != 1) {
-            rc = -EINVAL;
-            goto done;
-        }
-        rc = bletiny_write_long(conn_handle, attrs[0].handle,
-                                attrs[0].offset, attrs[0].om);
-        attrs[0].om = NULL;
-    } else if (num_attrs > 1) {
-        rc = bletiny_write_reliable(conn_handle, attrs, num_attrs);
-    } else if (num_attrs == 1) {
-        rc = bletiny_write(conn_handle, attrs[0].handle, attrs[0].om);
-        attrs[0].om = NULL;
-    } else {
-        rc = -EINVAL;
-    }
-
-done:
-    for (i = 0; i < sizeof attrs / sizeof attrs[0]; i++) {
-        os_mbuf_free_chain(attrs[i].om);
-    }
-
-    if (rc != 0) {
-        console_printf("error writing characteristic; rc=%d\n", rc);
-    }
-
-    return rc;
-}
-
-/*****************************************************************************
- * store                                                                     *
- *****************************************************************************/
-
-static struct kv_pair cmd_keystore_entry_type[] = {
-    { "msec",       BLE_STORE_OBJ_TYPE_PEER_SEC },
-    { "ssec",       BLE_STORE_OBJ_TYPE_OUR_SEC },
-    { "cccd",       BLE_STORE_OBJ_TYPE_CCCD },
-    { NULL }
-};
-
-static void
-bletiny_keystore_parse_keydata_help(void)
-{
-    console_printf("Available keystore parse keydata params: \n");
-    help_cmd_kv("type", cmd_keystore_entry_type);
-    help_cmd_kv("addr_type", cmd_addr_type);
-    help_cmd_byte_stream_exact_length("addr", 6);
-    help_cmd_uint16("ediv");
-    help_cmd_uint64("rand");
-}
-
-static int
-cmd_keystore_parse_keydata(int argc, char **argv, union ble_store_key *out,
-                           int *obj_type)
-{
-    int rc;
-
-    memset(out, 0, sizeof(*out));
-    *obj_type = parse_arg_kv("type", cmd_keystore_entry_type, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'type' parameter\n");
-        help_cmd_kv("type", cmd_keystore_entry_type);
-        return rc;
-    }
-
-    switch (*obj_type) {
-    case BLE_STORE_OBJ_TYPE_PEER_SEC:
-    case BLE_STORE_OBJ_TYPE_OUR_SEC:
-        out->sec.peer_addr.type = parse_arg_kv("addr_type", cmd_addr_type, &rc);
-        if (rc != 0) {
-            console_printf("invalid 'addr_type' parameter\n");
-            help_cmd_kv("addr_type", cmd_addr_type);
-            return rc;
-        }
-
-        rc = parse_arg_mac("addr", out->sec.peer_addr.val);
-        if (rc != 0) {
-            console_printf("invalid 'addr' parameter\n");
-            help_cmd_byte_stream_exact_length("addr", 6);
-            return rc;
-        }
-
-        out->sec.ediv = parse_arg_uint16("ediv", &rc);
-        if (rc != 0) {
-            console_printf("invalid 'ediv' parameter\n");
-            help_cmd_uint16("ediv");
-            return rc;
-        }
-
-        out->sec.rand_num = parse_arg_uint64("rand", &rc);
-        if (rc != 0) {
-            console_printf("invalid 'rand' parameter\n");
-            help_cmd_uint64("rand");
-            return rc;
-        }
-        return 0;
-
-    default:
-        return EINVAL;
-    }
-}
-
-static void
-bletiny_keystore_parse_valuedata_help(void)
-{
-    console_printf("Available keystore parse valuedata params: \n");
-    help_cmd_byte_stream_exact_length("ltk", 16);
-    help_cmd_byte_stream_exact_length("irk", 16);
-    help_cmd_byte_stream_exact_length("csrk", 16);
-}
-
-static int
-cmd_keystore_parse_valuedata(int argc, char **argv,
-                             int obj_type,
-                             union ble_store_key *key,
-                             union ble_store_value *out)
-{
-    int rc;
-    int valcnt = 0;
-    memset(out, 0, sizeof(*out));
-
-    switch (obj_type) {
-        case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        case BLE_STORE_OBJ_TYPE_OUR_SEC:
-            rc = parse_arg_byte_stream_exact_length("ltk", out->sec.ltk, 16);
-            if (rc == 0) {
-                out->sec.ltk_present = 1;
-                swap_in_place(out->sec.ltk, 16);
-                valcnt++;
-            } else if (rc != ENOENT) {
-                console_printf("invalid 'ltk' parameter\n");
-                help_cmd_byte_stream_exact_length("ltk", 16);
-                return rc;
-            }
-            rc = parse_arg_byte_stream_exact_length("irk", out->sec.irk, 16);
-            if (rc == 0) {
-                out->sec.irk_present = 1;
-                swap_in_place(out->sec.irk, 16);
-                valcnt++;
-            } else if (rc != ENOENT) {
-                console_printf("invalid 'irk' parameter\n");
-                help_cmd_byte_stream_exact_length("irk", 16);
-                return rc;
-            }
-            rc = parse_arg_byte_stream_exact_length("csrk", out->sec.csrk, 16);
-            if (rc == 0) {
-                out->sec.csrk_present = 1;
-                swap_in_place(out->sec.csrk, 16);
-                valcnt++;
-            } else if (rc != ENOENT) {
-                console_printf("invalid 'csrk' parameter\n");
-                help_cmd_byte_stream_exact_length("csrk", 16);
-                return rc;
-            }
-            out->sec.peer_addr = key->sec.peer_addr;
-            out->sec.ediv = key->sec.ediv;
-            out->sec.rand_num = key->sec.rand_num;
-            break;
-    }
-
-    if (valcnt) {
-        return 0;
-    }
-    return -1;
-}
-
-static void
-bletiny_keystore_add_help(void)
-{
-    console_printf("Available keystore add commands: \n");
-    console_printf("\thelp\n");
-    bletiny_keystore_parse_keydata_help();
-    bletiny_keystore_parse_valuedata_help();
-}
-
-static int
-cmd_keystore_add(int argc, char **argv)
-{
-    union ble_store_key key;
-    union ble_store_value value;
-    int obj_type;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_keystore_add_help();
-        return 0;
-    }
-
-    rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type);
-
-    if (rc) {
-        return rc;
-    }
-
-    rc = cmd_keystore_parse_valuedata(argc, argv, obj_type, &key, &value);
-
-    if (rc) {
-        return rc;
-    }
-
-    switch(obj_type) {
-        case BLE_STORE_OBJ_TYPE_PEER_SEC:
-            rc = ble_store_write_peer_sec(&value.sec);
-            break;
-        case BLE_STORE_OBJ_TYPE_OUR_SEC:
-            rc = ble_store_write_our_sec(&value.sec);
-            break;
-        case BLE_STORE_OBJ_TYPE_CCCD:
-            rc = ble_store_write_cccd(&value.cccd);
-            break;
-        default:
-            rc = ble_store_write(obj_type, &value);
-    }
-    return rc;
-}
-
-static void
-bletiny_keystore_del_help(void)
-{
-    console_printf("Available keystore del commands: \n");
-    console_printf("\thelp\n");
-    bletiny_keystore_parse_keydata_help();
-}
-
-static int
-cmd_keystore_del(int argc, char **argv)
-{
-    union ble_store_key key;
-    int obj_type;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_keystore_del_help();
-        return 0;
-    }
-
-    rc = cmd_keystore_parse_keydata(argc, argv, &key, &obj_type);
-
-    if (rc) {
-        return rc;
-    }
-    rc = ble_store_delete(obj_type, &key);
-    return rc;
-}
-
-static int
-cmd_keystore_iterator(int obj_type,
-                      union ble_store_value *val,
-                      void *cookie) {
-
-    switch (obj_type) {
-        case BLE_STORE_OBJ_TYPE_PEER_SEC:
-        case BLE_STORE_OBJ_TYPE_OUR_SEC:
-            console_printf("Key: ");
-            if (ble_addr_cmp(&val->sec.peer_addr, BLE_ADDR_ANY) == 0) {
-                console_printf("ediv=%u ", val->sec.ediv);
-                console_printf("ediv=%llu ", val->sec.rand_num);
-            } else {
-                console_printf("addr_type=%u ", val->sec.peer_addr.type);
-                print_addr(val->sec.peer_addr.val);
-            }
-            console_printf("\n");
-
-            if (val->sec.ltk_present) {
-                console_printf("    LTK: ");
-                print_bytes(val->sec.ltk, 16);
-                console_printf("\n");
-            }
-            if (val->sec.irk_present) {
-                console_printf("    IRK: ");
-                print_bytes(val->sec.irk, 16);
-                console_printf("\n");
-            }
-            if (val->sec.csrk_present) {
-                console_printf("    CSRK: ");
-                print_bytes(val->sec.csrk, 16);
-                console_printf("\n");
-            }
-            break;
-    }
-    return 0;
-}
-
-static void
-bletiny_keystore_show_help(void)
-{
-    console_printf("Available keystore show commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available keystore show params: \n");
-    help_cmd_kv("type", cmd_keystore_entry_type);
-}
-
-static int
-cmd_keystore_show(int argc, char **argv)
-{
-    int type;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_keystore_show_help();
-        return 0;
-    }
-
-    type = parse_arg_kv("type", cmd_keystore_entry_type, &rc);
-    if (rc != 0) {
-        console_printf("invalid 'type' parameter\n");
-        help_cmd_kv("type", cmd_keystore_entry_type);
-        return rc;
-    }
-
-    ble_store_iterate(type, &cmd_keystore_iterator, NULL);
-    return 0;
-}
-
-static struct cmd_entry cmd_keystore_entries[];
-
-static int
-cmd_keystore_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available keystore commands:\n");
-    for (i = 0; cmd_keystore_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_keystore_entries[i].name);
-    }
-    return 0;
-}
-
-static struct cmd_entry cmd_keystore_entries[] = {
-    { "add", cmd_keystore_add },
-    { "del", cmd_keystore_del },
-    { "show", cmd_keystore_show },
-    { "help", cmd_keystore_help },
-    { NULL, NULL }
-};
-
-static int
-cmd_keystore(int argc, char **argv)
-{
-    int rc;
-
-    rc = cmd_exec(cmd_keystore_entries, argc, argv);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $passkey                                                                  *
- *****************************************************************************/
-
-static void
-bletiny_passkey_help(void)
-{
-    console_printf("Available passkey commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available passkey params: \n");
-    help_cmd_uint16("conn");
-    help_cmd_uint16("action");
-    help_cmd_long_bounds("key", 0, 999999);
-    help_cmd_byte_stream_exact_length("oob", 16);
-    help_cmd_extract("yesno");
-}
-
-static int
-cmd_passkey(int argc, char **argv)
-{
-#if !NIMBLE_BLE_SM
-    return BLE_HS_ENOTSUP;
-#endif
-
-    uint16_t conn_handle;
-    struct ble_sm_io pk;
-    char *yesno;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_passkey_help();
-        return 0;
-    }
-
-    conn_handle = parse_arg_uint16("conn", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'conn' parameter\n");
-        help_cmd_uint16("conn");
-        return rc;
-    }
-
-    pk.action = parse_arg_uint16("action", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'action' parameter\n");
-        help_cmd_uint16("action");
-        return rc;
-    }
-
-    switch (pk.action) {
-        case BLE_SM_IOACT_INPUT:
-        case BLE_SM_IOACT_DISP:
-           /* passkey is 6 digit number */
-           pk.passkey = parse_arg_long_bounds("key", 0, 999999, &rc);
-           if (rc != 0) {
-               console_printf("invalid 'key' parameter\n");
-               help_cmd_long_bounds("key", 0, 999999);
-               return rc;
-           }
-           break;
-
-        case BLE_SM_IOACT_OOB:
-            rc = parse_arg_byte_stream_exact_length("oob", pk.oob, 16);
-            if (rc != 0) {
-                console_printf("invalid 'oob' parameter\n");
-                help_cmd_byte_stream_exact_length("oob", 16);
-                return rc;
-            }
-            break;
-
-        case BLE_SM_IOACT_NUMCMP:
-            yesno = parse_arg_extract("yesno");
-            if (yesno == NULL) {
-                console_printf("invalid 'yesno' parameter\n");
-                help_cmd_extract("yesno");
-                return EINVAL;
-            }
-
-            switch (yesno[0]) {
-            case 'y':
-            case 'Y':
-                pk.numcmp_accept = 1;
-                break;
-            case 'n':
-            case 'N':
-                pk.numcmp_accept = 0;
-                break;
-
-            default:
-                console_printf("invalid 'yesno' parameter\n");
-                help_cmd_extract("yesno");
-                return EINVAL;
-            }
-            break;
-
-       default:
-         console_printf("invalid passkey action action=%d\n", pk.action);
-         return EINVAL;
-    }
-
-    rc = ble_sm_inject_io(conn_handle, &pk);
-    if (rc != 0) {
-        console_printf("error providing passkey; rc=%d\n", rc);
-        return rc;
-    }
-
-    return 0;
-}
-
-/*****************************************************************************
- * $tx                                                                     *
- *                                                                         *
- * Command to transmit 'num' packets of size 'len' at rate 'r' to
- * handle 'h' Note that length must be <= 251. The rate is in msecs.
- *
- *****************************************************************************/
-
-static void
-bletiny_tx_help(void)
-{
-    console_printf("Available tx commands: \n");
-    console_printf("\thelp\n");
-    console_printf("Available tx params: \n");
-    help_cmd_uint16("r");
-    help_cmd_uint16("l");
-    help_cmd_uint16("n");
-    help_cmd_uint16("h");
-}
-
-static int
-cmd_tx(int argc, char **argv)
-{
-    int rc;
-    uint16_t rate;
-    uint16_t len;
-    uint16_t handle;
-    uint16_t num;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_tx_help();
-        return 0;
-    }
-
-    rate = parse_arg_uint16("r", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'r' parameter\n");
-        help_cmd_uint16("r");
-        return rc;
-    }
-
-    len = parse_arg_uint16("l", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'l' parameter\n");
-        help_cmd_uint16("l");
-        return rc;
-    }
-    if ((len > 251) || (len < 4)) {
-        console_printf("error: len must be between 4 and 251, inclusive");
-    }
-
-    num = parse_arg_uint16("n", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'n' parameter\n");
-        help_cmd_uint16("n");
-        return rc;
-    }
-
-    handle = parse_arg_uint16("h", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'h' parameter\n");
-        help_cmd_uint16("h");
-        return rc;
-    }
-
-    rc = bletiny_tx_start(handle, len, rate, num);
-    return rc;
-}
-
-static struct cmd_entry cmd_b_entries[];
-
-static int
-cmd_help(int argc, char **argv)
-{
-    int i;
-
-    console_printf("Available commands:\n");
-    for (i = 0; cmd_b_entries[i].name != NULL; i++) {
-        console_printf("\t%s\n", cmd_b_entries[i].name);
-    }
-    return 0;
-}
-
-/*****************************************************************************
- * $svcch                                                                    *
- *****************************************************************************/
-
-static void
-bletiny_svcchg_help(void)
-{
-    console_printf("Available svcchg params: \n");
-    help_cmd_uint16("start");
-    help_cmd_uint16("end");
-}
-
-static int
-cmd_svcchg(int argc, char **argv)
-{
-    uint16_t start;
-    uint16_t end;
-    int rc;
-
-    if (argc > 1 && strcmp(argv[1], "help") == 0) {
-        bletiny_svcchg_help();
-        return 0;
-    }
-
-    start = parse_arg_uint16("start", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'start' parameter\n");
-        help_cmd_uint16("start");
-        return rc;
-    }
-
-    end = parse_arg_uint16("end", &rc);
-    if (rc != 0) {
-        console_printf("invalid 'end' parameter\n");
-        help_cmd_uint16("end");
-        return rc;
-    }
-
-    ble_svc_gatt_changed(start, end);
-
-    return 0;
-}
-
-/*****************************************************************************
- * $init                                                                     *
- *****************************************************************************/
-
-static struct cmd_entry cmd_b_entries[] = {
-    { "adv",        cmd_adv },
-    { "conn",       cmd_conn },
-    { "chrup",      cmd_chrup },
-    { "datalen",    cmd_datalen },
-    { "disc",       cmd_disc },
-    { "find",       cmd_find },
-    { "help",       cmd_help },
-    { "l2cap",      cmd_l2cap },
-    { "mtu",        cmd_mtu },
-    { "passkey",    cmd_passkey },
-    { "read",       cmd_read },
-    { "rssi",       cmd_rssi },
-    { "scan",       cmd_scan },
-    { "show",       cmd_show },
-    { "sec",        cmd_sec },
-    { "set",        cmd_set },
-    { "store",      cmd_keystore },
-    { "term",       cmd_term },
-    { "update",     cmd_update },
-    { "tx",         cmd_tx },
-    { "wl",         cmd_wl },
-    { "write",      cmd_write },
-    { "svcchg",     cmd_svcchg },
-    { NULL, NULL }
-};
-
-static int
-cmd_b_exec(int argc, char **argv)
-{
-    int rc;
-
-    rc = parse_arg_all(argc - 1, argv + 1);
-    if (rc != 0) {
-        goto done;
-    }
-
-    rc = cmd_exec(cmd_b_entries, argc, argv);
-    if (rc != 0) {
-        console_printf("error; rc=%d\n", rc);
-        goto done;
-    }
-
-    rc = 0;
-
-done:
-    return rc;
-}
-
-int
-cmd_init(void)
-{
-    int rc;
-
-    rc = shell_cmd_register(&cmd_b);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
diff --git a/apps/bletiny/src/gatt_svr.c b/apps/bletiny/src/gatt_svr.c
deleted file mode 100644
index 936546ff0e..0000000000
--- a/apps/bletiny/src/gatt_svr.c
+++ /dev/null
@@ -1,597 +0,0 @@
-/*
- * 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 <string.h>
-#include "bsp/bsp.h"
-#include "console/console.h"
-#include "host/ble_hs.h"
-#include "host/ble_uuid.h"
-#include "bletiny.h"
-
-/* 0000xxxx-8c26-476f-89a7-a108033a69c7 */
-#define PTS_UUID_DECLARE(uuid16)                                \
-    ((const ble_uuid_t *) (&(ble_uuid128_t) BLE_UUID128_INIT(   \
-        0xc7, 0x69, 0x3a, 0x03, 0x08, 0xa1, 0xa7, 0x89,         \
-        0x6f, 0x47, 0x26, 0x8c, uuid16, uuid16 >> 8, 0x00, 0x00 \
-    )))
-
-#define  PTS_SVC                         0x0001
-#define  PTS_CHR_READ                    0x0002
-#define  PTS_CHR_WRITE                   0x0003
-#define  PTS_CHR_RELIABLE_WRITE          0x0004
-#define  PTS_CHR_WRITE_NO_RSP            0x0005
-#define  PTS_CHR_READ_WRITE              0x0006
-#define  PTS_CHR_READ_WRITE_ENC          0x0007
-#define  PTS_CHR_READ_WRITE_AUTHEN       0x0008
-#define  PTS_DSC_READ                    0x0009
-#define  PTS_DSC_WRITE                   0x000a
-#define  PTS_DSC_READ_WRITE              0x000b
-#define  PTS_DSC_READ_WRITE_ENC          0x000c
-#define  PTS_DSC_READ_WRITE_AUTHEN       0x000d
-
-#define  PTS_LONG_SVC                    0x0011
-#define  PTS_LONG_CHR_READ               0x0012
-#define  PTS_LONG_CHR_WRITE              0x0013
-#define  PTS_LONG_CHR_RELIABLE_WRITE     0x0014
-#define  PTS_LONG_CHR_READ_WRITE         0x0015
-#define  PTS_LONG_CHR_READ_WRITE_ALT     0x0016
-#define  PTS_LONG_CHR_READ_WRITE_ENC     0x0017
-#define  PTS_LONG_CHR_READ_WRITE_AUTHEN  0x0018
-#define  PTS_LONG_DSC_READ               0x0019
-#define  PTS_LONG_DSC_WRITE              0x001a
-#define  PTS_LONG_DSC_READ_WRITE         0x001b
-#define  PTS_LONG_DSC_READ_WRITE_ENC     0x001c
-#define  PTS_LONG_DSC_READ_WRITE_AUTHEN  0x001d
-
-/**
- * The vendor specific security test service consists of two characteristics:
- *     o random-number-generator: generates a random 32-bit number each time
- *       it is read.  This characteristic can only be read over an encrypted
- *       connection.
- *     o static-value: a single-byte characteristic that can always be read,
- *       but can only be written over an encrypted connection.
- */
-
-/* 59462f12-9543-9999-12c8-58b459a2712d */
-static const ble_uuid128_t gatt_svr_svc_sec_test_uuid =
-    BLE_UUID128_INIT(0x2d, 0x71, 0xa2, 0x59, 0xb4, 0x58, 0xc8, 0x12,
-                     0x99, 0x99, 0x43, 0x95, 0x12, 0x2f, 0x46, 0x59);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df6 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_rand_uuid =
-    BLE_UUID128_INIT(0xf6, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
-                     0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df7 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_static_uuid =
-    BLE_UUID128_INIT(0xf7, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
-                     0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-/* 5c3a659e-897e-45e1-b016-007107c96df8 */
-static const ble_uuid128_t gatt_svr_chr_sec_test_static_auth_uuid =
-    BLE_UUID128_INIT(0xf8, 0x6d, 0xc9, 0x07, 0x71, 0x00, 0x16, 0xb0,
-                     0xe1, 0x45, 0x7e, 0x89, 0x9e, 0x65, 0x3a, 0x5c);
-
-static uint8_t gatt_svr_sec_test_static_val;
-
-static uint8_t gatt_svr_pts_static_val;
-static uint8_t gatt_svr_pts_static_long_val[30];
-static uint8_t gatt_svr_pts_static_long_val_alt[30];
-
-static int
-gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt,
-                             void *arg);
-
-static int
-gatt_svr_access_test(uint16_t conn_handle, uint16_t attr_handle,
-                     struct ble_gatt_access_ctxt *ctxt,
-                     void *arg);
-
-static int
-gatt_svr_long_access_test(uint16_t conn_handle, uint16_t attr_handle,
-                                  struct ble_gatt_access_ctxt *ctxt,
-                                  void *arg);
-
-static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
-    {
-        /*** Service: PTS test. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = PTS_UUID_DECLARE(PTS_SVC),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_READ),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_READ,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_WRITE),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_RELIABLE_WRITE),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_RELIABLE_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_WRITE_NO_RSP),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE_NO_RSP,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_ENC),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC |
-                BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
-                .min_key_size = 16,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_CHR_READ_WRITE_AUTHEN),
-                .access_cb = gatt_svr_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_AUTHEN |
-                BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
-
-                .descriptors = (struct ble_gatt_dsc_def[]){ {
-                        .uuid = PTS_UUID_DECLARE(PTS_DSC_READ),
-                        .access_cb = gatt_svr_access_test,
-                        .att_flags = BLE_ATT_F_READ,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_DSC_WRITE),
-                        .access_cb = gatt_svr_access_test,
-                        .att_flags = BLE_ATT_F_WRITE,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_DSC_READ_WRITE),
-                        .access_cb = gatt_svr_access_test,
-                        .att_flags = BLE_ATT_F_READ | BLE_ATT_F_WRITE,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_DSC_READ_WRITE_ENC),
-                        .access_cb = gatt_svr_access_test,
-                        .att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_ENC |
-                        BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_ENC,
-                        .min_key_size = 16,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_DSC_READ_WRITE_AUTHEN),
-                        .access_cb = gatt_svr_access_test,
-                        .att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_AUTHEN |
-                        BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_AUTHEN,
-                    }, {
-                        0, /* No more descriptors in this characteristic. */
-                    } }
-            }, {
-                0, /* No more characteristics in this service. */
-            } },
-    },
-
-    {
-        /*** Service: PTS long test. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = PTS_UUID_DECLARE(PTS_LONG_SVC),
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_READ,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_WRITE),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_RELIABLE_WRITE),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_RELIABLE_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE_ALT),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE_ENC),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC |
-                BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
-                .min_key_size = 16,
-            }, {
-                .uuid = PTS_UUID_DECLARE(PTS_LONG_CHR_READ_WRITE_AUTHEN),
-                .access_cb = gatt_svr_long_access_test,
-                .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_AUTHEN |
-                BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_AUTHEN,
-
-                .descriptors = (struct ble_gatt_dsc_def[]){ {
-                        .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_READ),
-                        .access_cb = gatt_svr_long_access_test,
-                        .att_flags = BLE_ATT_F_READ,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_WRITE),
-                        .access_cb = gatt_svr_long_access_test,
-                        .att_flags = BLE_ATT_F_WRITE,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_READ_WRITE),
-                        .access_cb = gatt_svr_long_access_test,
-                        .att_flags = BLE_ATT_F_READ | BLE_ATT_F_WRITE,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_READ_WRITE_ENC),
-                        .access_cb = gatt_svr_long_access_test,
-                        .att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_ENC |
-                        BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_ENC,
-                        .min_key_size = 16,
-                    }, {
-                        .uuid = PTS_UUID_DECLARE(PTS_LONG_DSC_READ_WRITE_AUTHEN),
-                        .access_cb = gatt_svr_long_access_test,
-                        .att_flags = BLE_ATT_F_READ | BLE_ATT_F_READ_AUTHEN |
-                        BLE_ATT_F_WRITE | BLE_ATT_F_WRITE_AUTHEN,
-                    }, {
-                        0, /* No more descriptors in this characteristic. */
-                    } }
-            }, {
-                0, /* No more characteristics in this service. */
-            } },
-    },
-
-    {
-        /*** Service: Security test. */
-        .type = BLE_GATT_SVC_TYPE_PRIMARY,
-        .uuid = &gatt_svr_svc_sec_test_uuid.u,
-        .characteristics = (struct ble_gatt_chr_def[]) { {
-            /*** Characteristic: Random number generator. */
-            .uuid = &gatt_svr_chr_sec_test_rand_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_ENC,
-        }, {
-            /*** Characteristic: Static value. */
-            .uuid = &gatt_svr_chr_sec_test_static_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ |
-                     BLE_GATT_CHR_F_WRITE | BLE_GATT_CHR_F_WRITE_ENC,
-        }, {
-            /*** Characteristic: Static value. */
-            .uuid = &gatt_svr_chr_sec_test_static_auth_uuid.u,
-            .access_cb = gatt_svr_chr_access_sec_test,
-            .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_READ_AUTHEN,
-        }, {
-            0, /* No more characteristics in this service. */
-        } },
-    },
-
-    {
-        0, /* No more services. */
-    },
-};
-
-static int
-gatt_svr_chr_write(struct os_mbuf *om, uint16_t min_len, uint16_t max_len,
-                   void *dst, uint16_t *len)
-{
-    uint16_t om_len;
-    int rc;
-
-    om_len = OS_MBUF_PKTLEN(om);
-    if (om_len < min_len || om_len > max_len) {
-        return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
-    }
-
-    rc = ble_hs_mbuf_to_flat(om, dst, max_len, len);
-    if (rc != 0) {
-        return BLE_ATT_ERR_UNLIKELY;
-    }
-
-    return 0;
-}
-
-static int
-gatt_svr_chr_access_sec_test(uint16_t conn_handle, uint16_t attr_handle,
-                             struct ble_gatt_access_ctxt *ctxt,
-                             void *arg)
-{
-    const ble_uuid_t *uuid;
-    int rand_num;
-    int rc;
-
-    uuid = ctxt->chr->uuid;
-
-    /* Determine which characteristic is being accessed by examining its
-     * 128-bit UUID.
-     */
-
-    if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_rand_uuid.u) == 0) {
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-
-        /* Respond with a 32-bit random number. */
-        rand_num = rand();
-        rc = os_mbuf_append(ctxt->om, &rand_num, sizeof rand_num);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-    }
-
-    if (ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_uuid.u) == 0 ||
-        ble_uuid_cmp(uuid, &gatt_svr_chr_sec_test_static_auth_uuid.u) == 0) {
-        switch (ctxt->op) {
-        case BLE_GATT_ACCESS_OP_READ_CHR:
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_sec_test_static_val,
-                                sizeof gatt_svr_sec_test_static_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-        case BLE_GATT_ACCESS_OP_WRITE_CHR:
-            rc = gatt_svr_chr_write(ctxt->om,
-                                    sizeof gatt_svr_sec_test_static_val,
-                                    sizeof gatt_svr_sec_test_static_val,
-                                    &gatt_svr_sec_test_static_val, NULL);
-            return rc;
-
-        default:
-            assert(0);
-            return BLE_ATT_ERR_UNLIKELY;
-        }
-    }
-
-    /* Unknown characteristic; the nimble stack should not have called this
-     * function.
-     */
-    assert(0);
-    return BLE_ATT_ERR_UNLIKELY;
-}
-
-/* This method is used for PTS testing only, to extract 16 bit value
- * from 128 bit vendor specific UUID.
- */
-static uint16_t
-extract_uuid16_from_pts_uuid128(const ble_uuid_t *uuid)
-{
-    const uint8_t *u8ptr;
-    uint16_t uuid16;
-
-    u8ptr = BLE_UUID128(uuid)->value;
-    uuid16 = u8ptr[12];
-    uuid16 |= (uint16_t)u8ptr[13] << 8;
-    return uuid16;
-}
-
-static int
-gatt_svr_access_test(uint16_t conn_handle, uint16_t attr_handle,
-                     struct ble_gatt_access_ctxt *ctxt,
-                     void *arg)
-{
-    uint16_t uuid16;
-    int rc;
-
-    uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case PTS_CHR_READ:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val,
-                            sizeof gatt_svr_pts_static_val);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case PTS_CHR_WRITE:
-    case PTS_CHR_RELIABLE_WRITE:
-    case PTS_CHR_WRITE_NO_RSP:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_val,
-                                    &gatt_svr_pts_static_val, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val,
-                                sizeof gatt_svr_pts_static_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case PTS_CHR_READ_WRITE:
-    case PTS_CHR_READ_WRITE_ENC:
-    case PTS_CHR_READ_WRITE_AUTHEN:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_val,
-                                    &gatt_svr_pts_static_val, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val,
-                                sizeof gatt_svr_pts_static_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case PTS_DSC_READ:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val,
-                            sizeof gatt_svr_pts_static_val);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case PTS_DSC_WRITE:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC);
-        rc = gatt_svr_chr_write(ctxt->om,0,
-                                sizeof gatt_svr_pts_static_val,
-                                &gatt_svr_pts_static_val, NULL);
-        return rc;
-
-    case PTS_DSC_READ_WRITE:
-    case PTS_DSC_READ_WRITE_ENC:
-    case PTS_DSC_READ_WRITE_AUTHEN:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_val,
-                                    &gatt_svr_pts_static_val, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_val,
-                                sizeof gatt_svr_pts_static_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    default:
-        assert(0);
-        return BLE_ATT_ERR_UNLIKELY;
-    }
-}
-
-static int
-gatt_svr_long_access_test(uint16_t conn_handle, uint16_t attr_handle,
-                          struct ble_gatt_access_ctxt *ctxt,
-                          void *arg)
-{
-    uint16_t uuid16;
-    int rc;
-
-    uuid16 = extract_uuid16_from_pts_uuid128(ctxt->chr->uuid);
-    assert(uuid16 != 0);
-
-    switch (uuid16) {
-    case PTS_LONG_CHR_READ:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val,
-                            sizeof gatt_svr_pts_static_long_val);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case PTS_LONG_CHR_WRITE:
-    case PTS_LONG_CHR_RELIABLE_WRITE:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR);
-        rc = gatt_svr_chr_write(ctxt->om,0,
-                                sizeof gatt_svr_pts_static_long_val,
-                                &gatt_svr_pts_static_long_val, NULL);
-        return rc;
-
-    case PTS_LONG_CHR_READ_WRITE:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_long_val,
-                                    &gatt_svr_pts_static_long_val, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val,
-                                sizeof gatt_svr_pts_static_long_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case PTS_LONG_CHR_READ_WRITE_ALT:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_long_val_alt,
-                                    &gatt_svr_pts_static_long_val_alt, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val_alt,
-                                sizeof gatt_svr_pts_static_long_val_alt);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case PTS_LONG_CHR_READ_WRITE_ENC:
-    case PTS_LONG_CHR_READ_WRITE_AUTHEN:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_long_val,
-                                    &gatt_svr_pts_static_long_val, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val,
-                                sizeof gatt_svr_pts_static_long_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    case PTS_LONG_DSC_READ:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC);
-        rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val,
-                            sizeof gatt_svr_pts_static_long_val);
-        return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-
-    case PTS_LONG_DSC_WRITE:
-        assert(ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC);
-        rc = gatt_svr_chr_write(ctxt->om,0,
-                                sizeof gatt_svr_pts_static_long_val,
-                                &gatt_svr_pts_static_long_val, NULL);
-        return rc;
-
-    case PTS_LONG_DSC_READ_WRITE:
-    case PTS_LONG_DSC_READ_WRITE_ENC:
-    case PTS_LONG_DSC_READ_WRITE_AUTHEN:
-        if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_DSC) {
-            rc = gatt_svr_chr_write(ctxt->om,0,
-                                    sizeof gatt_svr_pts_static_long_val,
-                                    &gatt_svr_pts_static_long_val, NULL);
-            return rc;
-        } else if (ctxt->op == BLE_GATT_ACCESS_OP_READ_DSC) {
-            rc = os_mbuf_append(ctxt->om, &gatt_svr_pts_static_long_val,
-                                sizeof gatt_svr_pts_static_long_val);
-            return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
-        }
-
-    default:
-        assert(0);
-        return BLE_ATT_ERR_UNLIKELY;
-    }
-}
-
-void
-gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
-{
-    char buf[BLE_UUID_STR_LEN];
-
-    switch (ctxt->op) {
-    case BLE_GATT_REGISTER_OP_SVC:
-        BLETINY_LOG(DEBUG, "registered service %s with handle=%d\n",
-                    ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
-                    ctxt->svc.handle);
-        break;
-
-    case BLE_GATT_REGISTER_OP_CHR:
-        BLETINY_LOG(DEBUG, "registering characteristic %s with "
-                           "def_handle=%d val_handle=%d\n",
-                    ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
-                    ctxt->chr.def_handle,
-                    ctxt->chr.val_handle);
-        break;
-
-    case BLE_GATT_REGISTER_OP_DSC:
-        BLETINY_LOG(DEBUG, "registering descriptor %s with handle=%d\n",
-                    ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
-                    ctxt->dsc.handle);
-        break;
-
-    default:
-        assert(0);
-        break;
-    }
-}
-
-int
-gatt_svr_register(void)
-{
-    int rc;
-
-    rc = ble_gatts_register_svcs(gatt_svr_svcs, gatt_svr_register_cb, NULL);
-    return rc;
-}
-
-int
-gatt_svr_init(void)
-{
-    int rc;
-
-    rc = ble_gatts_count_cfg(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
-
-    rc = ble_gatts_add_svcs(gatt_svr_svcs);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
diff --git a/apps/bletiny/src/main.c b/apps/bletiny/src/main.c
deleted file mode 100755
index 25ba5b06e4..0000000000
--- a/apps/bletiny/src/main.c
+++ /dev/null
@@ -1,1954 +0,0 @@
-/*
- * 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 <string.h>
-#include <stdio.h>
-#include <errno.h>
-#include "syscfg/syscfg.h"
-#include "sysinit/sysinit.h"
-#include "bsp/bsp.h"
-#include "log/log.h"
-#include "stats/stats.h"
-#include "os/os.h"
-#include "bsp/bsp.h"
-#include "hal/hal_gpio.h"
-#include "console/console.h"
-#include "shell/shell.h"
-#include "bletiny.h"
-
-/* BLE */
-#include "nimble/ble.h"
-#include "nimble/nimble_opt.h"
-#include "nimble/ble_hci_trans.h"
-#include "controller/ble_ll.h"
-#include "host/ble_hs.h"
-#include "host/ble_hs_adv.h"
-#include "host/ble_uuid.h"
-#include "host/ble_att.h"
-#include "host/ble_gap.h"
-#include "host/ble_gatt.h"
-#include "host/ble_store.h"
-#include "host/ble_sm.h"
-
-/* RAM HCI transport. */
-#include "transport/ram/ble_hci_ram.h"
-
-/* Mandatory services. */
-#include "services/gap/ble_svc_gap.h"
-#include "services/gatt/ble_svc_gatt.h"
-
-/* XXX: An app should not include private headers from a library.  The bletiny
- * app uses some of nimble's internal details for logging.
- */
-#include "../src/ble_hs_conn_priv.h"
-#include "../src/ble_hs_atomic_priv.h"
-#include "../src/ble_hs_hci_priv.h"
-
-#if MYNEWT_VAL(BLE_ROLE_CENTRAL)
-#define BLETINY_MAX_SVCS               32
-#define BLETINY_MAX_CHRS               64
-#define BLETINY_MAX_DSCS               64
-#else
-#define BLETINY_MAX_SVCS               1
-#define BLETINY_MAX_CHRS               1
-#define BLETINY_MAX_DSCS               1
-#endif
-
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
-#define BLETINY_COC_MTU               (256)
-/* We use same pool for incoming and outgoing sdu */
-#define BLETINY_COC_BUF_COUNT         (3 * MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM))
-#endif
-
-struct log bletiny_log;
-
-bssnz_t struct bletiny_conn bletiny_conns[MYNEWT_VAL(BLE_MAX_CONNECTIONS)];
-int bletiny_num_conns;
-
-static void *bletiny_svc_mem;
-static struct os_mempool bletiny_svc_pool;
-
-static void *bletiny_chr_mem;
-static struct os_mempool bletiny_chr_pool;
-
-static void *bletiny_dsc_mem;
-static struct os_mempool bletiny_dsc_pool;
-
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM)
-static void *bletiny_coc_conn_mem;
-static struct os_mempool bletiny_coc_conn_pool;
-
-static void *bletiny_sdu_coc_mem;
-struct os_mbuf_pool sdu_os_mbuf_pool;
-static struct os_mempool sdu_coc_mbuf_mempool;
-#endif
-
-static struct os_callout bletiny_tx_timer;
-struct bletiny_tx_data_s
-{
-    uint16_t tx_num;
-    uint16_t tx_rate;
-    uint16_t tx_handle;
-    uint16_t tx_len;
-};
-static struct bletiny_tx_data_s bletiny_tx_data;
-int bletiny_full_disc_prev_chr_val;
-
-#define XSTR(s) STR(s)
-#ifndef STR
-#define STR(s) #s
-#endif
-
-
-#ifdef DEVICE_NAME
-#define BLETINY_AUTO_DEVICE_NAME    XSTR(DEVICE_NAME)
-#else
-#define BLETINY_AUTO_DEVICE_NAME    ""
-#endif
-
-static void
-bletiny_print_error(char *msg, uint16_t conn_handle,
-                    const struct ble_gatt_error *error)
-{
-    if (msg == NULL) {
-        msg = "ERROR";
-    }
-
-    console_printf("%s: conn_handle=%d status=%d att_handle=%d\n",
-                   msg, conn_handle, error->status, error->att_handle);
-}
-
-static void
-bletiny_print_adv_fields(const struct ble_hs_adv_fields *fields)
-{
-    uint8_t *u8p;
-    int i;
-
-    if (fields->flags != 0) {
-        console_printf("    flags=0x%02x:\n", fields->flags);
-
-        if (!(fields->flags & BLE_HS_ADV_F_DISC_LTD) &&
-                !(fields->flags & BLE_HS_ADV_F_DISC_GEN)) {
-                console_printf("        Non-discoverable mode\n");
-        }
-
-        if (fields->flags & BLE_HS_ADV_F_DISC_LTD) {
-                console_printf("        Limited discoverable mode\n");
-        }
-
-        if (fields->flags & BLE_HS_ADV_F_DISC_GEN) {
-                console_printf("        General discoverable mode\n");
-        }
-
-        if (fields->flags & BLE_HS_ADV_F_BREDR_UNSUP) {
-                console_printf("        BR/EDR not supported\n");
-        }
-    }
-
-    if (fields->uuids16 != NULL) {
-        console_printf("    uuids16(%scomplete)=",
-                       fields->uuids16_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids16; i++) {
-            print_uuid(&fields->uuids16[i].u);
-            console_printf(" ");
-        }
-        console_printf("\n");
-    }
-
-    if (fields->uuids32 != NULL) {
-        console_printf("    uuids32(%scomplete)=",
-                       fields->uuids32_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids32; i++) {
-            print_uuid(&fields->uuids32[i].u);
-            console_printf(" ");
-        }
-        console_printf("\n");
-    }
-
-    if (fields->uuids128 != NULL) {
-        console_printf("    uuids128(%scomplete)=",
-                       fields->uuids128_is_complete ? "" : "in");
-        for (i = 0; i < fields->num_uuids128; i++) {
-            print_uuid(&fields->uuids128[i].u);
-            console_printf(" ");
-        }
-        console_printf("\n");
-    }
-
-    if (fields->name != NULL) {
-        console_printf("    name(%scomplete)=",
-                       fields->name_is_complete ? "" : "in");
-        console_write((char *)fields->name, fields->name_len);
-        console_printf("\n");
-    }
-
-    if (fields->tx_pwr_lvl_is_present) {
-        console_printf("    tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
-    }
-
-    if (fields->slave_itvl_range != NULL) {
-        console_printf("    slave_itvl_range=");
-        print_bytes(fields->slave_itvl_range,
-                            BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
-        console_printf("\n");
-    }
-
-    if (fields->svc_data_uuid16 != NULL) {
-        console_printf("    svc_data_uuid16=");
-        print_bytes(fields->svc_data_uuid16,
-                            fields->svc_data_uuid16_len);
-        console_printf("\n");
-    }
-
-    if (fields->public_tgt_addr != NULL) {
-        console_printf("    public_tgt_addr=");
-        u8p = fields->public_tgt_addr;
-        for (i = 0; i < fields->num_public_tgt_addrs; i++) {
-            print_addr(u8p);
-            u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
-        }
-        console_printf("\n");
-    }
-
-    if (fields->appearance_is_present) {
-        console_printf("    appearance=0x%04x\n", fields->appearance);
-    }
-
-    if (fields->adv_itvl_is_present) {
-        console_printf("    adv_itvl=0x%04x\n", fields->adv_itvl);
-    }
-
-    if (fields->svc_data_uuid32 != NULL) {
-        console_printf("    svc_data_uuid32=");
-        print_bytes(fields->svc_data_uuid32,
-                             fields->svc_data_uuid32_len);
-        console_printf("\n");
-    }
-
-    if (fields->svc_data_uuid128 != NULL) {
-        console_printf("    svc_data_uuid128=");
-        print_bytes(fields->svc_data_uuid128,
-                            fields->svc_data_uuid128_len);
-        console_printf("\n");
-    }
-
-    if (fields->uri != NULL) {
-        console_printf("    uri=");
-        print_bytes(fields->uri, fields->uri_len);
-        console_printf("\n");
-    }
-
-    if (fields->mfg_data != NULL) {
-        console_printf("    mfg_data=");
-        print_bytes(fields->mfg_data, fields->mfg_data_len);
-        console_printf("\n");
-    }
-}
-
-static int
-bletiny_conn_find_idx(uint16_t handle)
-{
-    int i;
-
-    for (i = 0; i < bletiny_num_conns; i++) {
-        if (bletiny_conns[i].handle == handle) {
-            return i;
-        }
-    }
-
-    return -1;
-}
-
-static struct bletiny_conn *
-bletiny_conn_find(uint16_t handle)
-{
-    int idx;
-
-    idx = bletiny_conn_find_idx(handle);
-    if (idx == -1) {
-        return NULL;
-    } else {
-        return bletiny_conns + idx;
-    }
-}
-
-static struct bletiny_svc *
-bletiny_svc_find_prev(struct bletiny_conn *conn, uint16_t svc_start_handle)
-{
-    struct bletiny_svc *prev;
-    struct bletiny_svc *svc;
-
-    prev = NULL;
-    SLIST_FOREACH(svc, &conn->svcs, next) {
-        if (svc->svc.start_handle >= svc_start_handle) {
-            break;
-        }
-
-        prev = svc;
-    }
-
-    return prev;
-}
-
-static struct bletiny_svc *
-bletiny_svc_find(struct bletiny_conn *conn, uint16_t svc_start_handle,
-                 struct bletiny_svc **out_prev)
-{
-    struct bletiny_svc *prev;
-    struct bletiny_svc *svc;
-
-    prev = bletiny_svc_find_prev(conn, svc_start_handle);
-    if (prev == NULL) {
-        svc = SLIST_FIRST(&conn->svcs);
-    } else {
-        svc = SLIST_NEXT(prev, next);
-    }
-
-    if (svc != NULL && svc->svc.start_handle != svc_start_handle) {
-        svc = NULL;
-    }
-
-    if (out_prev != NULL) {
-        *out_prev = prev;
-    }
-    return svc;
-}
-
-static struct bletiny_svc *
-bletiny_svc_find_range(struct bletiny_conn *conn, uint16_t attr_handle)
-{
-    struct bletiny_svc *svc;
-
-    SLIST_FOREACH(svc, &conn->svcs, next) {
-        if (svc->svc.start_handle <= attr_handle &&
-            svc->svc.end_handle >= attr_handle) {
-
-            return svc;
-        }
-    }
-
-    return NULL;
-}
-
-static void
-bletiny_chr_delete(struct bletiny_chr *chr)
-{
-    struct bletiny_dsc *dsc;
-
-    while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) {
-        SLIST_REMOVE_HEAD(&chr->dscs, next);
-        os_memblock_put(&bletiny_dsc_pool, dsc);
-    }
-
-    os_memblock_put(&bletiny_chr_pool, chr);
-}
-
-static void
-bletiny_svc_delete(struct bletiny_svc *svc)
-{
-    struct bletiny_chr *chr;
-
-    while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) {
-        SLIST_REMOVE_HEAD(&svc->chrs, next);
-        bletiny_chr_delete(chr);
-    }
-
-    os_memblock_put(&bletiny_svc_pool, svc);
-}
-
-static struct bletiny_svc *
-bletiny_svc_add(uint16_t conn_handle, const struct ble_gatt_svc *gatt_svc)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_svc *prev;
-    struct bletiny_svc *svc;
-
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        BLETINY_LOG(DEBUG, "RECEIVED SERVICE FOR UNKNOWN CONNECTION; "
-                           "HANDLE=%d\n",
-                    conn_handle);
-        return NULL;
-    }
-
-    svc = bletiny_svc_find(conn, gatt_svc->start_handle, &prev);
-    if (svc != NULL) {
-        /* Service already discovered. */
-        return svc;
-    }
-
-    svc = os_memblock_get(&bletiny_svc_pool);
-    if (svc == NULL) {
-        BLETINY_LOG(DEBUG, "OOM WHILE DISCOVERING SERVICE\n");
-        return NULL;
-    }
-    memset(svc, 0, sizeof *svc);
-
-    svc->svc = *gatt_svc;
-    SLIST_INIT(&svc->chrs);
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&conn->svcs, svc, next);
-    } else {
-        SLIST_INSERT_AFTER(prev, svc, next);
-    }
-
-    return svc;
-}
-
-static struct bletiny_chr *
-bletiny_chr_find_prev(const struct bletiny_svc *svc, uint16_t chr_val_handle)
-{
-    struct bletiny_chr *prev;
-    struct bletiny_chr *chr;
-
-    prev = NULL;
-    SLIST_FOREACH(chr, &svc->chrs, next) {
-        if (chr->chr.val_handle >= chr_val_handle) {
-            break;
-        }
-
-        prev = chr;
-    }
-
-    return prev;
-}
-
-static struct bletiny_chr *
-bletiny_chr_find(const struct bletiny_svc *svc, uint16_t chr_val_handle,
-                 struct bletiny_chr **out_prev)
-{
-    struct bletiny_chr *prev;
-    struct bletiny_chr *chr;
-
-    prev = bletiny_chr_find_prev(svc, chr_val_handle);
-    if (prev == NULL) {
-        chr = SLIST_FIRST(&svc->chrs);
-    } else {
-        chr = SLIST_NEXT(prev, next);
-    }
-
-    if (chr != NULL && chr->chr.val_handle != chr_val_handle) {
-        chr = NULL;
-    }
-
-    if (out_prev != NULL) {
-        *out_prev = prev;
-    }
-    return chr;
-}
-
-static struct bletiny_chr *
-bletiny_chr_add(uint16_t conn_handle,  uint16_t svc_start_handle,
-                const struct ble_gatt_chr *gatt_chr)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_chr *prev;
-    struct bletiny_chr *chr;
-    struct bletiny_svc *svc;
-
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        BLETINY_LOG(DEBUG, "RECEIVED SERVICE FOR UNKNOWN CONNECTION; "
-                           "HANDLE=%d\n",
-                    conn_handle);
-        return NULL;
-    }
-
-    svc = bletiny_svc_find(conn, svc_start_handle, NULL);
-    if (svc == NULL) {
-        BLETINY_LOG(DEBUG, "CAN'T FIND SERVICE FOR DISCOVERED CHR; HANDLE=%d\n",
-                    conn_handle);
-        return NULL;
-    }
-
-    chr = bletiny_chr_find(svc, gatt_chr->val_handle, &prev);
-    if (chr != NULL) {
-        /* Characteristic already discovered. */
-        return chr;
-    }
-
-    chr = os_memblock_get(&bletiny_chr_pool);
-    if (chr == NULL) {
-        BLETINY_LOG(DEBUG, "OOM WHILE DISCOVERING CHARACTERISTIC\n");
-        return NULL;
-    }
-    memset(chr, 0, sizeof *chr);
-
-    chr->chr = *gatt_chr;
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&svc->chrs, chr, next);
-    } else {
-        SLIST_NEXT(prev, next) = chr;
-    }
-
-    return chr;
-}
-
-static struct bletiny_dsc *
-bletiny_dsc_find_prev(const struct bletiny_chr *chr, uint16_t dsc_handle)
-{
-    struct bletiny_dsc *prev;
-    struct bletiny_dsc *dsc;
-
-    prev = NULL;
-    SLIST_FOREACH(dsc, &chr->dscs, next) {
-        if (dsc->dsc.handle >= dsc_handle) {
-            break;
-        }
-
-        prev = dsc;
-    }
-
-    return prev;
-}
-
-static struct bletiny_dsc *
-bletiny_dsc_find(const struct bletiny_chr *chr, uint16_t dsc_handle,
-                 struct bletiny_dsc **out_prev)
-{
-    struct bletiny_dsc *prev;
-    struct bletiny_dsc *dsc;
-
-    prev = bletiny_dsc_find_prev(chr, dsc_handle);
-    if (prev == NULL) {
-        dsc = SLIST_FIRST(&chr->dscs);
-    } else {
-        dsc = SLIST_NEXT(prev, next);
-    }
-
-    if (dsc != NULL && dsc->dsc.handle != dsc_handle) {
-        dsc = NULL;
-    }
-
-    if (out_prev != NULL) {
-        *out_prev = prev;
-    }
-    return dsc;
-}
-
-static struct bletiny_dsc *
-bletiny_dsc_add(uint16_t conn_handle, uint16_t chr_val_handle,
-                const struct ble_gatt_dsc *gatt_dsc)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_dsc *prev;
-    struct bletiny_dsc *dsc;
-    struct bletiny_svc *svc;
-    struct bletiny_chr *chr;
-
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        BLETINY_LOG(DEBUG, "RECEIVED SERVICE FOR UNKNOWN CONNECTION; "
-                           "HANDLE=%d\n",
-                    conn_handle);
-        return NULL;
-    }
-
-    svc = bletiny_svc_find_range(conn, chr_val_handle);
-    if (svc == NULL) {
-        BLETINY_LOG(DEBUG, "CAN'T FIND SERVICE FOR DISCOVERED DSC; HANDLE=%d\n",
-                    conn_handle);
-        return NULL;
-    }
-
-    chr = bletiny_chr_find(svc, chr_val_handle, NULL);
-    if (chr == NULL) {
-        BLETINY_LOG(DEBUG, "CAN'T FIND CHARACTERISTIC FOR DISCOVERED DSC; "
-                           "HANDLE=%d\n",
-                    conn_handle);
-        return NULL;
-    }
-
-    dsc = bletiny_dsc_find(chr, gatt_dsc->handle, &prev);
-    if (dsc != NULL) {
-        /* Descriptor already discovered. */
-        return dsc;
-    }
-
-    dsc = os_memblock_get(&bletiny_dsc_pool);
-    if (dsc == NULL) {
-        console_printf("OOM WHILE DISCOVERING DESCRIPTOR\n");
-        return NULL;
-    }
-    memset(dsc, 0, sizeof *dsc);
-
-    dsc->dsc = *gatt_dsc;
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&chr->dscs, dsc, next);
-    } else {
-        SLIST_NEXT(prev, next) = dsc;
-    }
-
-    return dsc;
-}
-
-static struct bletiny_conn *
-bletiny_conn_add(struct ble_gap_conn_desc *desc)
-{
-    struct bletiny_conn *conn;
-
-    assert(bletiny_num_conns < MYNEWT_VAL(BLE_MAX_CONNECTIONS));
-
-    conn = bletiny_conns + bletiny_num_conns;
-    bletiny_num_conns++;
-
-    conn->handle = desc->conn_handle;
-    SLIST_INIT(&conn->svcs);
-    SLIST_INIT(&conn->coc_list);
-
-    return conn;
-}
-
-static void
-bletiny_conn_delete_idx(int idx)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_svc *svc;
-
-    assert(idx >= 0 && idx < bletiny_num_conns);
-
-    conn = bletiny_conns + idx;
-    while ((svc = SLIST_FIRST(&conn->svcs)) != NULL) {
-        SLIST_REMOVE_HEAD(&conn->svcs, next);
-        bletiny_svc_delete(svc);
-    }
-
-    /* This '#if' is not strictly necessary.  It is here to prevent a spurious
-     * warning from being reported.
-     */
-#if MYNEWT_VAL(BLE_MAX_CONNECTIONS) > 1
-    int i;
-    for (i = idx + 1; i < bletiny_num_conns; i++) {
-        bletiny_conns[i - 1] = bletiny_conns[i];
-    }
-#endif
-
-    bletiny_num_conns--;
-}
-
-static int
-bletiny_on_mtu(uint16_t conn_handle, const struct ble_gatt_error *error,
-               uint16_t mtu, void *arg)
-{
-    switch (error->status) {
-    case 0:
-        console_printf("mtu exchange complete: conn_handle=%d mtu=%d\n",
-                       conn_handle, mtu);
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_full_disc_complete(int rc)
-{
-    console_printf("full discovery complete; rc=%d\n", rc);
-    bletiny_full_disc_prev_chr_val = 0;
-}
-
-static void
-bletiny_disc_full_dscs(uint16_t conn_handle)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_chr *chr;
-    struct bletiny_svc *svc;
-    int rc;
-
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        BLETINY_LOG(DEBUG, "Failed to discover descriptors for conn=%d; "
-                           "not connected\n", conn_handle);
-        bletiny_full_disc_complete(BLE_HS_ENOTCONN);
-        return;
-    }
-
-    SLIST_FOREACH(svc, &conn->svcs, next) {
-        SLIST_FOREACH(chr, &svc->chrs, next) {
-            if (!chr_is_empty(svc, chr) &&
-                SLIST_EMPTY(&chr->dscs) &&
-                bletiny_full_disc_prev_chr_val <= chr->chr.def_handle) {
-
-                rc = bletiny_disc_all_dscs(conn_handle,
-                                           chr->chr.val_handle,
-                                           chr_end_handle(svc, chr));
-                if (rc != 0) {
-                    bletiny_full_disc_complete(rc);
-                }
-
-                bletiny_full_disc_prev_chr_val = chr->chr.val_handle;
-                return;
-            }
-        }
-    }
-
-    /* All descriptors discovered. */
-    bletiny_full_disc_complete(0);
-}
-
-static void
-bletiny_disc_full_chrs(uint16_t conn_handle)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_svc *svc;
-    int rc;
-
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        BLETINY_LOG(DEBUG, "Failed to discover characteristics for conn=%d; "
-                           "not connected\n", conn_handle);
-        bletiny_full_disc_complete(BLE_HS_ENOTCONN);
-        return;
-    }
-
-    SLIST_FOREACH(svc, &conn->svcs, next) {
-        if (!svc_is_empty(svc) && !svc->char_disc_sent) {
-            /* Since it might happen that service does not have characteristics
-             * for some reason, lets keep track on services for which we send
-             * characteristic discovery
-             */
-            svc->char_disc_sent = true;
-            rc = bletiny_disc_all_chrs(conn_handle, svc->svc.start_handle,
-                                       svc->svc.end_handle);
-            if (rc != 0) {
-                bletiny_full_disc_complete(rc);
-            }
-            return;
-        }
-    }
-
-    /* All characteristics discovered. */
-    bletiny_disc_full_dscs(conn_handle);
-}
-
-static int
-bletiny_on_disc_s(uint16_t conn_handle, const struct ble_gatt_error *error,
-                  const struct ble_gatt_svc *service, void *arg)
-{
-    switch (error->status) {
-    case 0:
-        bletiny_svc_add(conn_handle, service);
-        break;
-
-    case BLE_HS_EDONE:
-        console_printf("service discovery successful\n");
-        if (bletiny_full_disc_prev_chr_val > 0) {
-            bletiny_disc_full_chrs(conn_handle);
-        }
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-bletiny_on_disc_c(uint16_t conn_handle, const struct ble_gatt_error *error,
-                  const struct ble_gatt_chr *chr, void *arg)
-{
-    intptr_t svc_start_handle;
-
-    svc_start_handle = (intptr_t)arg;
-
-    switch (error->status) {
-    case 0:
-        bletiny_chr_add(conn_handle, svc_start_handle, chr);
-        break;
-
-    case BLE_HS_EDONE:
-        console_printf("characteristic discovery successful\n");
-        if (bletiny_full_disc_prev_chr_val > 0) {
-            bletiny_disc_full_chrs(conn_handle);
-        }
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-bletiny_on_disc_d(uint16_t conn_handle, const struct ble_gatt_error *error,
-                  uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
-                  void *arg)
-{
-    switch (error->status) {
-    case 0:
-        bletiny_dsc_add(conn_handle, chr_val_handle, dsc);
-        break;
-
-    case BLE_HS_EDONE:
-        console_printf("descriptor discovery successful\n");
-        if (bletiny_full_disc_prev_chr_val > 0) {
-            bletiny_disc_full_dscs(conn_handle);
-        }
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-bletiny_on_read(uint16_t conn_handle, const struct ble_gatt_error *error,
-                struct ble_gatt_attr *attr, void *arg)
-{
-    switch (error->status) {
-    case 0:
-        console_printf("characteristic read; conn_handle=%d "
-                       "attr_handle=%d len=%d value=", conn_handle,
-                       attr->handle, OS_MBUF_PKTLEN(attr->om));
-        print_mbuf(attr->om);
-        console_printf("\n");
-        break;
-
-    case BLE_HS_EDONE:
-        console_printf("characteristic read complete\n");
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-bletiny_on_write(uint16_t conn_handle, const struct ble_gatt_error *error,
-                 struct ble_gatt_attr *attr, void *arg)
-{
-    switch (error->status) {
-    case 0:
-        console_printf("characteristic write complete; conn_handle=%d "
-                       "attr_handle=%d\n", conn_handle, attr->handle);
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-bletiny_on_write_reliable(uint16_t conn_handle,
-                          const struct ble_gatt_error *error,
-                          struct ble_gatt_attr *attrs, uint8_t num_attrs,
-                          void *arg)
-{
-    int i;
-
-    switch (error->status) {
-    case 0:
-        console_printf("characteristic write reliable complete; "
-                       "conn_handle=%d", conn_handle);
-
-        for (i = 0; i < num_attrs; i++) {
-            console_printf(" attr_handle=%d len=%d value=", attrs[i].handle,
-                           OS_MBUF_PKTLEN(attrs[i].om));
-            print_mbuf(attrs[i].om);
-        }
-        console_printf("\n");
-        break;
-
-    default:
-        bletiny_print_error(NULL, conn_handle, error);
-        break;
-    }
-
-    return 0;
-}
-
-static int
-bletiny_gap_event(struct ble_gap_event *event, void *arg)
-{
-    struct ble_gap_conn_desc desc;
-    struct ble_hs_adv_fields fields;
-    int conn_idx;
-    int rc;
-
-    switch (event->type) {
-    case BLE_GAP_EVENT_CONNECT:
-        console_printf("connection %s; status=%d ",
-                       event->connect.status == 0 ? "established" : "failed",
-                       event->connect.status);
-
-        if (event->connect.status == 0) {
-            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
-            assert(rc == 0);
-            print_conn_desc(&desc);
-            bletiny_conn_add(&desc);
-        }
-        return 0;
-
-    case BLE_GAP_EVENT_DISCONNECT:
-        console_printf("disconnect; reason=%d ", event->disconnect.reason);
-        print_conn_desc(&event->disconnect.conn);
-
-        conn_idx = bletiny_conn_find_idx(event->disconnect.conn.conn_handle);
-        if (conn_idx != -1) {
-            bletiny_conn_delete_idx(conn_idx);
-        }
-        return 0;
-
-    case BLE_GAP_EVENT_DISC:
-        console_printf("received advertisement; event_type=%d rssi=%d "
-                       "addr_type=%d addr=", event->disc.event_type,
-                       event->disc.rssi, event->disc.addr.type);
-        print_addr(event->disc.addr.val);
-
-        /*
-         * There is no adv data to print in case of connectable
-         * directed advertising
-         */
-        if (event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_HD ||
-                event->disc.event_type == BLE_HCI_ADV_TYPE_ADV_DIRECT_IND_LD) {
-                console_printf("\nConnectable directed advertising event\n");
-                return 0;
-        }
-
-        console_printf(" length_data=%d data=",
-                               event->disc.length_data);
-        print_bytes(event->disc.data, event->disc.length_data);
-        console_printf(" fields:\n");
-        ble_hs_adv_parse_fields(&fields, event->disc.data,
-                                event->disc.length_data);
-        bletiny_print_adv_fields(&fields);
-        console_printf("\n");
-        return 0;
-
-    case BLE_GAP_EVENT_DISC_COMPLETE:
-        console_printf("scanning finished\n");
-        return 0;
-
-    case BLE_GAP_EVENT_ADV_COMPLETE:
-        console_printf("advertising complete.\n");
-        return 0;
-
-    case BLE_GAP_EVENT_CONN_CANCEL:
-        console_printf("connection procedure cancelled.\n");
-        return 0;
-
-    case BLE_GAP_EVENT_CONN_UPDATE:
-        console_printf("connection updated; status=%d ",
-                       event->conn_update.status);
-        rc = ble_gap_conn_find(event->conn_update.conn_handle, &desc);
-        assert(rc == 0);
-        print_conn_desc(&desc);
-        return 0;
-
-    case BLE_GAP_EVENT_CONN_UPDATE_REQ:
-        console_printf("connection update request\n");
-        *event->conn_update_req.self_params =
-            *event->conn_update_req.peer_params;
-        return 0;
-
-    case BLE_GAP_EVENT_PASSKEY_ACTION:
-        console_printf("passkey action event; action=%d",
-                       event->passkey.params.action);
-        if (event->passkey.params.action == BLE_SM_IOACT_NUMCMP) {
-            console_printf(" numcmp=%lu",
-                           (unsigned long)event->passkey.params.numcmp);
-        }
-        console_printf("\n");
-        return 0;
-
-    case BLE_GAP_EVENT_ENC_CHANGE:
-        console_printf("encryption change event; status=%d ",
-                       event->enc_change.status);
-        rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
-        assert(rc == 0);
-        print_conn_desc(&desc);
-        return 0;
-
-    case BLE_GAP_EVENT_NOTIFY_RX:
-        console_printf("notification rx event; attr_handle=%d indication=%d "
-                       "len=%d data=",
-                       event->notify_rx.attr_handle,
-                       event->notify_rx.indication,
-                       OS_MBUF_PKTLEN(event->notify_rx.om));
-
-        print_mbuf(event->notify_rx.om);
-        console_printf("\n");
-        return 0;
-
-    case BLE_GAP_EVENT_NOTIFY_TX:
-        console_printf("notification tx event; status=%d attr_handle=%d "
-                       "indication=%d\n",
-                       event->notify_tx.status,
-                       event->notify_tx.attr_handle,
-                       event->notify_tx.indication);
-        return 0;
-
-    case BLE_GAP_EVENT_SUBSCRIBE:
-        console_printf("subscribe event; conn_handle=%d attr_handle=%d "
-                       "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
-                       event->subscribe.conn_handle,
-                       event->subscribe.attr_handle,
-                       event->subscribe.reason,
-                       event->subscribe.prev_notify,
-                       event->subscribe.cur_notify,
-                       event->subscribe.prev_indicate,
-                       event->subscribe.cur_indicate);
-        return 0;
-
-    case BLE_GAP_EVENT_MTU:
-        console_printf("mtu update event; conn_handle=%d cid=%d mtu=%d\n",
-                       event->mtu.conn_handle,
-                       event->mtu.channel_id,
-                       event->mtu.value);
-        return 0;
-
-    case BLE_GAP_EVENT_IDENTITY_RESOLVED:
-        console_printf("identity resolved ");
-        rc = ble_gap_conn_find(event->identity_resolved.conn_handle, &desc);
-        assert(rc == 0);
-        print_conn_desc(&desc);
-        return 0;
-
-    default:
-        return 0;
-    }
-}
-
-static void
-bletiny_on_l2cap_update(uint16_t conn_handle, int status, void *arg)
-{
-    console_printf("l2cap update complete; conn_handle=%d status=%d\n",
-                   conn_handle, status);
-}
-
-static void
-bletiny_tx_timer_cb(struct os_event *ev)
-{
-    int i;
-    uint8_t len;
-    int32_t timeout;
-    uint8_t *dptr;
-    struct os_mbuf *om;
-
-    if ((bletiny_tx_data.tx_num == 0) || (bletiny_tx_data.tx_len == 0)) {
-        return;
-    }
-
-    len = bletiny_tx_data.tx_len;
-
-    om = NULL;
-    if (os_msys_num_free() >= 4) {
-        om = os_msys_get_pkthdr(len + 4, sizeof(struct ble_mbuf_hdr));
-    }
-
-    if (om) {
-        /* Put the HCI header in the mbuf */
-        om->om_len = len + 4;
-        put_le16(om->om_data, bletiny_tx_data.tx_handle);
-        put_le16(om->om_data + 2, len);
-        dptr = om->om_data + 4;
-
-        /*
-         * NOTE: first byte gets 0xff so not confused with l2cap channel.
-         * The rest of the data gets filled with incrementing pattern starting
-         * from 0.
-         */
-        put_le16(dptr, len - 4);
-        dptr[2] = 0xff;
-        dptr[3] = 0xff;
-        dptr += 4;
-        len -= 4;
-
-        for (i = 0; i < len; ++i) {
-            *dptr = i;
-            ++dptr;
-        }
-
-        /* Set packet header length */
-        OS_MBUF_PKTHDR(om)->omp_len = om->om_len;
-        ble_hci_trans_hs_acl_tx(om);
-
-        --bletiny_tx_data.tx_num;
-    }
-
-    if (bletiny_tx_data.tx_num) {
-        timeout = (int32_t)bletiny_tx_data.tx_rate;
-        timeout = (timeout * OS_TICKS_PER_SEC) / 1000;
-        os_callout_reset(&bletiny_tx_timer, timeout);
-    }
-}
-
-int
-bletiny_exchange_mtu(uint16_t conn_handle)
-{
-    int rc;
-
-    rc = ble_gattc_exchange_mtu(conn_handle, bletiny_on_mtu, NULL);
-    return rc;
-}
-
-int
-bletiny_disc_all_chrs(uint16_t conn_handle, uint16_t start_handle,
-                      uint16_t end_handle)
-{
-    intptr_t svc_start_handle;
-    int rc;
-
-    svc_start_handle = start_handle;
-    rc = ble_gattc_disc_all_chrs(conn_handle, start_handle, end_handle,
-                                 bletiny_on_disc_c, (void *)svc_start_handle);
-    return rc;
-}
-
-int
-bletiny_disc_chrs_by_uuid(uint16_t conn_handle, uint16_t start_handle,
-                           uint16_t end_handle, const ble_uuid_t *uuid)
-{
-    intptr_t svc_start_handle;
-    int rc;
-
-    svc_start_handle = start_handle;
-    rc = ble_gattc_disc_chrs_by_uuid(conn_handle, start_handle, end_handle,
-                                     uuid, bletiny_on_disc_c,
-                                     (void *)svc_start_handle);
-    return rc;
-}
-
-int
-bletiny_disc_svcs(uint16_t conn_handle)
-{
-    int rc;
-
-    rc = ble_gattc_disc_all_svcs(conn_handle, bletiny_on_disc_s, NULL);
-    return rc;
-}
-
-int
-bletiny_disc_svc_by_uuid(uint16_t conn_handle, const ble_uuid_t *uuid)
-{
-    int rc;
-
-    rc = ble_gattc_disc_svc_by_uuid(conn_handle, uuid,
-                                    bletiny_on_disc_s, NULL);
-    return rc;
-}
-
-int
-bletiny_disc_all_dscs(uint16_t conn_handle, uint16_t start_handle,
-                      uint16_t end_handle)
-{
-    int rc;
-
-    rc = ble_gattc_disc_all_dscs(conn_handle, start_handle, end_handle,
-                                 bletiny_on_disc_d, NULL);
-    return rc;
-}
-
-int
-bletiny_disc_full(uint16_t conn_handle)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_svc *svc;
-
-    /* Undiscover everything first. */
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        return BLE_HS_ENOTCONN;
-    }
-
-    while ((svc = SLIST_FIRST(&conn->svcs)) != NULL) {
-        SLIST_REMOVE_HEAD(&conn->svcs, next);
-        bletiny_svc_delete(svc);
-    }
-
-    bletiny_full_disc_prev_chr_val = 1;
-    bletiny_disc_svcs(conn_handle);
-
-    return 0;
-}
-
-int
-bletiny_find_inc_svcs(uint16_t conn_handle, uint16_t start_handle,
-                       uint16_t end_handle)
-{
-    int rc;
-
-    rc = ble_gattc_find_inc_svcs(conn_handle, start_handle, end_handle,
-                                 bletiny_on_disc_s, NULL);
-    return rc;
-}
-
-int
-bletiny_read(uint16_t conn_handle, uint16_t attr_handle)
-{
-    struct os_mbuf *om;
-    int rc;
-
-    if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
-        rc = ble_att_svr_read_local(attr_handle, &om);
-        if (rc == 0) {
-            console_printf("read local; attr_handle=%d len=%d value=",
-                           attr_handle, OS_MBUF_PKTLEN(om));
-            print_mbuf(om);
-            console_printf("\n");
-
-            os_mbuf_free_chain(om);
-        }
-    } else {
-        rc = ble_gattc_read(conn_handle, attr_handle, bletiny_on_read, NULL);
-    }
-    return rc;
-}
-
-int
-bletiny_read_long(uint16_t conn_handle, uint16_t attr_handle, uint16_t offset)
-{
-    int rc;
-
-    rc = ble_gattc_read_long(conn_handle, attr_handle, offset,
-                             bletiny_on_read, NULL);
-    return rc;
-}
-
-int
-bletiny_read_by_uuid(uint16_t conn_handle, uint16_t start_handle,
-                      uint16_t end_handle, const ble_uuid_t *uuid)
-{
-    int rc;
-
-    rc = ble_gattc_read_by_uuid(conn_handle, start_handle, end_handle, uuid,
-                                bletiny_on_read, NULL);
-    return rc;
-}
-
-int
-bletiny_read_mult(uint16_t conn_handle, uint16_t *attr_handles,
-                   int num_attr_handles)
-{
-    int rc;
-
-    rc = ble_gattc_read_mult(conn_handle, attr_handles, num_attr_handles,
-                             bletiny_on_read, NULL);
-    return rc;
-}
-
-int
-bletiny_write(uint16_t conn_handle, uint16_t attr_handle, struct os_mbuf *om)
-{
-    int rc;
-
-    if (conn_handle == BLE_HS_CONN_HANDLE_NONE) {
-        rc = ble_att_svr_write_local(attr_handle, om);
-    } else {
-        rc = ble_gattc_write(conn_handle, attr_handle, om,
-                             bletiny_on_write, NULL);
-    }
-
-    return rc;
-}
-
-int
-bletiny_write_no_rsp(uint16_t conn_handle, uint16_t attr_handle,
-                     struct os_mbuf *om)
-{
-    int rc;
-
-    rc = ble_gattc_write_no_rsp(conn_handle, attr_handle, om);
-
-    return rc;
-}
-
-int
-bletiny_write_long(uint16_t conn_handle, uint16_t attr_handle,
-                   uint16_t offset, struct os_mbuf *om)
-{
-    int rc;
-
-    rc = ble_gattc_write_long(conn_handle, attr_handle, offset,
-                              om, bletiny_on_write, NULL);
-    return rc;
-}
-
-int
-bletiny_write_reliable(uint16_t conn_handle,
-                       struct ble_gatt_attr *attrs,
-                       int num_attrs)
-{
-    int rc;
-
-    rc = ble_gattc_write_reliable(conn_handle, attrs, num_attrs,
-                                  bletiny_on_write_reliable, NULL);
-    return rc;
-}
-
-int
-bletiny_adv_stop(void)
-{
-    int rc;
-
-    rc = ble_gap_adv_stop();
-    return rc;
-}
-
-int
-bletiny_adv_start(uint8_t own_addr_type, const ble_addr_t *direct_addr,
-                  int32_t duration_ms, const struct ble_gap_adv_params *params)
-{
-    int rc;
-
-    rc = ble_gap_adv_start(own_addr_type, direct_addr, duration_ms, params,
-                           bletiny_gap_event, NULL);
-    return rc;
-}
-
-int
-bletiny_conn_initiate(uint8_t own_addr_type, const ble_addr_t *peer_addr,
-                      int32_t duration_ms, struct ble_gap_conn_params *params)
-{
-    int rc;
-
-    rc = ble_gap_connect(own_addr_type, peer_addr, duration_ms, params,
-                         bletiny_gap_event, NULL);
-
-    return rc;
-}
-
-int
-bletiny_conn_cancel(void)
-{
-    int rc;
-
-    rc = ble_gap_conn_cancel();
-    return rc;
-}
-
-int
-bletiny_term_conn(uint16_t conn_handle, uint8_t reason)
-{
-    int rc;
-
-    rc = ble_gap_terminate(conn_handle, reason);
-    return rc;
-}
-
-int
-bletiny_wl_set(ble_addr_t *addrs, int addrs_count)
-{
-    int rc;
-
-    rc = ble_gap_wl_set(addrs, addrs_count);
-    return rc;
-}
-
-int
-bletiny_scan(uint8_t own_addr_type, int32_t duration_ms,
-             const struct ble_gap_disc_params *disc_params)
-{
-    int rc;
-
-    rc = ble_gap_disc(own_addr_type, duration_ms, disc_params,
-                      bletiny_gap_event, NULL);
-    return rc;
-}
-
-int
-bletiny_scan_cancel(void)
-{
-    int rc;
-
-    rc = ble_gap_disc_cancel();
-    return rc;
-}
-
-int
-bletiny_set_adv_data(struct ble_hs_adv_fields *adv_fields)
-{
-    int rc;
-
-    rc = ble_gap_adv_set_fields(adv_fields);
-    return rc;
-}
-
-int
-bletiny_update_conn(uint16_t conn_handle, struct ble_gap_upd_params *params)
-{
-    int rc;
-
-    rc = ble_gap_update_params(conn_handle, params);
-    return rc;
-}
-
-void
-bletiny_chrup(uint16_t attr_handle)
-{
-    ble_gatts_chr_updated(attr_handle);
-}
-
-int
-bletiny_datalen(uint16_t conn_handle, uint16_t tx_octets, uint16_t tx_time)
-{
-    int rc;
-
-    rc = ble_hs_hci_util_set_data_len(conn_handle, tx_octets, tx_time);
-    return rc;
-}
-
-int
-bletiny_l2cap_update(uint16_t conn_handle,
-                     struct ble_l2cap_sig_update_params *params)
-{
-    int rc;
-
-    rc = ble_l2cap_sig_update(conn_handle, params, bletiny_on_l2cap_update,
-                              NULL);
-    return rc;
-}
-
-int
-bletiny_sec_pair(uint16_t conn_handle)
-{
-#if !NIMBLE_BLE_SM
-    return BLE_HS_ENOTSUP;
-#endif
-
-    int rc;
-
-    rc = ble_gap_pair_initiate(conn_handle);
-    return rc;
-}
-
-int
-bletiny_sec_start(uint16_t conn_handle)
-{
-#if !NIMBLE_BLE_SM
-    return BLE_HS_ENOTSUP;
-#endif
-
-    int rc;
-
-    rc = ble_gap_security_initiate(conn_handle);
-    return rc;
-}
-
-int
-bletiny_sec_restart(uint16_t conn_handle,
-                    uint8_t *ltk,
-                    uint16_t ediv,
-                    uint64_t rand_val,
-                    int auth)
-{
-#if !NIMBLE_BLE_SM
-    return BLE_HS_ENOTSUP;
-#endif
-
-    struct ble_store_value_sec value_sec;
-    struct ble_store_key_sec key_sec;
-    struct ble_gap_conn_desc desc;
-    ble_hs_conn_flags_t conn_flags;
-    int rc;
-
-    if (ltk == NULL) {
-        /* The user is requesting a store lookup. */
-        rc = ble_gap_conn_find(conn_handle, &desc);
-        if (rc != 0) {
-            return rc;
-        }
-
-        memset(&key_sec, 0, sizeof key_sec);
-        key_sec.peer_addr = desc.peer_id_addr;
-
-        rc = ble_hs_atomic_conn_flags(conn_handle, &conn_flags);
-        if (rc != 0) {
-            return rc;
-        }
-        if (conn_flags & BLE_HS_CONN_F_MASTER) {
-            rc = ble_store_read_peer_sec(&key_sec, &value_sec);
-        } else {
-            rc = ble_store_read_our_sec(&key_sec, &value_sec);
-        }
-        if (rc != 0) {
-            return rc;
-        }
-
-        ltk = value_sec.ltk;
-        ediv = value_sec.ediv;
-        rand_val = value_sec.rand_num;
-        auth = value_sec.authenticated;
-    }
-
-    rc = ble_gap_encryption_initiate(conn_handle, ltk, ediv, rand_val, auth);
-    return rc;
-}
-
-/**
- * Called to start transmitting 'num' packets at rate 'rate' of size 'size'
- * to connection handle 'handle'
- *
- * @param handle
- * @param len
- * @param rate
- * @param num
- *
- * @return int
- */
-int
-bletiny_tx_start(uint16_t handle, uint16_t len, uint16_t rate, uint16_t num)
-{
-    /* Cannot be currently in a session */
-    if (num == 0) {
-        return 0;
-    }
-
-    /* Do not allow start if already in progress */
-    if (bletiny_tx_data.tx_num != 0) {
-        return -1;
-    }
-
-    /* XXX: for now, must have contiguous mbuf space */
-    if ((len + 4) > MYNEWT_VAL_MSYS_1_BLOCK_SIZE) {
-        return -2;
-    }
-
-    bletiny_tx_data.tx_num = num;
-    bletiny_tx_data.tx_rate = rate;
-    bletiny_tx_data.tx_len = len;
-    bletiny_tx_data.tx_handle = handle;
-
-    os_callout_reset(&bletiny_tx_timer, 0);
-
-    return 0;
-}
-
-int
-bletiny_rssi(uint16_t conn_handle, int8_t *out_rssi)
-{
-    int rc;
-
-    rc = ble_gap_conn_rssi(conn_handle, out_rssi);
-    if (rc != 0) {
-        return rc;
-    }
-
-    return 0;
-}
-
-static void
-bletiny_on_reset(int reason)
-{
-    console_printf("Error: Resetting state; reason=%d\n", reason);
-}
-
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
-
-static int
-bletiny_l2cap_coc_add(uint16_t conn_handle, struct ble_l2cap_chan *chan)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_l2cap_coc *coc;
-    struct bletiny_l2cap_coc *prev, *cur;
-
-    conn = bletiny_conn_find(conn_handle);
-    assert(conn != NULL);
-
-    coc = os_memblock_get(&bletiny_coc_conn_pool);
-    if (!coc) {
-        return ENOMEM;
-    }
-
-    coc->chan = chan;
-
-    prev = NULL;
-    SLIST_FOREACH(cur, &conn->coc_list, next) {
-        prev = cur;
-    }
-
-    if (prev == NULL) {
-        SLIST_INSERT_HEAD(&conn->coc_list, coc, next);
-    } else {
-        SLIST_INSERT_AFTER(prev, coc, next);
-    }
-
-    return 0;
-}
-
-static void
-bletiny_l2cap_coc_remove(uint16_t conn_handle, struct ble_l2cap_chan *chan)
-{
-    struct bletiny_conn *conn;
-    struct bletiny_l2cap_coc *coc;
-    struct bletiny_l2cap_coc *cur;
-
-    conn = bletiny_conn_find(conn_handle);
-    assert(conn != NULL);
-
-    coc = NULL;
-    SLIST_FOREACH(cur, &conn->coc_list, next) {
-        if (cur->chan == chan) {
-            coc = cur;
-            break;
-        }
-    }
-
-    if (!coc) {
-        return;
-    }
-
-    SLIST_REMOVE(&conn->coc_list, coc, bletiny_l2cap_coc, next);
-    os_memblock_put(&bletiny_coc_conn_pool, coc);
-}
-
-static void
-bletiny_l2cap_coc_recv(struct ble_l2cap_chan *chan, struct os_mbuf *sdu)
-{
-    console_printf("LE CoC SDU received, chan: 0x%08lx, data len %d\n",
-                   (uint32_t) chan, OS_MBUF_PKTLEN(sdu));
-
-    os_mbuf_free_chain(sdu);
-    sdu = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
-    assert(sdu != NULL);
-
-    ble_l2cap_recv_ready(chan, sdu);
-}
-
-static int
-bletiny_l2cap_coc_accept(uint16_t conn_handle, uint16_t peer_mtu,
-                           struct ble_l2cap_chan *chan)
-{
-    struct os_mbuf *sdu_rx;
-
-    console_printf("LE CoC accepting, chan: 0x%08lx, peer_mtu %d\n",
-                       (uint32_t) chan, peer_mtu);
-
-    sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
-    if (!sdu_rx) {
-        return BLE_HS_ENOMEM;
-    }
-
-    ble_l2cap_recv_ready(chan, sdu_rx);
-
-    return 0;
-}
-
-static int
-bletiny_l2cap_event(struct ble_l2cap_event *event, void *arg)
-{
-    switch(event->type) {
-        case BLE_L2CAP_EVENT_COC_CONNECTED:
-            if (event->connect.status) {
-                console_printf("LE COC error: %d\n", event->connect.status);
-                return 0;
-            }
-
-            console_printf("LE COC connected, conn: %d, chan: 0x%08lx\n",
-                           event->connect.conn_handle,
-                           (uint32_t) event->connect.chan);
-
-            bletiny_l2cap_coc_add(event->connect.conn_handle,
-                                  event->connect.chan);
-
-            return 0;
-        case BLE_L2CAP_EVENT_COC_DISCONNECTED:
-            console_printf("LE CoC disconnected, chan: 0x%08lx\n",
-                           (uint32_t) event->disconnect.chan);
-
-            bletiny_l2cap_coc_remove(event->disconnect.conn_handle,
-                                     event->disconnect.chan);
-            return 0;
-        case BLE_L2CAP_EVENT_COC_ACCEPT:
-            return bletiny_l2cap_coc_accept(event->accept.conn_handle,
-                                            event->accept.peer_sdu_size,
-                                            event->accept.chan);
-
-        case BLE_L2CAP_EVENT_COC_DATA_RECEIVED:
-            bletiny_l2cap_coc_recv(event->receive.chan, event->receive.sdu_rx);
-            return 0;
-        default:
-            return 0;
-    }
-}
-#endif
-
-int
-bletiny_l2cap_create_srv(uint16_t psm)
-{
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
-    console_printf("BLE L2CAP LE COC not supported.");
-    console_printf(" Configure nimble host to enable it\n");
-    return 0;
-#else
-
-    return ble_l2cap_create_server(psm, BLETINY_COC_MTU, bletiny_l2cap_event,
-                                                                       NULL);
-#endif
-}
-
-int
-bletiny_l2cap_connect(uint16_t conn_handle, uint16_t psm)
-{
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
-    console_printf("BLE L2CAP LE COC not supported.");
-    console_printf(" Configure nimble host to enable it\n");
-    return 0;
-#else
-
-    struct os_mbuf *sdu_rx;
-
-    sdu_rx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
-    assert(sdu_rx != NULL);
-
-    return ble_l2cap_connect(conn_handle, psm, BLETINY_COC_MTU, sdu_rx,
-                             bletiny_l2cap_event, NULL);
-#endif
-}
-
-int
-bletiny_l2cap_disconnect(uint16_t conn_handle, uint16_t idx)
-{
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
-    console_printf("BLE L2CAP LE COC not supported.");
-    console_printf(" Configure nimble host to enable it\n");
-    return 0;
-#else
-
-    struct bletiny_conn *conn;
-    struct bletiny_l2cap_coc *coc;
-    int i;
-    int rc = 0;
-
-    conn = bletiny_conn_find(conn_handle);
-    assert(conn != NULL);
-
-    i = 0;
-    SLIST_FOREACH(coc, &conn->coc_list, next) {
-        if (i == idx) {
-                break;
-        }
-        i++;
-    }
-    assert(coc != NULL);
-
-    rc = ble_l2cap_disconnect(coc->chan);
-    if (rc) {
-        console_printf("Could not disconnect channel rc=%d\n", rc);
-    }
-
-    return rc;
-#endif
-}
-
-int
-bletiny_l2cap_send(uint16_t conn_handle, uint16_t idx, uint16_t bytes)
-{
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) == 0
-    console_printf("BLE L2CAP LE COC not supported.");
-    console_printf(" Configure nimble host to enable it\n");
-    return 0;
-#else
-
-    struct bletiny_conn *conn;
-    struct bletiny_l2cap_coc *coc;
-    struct os_mbuf *sdu_tx;
-    uint8_t b[] = {0x00, 0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88, 0x99};
-    int i;
-    int rc;
-
-    console_printf("conn=%d, idx=%d, bytes=%d\n", conn_handle, idx, bytes);
-
-    conn = bletiny_conn_find(conn_handle);
-    if (conn == NULL) {
-        console_printf("conn=%d does not exist\n", conn_handle);
-        return 0;
-    }
-
-    i = 0;
-    SLIST_FOREACH(coc, &conn->coc_list, next) {
-        if (i == idx) {
-            break;
-        }
-        i++;
-    }
-    if (coc == NULL) {
-        console_printf("Are you sure your channel exist?\n");
-        return 0;
-    }
-
-    sdu_tx = os_mbuf_get_pkthdr(&sdu_os_mbuf_pool, 0);
-    if (sdu_tx == NULL) {
-        console_printf("No memory in the test sdu pool\n");
-        return 0;
-    }
-
-    /* For the testing purpose we fill up buffer with known data, easy
-     * to validate on other side. In this loop we add as many full chunks as we
-     * can
-     */
-    for (i = 0; i < bytes / sizeof(b); i++) {
-        rc = os_mbuf_append(sdu_tx, b, sizeof(b));
-        if (rc) {
-            console_printf("Cannot append data %i !\n", i);
-            os_mbuf_free_chain(sdu_tx);
-            return rc;
-        }
-    }
-
-    /* Here we add the rest < sizeof(b) */
-    rc = os_mbuf_append(sdu_tx, b, bytes - (sizeof(b) * i));
-    if (rc) {
-        console_printf("Cannot append data %i !\n", i);
-        os_mbuf_free_chain(sdu_tx);
-        return rc;
-    }
-
-    rc = ble_l2cap_send(coc->chan, sdu_tx);
-    if (rc) {
-        console_printf("Could not send data rc=%d\n", rc);
-        if (rc == BLE_HS_EBUSY) {
-            os_mbuf_free_chain(sdu_tx);
-        }
-    }
-
-    return rc;
-
-#endif
-}
-/**
- * main
- *
- * The main task for the project. This function initializes the packages,
- * then starts serving events from default event queue.
- *
- * @return int NOTE: this function should never return!
- */
-int
-main(int argc, char **argv)
-{
-    int rc;
-
-#ifdef ARCH_sim
-    mcu_sim_parse_args(argc, argv);
-#endif
-
-    /* Initialize OS */
-    sysinit();
-
-    /* Allocate some application specific memory pools. */
-    bletiny_svc_mem = malloc(
-        OS_MEMPOOL_BYTES(BLETINY_MAX_SVCS, sizeof (struct bletiny_svc)));
-    assert(bletiny_svc_mem != NULL);
-
-    rc = os_mempool_init(&bletiny_svc_pool, BLETINY_MAX_SVCS,
-                         sizeof (struct bletiny_svc), bletiny_svc_mem,
-                         "bletiny_svc_pool");
-    assert(rc == 0);
-
-    bletiny_chr_mem = malloc(
-        OS_MEMPOOL_BYTES(BLETINY_MAX_CHRS, sizeof (struct bletiny_chr)));
-    assert(bletiny_chr_mem != NULL);
-
-    rc = os_mempool_init(&bletiny_chr_pool, BLETINY_MAX_CHRS,
-                         sizeof (struct bletiny_chr), bletiny_chr_mem,
-                         "bletiny_chr_pool");
-    assert(rc == 0);
-
-    bletiny_dsc_mem = malloc(
-        OS_MEMPOOL_BYTES(BLETINY_MAX_DSCS, sizeof (struct bletiny_dsc)));
-    assert(bletiny_dsc_mem != NULL);
-
-    rc = os_mempool_init(&bletiny_dsc_pool, BLETINY_MAX_DSCS,
-                         sizeof (struct bletiny_dsc), bletiny_dsc_mem,
-                         "bletiny_dsc_pool");
-    assert(rc == 0);
-
-#if MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM) != 0
-    /* For testing we want to support all the available channels */
-    bletiny_sdu_coc_mem = malloc(
-        OS_MEMPOOL_BYTES(BLETINY_COC_BUF_COUNT, BLETINY_COC_MTU));
-    assert(bletiny_sdu_coc_mem != NULL);
-
-    rc = os_mempool_init(&sdu_coc_mbuf_mempool, BLETINY_COC_BUF_COUNT,
-                         BLETINY_COC_MTU, bletiny_sdu_coc_mem,
-                         "bletiny_coc_sdu_pool");
-    assert(rc == 0);
-
-    rc = os_mbuf_pool_init(&sdu_os_mbuf_pool, &sdu_coc_mbuf_mempool,
-                           BLETINY_COC_MTU, BLETINY_COC_BUF_COUNT);
-    assert(rc == 0);
-
-    bletiny_coc_conn_mem = malloc(
-        OS_MEMPOOL_BYTES(MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
-                         sizeof (struct bletiny_l2cap_coc)));
-    assert(bletiny_coc_conn_mem != NULL);
-
-    rc = os_mempool_init(&bletiny_coc_conn_pool,
-                         MYNEWT_VAL(BLE_L2CAP_COC_MAX_NUM),
-                         sizeof (struct bletiny_l2cap_coc), bletiny_coc_conn_mem,
-                         "bletiny_coc_conn_pool");
-    assert(rc == 0);
-#endif
-
-    /* Initialize the logging system. */
-    log_register("bletiny", &bletiny_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
-    /* Initialize the NimBLE host configuration. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-    ble_hs_cfg.reset_cb = bletiny_on_reset;
-    ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
-
-    rc = gatt_svr_init();
-    assert(rc == 0);
-
-    rc = cmd_init();
-    assert(rc == 0);
-
-    /* Set the default device name. */
-    rc = ble_svc_gap_device_name_set("nimble-bletiny");
-    assert(rc == 0);
-
-    /* Create a callout (timer).  This callout is used by the "tx" bletiny
-     * command to repeatedly send packets of sequential data bytes.
-     */
-    os_callout_init(&bletiny_tx_timer, os_eventq_dflt_get(),
-                    bletiny_tx_timer_cb, NULL);
-
-    while (1) {
-        os_eventq_run(os_eventq_dflt_get());
-    }
-    /* os start should never return. If it does, this should be an error */
-    assert(0);
-
-    return 0;
-}
diff --git a/apps/bletiny/src/misc.c b/apps/bletiny/src/misc.c
deleted file mode 100644
index d39016b22e..0000000000
--- a/apps/bletiny/src/misc.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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 "console/console.h"
-#include "host/ble_uuid.h"
-#include "host/ble_gap.h"
-
-#include "bletiny.h"
-
-/**
- * Utility function to log an array of bytes.
- */
-void
-print_bytes(const uint8_t *bytes, int len)
-{
-    int i;
-
-    for (i = 0; i < len; i++) {
-        console_printf("%s0x%02x", i != 0 ? ":" : "", bytes[i]);
-    }
-}
-
-void
-print_mbuf(const struct os_mbuf *om)
-{
-    int colon;
-
-    colon = 0;
-    while (om != NULL) {
-        if (colon) {
-            console_printf(":");
-        } else {
-            colon = 1;
-        }
-        print_bytes(om->om_data, om->om_len);
-        om = SLIST_NEXT(om, om_next);
-    }
-}
-
-void
-print_addr(const void *addr)
-{
-    const uint8_t *u8p;
-
-    u8p = addr;
-    console_printf("%02x:%02x:%02x:%02x:%02x:%02x",
-                   u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
-}
-
-void
-print_uuid(const ble_uuid_t *uuid)
-{
-    char buf[BLE_UUID_STR_LEN];
-
-    ble_uuid_to_str(uuid, buf);
-
-    console_printf(buf);
-}
-
-int
-svc_is_empty(const struct bletiny_svc *svc)
-{
-    return svc->svc.end_handle < svc->svc.start_handle;
-}
-
-uint16_t
-chr_end_handle(const struct bletiny_svc *svc, const struct bletiny_chr *chr)
-{
-    const struct bletiny_chr *next_chr;
-
-    next_chr = SLIST_NEXT(chr, next);
-    if (next_chr != NULL) {
-        return next_chr->chr.def_handle - 1;
-    } else {
-        return svc->svc.end_handle;
-    }
-}
-
-int
-chr_is_empty(const struct bletiny_svc *svc, const struct bletiny_chr *chr)
-{
-    return chr_end_handle(svc, chr) <= chr->chr.val_handle;
-}
-
-void
-print_conn_desc(const struct ble_gap_conn_desc *desc)
-{
-    console_printf("handle=%d our_ota_addr_type=%d our_ota_addr=",
-                   desc->conn_handle, desc->our_ota_addr.type);
-    print_addr(desc->our_ota_addr.val);
-    console_printf(" our_id_addr_type=%d our_id_addr=",
-                   desc->our_id_addr.type);
-    print_addr(desc->our_id_addr.val);
-    console_printf(" peer_ota_addr_type=%d peer_ota_addr=",
-                   desc->peer_ota_addr.type);
-    print_addr(desc->peer_ota_addr.val);
-    console_printf(" peer_id_addr_type=%d peer_id_addr=",
-                   desc->peer_id_addr.type);
-    print_addr(desc->peer_id_addr.val);
-    console_printf(" conn_itvl=%d conn_latency=%d supervision_timeout=%d "
-                   "encrypted=%d authenticated=%d bonded=%d\n",
-                   desc->conn_itvl, desc->conn_latency,
-                   desc->supervision_timeout,
-                   desc->sec_state.encrypted,
-                   desc->sec_state.authenticated,
-                   desc->sec_state.bonded);
-}
diff --git a/apps/bletiny/src/parse.c b/apps/bletiny/src/parse.c
deleted file mode 100644
index 4cb2eb75c1..0000000000
--- a/apps/bletiny/src/parse.c
+++ /dev/null
@@ -1,520 +0,0 @@
-/*
- * 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 <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <stdarg.h>
-#include <errno.h>
-#include <assert.h>
-#include "console/console.h"
-#include "host/ble_uuid.h"
-#include "bletiny.h"
-
-#define CMD_MAX_ARGS        16
-
-static char *cmd_args[CMD_MAX_ARGS][2];
-static int cmd_num_args;
-
-int
-parse_err_too_few_args(char *cmd_name)
-{
-    console_printf("Error: too few arguments for command \"%s\"\n",
-                   cmd_name);
-    return -1;
-}
-
-const struct cmd_entry *
-parse_cmd_find(const struct cmd_entry *cmds, char *name)
-{
-    const struct cmd_entry *cmd;
-    int i;
-
-    for (i = 0; cmds[i].name != NULL; i++) {
-        cmd = cmds + i;
-        if (strcmp(name, cmd->name) == 0) {
-            return cmd;
-        }
-    }
-
-    return NULL;
-}
-
-struct kv_pair *
-parse_kv_find(struct kv_pair *kvs, char *name)
-{
-    struct kv_pair *kv;
-    int i;
-
-    for (i = 0; kvs[i].key != NULL; i++) {
-        kv = kvs + i;
-        if (strcmp(name, kv->key) == 0) {
-            return kv;
-        }
-    }
-
-    return NULL;
-}
-
-int
-parse_arg_find_idx(const char *key)
-{
-    int i;
-
-    for (i = 0; i < cmd_num_args; i++) {
-        if (strcmp(cmd_args[i][0], key) == 0) {
-            return i;
-        }
-    }
-
-    return -1;
-}
-
-char *
-parse_arg_peek(const char *key)
-{
-    int i;
-
-    for (i = 0; i < cmd_num_args; i++) {
-        if (strcmp(cmd_args[i][0], key) == 0) {
-            return cmd_args[i][1];
-        }
-    }
-
-    return NULL;
-}
-
-char *
-parse_arg_extract(const char *key)
-{
-    int i;
-
-    for (i = 0; i < cmd_num_args; i++) {
-        if (strcmp(cmd_args[i][0], key) == 0) {
-            /* Erase parameter. */
-            cmd_args[i][0][0] = '\0';
-
-            return cmd_args[i][1];
-        }
-    }
-
-    return NULL;
-}
-
-/**
- * Determines which number base to use when parsing the specified numeric
- * string.  This just avoids base '0' so that numbers don't get interpreted as
- * octal.
- */
-static int
-parse_arg_long_base(char *sval)
-{
-    if (sval[0] == '0' && sval[1] == 'x') {
-        return 0;
-    } else {
-        return 10;
-    }
-}
-
-long
-parse_long_bounds(char *sval, long min, long max, int *out_status)
-{
-    char *endptr;
-    long lval;
-
-    lval = strtol(sval, &endptr, parse_arg_long_base(sval));
-    if (sval[0] != '\0' && *endptr == '\0' &&
-        lval >= min && lval <= max) {
-
-        *out_status = 0;
-        return lval;
-    }
-
-    *out_status = EINVAL;
-    return 0;
-}
-
-long
-parse_arg_long_bounds_peek(char *name, long min, long max, int *out_status)
-{
-    char *sval;
-
-    sval = parse_arg_peek(name);
-    if (sval == NULL) {
-        *out_status = ENOENT;
-        return 0;
-    }
-    return parse_long_bounds(sval, min, max, out_status);
-}
-
-long
-parse_arg_long_bounds(char *name, long min, long max, int *out_status)
-{
-    char *sval;
-
-    sval = parse_arg_extract(name);
-    if (sval == NULL) {
-        *out_status = ENOENT;
-        return 0;
-    }
-    return parse_long_bounds(sval, min, max, out_status);
-}
-
-long
-parse_arg_long_bounds_default(char *name, long min, long max,
-                              long dflt, int *out_status)
-{
-    long val;
-    int rc;
-
-    val = parse_arg_long_bounds(name, min, max, &rc);
-    if (rc == ENOENT) {
-        rc = 0;
-        val = dflt;
-    }
-
-    *out_status = rc;
-
-    return val;
-}
-
-uint64_t
-parse_arg_uint64_bounds(char *name, uint64_t min, uint64_t max, int *out_status)
-{
-    char *endptr;
-    char *sval;
-    uint64_t lval;
-
-    sval = parse_arg_extract(name);
-    if (sval == NULL) {
-        *out_status = ENOENT;
-        return 0;
-    }
-
-    lval = strtoull(sval, &endptr, parse_arg_long_base(sval));
-    if (sval[0] != '\0' && *endptr == '\0' &&
-        lval >= min && lval <= max) {
-
-        *out_status = 0;
-        return lval;
-    }
-
-    *out_status = EINVAL;
-    return 0;
-}
-
-long
-parse_arg_long(char *name, int *out_status)
-{
-    return parse_arg_long_bounds(name, LONG_MIN, LONG_MAX, out_status);
-}
-
-uint8_t
-parse_arg_bool(char *name, int *out_status)
-{
-    return parse_arg_long_bounds(name, 0, 1, out_status);
-}
-
-uint8_t
-parse_arg_bool_default(char *name, uint8_t dflt, int *out_status)
-{
-    return parse_arg_long_bounds_default(name, 0, 1, dflt, out_status);
-}
-
-uint8_t
-parse_arg_uint8(char *name, int *out_status)
-{
-    return parse_arg_long_bounds(name, 0, UINT8_MAX, out_status);
-}
-
-uint16_t
-parse_arg_uint16(char *name, int *out_status)
-{
-    return parse_arg_long_bounds(name, 0, UINT16_MAX, out_status);
-}
-
-uint16_t
-parse_arg_uint16_peek(char *name, int *out_status)
-{
-    return parse_arg_long_bounds_peek(name, 0, UINT16_MAX, out_status);
-}
-
-uint32_t
-parse_arg_uint32(char *name, int *out_status)
-{
-    return parse_arg_uint64_bounds(name, 0, UINT32_MAX, out_status);
-}
-
-uint64_t
-parse_arg_uint64(char *name, int *out_status)
-{
-    return parse_arg_uint64_bounds(name, 0, UINT64_MAX, out_status);
-}
-
-uint8_t
-parse_arg_uint8_dflt(char *name, uint8_t dflt, int *out_status)
-{
-    uint8_t val;
-    int rc;
-
-    val = parse_arg_uint8(name, &rc);
-    if (rc == ENOENT) {
-        val = dflt;
-        rc = 0;
-    }
-
-    *out_status = rc;
-    return val;
-}
-
-uint16_t
-parse_arg_uint16_dflt(char *name, uint16_t dflt, int *out_status)
-{
-    uint16_t val;
-    int rc;
-
-    val = parse_arg_uint16(name, &rc);
-    if (rc == ENOENT) {
-        val = dflt;
-        rc = 0;
-    }
-
-    *out_status = rc;
-    return val;
-}
-
-uint32_t
-parse_arg_uint32_dflt(char *name, uint32_t dflt, int *out_status)
-{
-    uint32_t val;
-    int rc;
-
-    val = parse_arg_uint32(name, &rc);
-    if (rc == ENOENT) {
-        val = dflt;
-        rc = 0;
-    }
-
-    *out_status = rc;
-    return val;
-}
-
-int
-parse_arg_kv(char *name, struct kv_pair *kvs, int *out_status)
-{
-    struct kv_pair *kv;
-    char *sval;
-
-    sval = parse_arg_extract(name);
-    if (sval == NULL) {
-        *out_status = ENOENT;
-        return -1;
-    }
-
-    kv = parse_kv_find(kvs, sval);
-    if (kv == NULL) {
-        *out_status = EINVAL;
-        return -1;
-    }
-
-    *out_status = 0;
-    return kv->val;
-}
-
-int
-parse_arg_kv_default(char *name, struct kv_pair *kvs, int def_val,
-                     int *out_status)
-{
-    int val;
-    int rc;
-
-    val = parse_arg_kv(name, kvs, &rc);
-    if (rc == ENOENT) {
-        rc = 0;
-        val = def_val;
-    }
-
-    *out_status = rc;
-
-    return val;
-}
-
-
-static int
-parse_arg_byte_stream_delim(char *sval, char *delims, int max_len,
-                            uint8_t *dst, int *out_len)
-{
-    unsigned long ul;
-    char *endptr;
-    char *token;
-    int i;
-
-    i = 0;
-    for (token = strtok(sval, delims);
-         token != NULL;
-         token = strtok(NULL, delims)) {
-
-        if (i >= max_len) {
-            return EINVAL;
-        }
-
-        ul = strtoul(token, &endptr, 16);
-        if (sval[0] == '\0' || *endptr != '\0' || ul > UINT8_MAX) {
-            return -1;
-        }
-
-        dst[i] = ul;
-        i++;
-    }
-
-    *out_len = i;
-
-    return 0;
-}
-
-int
-parse_arg_byte_stream(char *name, int max_len, uint8_t *dst, int *out_len)
-{
-    char *sval;
-
-    sval = parse_arg_extract(name);
-    if (sval == NULL) {
-        return ENOENT;
-    }
-
-    return parse_arg_byte_stream_delim(sval, ":-", max_len, dst, out_len);
-}
-
-int
-parse_arg_byte_stream_exact_length(char *name, uint8_t *dst, int len)
-{
-    int actual_len;
-    int rc;
-
-    rc = parse_arg_byte_stream(name, len, dst, &actual_len);
-    if (rc != 0) {
-        return rc;
-    }
-
-    if (actual_len != len) {
-        return EINVAL;
-    }
-
-    return 0;
-}
-
-static void
-parse_reverse_bytes(uint8_t *bytes, int len)
-{
-    uint8_t tmp;
-    int i;
-
-    for (i = 0; i < len / 2; i++) {
-        tmp = bytes[i];
-        bytes[i] = bytes[len - i - 1];
-        bytes[len - i - 1] = tmp;
-    }
-}
-
-int
-parse_arg_mac(char *name, uint8_t *dst)
-{
-    int rc;
-
-    rc = parse_arg_byte_stream_exact_length(name, dst, 6);
-    if (rc != 0) {
-        return rc;
-    }
-
-    parse_reverse_bytes(dst, 6);
-
-    return 0;
-}
-
-int
-parse_arg_uuid(char *str, ble_uuid_any_t *uuid)
-{
-    uint16_t uuid16;
-    uint8_t val[16];
-    int len;
-    int rc;
-
-    uuid16 = parse_arg_uint16_peek(str, &rc);
-    switch (rc) {
-    case ENOENT:
-        parse_arg_extract(str);
-        return ENOENT;
-
-    case 0:
-        len = 2;
-        val[0] = uuid16;
-        val[1] = uuid16 >> 8;
-        parse_arg_extract(str);
-        break;
-
-    default:
-        len = 16;
-        rc = parse_arg_byte_stream_exact_length(str, val, 16);
-        if (rc != 0) {
-            return EINVAL;
-        }
-        parse_reverse_bytes(val, 16);
-        break;
-    }
-
-    rc = ble_uuid_init_from_buf(uuid, val, len);
-    if (rc != 0) {
-        return EINVAL;
-    } else {
-        return 0;
-    }
-}
-
-int
-parse_arg_all(int argc, char **argv)
-{
-    char *key;
-    char *val;
-    int i;
-
-    cmd_num_args = 0;
-
-    for (i = 0; i < argc; i++) {
-        key = strtok(argv[i], "=");
-        val = strtok(NULL, "=");
-
-        if (key != NULL && val != NULL) {
-            if (strlen(key) == 0) {
-                console_printf("Error: invalid argument: %s\n", argv[i]);
-                return -1;
-            }
-
-            if (cmd_num_args >= CMD_MAX_ARGS) {
-                console_printf("Error: too many arguments");
-                return -1;
-            }
-
-            cmd_args[cmd_num_args][0] = key;
-            cmd_args[cmd_num_args][1] = val;
-            cmd_num_args++;
-        }
-    }
-
-    return 0;
-}
diff --git a/apps/bletiny/syscfg.yml b/apps/bletiny/syscfg.yml
deleted file mode 100644
index 96fe5b6411..0000000000
--- a/apps/bletiny/syscfg.yml
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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.
-#
-
-# Package: apps/bletiny
-
-syscfg.vals:
-    # Enable the shell task.
-    SHELL_TASK: 1
-
-    # Set log level to info (disable debug logging).
-    LOG_LEVEL: 1
-
-    # Disable security manager (pairing and bonding).
-    BLE_SM_LEGACY: 0
-    BLE_SM_SC: 0
-
-    # Disable eddystone beacons.
-    BLE_EDDYSTONE: 0
-
-    # Default task settings
-    OS_MAIN_STACK_SIZE: 512
diff --git a/apps/bleuart/pkg.yml b/apps/bleuart/pkg.yml
index c5fbf5a678..7aa0ad9354 100644
--- a/apps/bleuart/pkg.yml
+++ b/apps/bleuart/pkg.yml
@@ -18,22 +18,24 @@
 pkg.name: apps/bleuart
 pkg.type: app
 pkg.description: Simple BLE uart application.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
 
 pkg.deps:
-    - kernel/os
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/host/services/gap
-    - net/nimble/host/services/gatt
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/full
-    - libc/baselibc
-    - mgmt/newtmgr
-    - mgmt/newtmgr/transport/ble
-    - net/nimble/host/services/bleuart
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/nimble/controller"
+    - "@apache-mynewt-core/net/nimble/host"
+    - "@apache-mynewt-core/net/nimble/host/services/gap"
+    - "@apache-mynewt-core/net/nimble/host/services/gatt"
+    - "@apache-mynewt-core/net/nimble/host/store/ram"
+    - "@apache-mynewt-core/net/nimble/transport/ram"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/libc/baselibc"
+    - "@apache-mynewt-core/mgmt/newtmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/ble"
+    - "@apache-mynewt-core/net/nimble/host/services/bleuart"
diff --git a/apps/bleuart/src/main.c b/apps/bleuart/src/main.c
old mode 100755
new mode 100644
index e13712c7d8..d9b5d88f3b
--- a/apps/bleuart/src/main.c
+++ b/apps/bleuart/src/main.c
@@ -21,9 +21,7 @@
 #include <string.h>
 #include <stdio.h>
 #include <errno.h>
-#include "sysinit/sysinit.h"
-#include "bsp/bsp.h"
-#include "os/os.h"
+#include "os/mynewt.h"
 #include "bsp/bsp.h"
 #include "hal/hal_gpio.h"
 #include <imgmgr/imgmgr.h>
@@ -159,6 +157,28 @@ bleuart_gap_event(struct ble_gap_event *event, void *arg)
         /* Connection terminated; resume advertising. */
         bleuart_advertise();
         return 0;
+
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        /* Advertising terminated; resume advertising. */
+        bleuart_advertise();
+        return 0;
+
+    case BLE_GAP_EVENT_REPEAT_PAIRING:
+        /* We already have a bond with the peer, but it is attempting to
+         * establish a new secure link.  This app sacrifices security for
+         * convenience: just throw away the old bond and accept the new link.
+         */
+
+        /* Delete the old bond. */
+        rc = ble_gap_conn_find(event->repeat_pairing.conn_handle, &desc);
+        assert(rc == 0);
+        ble_store_util_delete_peer(&desc.peer_id_addr);
+
+        /* Return BLE_GAP_REPEAT_PAIRING_RETRY to indicate that the host should
+         * continue with the pairing operation.
+         */
+        return BLE_GAP_REPEAT_PAIRING_RETRY;
     }
 
     return 0;
@@ -188,9 +208,8 @@ main(void)
     sysinit();
 
     /* Initialize the BLE host. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
     ble_hs_cfg.sync_cb = bleuart_on_sync;
+    ble_hs_cfg.store_status_cb = ble_store_util_status_rr;
 
     rc = bleuart_gatt_svr_init();
     assert(rc == 0);
diff --git a/apps/boot/pkg.yml b/apps/boot/pkg.yml
index 1cd6c29520..7d07516162 100644
--- a/apps/boot/pkg.yml
+++ b/apps/boot/pkg.yml
@@ -20,16 +20,15 @@
 pkg.name: apps/boot
 pkg.type: app
 pkg.description: Boot loader application.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
     - loader
 
 pkg.deps:
-    - boot/bootutil
-    - kernel/os
-    - sys/console/stub
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/console/stub"
 
-pkg.deps.BOOT_SERIAL.OVERWRITE:
-    - sys/console/minimal
-    - boot/boot_serial
+pkg.deps.BOOT_SERIAL:
+    - "@apache-mynewt-core/boot/boot_serial"
diff --git a/apps/boot/src/boot.c b/apps/boot/src/boot.c
old mode 100755
new mode 100644
index d6f0325a75..22dded3ca8
--- a/apps/boot/src/boot.c
+++ b/apps/boot/src/boot.c
@@ -20,16 +20,12 @@
 #include <assert.h>
 #include <stddef.h>
 #include <inttypes.h>
-#include "syscfg/syscfg.h"
+#include "os/mynewt.h"
 #include <flash_map/flash_map.h>
-#include <os/os.h>
 
 #include <hal/hal_bsp.h>
 #include <hal/hal_system.h>
 #include <hal/hal_flash.h>
-#if MYNEWT_VAL(BOOT_SERIAL)
-#include <sysinit/sysinit.h>
-#endif
 #include <console/console.h>
 #include "bootutil/image.h"
 #include "bootutil/bootutil.h"
diff --git a/apps/bsncent/pkg.yml b/apps/bsncent/pkg.yml
new file mode 100644
index 0000000000..bfa57ebc2d
--- /dev/null
+++ b/apps/bsncent/pkg.yml
@@ -0,0 +1,36 @@
+# 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.
+#
+pkg.name: apps/bsncent
+pkg.type: app
+pkg.description: Simple BLE central application.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/nimble/controller"
+    - "@apache-mynewt-core/net/nimble/host"
+    - "@apache-mynewt-core/net/nimble/host/services/gap"
+    - "@apache-mynewt-core/net/nimble/host/services/gatt"
+    - "@apache-mynewt-core/net/nimble/host/store/ram"
+    - "@apache-mynewt-core/net/nimble/transport/ram"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
diff --git a/apps/bsncent/src/bsncent.h b/apps/bsncent/src/bsncent.h
new file mode 100644
index 0000000000..8363f5e849
--- /dev/null
+++ b/apps/bsncent/src/bsncent.h
@@ -0,0 +1,117 @@
+/*
+ * 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 H_BSNCENT_
+#define H_BSNCENT_
+
+#include "os/mynewt.h"
+#include "modlog/modlog.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ble_hs_adv_fields;
+struct ble_gap_conn_desc;
+struct ble_hs_cfg;
+union ble_store_value;
+union ble_store_key;
+
+#define BSNCENT_SVC_GENDATA                 0x1811
+#define BSNCENT_CHR_SUP_NEW_ALERT_CAT_UUID  0x2A47
+#define BSNCENT_CHR_NEW_ALERT               0x2A46
+#define BSNCENT_CHR_SUP_UNR_ALERT_CAT_UUID  0x2A48
+#define BSNCENT_CHR_UNR_ALERT_STAT_UUID     0x2A45
+#define BSNCENT_CHR_ALERT_NOT_CTRL_PT       0x2A44
+
+/** GATT server. */
+void gatt_svr_register(void);
+void gatt_svr_init_cfg(struct ble_hs_cfg *cfg);
+
+
+/** Misc. */
+void print_bytes(const uint8_t *bytes, int len);
+void print_mbuf(const struct os_mbuf *om);
+char *addr_str(const void *addr);
+void print_uuid(const ble_uuid_t *uuid);
+void print_conn_desc(const struct ble_gap_conn_desc *desc);
+void print_adv_fields(const struct ble_hs_adv_fields *fields);
+
+/** Peer. */
+struct peer_dsc {
+    SLIST_ENTRY(peer_dsc) next;
+    struct ble_gatt_dsc dsc;
+};
+SLIST_HEAD(peer_dsc_list, peer_dsc);
+
+struct peer_chr {
+    SLIST_ENTRY(peer_chr) next;
+    struct ble_gatt_chr chr;
+
+    struct peer_dsc_list dscs;
+};
+SLIST_HEAD(peer_chr_list, peer_chr);
+
+struct peer_svc {
+    SLIST_ENTRY(peer_svc) next;
+    struct ble_gatt_svc svc;
+
+    struct peer_chr_list chrs;
+};
+SLIST_HEAD(peer_svc_list, peer_svc);
+
+struct peer;
+typedef void peer_disc_fn(const struct peer *peer, int status, void *arg);
+
+struct peer {
+    SLIST_ENTRY(peer) next;
+
+    uint16_t conn_handle;
+
+    /** List of discovered GATT services. */
+    struct peer_svc_list svcs;
+
+    /** Keeps track of where we are in the service discovery process. */
+    uint16_t disc_prev_chr_val;
+    struct peer_svc *cur_svc;
+
+    /** Callback that gets executed when service discovery completes. */
+    peer_disc_fn *disc_cb;
+    void *disc_cb_arg;
+};
+
+int peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb,
+                  void *disc_cb_arg);
+const struct peer_dsc *
+peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
+                   const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid);
+const struct peer_chr *
+peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
+                   const ble_uuid_t *chr_uuid);
+const struct peer_svc *
+peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid);
+int peer_delete(uint16_t conn_handle);
+int peer_add(uint16_t conn_handle);
+int peer_count(void);
+int peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/apps/bsncent/src/main.c b/apps/bsncent/src/main.c
new file mode 100644
index 0000000000..bb9d4bdc71
--- /dev/null
+++ b/apps/bsncent/src/main.c
@@ -0,0 +1,450 @@
+/*
+ * 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 <string.h>
+#include "os/mynewt.h"
+#include "bsp/bsp.h"
+#include "console/console.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "controller/ble_ll.h"
+#include "host/ble_hs.h"
+
+/* RAM HCI transport. */
+#include "transport/ram/ble_hci_ram.h"
+
+/* Mandatory services. */
+#include "services/gap/ble_svc_gap.h"
+#include "services/gatt/ble_svc_gatt.h"
+
+/* Application-specified header. */
+#include "bsncent.h"
+
+#define BSNCENT_PRINT_RATE      (OS_TICKS_PER_SEC * 10)
+
+static uint32_t num_notify_pkts_rx;
+static uint32_t num_notify_bytes_rx;
+
+/* Prints statistics every 10 seconds. */
+static struct os_callout bsncent_print_timer;
+
+/* c66f3301-33b3-4687-850a-d52b0d5d1e3c */
+static const ble_uuid128_t bsncent_svc_gendata_uuid =
+    BLE_UUID128_INIT(0x3c, 0x1e, 0x5d, 0x0d, 0x2b, 0xd5, 0x0a, 0x85,
+                     0x87, 0x46, 0xb3, 0x33, 0x01, 0x33, 0x6f, 0xc6);
+
+/* c66f3301-33b3-4687-850a-d52b0d5d1e3d */
+static const ble_uuid128_t bsncent_chr_gendata_uuid =
+    BLE_UUID128_INIT(0x3d, 0x1e, 0x5d, 0x0d, 0x2b, 0xd5, 0x0a, 0x85,
+                     0x87, 0x46, 0xb3, 0x33, 0x01, 0x33, 0x6f, 0xc6);
+
+static const uint8_t bsncent_cent_public_addr[6] = {
+    0x0a, 0x0b, 0x09, 0x09, 0x09, 0x00,
+};
+
+static const ble_addr_t bsncent_peer_addrs[] = {
+    { BLE_ADDR_PUBLIC, { 0x0a, 0x0b, 0x09, 0x09, 0x09, 0x01 } },
+    { BLE_ADDR_PUBLIC, { 0x0a, 0x0b, 0x09, 0x09, 0x09, 0x02 } },
+    { BLE_ADDR_PUBLIC, { 0x0a, 0x0b, 0x09, 0x09, 0x09, 0x03 } },
+    { BLE_ADDR_PUBLIC, { 0x0a, 0x0b, 0x09, 0x09, 0x09, 0x04 } },
+    { BLE_ADDR_PUBLIC, { 0x0a, 0x0b, 0x09, 0x09, 0x09, 0x05 } },
+};
+static const int bsncent_num_peer_addrs =
+    sizeof bsncent_peer_addrs / sizeof bsncent_peer_addrs[0];
+
+static int bsncent_gap_event(struct ble_gap_event *event, void *arg);
+
+static const struct ble_gap_conn_params ble_gap_conn_params_bsn = {
+   .scan_itvl = 0x0010,
+   .scan_window = 0x0010,
+   .itvl_min = 13,
+   .itvl_max = 13,
+   .latency = BLE_GAP_INITIAL_CONN_LATENCY,
+   .supervision_timeout = BLE_GAP_INITIAL_SUPERVISION_TIMEOUT,
+   .min_ce_len = BLE_GAP_INITIAL_CONN_MIN_CE_LEN,
+   .max_ce_len = BLE_GAP_INITIAL_CONN_MAX_CE_LEN,
+};
+
+/**
+ * Application callback.  Called when the attempt to subscribe to notifications
+ * for the ANS Unread Alert Status characteristic has completed.
+ */
+static int
+bsncent_on_subscribe(uint16_t conn_handle,
+                     const struct ble_gatt_error *error,
+                     struct ble_gatt_attr *attr,
+                     void *arg)
+{
+    MODLOG_DFLT(INFO, "Subscribe complete; status=%d conn_handle=%d "
+                      "attr_handle=%d\n",
+                error->status, conn_handle, attr->handle);
+
+    return 0;
+}
+
+/**
+ * Performs three concurrent GATT operations against the specified peer:
+ * 1. Reads the ANS Supported New Alert Category characteristic.
+ * 2. Writes the ANS Alert Notification Control Point characteristic.
+ * 3. Subscribes to notifications for the ANS Unread Alert Status
+ *    characteristic.
+ *
+ * If the peer does not support a required service, characteristic, or
+ * descriptor, then the peer lied when it claimed support for the alert
+ * notification service!  When this happens, or if a GATT procedure fails,
+ * this function immediately terminates the connection.
+ */
+static void
+bsncent_subscribe(const struct peer *peer)
+{
+    const struct peer_dsc *dsc;
+    uint8_t value[2];
+    int rc;
+
+    /* Subscribe to notifications for the gendata characteristic.
+     * A central enables notifications by writing two bytes (1, 0) to the
+     * characteristic's client-characteristic-configuration-descriptor (CCCD).
+     */
+    dsc = peer_dsc_find_uuid(
+        peer,
+        &bsncent_svc_gendata_uuid.u,
+        &bsncent_chr_gendata_uuid.u,
+        BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16));
+    if (dsc == NULL) {
+        MODLOG_DFLT(ERROR, "Error: Peer lacks a CCCD for the generic data "
+                           "characteristic\n");
+        goto err;
+    }
+
+    value[0] = 1;
+    value[1] = 0;
+    rc = ble_gattc_write_flat(peer->conn_handle, dsc->dsc.handle,
+                              value, sizeof value, bsncent_on_subscribe, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "Error: Failed to subscribe to characteristic; "
+                           "rc=%d\n", rc);
+        goto err;
+    }
+
+    return;
+
+err:
+    /* Terminate the connection. */
+    ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+}
+
+/**
+ * Called when service discovery of the specified peer has completed.
+ */
+static void
+bsncent_on_disc_complete(const struct peer *peer, int status, void *arg)
+{
+
+    if (status != 0) {
+        /* Service discovery failed.  Terminate the connection. */
+        MODLOG_DFLT(ERROR, "Error: Service discovery failed; status=%d "
+                           "conn_handle=%d\n", status, peer->conn_handle);
+        ble_gap_terminate(peer->conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+        return;
+    }
+
+    /* Service discovery has completed successfully.  Now we have a complete
+     * list of services, characteristics, and descriptors that the peer
+     * supports.
+     */
+    MODLOG_DFLT(ERROR, "Service discovery complete; status=%d "
+                       "conn_handle=%d\n", status, peer->conn_handle);
+
+    /* Now subscribe to the gendata characterustic. */
+    bsncent_subscribe(peer);
+}
+
+
+static int
+bsncent_on_mtu_exchanged(uint16_t conn_handle,
+                         const struct ble_gatt_error *error,
+                         uint16_t mtu, void *arg)
+{
+    int rc;
+
+    if (error->status != 0) {
+        MODLOG_DFLT(ERROR, "MTU exchange failed; rc=%d\n", error->status);
+        ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+        return 0;
+    }
+
+    /* Perform service discovery. */
+    rc = peer_disc_all(conn_handle, bsncent_on_disc_complete, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "Failed to discover services; rc=%d\n", rc);
+        ble_gap_terminate(conn_handle, BLE_ERR_REM_USER_CONN_TERM);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void
+bsncent_connect(void)
+{
+    int rc;
+
+    rc = ble_gap_connect(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
+                         &ble_gap_conn_params_bsn, bsncent_gap_event, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "Error connecting; rc=%d\n", rc);
+        if (!((rc == BLE_HS_EALREADY) || (rc == BLE_HS_EBUSY))) {
+            /* Only assert if we are not already trying */
+            assert(0);
+        }
+    }
+}
+
+static void
+bsncent_fill_wl(void)
+{
+    int rc;
+
+    rc = ble_gap_wl_set(bsncent_peer_addrs, bsncent_num_peer_addrs);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "Error setting white list; rc=%d\n", rc);
+        assert(0);
+    }
+}
+
+static void
+bsncent_print_timer_reset(void)
+{
+    int rc;
+
+    rc = os_callout_reset(&bsncent_print_timer, BSNCENT_PRINT_RATE);
+    assert(rc == 0);
+}
+
+/**
+ * Prints statistics every 10 seconds.
+ */
+static void
+bsncent_print_timer_exp(struct os_event *ev)
+{
+    static uint32_t prev_bytes;
+    static uint32_t prev_pkts;
+    uint32_t diff_bytes;
+    uint32_t diff_pkts;
+
+    console_printf("--\n");
+    console_printf("%8d connections\n", peer_count());
+    console_printf("%8lu packets received\n",
+                   (unsigned long)num_notify_pkts_rx);
+    console_printf("%8lu bytes received\n",
+                   (unsigned long)num_notify_bytes_rx);
+
+    if (prev_pkts != 0) {
+        diff_pkts = num_notify_pkts_rx - prev_pkts;
+        diff_bytes = num_notify_bytes_rx - prev_bytes;
+
+        console_printf("%8lu packets per second\n",
+                       (unsigned long)(diff_pkts /
+                                       (BSNCENT_PRINT_RATE /
+                                        OS_TICKS_PER_SEC)));
+        console_printf("%8lu bytes per second\n",
+                       (unsigned long)(diff_bytes /
+                                       (BSNCENT_PRINT_RATE /
+                                        OS_TICKS_PER_SEC)));
+    }
+
+    prev_pkts = num_notify_pkts_rx;
+    prev_bytes = num_notify_bytes_rx;
+
+    bsncent_print_timer_reset();
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that is
+ * established.  bsncent uses the same callback for all connections.
+ *
+ * @param event                 The event being signalled.
+ * @param arg                   Application-specified argument; unused by
+ *                                  bsncent.
+ *
+ * @return                      0 if the application successfully handled the
+ *                                  event; nonzero on failure.  The semantics
+ *                                  of the return code is specific to the
+ *                                  particular GAP event being signalled.
+ */
+static int
+bsncent_gap_event(struct ble_gap_event *event, void *arg)
+{
+    struct ble_gap_conn_desc desc;
+    int rc;
+
+    switch (event->type) {
+    case BLE_GAP_EVENT_CONNECT:
+        /* A new connection was established or a connection attempt failed. */
+        if (event->connect.status == 0) {
+            /* Connection successfully established. */
+            MODLOG_DFLT(INFO, "Connection established ");
+
+            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+            assert(rc == 0);
+            print_conn_desc(&desc);
+            MODLOG_DFLT(INFO, "\n");
+
+            /* Remember peer. */
+            rc = peer_add(event->connect.conn_handle);
+            if (rc != 0) {
+                MODLOG_DFLT(ERROR, "Failed to add peer; rc=%d\n", rc);
+                assert(0);
+            }
+
+            /* Try to connect to next peer if any remain unconnected. */
+            if (peer_count() < bsncent_num_peer_addrs) {
+                bsncent_connect();
+            }
+
+            /* Negotiate ATT MTU. */
+            rc = ble_gattc_exchange_mtu(event->connect.conn_handle,
+                                        bsncent_on_mtu_exchanged, NULL);
+            if (rc != 0) {
+                MODLOG_DFLT(ERROR, "Failed to exchange MTU; rc=%d\n", rc);
+                return 0;
+            }
+        } else {
+            /* Connection attempt failed; resume connecting. */
+            MODLOG_DFLT(ERROR, "Error: Connection failed; status=%d\n",
+                        event->connect.status);
+            bsncent_connect();
+        }
+
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        /* Connection terminated. */
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        /* Forget about peer. */
+        peer_delete(event->disconnect.conn.conn_handle);
+
+        /* Resume scanning. */
+        bsncent_connect();
+        return 0;
+
+    case BLE_GAP_EVENT_ENC_CHANGE:
+        /* Encryption has been enabled or disabled for this connection. */
+        MODLOG_DFLT(INFO, "encryption change event; status=%d ",
+                    event->enc_change.status);
+        rc = ble_gap_conn_find(event->enc_change.conn_handle, &desc);
+        assert(rc == 0);
+        print_conn_desc(&desc);
+        return 0;
+
+    case BLE_GAP_EVENT_NOTIFY_RX:
+        /* Peer sent us a notification or indication. */
+        MODLOG_DFLT(DEBUG, "received %s; conn_handle=%d attr_handle=%d "
+                           "attr_len=%d\n",
+                    event->notify_rx.indication ?
+                        "indication" :
+                        "notification",
+                    event->notify_rx.conn_handle,
+                    event->notify_rx.attr_handle,
+                    OS_MBUF_PKTLEN(event->notify_rx.om));
+
+        num_notify_pkts_rx++;
+        num_notify_bytes_rx += OS_MBUF_PKTLEN(event->notify_rx.om);
+
+        /* Attribute data is contained in event->notify_rx.attr_data. */
+        return 0;
+
+    case BLE_GAP_EVENT_MTU:
+        MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
+                    event->mtu.conn_handle,
+                    event->mtu.channel_id,
+                    event->mtu.value);
+        return 0;
+
+    default:
+        return 0;
+    }
+}
+
+static void
+bsncent_on_reset(int reason)
+{
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
+}
+
+static void
+bsncent_on_sync(void)
+{
+    /* Start printing statistics. */
+    bsncent_print_timer_reset();
+
+    /* Add the five known peripherals to the white list. */
+    bsncent_fill_wl();
+
+    /* Attempt to connect to the first peripheral. */
+    bsncent_connect();
+}
+
+/**
+ * main
+ *
+ * All application logic and NimBLE host work is performed in default task.
+ *
+ * @return int NOTE: this function should never return!
+ */
+int
+main(void)
+{
+    int rc;
+
+    /* Set initial BLE device address. */
+    memcpy(g_dev_addr, bsncent_cent_public_addr, 6);
+
+    /* Initialize OS */
+    sysinit();
+
+    /* Configure the host. */
+    ble_hs_cfg.reset_cb = bsncent_on_reset;
+    ble_hs_cfg.sync_cb = bsncent_on_sync;
+
+    os_callout_init(&bsncent_print_timer, os_eventq_dflt_get(),
+                    bsncent_print_timer_exp, NULL);
+
+    /* XXX: I think some of these need to be based on # of connections */
+    /* Initialize data structures to track connected peers. */
+    rc = peer_init(MYNEWT_VAL(BLE_MAX_CONNECTIONS), 64, 96, 64);
+    assert(rc == 0);
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set(MYNEWT_VAL(BSNCENT_BLE_NAME));
+    assert(rc == 0);
+
+    /* os start should never return. If it does, this should be an error */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+
+    return 0;
+}
diff --git a/apps/bsncent/src/misc.c b/apps/bsncent/src/misc.c
new file mode 100644
index 0000000000..7b00273270
--- /dev/null
+++ b/apps/bsncent/src/misc.c
@@ -0,0 +1,209 @@
+/*
+ * 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 <string.h>
+#include "host/ble_hs.h"
+#include "host/ble_uuid.h"
+#include "bsncent.h"
+
+/**
+ * Utility function to log an array of bytes.
+ */
+void
+print_bytes(const uint8_t *bytes, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        MODLOG_DFLT(DEBUG, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
+    }
+}
+
+void
+print_mbuf(const struct os_mbuf *om)
+{
+    int colon;
+
+    colon = 0;
+    while (om != NULL) {
+        if (colon) {
+            MODLOG_DFLT(DEBUG, ":");
+        } else {
+            colon = 1;
+        }
+        print_bytes(om->om_data, om->om_len);
+        om = SLIST_NEXT(om, om_next);
+    }
+}
+
+char *
+addr_str(const void *addr)
+{
+    static char buf[6 * 2 + 5 + 1];
+    const uint8_t *u8p;
+
+    u8p = addr;
+    sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x",
+            u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
+
+    return buf;
+}
+
+void
+print_uuid(const ble_uuid_t *uuid)
+{
+    char buf[BLE_UUID_STR_LEN];
+
+    MODLOG_DFLT(DEBUG, "%s", ble_uuid_to_str(uuid, buf));
+}
+
+/**
+ * Logs information about a connection to the console.
+ */
+void
+print_conn_desc(const struct ble_gap_conn_desc *desc)
+{
+    MODLOG_DFLT(DEBUG, "handle=%d our_ota_addr_type=%d our_ota_addr=%s ",
+                desc->conn_handle, desc->our_ota_addr.type,
+                addr_str(desc->our_ota_addr.val));
+    MODLOG_DFLT(DEBUG, "our_id_addr_type=%d our_id_addr=%s ",
+                desc->our_id_addr.type, addr_str(desc->our_id_addr.val));
+    MODLOG_DFLT(DEBUG, "peer_ota_addr_type=%d peer_ota_addr=%s ",
+                desc->peer_ota_addr.type, addr_str(desc->peer_ota_addr.val));
+    MODLOG_DFLT(DEBUG, "peer_id_addr_type=%d peer_id_addr=%s ",
+                desc->peer_id_addr.type, addr_str(desc->peer_id_addr.val));
+    MODLOG_DFLT(DEBUG, "conn_itvl=%d conn_latency=%d supervision_timeout=%d "
+                "encrypted=%d authenticated=%d bonded=%d",
+                desc->conn_itvl, desc->conn_latency,
+                desc->supervision_timeout,
+                desc->sec_state.encrypted,
+                desc->sec_state.authenticated,
+                desc->sec_state.bonded);
+}
+
+
+void
+print_adv_fields(const struct ble_hs_adv_fields *fields)
+{
+    char s[BLE_HS_ADV_MAX_SZ];
+    const uint8_t *u8p;
+    int i;
+
+    if (fields->flags != 0) {
+        MODLOG_DFLT(DEBUG, "    flags=0x%02x\n", fields->flags);
+    }
+
+    if (fields->uuids16 != NULL) {
+        MODLOG_DFLT(DEBUG, "    uuids16(%scomplete)=",
+                    fields->uuids16_is_complete ? "" : "in");
+        for (i = 0; i < fields->num_uuids16; i++) {
+            print_uuid(&fields->uuids16[i].u);
+            MODLOG_DFLT(DEBUG, " ");
+        }
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->uuids32 != NULL) {
+        MODLOG_DFLT(DEBUG, "    uuids32(%scomplete)=",
+                    fields->uuids32_is_complete ? "" : "in");
+        for (i = 0; i < fields->num_uuids32; i++) {
+            print_uuid(&fields->uuids32[i].u);
+            MODLOG_DFLT(DEBUG, " ");
+        }
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->uuids128 != NULL) {
+        MODLOG_DFLT(DEBUG, "    uuids128(%scomplete)=",
+                    fields->uuids128_is_complete ? "" : "in");
+        for (i = 0; i < fields->num_uuids128; i++) {
+            print_uuid(&fields->uuids128[i].u);
+            MODLOG_DFLT(DEBUG, " ");
+        }
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->name != NULL) {
+        assert(fields->name_len < sizeof s - 1);
+        memcpy(s, fields->name, fields->name_len);
+        s[fields->name_len] = '\0';
+        MODLOG_DFLT(DEBUG, "    name(%scomplete)=%s\n",
+                    fields->name_is_complete ? "" : "in", s);
+    }
+
+    if (fields->tx_pwr_lvl_is_present) {
+        MODLOG_DFLT(DEBUG, "    tx_pwr_lvl=%d\n", fields->tx_pwr_lvl);
+    }
+
+    if (fields->slave_itvl_range != NULL) {
+        MODLOG_DFLT(DEBUG, "    slave_itvl_range=");
+        print_bytes(fields->slave_itvl_range, BLE_HS_ADV_SLAVE_ITVL_RANGE_LEN);
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->svc_data_uuid16 != NULL) {
+        MODLOG_DFLT(DEBUG, "    svc_data_uuid16=");
+        print_bytes(fields->svc_data_uuid16, fields->svc_data_uuid16_len);
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->public_tgt_addr != NULL) {
+        MODLOG_DFLT(DEBUG, "    public_tgt_addr=");
+        u8p = fields->public_tgt_addr;
+        for (i = 0; i < fields->num_public_tgt_addrs; i++) {
+            MODLOG_DFLT(DEBUG, "public_tgt_addr=%s ", addr_str(u8p));
+            u8p += BLE_HS_ADV_PUBLIC_TGT_ADDR_ENTRY_LEN;
+        }
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->appearance_is_present) {
+        MODLOG_DFLT(DEBUG, "    appearance=0x%04x\n", fields->appearance);
+    }
+
+    if (fields->adv_itvl_is_present) {
+        MODLOG_DFLT(DEBUG, "    adv_itvl=0x%04x\n", fields->adv_itvl);
+    }
+
+    if (fields->svc_data_uuid32 != NULL) {
+        MODLOG_DFLT(DEBUG, "    svc_data_uuid32=");
+        print_bytes(fields->svc_data_uuid32, fields->svc_data_uuid32_len);
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->svc_data_uuid128 != NULL) {
+        MODLOG_DFLT(DEBUG, "    svc_data_uuid128=");
+        print_bytes(fields->svc_data_uuid128, fields->svc_data_uuid128_len);
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->uri != NULL) {
+        MODLOG_DFLT(DEBUG, "    uri=");
+        print_bytes(fields->uri, fields->uri_len);
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+
+    if (fields->mfg_data != NULL) {
+        MODLOG_DFLT(DEBUG, "    mfg_data=");
+        print_bytes(fields->mfg_data, fields->mfg_data_len);
+        MODLOG_DFLT(DEBUG, "\n");
+    }
+}
diff --git a/apps/bsncent/src/peer.c b/apps/bsncent/src/peer.c
new file mode 100644
index 0000000000..0993e050c0
--- /dev/null
+++ b/apps/bsncent/src/peer.c
@@ -0,0 +1,812 @@
+/*
+ * 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 <string.h>
+#include "host/ble_hs.h"
+#include "bsncent.h"
+
+static void *peer_svc_mem;
+static struct os_mempool peer_svc_pool;
+
+static void *peer_chr_mem;
+static struct os_mempool peer_chr_pool;
+
+static void *peer_dsc_mem;
+static struct os_mempool peer_dsc_pool;
+
+static void *peer_mem;
+static struct os_mempool peer_pool;
+static SLIST_HEAD(, peer) peers;
+
+static struct peer_svc *
+peer_svc_find_range(struct peer *peer, uint16_t attr_handle);
+static struct peer_svc *
+peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
+              struct peer_svc **out_prev);
+int
+peer_svc_is_empty(const struct peer_svc *svc);
+
+uint16_t
+chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr);
+int
+chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr);
+static struct peer_chr *
+peer_chr_find(const struct peer_svc *svc, uint16_t chr_def_handle,
+              struct peer_chr **out_prev);
+static void
+peer_disc_chrs(struct peer *peer);
+
+static int
+peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                uint16_t chr_def_handle, const struct ble_gatt_dsc *dsc,
+                void *arg);
+
+static struct peer *
+peer_find(uint16_t conn_handle)
+{
+    struct peer *peer;
+
+    SLIST_FOREACH(peer, &peers, next) {
+        if (peer->conn_handle == conn_handle) {
+            return peer;
+        }
+    }
+
+    return NULL;
+}
+
+static void
+peer_disc_complete(struct peer *peer, int rc)
+{
+    peer->disc_prev_chr_val = 0;
+
+    /* Notify caller that discovery has completed. */
+    if (peer->disc_cb != NULL) {
+        peer->disc_cb(peer, rc, peer->disc_cb_arg);
+    }
+}
+
+static struct peer_dsc *
+peer_dsc_find_prev(const struct peer_chr *chr, uint16_t dsc_handle)
+{
+    struct peer_dsc *prev;
+    struct peer_dsc *dsc;
+
+    prev = NULL;
+    SLIST_FOREACH(dsc, &chr->dscs, next) {
+        if (dsc->dsc.handle >= dsc_handle) {
+            break;
+        }
+
+        prev = dsc;
+    }
+
+    return prev;
+}
+
+static struct peer_dsc *
+peer_dsc_find(const struct peer_chr *chr, uint16_t dsc_handle,
+              struct peer_dsc **out_prev)
+{
+    struct peer_dsc *prev;
+    struct peer_dsc *dsc;
+
+    prev = peer_dsc_find_prev(chr, dsc_handle);
+    if (prev == NULL) {
+        dsc = SLIST_FIRST(&chr->dscs);
+    } else {
+        dsc = SLIST_NEXT(prev, next);
+    }
+
+    if (dsc != NULL && dsc->dsc.handle != dsc_handle) {
+        dsc = NULL;
+    }
+
+    if (out_prev != NULL) {
+        *out_prev = prev;
+    }
+    return dsc;
+}
+
+static int
+peer_dsc_add(struct peer *peer, uint16_t chr_val_handle,
+             const struct ble_gatt_dsc *gatt_dsc)
+{
+    struct peer_dsc *prev;
+    struct peer_dsc *dsc;
+    struct peer_svc *svc;
+    struct peer_chr *chr;
+
+    svc = peer_svc_find_range(peer, chr_val_handle);
+    if (svc == NULL) {
+        /* Can't find service for discovered descriptor; this shouldn't
+         * happen.
+         */
+        assert(0);
+        return BLE_HS_EUNKNOWN;
+    }
+
+    chr = peer_chr_find(svc, chr_val_handle, NULL);
+    if (chr == NULL) {
+        /* Can't find characteristic for discovered descriptor; this shouldn't
+         * happen.
+         */
+        assert(0);
+        return BLE_HS_EUNKNOWN;
+    }
+
+    dsc = peer_dsc_find(chr, gatt_dsc->handle, &prev);
+    if (dsc != NULL) {
+        /* Descriptor already discovered. */
+        return 0;
+    }
+
+    dsc = os_memblock_get(&peer_dsc_pool);
+    if (dsc == NULL) {
+        /* Out of memory. */
+        return BLE_HS_ENOMEM;
+    }
+    memset(dsc, 0, sizeof *dsc);
+
+    dsc->dsc = *gatt_dsc;
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&chr->dscs, dsc, next);
+    } else {
+        SLIST_NEXT(prev, next) = dsc;
+    }
+
+    return 0;
+}
+
+static void
+peer_disc_dscs(struct peer *peer)
+{
+    struct peer_chr *chr;
+    struct peer_svc *svc;
+    int rc;
+
+    /* Search through the list of discovered characteristics for the first
+     * characteristic that contains undiscovered descriptors.  Then, discover
+     * all descriptors belonging to that characteristic.
+     */
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        SLIST_FOREACH(chr, &svc->chrs, next) {
+            if (!chr_is_empty(svc, chr) &&
+                SLIST_EMPTY(&chr->dscs) &&
+                peer->disc_prev_chr_val <= chr->chr.def_handle) {
+
+                rc = ble_gattc_disc_all_dscs(peer->conn_handle,
+                                             chr->chr.val_handle,
+                                             chr_end_handle(svc, chr),
+                                             peer_dsc_disced, peer);
+                if (rc != 0) {
+                    peer_disc_complete(peer, rc);
+                }
+
+                peer->disc_prev_chr_val = chr->chr.val_handle;
+                return;
+            }
+        }
+    }
+
+    /* All descriptors discovered. */
+    peer_disc_complete(peer, 0);
+}
+
+static int
+peer_dsc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                uint16_t chr_val_handle, const struct ble_gatt_dsc *dsc,
+                void *arg)
+{
+    struct peer *peer;
+    int rc;
+
+    peer = arg;
+    assert(peer->conn_handle == conn_handle);
+
+    switch (error->status) {
+    case 0:
+        rc = peer_dsc_add(peer, chr_val_handle, dsc);
+        break;
+
+    case BLE_HS_EDONE:
+        /* All descriptors in this characteristic discovered; start discovering
+         * descriptors in the next characteristic.
+         */
+        if (peer->disc_prev_chr_val > 0) {
+            peer_disc_dscs(peer);
+        }
+        rc = 0;
+        break;
+
+    default:
+        /* Error; abort discovery. */
+        rc = error->status;
+        break;
+    }
+
+    if (rc != 0) {
+        /* Error; abort discovery. */
+        peer_disc_complete(peer, rc);
+    }
+
+    return rc;
+}
+
+uint16_t
+chr_end_handle(const struct peer_svc *svc, const struct peer_chr *chr)
+{
+    const struct peer_chr *next_chr;
+
+    next_chr = SLIST_NEXT(chr, next);
+    if (next_chr != NULL) {
+        return next_chr->chr.def_handle - 1;
+    } else {
+        return svc->svc.end_handle;
+    }
+}
+
+int
+chr_is_empty(const struct peer_svc *svc, const struct peer_chr *chr)
+{
+    return chr_end_handle(svc, chr) <= chr->chr.val_handle;
+}
+
+static struct peer_chr *
+peer_chr_find_prev(const struct peer_svc *svc, uint16_t chr_val_handle)
+{
+    struct peer_chr *prev;
+    struct peer_chr *chr;
+
+    prev = NULL;
+    SLIST_FOREACH(chr, &svc->chrs, next) {
+        if (chr->chr.val_handle >= chr_val_handle) {
+            break;
+        }
+
+        prev = chr;
+    }
+
+    return prev;
+}
+
+static struct peer_chr *
+peer_chr_find(const struct peer_svc *svc, uint16_t chr_val_handle,
+              struct peer_chr **out_prev)
+{
+    struct peer_chr *prev;
+    struct peer_chr *chr;
+
+    prev = peer_chr_find_prev(svc, chr_val_handle);
+    if (prev == NULL) {
+        chr = SLIST_FIRST(&svc->chrs);
+    } else {
+        chr = SLIST_NEXT(prev, next);
+    }
+
+    if (chr != NULL && chr->chr.val_handle != chr_val_handle) {
+        chr = NULL;
+    }
+
+    if (out_prev != NULL) {
+        *out_prev = prev;
+    }
+    return chr;
+}
+
+static void
+peer_chr_delete(struct peer_chr *chr)
+{
+    struct peer_dsc *dsc;
+
+    while ((dsc = SLIST_FIRST(&chr->dscs)) != NULL) {
+        SLIST_REMOVE_HEAD(&chr->dscs, next);
+        os_memblock_put(&peer_dsc_pool, dsc);
+    }
+
+    os_memblock_put(&peer_chr_pool, chr);
+}
+
+static int
+peer_chr_add(struct peer *peer,  uint16_t svc_start_handle,
+             const struct ble_gatt_chr *gatt_chr)
+{
+    struct peer_chr *prev;
+    struct peer_chr *chr;
+    struct peer_svc *svc;
+
+    svc = peer_svc_find(peer, svc_start_handle, NULL);
+    if (svc == NULL) {
+        /* Can't find service for discovered characteristic; this shouldn't
+         * happen.
+         */
+        assert(0);
+        return BLE_HS_EUNKNOWN;
+    }
+
+    chr = peer_chr_find(svc, gatt_chr->def_handle, &prev);
+    if (chr != NULL) {
+        /* Characteristic already discovered. */
+        return 0;
+    }
+
+    chr = os_memblock_get(&peer_chr_pool);
+    if (chr == NULL) {
+        /* Out of memory. */
+        return BLE_HS_ENOMEM;
+    }
+    memset(chr, 0, sizeof *chr);
+
+    chr->chr = *gatt_chr;
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&svc->chrs, chr, next);
+    } else {
+        SLIST_NEXT(prev, next) = chr;
+    }
+
+    return 0;
+}
+
+static int
+peer_chr_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                const struct ble_gatt_chr *chr, void *arg)
+{
+    struct peer *peer;
+    int rc;
+
+    peer = arg;
+    assert(peer->conn_handle == conn_handle);
+
+    switch (error->status) {
+    case 0:
+        rc = peer_chr_add(peer, peer->cur_svc->svc.start_handle, chr);
+        break;
+
+    case BLE_HS_EDONE:
+        /* All characteristics in this service discovered; start discovering
+         * characteristics in the next service.
+         */
+        if (peer->disc_prev_chr_val > 0) {
+             peer_disc_chrs(peer);
+        }
+        rc = 0;
+        break;
+
+    default:
+        rc = error->status;
+        break;
+    }
+
+    if (rc != 0) {
+        /* Error; abort discovery. */
+        peer_disc_complete(peer, rc);
+    }
+
+    return rc;
+}
+
+static void
+peer_disc_chrs(struct peer *peer)
+{
+    struct peer_svc *svc;
+    int rc;
+
+    /* Search through the list of discovered service for the first service that
+     * contains undiscovered characteristics.  Then, discover all
+     * characteristics belonging to that service.
+     */
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (!peer_svc_is_empty(svc) && SLIST_EMPTY(&svc->chrs)) {
+            peer->cur_svc = svc;
+            rc = ble_gattc_disc_all_chrs(peer->conn_handle,
+                                         svc->svc.start_handle,
+                                         svc->svc.end_handle,
+                                         peer_chr_disced, peer);
+            if (rc != 0) {
+                peer_disc_complete(peer, rc);
+            }
+            return;
+        }
+    }
+
+    /* All characteristics discovered. */
+    peer_disc_dscs(peer);
+}
+
+int
+peer_svc_is_empty(const struct peer_svc *svc)
+{
+    return svc->svc.end_handle <= svc->svc.start_handle;
+}
+
+static struct peer_svc *
+peer_svc_find_prev(struct peer *peer, uint16_t svc_start_handle)
+{
+    struct peer_svc *prev;
+    struct peer_svc *svc;
+
+    prev = NULL;
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (svc->svc.start_handle >= svc_start_handle) {
+            break;
+        }
+
+        prev = svc;
+    }
+
+    return prev;
+}
+
+static struct peer_svc *
+peer_svc_find(struct peer *peer, uint16_t svc_start_handle,
+              struct peer_svc **out_prev)
+{
+    struct peer_svc *prev;
+    struct peer_svc *svc;
+
+    prev = peer_svc_find_prev(peer, svc_start_handle);
+    if (prev == NULL) {
+        svc = SLIST_FIRST(&peer->svcs);
+    } else {
+        svc = SLIST_NEXT(prev, next);
+    }
+
+    if (svc != NULL && svc->svc.start_handle != svc_start_handle) {
+        svc = NULL;
+    }
+
+    if (out_prev != NULL) {
+        *out_prev = prev;
+    }
+    return svc;
+}
+
+static struct peer_svc *
+peer_svc_find_range(struct peer *peer, uint16_t attr_handle)
+{
+    struct peer_svc *svc;
+
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (svc->svc.start_handle <= attr_handle &&
+            svc->svc.end_handle >= attr_handle) {
+
+            return svc;
+        }
+    }
+
+    return NULL;
+}
+
+const struct peer_svc *
+peer_svc_find_uuid(const struct peer *peer, const ble_uuid_t *uuid)
+{
+    const struct peer_svc *svc;
+
+    SLIST_FOREACH(svc, &peer->svcs, next) {
+        if (ble_uuid_cmp(&svc->svc.uuid.u, uuid) == 0) {
+            return svc;
+        }
+    }
+
+    return NULL;
+}
+
+const struct peer_chr *
+peer_chr_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
+                   const ble_uuid_t *chr_uuid)
+{
+    const struct peer_svc *svc;
+    const struct peer_chr *chr;
+
+    svc = peer_svc_find_uuid(peer, svc_uuid);
+    if (svc == NULL) {
+        return NULL;
+    }
+
+    SLIST_FOREACH(chr, &svc->chrs, next) {
+        if (ble_uuid_cmp(&chr->chr.uuid.u, chr_uuid) == 0) {
+            return chr;
+        }
+    }
+
+    return NULL;
+}
+
+const struct peer_dsc *
+peer_dsc_find_uuid(const struct peer *peer, const ble_uuid_t *svc_uuid,
+                   const ble_uuid_t *chr_uuid, const ble_uuid_t *dsc_uuid)
+{
+    const struct peer_chr *chr;
+    const struct peer_dsc *dsc;
+
+    chr = peer_chr_find_uuid(peer, svc_uuid, chr_uuid);
+    if (chr == NULL) {
+        return NULL;
+    }
+
+    SLIST_FOREACH(dsc, &chr->dscs, next) {
+        if (ble_uuid_cmp(&dsc->dsc.uuid.u, dsc_uuid) == 0) {
+            return dsc;
+        }
+    }
+
+    return NULL;
+}
+
+static int
+peer_svc_add(struct peer *peer, const struct ble_gatt_svc *gatt_svc)
+{
+    struct peer_svc *prev;
+    struct peer_svc *svc;
+
+    svc = peer_svc_find(peer, gatt_svc->start_handle, &prev);
+    if (svc != NULL) {
+        /* Service already discovered. */
+        return 0;
+    }
+
+    svc = os_memblock_get(&peer_svc_pool);
+    if (svc == NULL) {
+        /* Out of memory. */
+        return BLE_HS_ENOMEM;
+    }
+    memset(svc, 0, sizeof *svc);
+
+    svc->svc = *gatt_svc;
+    SLIST_INIT(&svc->chrs);
+
+    if (prev == NULL) {
+        SLIST_INSERT_HEAD(&peer->svcs, svc, next);
+    } else {
+        SLIST_INSERT_AFTER(prev, svc, next);
+    }
+
+    return 0;
+}
+
+static void
+peer_svc_delete(struct peer_svc *svc)
+{
+    struct peer_chr *chr;
+
+    while ((chr = SLIST_FIRST(&svc->chrs)) != NULL) {
+        SLIST_REMOVE_HEAD(&svc->chrs, next);
+        peer_chr_delete(chr);
+    }
+
+    os_memblock_put(&peer_svc_pool, svc);
+}
+
+static int
+peer_svc_disced(uint16_t conn_handle, const struct ble_gatt_error *error,
+                const struct ble_gatt_svc *service, void *arg)
+{
+    struct peer *peer;
+    int rc;
+
+    peer = arg;
+    assert(peer->conn_handle == conn_handle);
+
+    switch (error->status) {
+    case 0:
+        rc = peer_svc_add(peer, service);
+        break;
+
+    case BLE_HS_EDONE:
+        /* All services discovered; start discovering characteristics. */
+        if (peer->disc_prev_chr_val > 0) {
+            peer_disc_chrs(peer);
+        }
+        rc = 0;
+        break;
+
+    default:
+        rc = error->status;
+        break;
+    }
+
+    if (rc != 0) {
+        /* Error; abort discovery. */
+        peer_disc_complete(peer, rc);
+    }
+
+    return rc;
+}
+
+int
+peer_disc_all(uint16_t conn_handle, peer_disc_fn *disc_cb, void *disc_cb_arg)
+{
+    struct peer_svc *svc;
+    struct peer *peer;
+    int rc;
+
+    peer = peer_find(conn_handle);
+    if (peer == NULL) {
+        return BLE_HS_ENOTCONN;
+    }
+
+    /* Undiscover everything first. */
+    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
+        SLIST_REMOVE_HEAD(&peer->svcs, next);
+        peer_svc_delete(svc);
+    }
+
+    peer->disc_prev_chr_val = 1;
+    peer->disc_cb = disc_cb;
+    peer->disc_cb_arg = disc_cb_arg;
+
+    rc = ble_gattc_disc_all_svcs(conn_handle, peer_svc_disced, peer);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
+
+int
+peer_delete(uint16_t conn_handle)
+{
+    struct peer_svc *svc;
+    struct peer *peer;
+    int rc;
+
+    peer = peer_find(conn_handle);
+    if (peer == NULL) {
+        return BLE_HS_ENOTCONN;
+    }
+
+    SLIST_REMOVE(&peers, peer, peer, next);
+
+    while ((svc = SLIST_FIRST(&peer->svcs)) != NULL) {
+        SLIST_REMOVE_HEAD(&peer->svcs, next);
+        peer_svc_delete(svc);
+    }
+
+    rc = os_memblock_put(&peer_pool, peer);
+    if (rc != 0) {
+        return BLE_HS_EOS;
+    }
+
+    return 0;
+}
+
+int
+peer_add(uint16_t conn_handle)
+{
+    struct peer *peer;
+
+    /* Make sure the connection handle is unique. */
+    peer = peer_find(conn_handle);
+    if (peer != NULL) {
+        return BLE_HS_EALREADY;
+    }
+
+    peer = os_memblock_get(&peer_pool);
+    if (peer == NULL) {
+        /* Out of memory. */
+        return BLE_HS_ENOMEM;
+    }
+
+    memset(peer, 0, sizeof *peer);
+    peer->conn_handle = conn_handle;
+
+    SLIST_INSERT_HEAD(&peers, peer, next);
+
+    return 0;
+}
+
+int
+peer_count(void)
+{
+    return peer_pool.mp_num_blocks - peer_pool.mp_num_free;
+}
+
+static void
+peer_free_mem(void)
+{
+    free(peer_mem);
+    peer_mem = NULL;
+
+    free(peer_svc_mem);
+    peer_svc_mem = NULL;
+
+    free(peer_chr_mem);
+    peer_chr_mem = NULL;
+
+    free(peer_dsc_mem);
+    peer_dsc_mem = NULL;
+}
+
+int
+peer_init(int max_peers, int max_svcs, int max_chrs, int max_dscs)
+{
+    int rc;
+
+    /* Free memory first in case this function gets called more than once. */
+    peer_free_mem();
+
+    peer_mem = malloc(
+        OS_MEMPOOL_BYTES(max_peers, sizeof (struct peer)));
+    if (peer_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_pool, max_peers,
+                         sizeof (struct peer), peer_mem,
+                         "peer_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    peer_svc_mem = malloc(
+        OS_MEMPOOL_BYTES(max_svcs, sizeof (struct peer_svc)));
+    if (peer_svc_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_svc_pool, max_svcs,
+                         sizeof (struct peer_svc), peer_svc_mem,
+                         "peer_svc_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    peer_chr_mem = malloc(
+        OS_MEMPOOL_BYTES(max_chrs, sizeof (struct peer_chr)));
+    if (peer_chr_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_chr_pool, max_chrs,
+                         sizeof (struct peer_chr), peer_chr_mem,
+                         "peer_chr_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    peer_dsc_mem = malloc(
+        OS_MEMPOOL_BYTES(max_dscs, sizeof (struct peer_dsc)));
+    if (peer_dsc_mem == NULL) {
+        rc = BLE_HS_ENOMEM;
+        goto err;
+    }
+
+    rc = os_mempool_init(&peer_dsc_pool, max_dscs,
+                         sizeof (struct peer_dsc), peer_dsc_mem,
+                         "peer_dsc_pool");
+    if (rc != 0) {
+        rc = BLE_HS_EOS;
+        goto err;
+    }
+
+    return 0;
+
+err:
+    peer_free_mem();
+    return rc;
+}
diff --git a/apps/bsncent/syscfg.yml b/apps/bsncent/syscfg.yml
new file mode 100644
index 0000000000..2324068575
--- /dev/null
+++ b/apps/bsncent/syscfg.yml
@@ -0,0 +1,29 @@
+# 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.
+#
+
+syscfg.defs:
+    BSNCENT_BLE_NAME:
+        description: The BLE name to use.
+        value: '"bsncent"'
+
+syscfg.vals:
+    # Disable logging.
+    LOG_LEVEL: 255
+
+    # Turn strict scheduling on
+    BLE_LL_STRICT_CONN_SCHEDULING: 1
diff --git a/apps/bsnprph/pkg.yml b/apps/bsnprph/pkg.yml
new file mode 100644
index 0000000000..b4dbc1e0ea
--- /dev/null
+++ b/apps/bsnprph/pkg.yml
@@ -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.
+#
+pkg.name: apps/bsnprph
+pkg.type: app
+pkg.description: Simple BLE peripheral application.
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/boot/split"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/ble"
+    - "@apache-mynewt-core/net/nimble/controller"
+    - "@apache-mynewt-core/net/nimble/host"
+    - "@apache-mynewt-core/net/nimble/host/services/ans"
+    - "@apache-mynewt-core/net/nimble/host/services/gap"
+    - "@apache-mynewt-core/net/nimble/host/services/gatt"
+    - "@apache-mynewt-core/net/nimble/host/store/ram"
+    - "@apache-mynewt-core/net/nimble/transport/ram"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/sys/sysinit"
+    - "@apache-mynewt-core/sys/id"
diff --git a/apps/bsnprph/src/bsnprph.h b/apps/bsnprph/src/bsnprph.h
new file mode 100644
index 0000000000..e305ac70d2
--- /dev/null
+++ b/apps/bsnprph/src/bsnprph.h
@@ -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.
+ */
+
+#ifndef H_BSNPRPH_
+#define H_BSNPRPH_
+
+#include "os/mynewt.h"
+#include "modlog/modlog.h"
+#include "nimble/ble.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ble_hs_cfg;
+struct ble_gatt_register_ctxt;
+
+/** GATT server. */
+#define GATT_SVR_SVC_ALERT_UUID               0x1811
+#define GATT_SVR_CHR_SUP_NEW_ALERT_CAT_UUID   0x2A47
+#define GATT_SVR_CHR_NEW_ALERT                0x2A46
+#define GATT_SVR_CHR_SUP_UNR_ALERT_CAT_UUID   0x2A48
+#define GATT_SVR_CHR_UNR_ALERT_STAT_UUID      0x2A45
+#define GATT_SVR_CHR_ALERT_NOT_CTRL_PT        0x2A44
+
+void gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg);
+int gatt_svr_init(void);
+
+/** Misc. */
+void print_bytes(const uint8_t *bytes, int len);
+void print_addr(const void *addr);
+
+extern uint16_t gatt_svr_chr_gendata_val_handle;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/apps/bsnprph/src/gatt_svr.c b/apps/bsnprph/src/gatt_svr.c
new file mode 100644
index 0000000000..eefb57bba5
--- /dev/null
+++ b/apps/bsnprph/src/gatt_svr.c
@@ -0,0 +1,131 @@
+/*
+ * 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 <string.h>
+#include "bsp/bsp.h"
+#include "host/ble_hs.h"
+#include "host/ble_uuid.h"
+#include "bsnprph.h"
+
+/**
+ * The vendor specific security test service consists of two characteristics:
+ *     o random-number-generator: generates a random 32-bit number each time
+ *       it is read.  This characteristic can only be read over an encrypted
+ *       connection.
+ *     o static-value: a single-byte characteristic that can always be read,
+ *       but can only be written over an encrypted connection.
+ */
+
+/* c66f3301-33b3-4687-850a-d52b0d5d1e3c */
+static const ble_uuid128_t gatt_svr_svc_gendata_uuid =
+    BLE_UUID128_INIT(0x3c, 0x1e, 0x5d, 0x0d, 0x2b, 0xd5, 0x0a, 0x85,
+                     0x87, 0x46, 0xb3, 0x33, 0x01, 0x33, 0x6f, 0xc6);
+
+/* c66f3301-33b3-4687-850a-d52b0d5d1e3d */
+static const ble_uuid128_t gatt_svr_chr_gendata_uuid =
+    BLE_UUID128_INIT(0x3d, 0x1e, 0x5d, 0x0d, 0x2b, 0xd5, 0x0a, 0x85,
+                     0x87, 0x46, 0xb3, 0x33, 0x01, 0x33, 0x6f, 0xc6);
+
+static int
+gatt_svr_chr_access_gendata(uint16_t conn_handle, uint16_t attr_handle,
+                            struct ble_gatt_access_ctxt *ctxt,
+                            void *arg);
+
+uint16_t gatt_svr_chr_gendata_val_handle;
+
+static const struct ble_gatt_svc_def gatt_svr_svcs[] = {
+    {
+        /*** Service: Generic data. */
+        .type = BLE_GATT_SVC_TYPE_PRIMARY,
+        .uuid = &gatt_svr_svc_gendata_uuid.u,
+        .characteristics = (struct ble_gatt_chr_def[]) { {
+            /*** Characteristic: Generic data. */
+            .uuid = &gatt_svr_chr_gendata_uuid.u,
+            .access_cb = gatt_svr_chr_access_gendata,
+            .flags = BLE_GATT_CHR_F_NOTIFY,
+            .val_handle = &gatt_svr_chr_gendata_val_handle,
+        }, {
+            0, /* No more characteristics in this service. */
+        } },
+    },
+
+    {
+        0, /* No more services. */
+    },
+};
+
+static int
+gatt_svr_chr_access_gendata(uint16_t conn_handle, uint16_t attr_handle,
+                            struct ble_gatt_access_ctxt *ctxt,
+                            void *arg)
+{
+    return BLE_ATT_ERR_UNLIKELY;
+}
+
+void
+gatt_svr_register_cb(struct ble_gatt_register_ctxt *ctxt, void *arg)
+{
+    char buf[BLE_UUID_STR_LEN];
+
+    switch (ctxt->op) {
+    case BLE_GATT_REGISTER_OP_SVC:
+        MODLOG_DFLT(DEBUG, "registered service %s with handle=%d\n",
+                    ble_uuid_to_str(ctxt->svc.svc_def->uuid, buf),
+                    ctxt->svc.handle);
+        break;
+
+    case BLE_GATT_REGISTER_OP_CHR:
+        MODLOG_DFLT(DEBUG, "registering characteristic %s with "
+                           "def_handle=%d val_handle=%d\n",
+                    ble_uuid_to_str(ctxt->chr.chr_def->uuid, buf),
+                    ctxt->chr.def_handle,
+                    ctxt->chr.val_handle);
+        break;
+
+    case BLE_GATT_REGISTER_OP_DSC:
+        MODLOG_DFLT(DEBUG, "registering descriptor %s with handle=%d\n",
+                    ble_uuid_to_str(ctxt->dsc.dsc_def->uuid, buf),
+                    ctxt->dsc.handle);
+        break;
+
+    default:
+        assert(0);
+        break;
+    }
+}
+
+int
+gatt_svr_init(void)
+{
+    int rc;
+
+    rc = ble_gatts_count_cfg(gatt_svr_svcs);
+    if (rc != 0) {
+        return rc;
+    }
+
+    rc = ble_gatts_add_svcs(gatt_svr_svcs);
+    if (rc != 0) {
+        return rc;
+    }
+
+    return 0;
+}
diff --git a/apps/bsnprph/src/main.c b/apps/bsnprph/src/main.c
new file mode 100644
index 0000000000..64c6526ec9
--- /dev/null
+++ b/apps/bsnprph/src/main.c
@@ -0,0 +1,366 @@
+/*
+ * 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 <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include "os/mynewt.h"
+#include "bsp/bsp.h"
+#include "hal/hal_gpio.h"
+#include "console/console.h"
+#include "hal/hal_system.h"
+#include "config/config.h"
+#include "split/split.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+
+/* Application-specified header. */
+#include "bsnprph.h"
+
+#define BSNPRPH_PKT_SZ          80
+#define BSNPRPH_TX_TIMER_RATE   2
+
+static const uint8_t bsnprph_prph_public_addr[6] = {
+    0x0a, 0x0b, 0x09, 0x09, 0x09, 0x05,
+};
+
+static const ble_addr_t bsnprph_central_addr = {
+    BLE_ADDR_PUBLIC,
+    { 0x0a, 0x0b, 0x09, 0x09, 0x09, 0x00 },
+};
+
+/* Sends data to central at 60 Hz. */
+static struct os_callout bsnprph_tx_timer;
+
+/* The handle of the current connection. */
+static uint16_t bsnprph_conn_handle;
+
+static int bsnprph_gap_event(struct ble_gap_event *event, void *arg);
+
+/**
+ * Logs information about a connection to the console.
+ */
+static void
+bsnprph_print_conn_desc(struct ble_gap_conn_desc *desc)
+{
+    MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
+                desc->conn_handle, desc->our_ota_addr.type);
+    print_addr(desc->our_ota_addr.val);
+    MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
+                desc->our_id_addr.type);
+    print_addr(desc->our_id_addr.val);
+    MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
+                desc->peer_ota_addr.type);
+    print_addr(desc->peer_ota_addr.val);
+    MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
+                desc->peer_id_addr.type);
+    print_addr(desc->peer_id_addr.val);
+    MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
+                "encrypted=%d authenticated=%d bonded=%d\n",
+                desc->conn_itvl, desc->conn_latency,
+                desc->supervision_timeout,
+                desc->sec_state.encrypted,
+                desc->sec_state.authenticated,
+                desc->sec_state.bonded);
+}
+
+/**
+ * Enables advertising with the following parameters:
+ *     o General discoverable mode.
+ *     o Directed connectable mode.
+ */
+static void
+bsnprph_advertise(void)
+{
+    struct ble_gap_adv_params adv_params;
+    struct ble_hs_adv_fields fields;
+    const char *name;
+    int rc;
+
+    /**
+     *  Set the advertisement data included in our advertisements:
+     *     o Flags (indicates advertisement type and other general info).
+     *     o Advertising tx power.
+     *     o Device name.
+     *     o 16-bit service UUIDs (alert notifications).
+     */
+
+    memset(&fields, 0, sizeof fields);
+
+    /* Advertise two flags:
+     *     o Discoverability in forthcoming advertisement (general)
+     *     o BLE-only (BR/EDR unsupported).
+     */
+    fields.flags = BLE_HS_ADV_F_DISC_GEN |
+                   BLE_HS_ADV_F_BREDR_UNSUP;
+
+    /* Indicate that the TX power level field should be included; have the
+     * stack fill this value automatically.  This is done by assiging the
+     * special value BLE_HS_ADV_TX_PWR_LVL_AUTO.
+     */
+    fields.tx_pwr_lvl_is_present = 1;
+    fields.tx_pwr_lvl = BLE_HS_ADV_TX_PWR_LVL_AUTO;
+
+    name = ble_svc_gap_device_name();
+    fields.name = (uint8_t *)name;
+    fields.name_len = strlen(name);
+    fields.name_is_complete = 1;
+
+    fields.uuids16 = (ble_uuid16_t[]){
+        BLE_UUID16_INIT(GATT_SVR_SVC_ALERT_UUID)
+    };
+    fields.num_uuids16 = 1;
+    fields.uuids16_is_complete = 1;
+
+    rc = ble_gap_adv_set_fields(&fields);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
+        return;
+    }
+
+    /* Begin advertising. */
+    memset(&adv_params, 0, sizeof adv_params);
+    adv_params.conn_mode = BLE_GAP_CONN_MODE_DIR;
+    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+    adv_params.high_duty_cycle = 1;
+    rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, &bsnprph_central_addr,
+                           BLE_HS_FOREVER, &adv_params,
+                           bsnprph_gap_event, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        return;
+    }
+}
+
+static void
+bsnprph_tx_timer_reset(void)
+{
+    int rc;
+
+    rc = os_callout_reset(&bsnprph_tx_timer, BSNPRPH_TX_TIMER_RATE);
+    assert(rc == 0);
+}
+
+/**
+ * Transmits dummy data at 60 Hz.
+ */
+static void
+bsnprph_tx_timer_exp(struct os_event *ev)
+{
+    static uint8_t buf[BSNPRPH_PKT_SZ];
+    static uint8_t val;
+
+    struct os_mbuf *om;
+    int rc;
+
+    memset(buf, val, sizeof buf);
+    val++;
+
+    om = ble_hs_mbuf_from_flat(buf, sizeof buf);
+    if (om == NULL) {
+        /* XXX: OOM; log this. */
+    } else {
+        rc = ble_gattc_notify_custom(bsnprph_conn_handle,
+                                     gatt_svr_chr_gendata_val_handle, om);
+        if (rc != 0) {
+            /* XXX: Log this. */
+        }
+    }
+
+    bsnprph_tx_timer_reset();
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that forms.
+ * bsnprph uses the same callback for all connections.
+ *
+ * @param event                 The type of event being signalled.
+ * @param ctxt                  Various information pertaining to the event.
+ * @param arg                   Application-specified argument; unuesd by
+ *                                  bsnprph.
+ *
+ * @return                      0 if the application successfully handled the
+ *                                  event; nonzero on failure.  The semantics
+ *                                  of the return code is specific to the
+ *                                  particular GAP event being signalled.
+ */
+static int
+bsnprph_gap_event(struct ble_gap_event *event, void *arg)
+{
+    struct ble_gap_conn_desc desc;
+    int rc;
+
+    switch (event->type) {
+    case BLE_GAP_EVENT_CONNECT:
+        /* A new connection was established or a connection attempt failed. */
+        MODLOG_DFLT(INFO, "connection %s; status=%d ",
+                    event->connect.status == 0 ? "established" : "failed",
+                    event->connect.status);
+        if (event->connect.status == 0) {
+            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+            assert(rc == 0);
+            bsnprph_print_conn_desc(&desc);
+
+            bsnprph_conn_handle = event->connect.conn_handle;
+        }
+        MODLOG_DFLT(INFO, "\n");
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            bsnprph_advertise();
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        os_callout_stop(&bsnprph_tx_timer);
+
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        bsnprph_print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        /* Connection terminated; resume advertising. */
+        bsnprph_advertise();
+        return 0;
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        os_callout_stop(&bsnprph_tx_timer);
+        MODLOG_DFLT(INFO, "adv complete\n");
+        bsnprph_advertise();
+        return 0;
+
+    case BLE_GAP_EVENT_CONN_UPDATE:
+        /* The central has updated the connection parameters. */
+        MODLOG_DFLT(INFO, "connection updated; status=%d ",
+                    event->conn_update.status);
+        rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+        assert(rc == 0);
+        bsnprph_print_conn_desc(&desc);
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+    case BLE_GAP_EVENT_ENC_CHANGE:
+        /* Encryption has been enabled or disabled for this connection. */
+        MODLOG_DFLT(INFO, "encryption change event; status=%d ",
+                    event->enc_change.status);
+        rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+        assert(rc == 0);
+        bsnprph_print_conn_desc(&desc);
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+    case BLE_GAP_EVENT_SUBSCRIBE:
+        MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
+                          "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
+                    event->subscribe.conn_handle,
+                    event->subscribe.attr_handle,
+                    event->subscribe.reason,
+                    event->subscribe.prev_notify,
+                    event->subscribe.cur_notify,
+                    event->subscribe.prev_indicate,
+                    event->subscribe.cur_indicate);
+        if (event->subscribe.attr_handle == gatt_svr_chr_gendata_val_handle) {
+            /* Start transmitting notifications. */
+            bsnprph_tx_timer_reset();
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_MTU:
+        MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
+                    event->mtu.conn_handle,
+                    event->mtu.channel_id,
+                    event->mtu.value);
+        return 0;
+    }
+
+    return 0;
+}
+
+static void
+bsnprph_on_reset(int reason)
+{
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
+}
+
+static void
+bsnprph_on_sync(void)
+{
+    /* Begin advertising. */
+    bsnprph_advertise();
+}
+
+/**
+ * main
+ *
+ * The main task for the project. This function initializes the packages,
+ * then starts serving events from default event queue.
+ *
+ * @return int NOTE: this function should never return!
+ */
+int
+main(void)
+{
+    int rc;
+
+    /* Initialize OS */
+    sysinit();
+
+    /* Set initial BLE device address. */
+    memcpy(g_dev_addr, bsnprph_prph_public_addr, 6);
+
+    /* Initialize the NimBLE host configuration. */
+    ble_hs_cfg.reset_cb = bsnprph_on_reset;
+    ble_hs_cfg.sync_cb = bsnprph_on_sync;
+    ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
+
+    os_callout_init(&bsnprph_tx_timer, os_eventq_dflt_get(),
+                    bsnprph_tx_timer_exp, NULL);
+
+    rc = gatt_svr_init();
+    assert(rc == 0);
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set(MYNEWT_VAL(BSNPRPH_BLE_NAME));
+    assert(rc == 0);
+
+    /* If this app is acting as the loader in a split image setup, jump into
+     * the second stage application instead of starting the OS.
+     */
+#if MYNEWT_VAL(SPLIT_LOADER)
+    {
+        void *entry;
+        rc = split_app_go(&entry, true);
+        if (rc == 0) {
+            hal_system_start(entry);
+        }
+    }
+#endif
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    return 0;
+}
diff --git a/apps/bsnprph/src/misc.c b/apps/bsnprph/src/misc.c
new file mode 100644
index 0000000000..6b2e58432c
--- /dev/null
+++ b/apps/bsnprph/src/misc.c
@@ -0,0 +1,43 @@
+/*
+ * 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 "bsnprph.h"
+
+/**
+ * Utility function to log an array of bytes.
+ */
+void
+print_bytes(const uint8_t *bytes, int len)
+{
+    int i;
+
+    for (i = 0; i < len; i++) {
+        MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
+    }
+}
+
+void
+print_addr(const void *addr)
+{
+    const uint8_t *u8p;
+
+    u8p = addr;
+    MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
+             u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
+}
diff --git a/apps/bsnprph/syscfg.yml b/apps/bsnprph/syscfg.yml
new file mode 100644
index 0000000000..a20c1e8450
--- /dev/null
+++ b/apps/bsnprph/syscfg.yml
@@ -0,0 +1,32 @@
+# 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.
+#
+
+syscfg.defs:
+    BSNPRPH_BLE_NAME:
+        description: The BLE name to use.
+        value: '"bsnprph"'
+
+syscfg.vals:
+    # Use INFO log level to reduce code size.  DEBUG is too large for nRF51.
+    LOG_LEVEL: 1
+
+    # Disable central and observer roles.
+    BLE_ROLE_BROADCASTER: 1
+    BLE_ROLE_CENTRAL: 0
+    BLE_ROLE_OBSERVER: 0
+    BLE_ROLE_PERIPHERAL: 1
diff --git a/apps/fat2native/pkg.yml b/apps/fat2native/pkg.yml
deleted file mode 100644
index 1ba07f132e..0000000000
--- a/apps/fat2native/pkg.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-#
-# 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.
-#
-
-pkg.name: apps/fat2native
-pkg.type: app
-pkg.description: Support application for debugging the FAT File System.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
-pkg.homepage: "http://mynewt.apache.org/"
-pkg.keywords:
-
-pkg.deps:
-    - fs/fatfs
-    - hw/hal
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/stub
-    - kernel/os
diff --git a/apps/fat2native/src/main.c b/apps/fat2native/src/main.c
deleted file mode 100644
index 00e281b02b..0000000000
--- a/apps/fat2native/src/main.c
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * 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 <stdio.h>
-#include <unistd.h>
-#include <stdlib.h>
-
-#include <sysinit/sysinit.h>
-#include <fs/fs.h>
-
-#ifdef ARCH_sim
-#include <mcu/mcu_sim.h>
-#endif
-
-#include <fatfs/ff.h>
-#include <fs/fs_if.h>
-
-extern const struct fs_ops *fs_root_ops;
-static const char *progname;
-
-static void
-usage(int rc)
-{
-    printf("%s [-h][-f image_file]\n", progname);
-    printf("  Tool for operating on simulator flash image file\n");
-    printf("   -f: flash_file is the name of the flash image file\n");
-    exit(rc);
-}
-
-int
-main(int argc, char **argv)
-{
-    int ch;
-    FATFS fs;
-    FATFS *p_fs;
-    DWORD fre_clust, fre_sect, tot_sect;
-    FRESULT res;
-    struct fs_dir *dir;
-    struct fs_dirent *dirent;
-    struct fs_file *file;
-    char out_name[80];
-    uint8_t u8_len;
-    uint32_t u32_len;
-    int rc;
-    uint8_t buf[32];
-    static const BYTE ft[] = {0, 12, 16, 32};
-
-    progname = argv[0];
-
-    while ((ch = getopt(argc, argv, "f:v")) != -1) {
-        switch (ch) {
-        case 'f':
-            native_flash_file = optarg;
-            break;
-        case '?':
-        case 'h':
-        default:
-            usage(0);
-        }
-    }
-
-    sysinit();
-
-    /* TODO:
-     * log_register("fatfs-log", &nffs_log, &log_console_handler, NULL, LOG_SYSLEVEL);
-     */
-
-    f_mount(&fs, "0:", 0);
-
-    /* Get volume information and free clusters of drive 1 */
-    res = f_getfree("0:", &fre_clust, &p_fs);
-    if (res) {
-        printf("f_getfree() failed %d\n", res);
-        exit(1);
-    }
-
-    printf("\nFAT type = FAT%u\n"
-           "Number of FATs = %u\n"
-           "Root DIR entries = %u\n"
-           "Sectors/FAT = %lu\n"
-           "Volume start = %lu\n"
-           "FAT start = %lu\n"
-           "DIR start = %lu\n"
-           "Data start = %lu\n\n",
-        ft[p_fs->fs_type & 3], p_fs->n_fats, p_fs->n_rootdir, p_fs->fsize,
-        p_fs->volbase, p_fs->fatbase, p_fs->dirbase, p_fs->database);
-
-    /* Print the free space (assuming 512 bytes/sector) */
-
-    tot_sect = (p_fs->n_fatent - 2) * p_fs->csize;
-    fre_sect = fre_clust * p_fs->csize;
-
-    printf("%8lu KiB total drive space.\n"
-           "%8lu KiB available.\n",
-           tot_sect / 2, fre_sect / 2);
-
-    /* List contents of root directory */
-
-    rc = fs_root_ops->f_opendir("0:/", &dir);
-    if (rc != FS_EOK) {
-        printf("f_opendir() failed %d\n", rc);
-        exit(1);
-    }
-
-    printf("\nListing 0:/\n");
-
-    while (1) {
-        rc = fs_root_ops->f_readdir(dir, &dirent);
-        if (rc == FS_ENOENT) {
-            break;
-        } else if (rc != FS_EOK) {
-            printf("f_readdir() failed %d\n", rc);
-            exit(1);
-        }
-
-        rc = fs_root_ops->f_dirent_name(dirent, sizeof(out_name), out_name, &u8_len);
-        printf("%s\n", out_name);
-    }
-
-    fs_root_ops->f_closedir(dir);
-
-    /* If a README.txt exists, print contents */
-    rc = fs_root_ops->f_open("0:/README.txt", FS_ACCESS_READ, &file);
-    if (rc == FS_EOK) {
-        printf("\nREADME.txt found, showing contents:\n\n");
-        printf("------------------------------------------------\n");
-
-        while (1) {
-            rc = fs_root_ops->f_read(file, sizeof(buf), buf, &u32_len);
-            printf("%s\n", buf);
-            if (u32_len != 32) {
-                break;
-            }
-        }
-
-        printf("------------------------------------------------\n");
-        fs_root_ops->f_close(file);
-    }
-
-    return 0;
-}
diff --git a/apps/ffs2native/pkg.yml b/apps/ffs2native/pkg.yml
index aecb7fdb79..3345cdce01 100644
--- a/apps/ffs2native/pkg.yml
+++ b/apps/ffs2native/pkg.yml
@@ -20,14 +20,14 @@
 pkg.name: apps/ffs2native
 pkg.type: app
 pkg.description: Support application for debugging the Newtron Flash File System.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
 
 pkg.deps:
-    - fs/nffs
-    - hw/hal
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/stub
-    - kernel/os
+    - "@apache-mynewt-core/fs/nffs"
+    - "@apache-mynewt-core/hw/hal"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/stats/stub"
+    - "@apache-mynewt-core/kernel/os"
diff --git a/apps/ffs2native/src/main.c b/apps/ffs2native/src/main.c
index 72b058b441..2a7323c1d2 100644
--- a/apps/ffs2native/src/main.c
+++ b/apps/ffs2native/src/main.c
@@ -24,18 +24,14 @@
 #include <unistd.h>
 #include <dirent.h>
 #include <string.h>
+#include "os/mynewt.h"
 #include "../src/nffs_priv.h"
-#include <os/queue.h>
 #include <fs/fs.h>
 #include <bsp/bsp.h>
 #include <nffs/nffs.h>
 #include <hal/hal_flash.h>
 #include <flash_map/flash_map.h>
 
-#include <sysinit/sysinit.h>
-#include <syscfg/syscfg.h>
-#include <sysflash/sysflash.h>
-
 #ifdef ARCH_sim
 #include <mcu/mcu_sim.h>
 #endif
diff --git a/apps/iptest/pkg.yml b/apps/iptest/pkg.yml
new file mode 100644
index 0000000000..311887f313
--- /dev/null
+++ b/apps/iptest/pkg.yml
@@ -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.
+#
+
+pkg.name: apps/iptest
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/config"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/id"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/net/ip/inet_def_service"
+
+pkg.deps.CONFIG_NFFS:
+    - "@apache-mynewt-core/fs/nffs"
+
+pkg.deps.CONFIG_FCB:
+    - "@apache-mynewt-core/fs/fcb"
+
+pkg.deps.BUILD_WITH_OIC:
+    - "@apache-mynewt-core/net/oic"
+    - "@apache-mynewt-core/encoding/cborattr"
diff --git a/apps/iptest/src/main.c b/apps/iptest/src/main.c
new file mode 100644
index 0000000000..f56fe5e28b
--- /dev/null
+++ b/apps/iptest/src/main.c
@@ -0,0 +1,423 @@
+/*
+ * 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/mynewt.h"
+#include <bsp/bsp.h>
+
+#include <hal/hal_gpio.h>
+#include <hal/hal_flash.h>
+#include <console/console.h>
+
+#include <config/config.h>
+#include <hal/hal_system.h>
+
+#include <bootutil/image.h>
+#include <bootutil/bootutil.h>
+
+#include <shell/shell.h>
+#include <mn_socket/mn_socket.h>
+#include <inet_def_service/inet_def_service.h>
+
+#include <assert.h>
+#include <string.h>
+#include <id/id.h>
+
+#if MYNEWT_VAL(BUILD_WITH_OIC)
+#include <oic/oc_api.h>
+#include <cborattr/cborattr.h>
+#endif
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+static int net_cli(int argc, char **argv);
+struct shell_cmd net_test_cmd = {
+    .sc_cmd = "net",
+    .sc_cmd_func = net_cli
+};
+
+static struct mn_socket *net_test_socket;
+static struct mn_socket *net_test_socket2;
+
+#if MYNEWT_VAL(BUILD_WITH_OIC)
+static void omgr_app_init(void);
+static const oc_handler_t omgr_oc_handler = {
+    .init = omgr_app_init,
+};
+#endif
+
+static void net_test_readable(void *arg, int err)
+{
+    console_printf("net_test_readable %x - %d\n", (int)arg, err);
+}
+
+static void net_test_writable(void *arg, int err)
+{
+    console_printf("net_test_writable %x - %d\n", (int)arg, err);
+}
+
+static const union mn_socket_cb net_test_cbs = {
+    .socket.readable = net_test_readable,
+    .socket.writable = net_test_writable
+};
+
+static int net_test_newconn(void *arg, struct mn_socket *new)
+{
+    console_printf("net_test_newconn %x - %x\n", (int)arg, (int)new);
+    mn_socket_set_cbs(new, NULL, &net_test_cbs);
+    net_test_socket2 = new;
+    return 0;
+}
+
+static const union mn_socket_cb net_listen_cbs =  {
+    .listen.newconn = net_test_newconn,
+};
+
+static int
+net_cli(int argc, char **argv)
+{
+    int rc;
+    struct mn_sockaddr_in sin;
+    struct mn_sockaddr_in *sinp;
+    uint16_t port;
+    uint32_t addr;
+    char *eptr;
+    struct os_mbuf *m;
+
+    if (argc < 2) {
+        return 0;
+    }
+    if (!strcmp(argv[1], "udp")) {
+        rc = mn_socket(&net_test_socket, MN_PF_INET, MN_SOCK_DGRAM, 0);
+        console_printf("mn_socket(UDP) = %d %x\n", rc,
+          (int)net_test_socket);
+    } else if (!strcmp(argv[1], "tcp")) {
+        rc = mn_socket(&net_test_socket, MN_PF_INET, MN_SOCK_STREAM, 0);
+        console_printf("mn_socket(TCP) = %d %x\n", rc,
+          (int)net_test_socket);
+    } else if (!strcmp(argv[1], "connect") || !strcmp(argv[1], "bind")) {
+        if (argc < 4) {
+            return 0;
+        }
+
+        if (mn_inet_pton(MN_AF_INET, argv[2], &addr) != 1) {
+            console_printf("Invalid address %s\n", argv[2]);
+            return 0;
+        }
+
+        port = strtoul(argv[3], &eptr, 0);
+        if (*eptr != '\0') {
+            console_printf("Invalid port %s\n", argv[3]);
+            return 0;
+        }
+        uint8_t *ip = (uint8_t *)&addr;
+
+        console_printf("%d.%d.%d.%d/%d\n", ip[0], ip[1], ip[2], ip[3], port);
+        memset(&sin, 0, sizeof(sin));
+        sin.msin_len = sizeof(sin);
+        sin.msin_family = MN_AF_INET;
+        sin.msin_port = htons(port);
+        sin.msin_addr.s_addr = addr;
+
+        if (!strcmp(argv[1], "connect")) {
+            mn_socket_set_cbs(net_test_socket, NULL, &net_test_cbs);
+            rc = mn_connect(net_test_socket, (struct mn_sockaddr *)&sin);
+            console_printf("mn_connect() = %d\n", rc);
+        } else {
+            mn_socket_set_cbs(net_test_socket, NULL, &net_test_cbs);
+            rc = mn_bind(net_test_socket, (struct mn_sockaddr *)&sin);
+            console_printf("mn_bind() = %d\n", rc);
+        }
+    } else if (!strcmp(argv[1], "listen")) {
+            mn_socket_set_cbs(net_test_socket, NULL, &net_listen_cbs);
+        rc = mn_listen(net_test_socket, 2);
+        console_printf("mn_listen() = %d\n", rc);
+    } else if (!strcmp(argv[1], "close")) {
+        rc = mn_close(net_test_socket);
+        console_printf("mn_close() = %d\n", rc);
+        net_test_socket = NULL;
+        if (net_test_socket2) {
+            rc = mn_close(net_test_socket2);
+            console_printf("mn_close() = %d\n", rc);
+            net_test_socket2 = NULL;
+        }
+    } else if (!strcmp(argv[1], "send")) {
+        if (argc < 3) {
+            return 0;
+        }
+        m = os_msys_get_pkthdr(16, 0);
+        if (!m) {
+            console_printf("out of mbufs\n");
+            return 0;
+        }
+        rc = os_mbuf_copyinto(m, 0, argv[2], strlen(argv[2]));
+        if (rc < 0) {
+            console_printf("can't copy data\n");
+            os_mbuf_free_chain(m);
+            return 0;
+        }
+        if (argc > 4) {
+            if (mn_inet_pton(MN_AF_INET, argv[3], &addr) != 1) {
+                console_printf("Invalid address %s\n", argv[2]);
+                return 0;
+            }
+
+            port = strtoul(argv[4], &eptr, 0);
+            if (*eptr != '\0') {
+                console_printf("Invalid port %s\n", argv[3]);
+                return 0;
+            }
+            uint8_t *ip = (uint8_t *)&addr;
+
+            console_printf("%d.%d.%d.%d/%d\n", ip[0], ip[1], ip[2], ip[3],
+              port);
+            memset(&sin, 0, sizeof(sin));
+            sin.msin_len = sizeof(sin);
+            sin.msin_family = MN_AF_INET;
+            sin.msin_port = htons(port);
+            sin.msin_addr.s_addr = addr;
+            sinp = &sin;
+        } else {
+            sinp = NULL;
+        }
+
+        if (net_test_socket2) {
+            rc = mn_sendto(net_test_socket2, m, (struct mn_sockaddr *)sinp);
+        } else {
+            rc = mn_sendto(net_test_socket, m, (struct mn_sockaddr *)sinp);
+        }
+        console_printf("mn_sendto() = %d\n", rc);
+    } else if (!strcmp(argv[1], "peer")) {
+        if (net_test_socket2) {
+            rc = mn_getpeername(net_test_socket2, (struct mn_sockaddr *)&sin);
+        } else {
+            rc = mn_getpeername(net_test_socket, (struct mn_sockaddr *)&sin);
+        }
+        console_printf("mn_getpeername() = %d\n", rc);
+        uint8_t *ip = (uint8_t *)&sin.msin_addr;
+
+        console_printf("%d.%d.%d.%d/%d\n", ip[0], ip[1], ip[2], ip[3],
+          ntohs(sin.msin_port));
+    } else if (!strcmp(argv[1], "recv")) {
+        if (net_test_socket2) {
+            rc = mn_recvfrom(net_test_socket2, &m, (struct mn_sockaddr *)&sin);
+        } else {
+            rc = mn_recvfrom(net_test_socket, &m, (struct mn_sockaddr *)&sin);
+        }
+        console_printf("mn_recvfrom() = %d\n", rc);
+        if (m) {
+            uint8_t *ip = (uint8_t *)&sin.msin_addr;
+
+            console_printf("%d.%d.%d.%d/%d\n", ip[0], ip[1], ip[2], ip[3],
+              ntohs(sin.msin_port));
+            m->om_data[m->om_len] = '\0';
+            console_printf("received %d bytes >%s<\n",
+              OS_MBUF_PKTHDR(m)->omp_len, (char *)m->om_data);
+            os_mbuf_free_chain(m);
+        }
+    } else if (!strcmp(argv[1], "mcast_join") ||
+      !strcmp(argv[1], "mcast_leave")) {
+        struct mn_mreq mm;
+        int val;
+
+        if (argc < 4) {
+            return 0;
+        }
+
+        val = strtoul(argv[2], &eptr, 0);
+        if (*eptr != '\0') {
+            console_printf("Invalid itf_idx %s\n", argv[2]);
+            return 0;
+        }
+
+        memset(&mm, 0, sizeof(mm));
+        mm.mm_idx = val;
+        mm.mm_family = MN_AF_INET;
+        if (mn_inet_pton(MN_AF_INET, argv[3], &mm.mm_addr) != 1) {
+            console_printf("Invalid address %s\n", argv[2]);
+            return 0;
+        }
+        if (!strcmp(argv[1], "mcast_join")) {
+            val = MN_MCAST_JOIN_GROUP;
+        } else {
+            val = MN_MCAST_LEAVE_GROUP;
+        }
+        rc = mn_setsockopt(net_test_socket, MN_SO_LEVEL, val, &mm);
+        console_printf("mn_setsockopt() = %d\n", rc);
+    } else if (!strcmp(argv[1], "listif")) {
+        struct mn_itf itf;
+        struct mn_itf_addr itf_addr;
+        char addr_str[48];
+
+        memset(&itf, 0, sizeof(itf));
+        while (1) {
+            rc = mn_itf_getnext(&itf);
+            if (rc) {
+                break;
+            }
+            console_printf("%d: %x %s\n", itf.mif_idx, itf.mif_flags,
+              itf.mif_name);
+            memset(&itf_addr, 0, sizeof(itf_addr));
+            while (1) {
+                rc = mn_itf_addr_getnext(&itf, &itf_addr);
+                if (rc) {
+                    break;
+                }
+                mn_inet_ntop(itf_addr.mifa_family, &itf_addr.mifa_addr,
+                  addr_str, sizeof(addr_str));
+                console_printf(" %s/%d\n", addr_str, itf_addr.mifa_plen);
+            }
+        }
+#if MYNEWT_VAL(MCU_STM32F4) || MYNEWT_VAL(MCU_STM32F7)
+    } else if (!strcmp(argv[1], "mii")) {
+        extern int stm32_mii_dump(int (*func)(const char *fmt, ...));
+
+        stm32_mii_dump(console_printf);
+#endif
+    } else if (!strcmp(argv[1], "service")) {
+        inet_def_service_init(os_eventq_dflt_get());
+#if MYNEWT_VAL(BUILD_WITH_OIC)
+    } else if (!strcmp(argv[1], "oic")) {
+        oc_main_init((oc_handler_t *)&omgr_oc_handler);
+#endif
+    } else {
+        console_printf("unknown cmd\n");
+    }
+    return 0;
+}
+
+#if MYNEWT_VAL(BUILD_WITH_OIC)
+static void
+app_get_light(oc_request_t *request, oc_interface_mask_t interface)
+{
+    bool value;
+
+    if (hal_gpio_read(LED_BLINK_PIN)) {
+        value = true;
+    } else {
+        value = false;
+    }
+    oc_rep_start_root_object();
+    switch (interface) {
+    case OC_IF_BASELINE:
+        oc_process_baseline_interface(request->resource);
+    case OC_IF_A:
+        oc_rep_set_boolean(root, value, value);
+        break;
+    default:
+        break;
+    }
+    oc_rep_end_root_object();
+    oc_send_response(request, OC_STATUS_OK);
+}
+
+static void
+app_set_light(oc_request_t *request, oc_interface_mask_t interface)
+{
+    bool value;
+    int len;
+    uint16_t data_off;
+    struct os_mbuf *m;
+    struct cbor_attr_t attrs[] = {
+        [0] = {
+            .attribute = "value",
+            .type = CborAttrBooleanType,
+            .addr.boolean = &value,
+            .dflt.boolean = false
+        },
+        [1] = {
+        }
+    };
+
+    len = coap_get_payload(request->packet, &m, &data_off);
+    if (cbor_read_mbuf_attrs(m, data_off, len, attrs)) {
+        oc_send_response(request, OC_STATUS_BAD_REQUEST);
+    } else {
+        hal_gpio_write(LED_BLINK_PIN, value == true);
+        oc_send_response(request, OC_STATUS_CHANGED);
+    }
+}
+
+static void
+omgr_app_init(void)
+{
+    oc_resource_t *res;
+
+    oc_init_platform("MyNewt", NULL, NULL);
+    oc_add_device("/oic/d", "oic.d.light", "MynewtLed", "1.0", "1.0", NULL,
+                  NULL);
+
+    res = oc_new_resource("/light/1", 1, 0);
+    oc_resource_bind_resource_type(res, "oic.r.switch.binary");
+    oc_resource_bind_resource_interface(res, OC_IF_A);
+    oc_resource_set_default_interface(res, OC_IF_A);
+
+    oc_resource_set_discoverable(res);
+    oc_resource_set_periodic_observable(res, 1);
+    oc_resource_set_request_handler(res, OC_GET, app_get_light);
+    oc_resource_set_request_handler(res, OC_PUT, app_set_light);
+    oc_resource_set_request_handler(res, OC_POST, app_set_light);
+    oc_add_resource(res);
+
+    hal_gpio_init_out(LED_BLINK_PIN, 1);
+}
+#endif
+
+/**
+ * main
+ *
+ * The main task for the project. This function initializes the packages, calls
+ * init_tasks to initialize additional tasks (and possibly other objects),
+ * then starts serving events from default event queue.
+ *
+ * @return int NOTE: this function should never return!
+ */
+int
+main(int argc, char **argv)
+{
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+#ifndef ARCH_sim
+    {
+        /*
+         * XXX set mac address when using STM32 ethernet XXX
+         * XXX move this somewhere else XXX
+         */
+        static uint8_t mac[6]= { 0, 1, 1, 2, 2, 3 };
+        int stm32_eth_set_hwaddr(uint8_t *addr);
+        stm32_eth_set_hwaddr(mac);
+    }
+#endif
+
+    sysinit();
+
+    console_printf("iptest\n");
+
+    shell_cmd_register(&net_test_cmd);
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
diff --git a/apps/iptest/syscfg.yml b/apps/iptest/syscfg.yml
new file mode 100644
index 0000000000..b24891cfc1
--- /dev/null
+++ b/apps/iptest/syscfg.yml
@@ -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.
+#
+
+# Package: apps/iptest
+
+syscfg.defs:
+    BUILD_WITH_OIC:
+       description: 'needed?'
+       value: 0
+
+syscfg.vals:
+    # Enable the shell task.
+    SHELL_TASK: 1
+
+    # Include names for statistics.
+    STATS_NAMES: 1
+
+    # Log reboot messages to a flash circular buffer.
+    REBOOT_LOG_FCB: 1
+    LOG_FCB: 1
+
+    CONFIG_FCB: 1
+
+    # Enable shell commands.
+    STATS_CLI: 1
+    LOG_CLI: 1
+    CONFIG_CLI: 1
+
+    ETH_0: 1
+
diff --git a/apps/lora_app_shell/pkg.yml b/apps/lora_app_shell/pkg.yml
new file mode 100644
index 0000000000..0bed1ebc06
--- /dev/null
+++ b/apps/lora_app_shell/pkg.yml
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+pkg.name: apps/lora_app_shell
+pkg.type: app
+pkg.description: "Example application which uses a variety of lora app eatures."
+pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/lora/node"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/util/parse"
+    - "@apache-mynewt-core/mgmt/oicmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/nmgr_os"
diff --git a/apps/lora_app_shell/src/las_cmd.c b/apps/lora_app_shell/src/las_cmd.c
new file mode 100644
index 0000000000..289071b151
--- /dev/null
+++ b/apps/lora_app_shell/src/las_cmd.c
@@ -0,0 +1,946 @@
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include "os/mynewt.h"
+#include "console/console.h"
+#include "shell/shell.h"
+#include "parse/parse.h"
+#include "node/lora_priv.h"
+#include "node/lora.h"
+
+extern void
+lora_app_shell_txd_func(uint8_t port, LoRaMacEventInfoStatus_t status,
+                        Mcps_t pkt_type, struct os_mbuf *om);
+
+extern void
+lora_app_shell_rxd_func(uint8_t port, LoRaMacEventInfoStatus_t status,
+                        Mcps_t pkt_type, struct os_mbuf *om);
+
+extern void
+lora_app_shell_join_cb(LoRaMacEventInfoStatus_t status, uint8_t attempts);
+
+extern void
+lora_app_shell_link_chk_cb(LoRaMacEventInfoStatus_t status, uint8_t num_gw,
+                           uint8_t demod_margin);
+
+#define LORA_APP_SHELL_MAX_APP_PAYLOAD  (250)
+static uint8_t las_cmd_app_tx_buf[LORA_APP_SHELL_MAX_APP_PAYLOAD];
+
+struct mib_pair {
+    char *mib_name;
+    Mib_t mib_param;
+};
+
+static struct mib_pair lora_mib[] = {
+    {"device_class",    MIB_DEVICE_CLASS},
+    {"nwk_joined",      MIB_NETWORK_JOINED},
+    {"adr",             MIB_ADR},
+    {"net_id",          MIB_NET_ID},
+    {"dev_addr",        MIB_DEV_ADDR},
+    {"nwk_skey",        MIB_NWK_SKEY},
+    {"app_skey",        MIB_APP_SKEY},
+    {"pub_nwk",         MIB_PUBLIC_NETWORK},
+    {"repeater",        MIB_REPEATER_SUPPORT},
+    {"rx2_chan",        MIB_RX2_CHANNEL},
+    {"rx2_def_chan",    MIB_RX2_DEFAULT_CHANNEL},
+    {"chan_mask",       MIB_CHANNELS_MASK},
+    {"chan_def_mask",   MIB_CHANNELS_DEFAULT_MASK},
+    {"chan_nb_rep",     MIB_CHANNELS_NB_REP},
+    {"max_rx_win_dur",  MIB_MAX_RX_WINDOW_DURATION},
+    {"rx_delay1",       MIB_RECEIVE_DELAY_1},
+    {"rx_delay2",       MIB_RECEIVE_DELAY_2},
+    {"join_acc_delay1", MIB_JOIN_ACCEPT_DELAY_1},
+    {"join_acc_delay2", MIB_JOIN_ACCEPT_DELAY_2},
+    {"chan_dr",         MIB_CHANNELS_DATARATE},
+    {"chan_def_dr",     MIB_CHANNELS_DEFAULT_DATARATE},
+    {"chan_tx_pwr",     MIB_CHANNELS_TX_POWER},
+    {"chan_def_tx_pwr", MIB_CHANNELS_DEFAULT_TX_POWER},
+    {"uplink_cntr",     MIB_UPLINK_COUNTER},
+    {"downlink_cntr",   MIB_DOWNLINK_COUNTER},
+    {"multicast_chan",  MIB_MULTICAST_CHANNEL},
+    {"sys_max_rx_err",  MIB_SYSTEM_MAX_RX_ERROR},
+    {"min_rx_symbols",  MIB_MIN_RX_SYMBOLS},
+    {NULL, (Mib_t)0}
+};
+
+static int las_cmd_wr_mib(int argc, char **argv);
+static int las_cmd_rd_mib(int argc, char **argv);
+static int las_cmd_wr_dev_eui(int argc, char **argv);
+static int las_cmd_rd_dev_eui(int argc, char **argv);
+static int las_cmd_wr_app_eui(int argc, char **argv);
+static int las_cmd_rd_app_eui(int argc, char **argv);
+static int las_cmd_wr_app_key(int argc, char **argv);
+static int las_cmd_rd_app_key(int argc, char **argv);
+static int las_cmd_app_port(int argc, char **argv);
+static int las_cmd_app_tx(int argc, char **argv);
+static int las_cmd_join(int argc, char **argv);
+static int las_cmd_link_chk(int argc, char **argv);
+
+static struct shell_cmd las_cmds[] = {
+    {
+        .sc_cmd = "las_wr_mib",
+        .sc_cmd_func = las_cmd_wr_mib,
+    },
+    {
+        .sc_cmd = "las_rd_mib",
+        .sc_cmd_func = las_cmd_rd_mib,
+    },
+    {
+        .sc_cmd = "las_rd_dev_eui",
+        .sc_cmd_func = las_cmd_rd_dev_eui,
+    },
+    {
+        .sc_cmd = "las_wr_dev_eui",
+        .sc_cmd_func = las_cmd_wr_dev_eui,
+    },
+    {
+        .sc_cmd = "las_rd_app_eui",
+        .sc_cmd_func = las_cmd_rd_app_eui,
+    },
+    {
+        .sc_cmd = "las_wr_app_eui",
+        .sc_cmd_func = las_cmd_wr_app_eui,
+    },
+    {
+        .sc_cmd = "las_rd_app_key",
+        .sc_cmd_func = las_cmd_rd_app_key,
+    },
+    {
+        .sc_cmd = "las_wr_app_key",
+        .sc_cmd_func = las_cmd_wr_app_key,
+    },
+    {
+        .sc_cmd = "las_app_port",
+        .sc_cmd_func = las_cmd_app_port,
+    },
+    {
+        .sc_cmd = "las_app_tx",
+        .sc_cmd_func = las_cmd_app_tx,
+    },
+    {
+        .sc_cmd = "las_join",
+        .sc_cmd_func = las_cmd_join,
+    },
+    {
+        .sc_cmd = "las_link_chk",
+        .sc_cmd_func = las_cmd_link_chk,
+    },
+    {
+        NULL, NULL,
+#if MYNEWT_VAL(SHELL_CMD_HELP)
+        NULL
+#endif
+    },
+};
+
+#define LAS_NUM_CLI_CMDS  (sizeof las_cmds / sizeof las_cmds[0])
+
+void
+las_cmd_disp_byte_str(uint8_t *bytes, int len)
+{
+    int i;
+
+    if (len > 0) {
+        for (i = 0; i < len - 1; ++i) {
+            console_printf("%02x:", bytes[i]);
+        }
+        console_printf("%02x\n", bytes[len - 1]);
+    }
+}
+
+static void
+las_cmd_disp_chan_mask(uint16_t *mask)
+{
+    uint16_t i;
+    uint16_t len;
+    uint16_t max_chans;
+    PhyParam_t phy_param;
+    GetPhyParams_t getPhy;
+
+    if (!mask) {
+        return;
+    }
+
+    getPhy.Attribute = PHY_MAX_NB_CHANNELS;
+    phy_param = RegionGetPhyParam(LORA_NODE_REGION, &getPhy);
+    max_chans = phy_param.Value;
+
+    len = max_chans / 16;
+    if ((len * 16) != max_chans) {
+        len += 1;
+    }
+
+    for (i = 0; i < len - 1; ++i) {
+        console_printf("%04x:", mask[i]);
+    }
+    console_printf("%04x\n", mask[len - 1]);
+}
+
+/**
+ * Display list of MAC mibs
+ *
+ */
+static void
+las_cmd_show_mibs(void)
+{
+    struct mib_pair *mp;
+
+    mp = &lora_mib[0];
+    while (mp->mib_name != NULL) {
+        console_printf("%s\n", mp->mib_name);
+        ++mp;
+    }
+}
+
+static struct mib_pair *
+las_find_mib_by_name(char *mibname)
+{
+    struct mib_pair *mp;
+
+    mp = &lora_mib[0];
+    while (mp->mib_name != NULL) {
+        if (!strcmp(mibname, mp->mib_name)) {
+            return mp;
+        }
+        ++mp;
+    }
+
+    return NULL;
+}
+
+static void
+las_cmd_wr_mib_help(void)
+{
+    console_printf("las_wr_mib <mib_name> <val> where mib_name is one of:\n");
+    las_cmd_show_mibs();
+}
+
+static int
+las_parse_bool(char *str)
+{
+    int rc;
+
+    if (!strcmp(str, "0")) {
+        rc = 0;
+    } else if (!strcmp(str, "1")) {
+        rc = 1;
+    } else {
+        console_printf("Invalid value. Valid values are 0 or 1\n");
+        rc = -1;
+    }
+
+    return rc;
+}
+
+static int
+las_cmd_wr_mib(int argc, char **argv)
+{
+    int rc;
+    int plen;
+    uint8_t key[LORA_KEY_LEN];
+    uint16_t mask[16];
+    int mask_len;
+    struct mib_pair *mp;
+    MibRequestConfirm_t mib;
+    GetPhyParams_t getPhy;
+    PhyParam_t phy_param;
+
+    if (argc < 3) {
+        console_printf("Invalid # of arguments\n");
+        goto wr_mib_err;
+    }
+
+    if (strcmp(argv[1], "help") == 0) {
+        las_cmd_wr_mib_help();
+        return 0;
+    }
+
+    mp = las_find_mib_by_name(argv[1]);
+    if (mp == NULL) {
+        console_printf("No mib named %s\n",argv[1]);
+        goto wr_mib_err;
+    }
+
+    /* parse value */
+    mib.Type = mp->mib_param;
+    switch (mib.Type) {
+        case MIB_DEVICE_CLASS:
+            if (!strcmp(argv[2], "A")) {
+                mib.Param.Class = CLASS_A;
+            } else if (!strcmp(argv[2], "B")) {
+                console_printf("Class B devices currently not supported\n");
+                return 0;
+            } else if (!strcmp(argv[2], "C")) {
+                mib.Param.Class = CLASS_C;
+            } else {
+                console_printf("Invalid value. Valid values are A, B or C\n");
+                return 0;
+            }
+            break;
+        case MIB_NETWORK_JOINED:
+            rc = las_parse_bool(argv[2]);
+            if (rc == 0) {
+                mib.Param.IsNetworkJoined = false;
+            } else if (rc == 1) {
+                mib.Param.IsNetworkJoined = true;
+            } else {
+                return 0;
+            }
+            break;
+        case MIB_ADR:
+            rc = las_parse_bool(argv[2]);
+            if (rc == 0) {
+                mib.Param.AdrEnable = false;
+            } else if (rc == 1) {
+                mib.Param.AdrEnable = true;
+            } else {
+                return 0;
+            }
+            break;
+        case MIB_NET_ID:
+            mib.Param.NetID = (uint32_t)parse_ull(argv[2], &rc);
+            if (rc) {
+                console_printf("Unable to parse value\n");
+                return 0;
+            }
+            break;
+        case MIB_DEV_ADDR:
+            mib.Param.DevAddr = (uint32_t)parse_ull(argv[2], &rc);
+            if (rc) {
+                console_printf("Unable to parse value\n");
+                return 0;
+            }
+            break;
+        case MIB_NWK_SKEY:
+            rc = parse_byte_stream(argv[2], LORA_KEY_LEN, key, &plen);
+            if (rc || (plen != LORA_KEY_LEN)) {
+                console_printf("Key does not parse. Must be 16 bytes"
+                               " and separated by : or -\n");
+                return 0;
+            }
+            mib.Param.NwkSKey = key;
+            break;
+        case MIB_APP_SKEY:
+            rc = parse_byte_stream(argv[2], LORA_KEY_LEN, key, &plen);
+            if (rc || (plen != LORA_KEY_LEN)) {
+                console_printf("Key does not parse. Must be 16 bytes"
+                               " and separated by : or -\n");
+                return 0;
+            }
+            mib.Param.AppSKey = key;
+            break;
+        case MIB_PUBLIC_NETWORK:
+            rc = las_parse_bool(argv[2]);
+            if (rc == 0) {
+                mib.Param.EnablePublicNetwork = false;
+            } else if (rc == 1) {
+                mib.Param.EnablePublicNetwork = true;
+            } else {
+                return 0;
+            }
+            break;
+        case MIB_REPEATER_SUPPORT:
+            rc = las_parse_bool(argv[2]);
+            if (rc == 0) {
+                mib.Param.EnableRepeaterSupport = false;
+            } else if (rc == 1) {
+                mib.Param.EnableRepeaterSupport = true;
+            } else {
+                return 0;
+            }
+            break;
+        case MIB_CHANNELS:
+            //mib.Param.ChannelList;
+            break;
+        case MIB_RX2_CHANNEL:
+            //mib.Param.Rx2Channel;
+            break;
+        case MIB_RX2_DEFAULT_CHANNEL:
+            //mib.Param.Rx2Channel;
+            break;
+        case MIB_CHANNELS_DEFAULT_MASK:
+            /* NOTE: fall-through intentional */
+        case MIB_CHANNELS_MASK:
+            memset(mask, 0, sizeof(mask));
+
+            getPhy.Attribute = PHY_MAX_NB_CHANNELS;
+            phy_param = RegionGetPhyParam(LORA_NODE_REGION, &getPhy);
+            mask_len = phy_param.Value / 8;
+            if ((mask_len * 8) != phy_param.Value) {
+                mask_len += 1;
+            }
+
+            /* NOTE: re-use of key here for temp buffer storage */
+            rc = parse_byte_stream(argv[2], mask_len, key, &plen);
+            if (rc || (plen != mask_len)) {
+                console_printf("Mask does not parse. Must be %d bytes"
+                               " and separated by : or -\n", mask_len);
+                return 0;
+            }
+
+            /* construct mask from byte stream */
+            rc = 0;
+            for (plen = 0; plen < mask_len; plen += 2) {
+                mask[rc] = key[plen];
+                if ((mask_len & 1) == 0) {
+                    mask[rc] += ((uint16_t)key[plen + 1]) << 8;
+                }
+                ++rc;
+            }
+
+            if (mib.Type == MIB_CHANNELS_DEFAULT_MASK) {
+                mib.Param.ChannelsDefaultMask = mask;
+            } else {
+                mib.Param.ChannelsMask = mask;
+            }
+            break;
+        case MIB_CHANNELS_NB_REP:
+            //mib.Param.ChannelNbRep;
+            break;
+        case MIB_MAX_RX_WINDOW_DURATION:
+            //mib.Param.MaxRxWindow;
+            break;
+        case MIB_RECEIVE_DELAY_1:
+            //mib.Param.ReceiveDelay1;
+            break;
+        case MIB_RECEIVE_DELAY_2:
+            //mib.Param.ReceiveDelay2;
+            break;
+        case MIB_JOIN_ACCEPT_DELAY_1:
+            //mib.Param.JoinAcceptDelay1;
+            break;
+        case MIB_JOIN_ACCEPT_DELAY_2:
+            //mib.Param.JoinAcceptDelay2;
+            break;
+        case MIB_CHANNELS_DEFAULT_DATARATE:
+            mib.Param.ChannelsDefaultDatarate = parse_ll(argv[2], &rc);
+            if (rc) {
+                console_printf("Unable to parse value\n");
+                return 0;
+            }
+            break;
+        case MIB_CHANNELS_DATARATE:
+            mib.Param.ChannelsDatarate = parse_ll(argv[2], &rc);
+            if (rc) {
+                console_printf("Unable to parse value\n");
+                return 0;
+            }
+            break;
+        case MIB_CHANNELS_DEFAULT_TX_POWER:
+            //mibGet.Param.ChannelsDefaultTxPower;
+            break;
+        case MIB_CHANNELS_TX_POWER:
+            //mib.Param.ChannelsTxPower;
+            break;
+        case MIB_UPLINK_COUNTER:
+            //mib.Param.UpLinkCounter;
+            break;
+        case MIB_DOWNLINK_COUNTER:
+            //mib.Param.DownLinkCounter;
+            break;
+        case MIB_MULTICAST_CHANNEL:
+            //mib.Param.MulticastList = MulticastChannels;
+            break;
+        default:
+            assert(0);
+            break;
+    }
+
+    if (LoRaMacMibSetRequestConfirm(&mib) != LORAMAC_STATUS_OK) {
+        console_printf("Mib not able to be set\n");
+        return 0;
+    }
+
+    console_printf("mib %s set\n", mp->mib_name);
+
+    return 0;
+
+wr_mib_err:
+    las_cmd_wr_mib_help();
+    return 0;
+}
+
+static void
+las_cmd_rd_mib_help(void)
+{
+    console_printf("las_rd_mib <mib_name> where mib_name is one of:\n");
+    las_cmd_show_mibs();
+}
+
+static int
+las_cmd_rd_mib(int argc, char **argv)
+{
+    struct mib_pair *mp;
+    LoRaMacStatus_t stat;
+    MibRequestConfirm_t mibGet;
+
+    if (argc != 2) {
+        console_printf("Invalid # of arguments\n");
+        goto rd_mib_err;
+    }
+
+    if (strcmp(argv[1], "help") == 0) {
+        las_cmd_rd_mib_help();
+        return 0;
+    }
+
+    mp = las_find_mib_by_name(argv[1]);
+    if (mp == NULL) {
+        console_printf("No mib named %s\n",argv[1]);
+        goto rd_mib_err;
+    }
+
+    /* Read the mib value */
+    mibGet.Type = mp->mib_param;
+    stat = LoRaMacMibGetRequestConfirm(&mibGet);
+    if (stat != LORAMAC_STATUS_OK) {
+        console_printf("Mib lookup failure\n");
+        goto rd_mib_err;
+    }
+
+    console_printf("%s=", mp->mib_name);
+    /* Display the value */
+    switch (mibGet.Type) {
+        case MIB_DEVICE_CLASS:
+            console_printf("%c\n", 'A' + mibGet.Param.Class);
+            break;
+        case MIB_NETWORK_JOINED:
+            console_printf("%d\n", mibGet.Param.IsNetworkJoined);
+            break;
+        case MIB_ADR:
+            console_printf("%d\n", mibGet.Param.AdrEnable);
+            break;
+        case MIB_NET_ID:
+            console_printf("%08lx\n", mibGet.Param.NetID);
+            break;
+        case MIB_DEV_ADDR:
+            console_printf("%08lx\n", mibGet.Param.DevAddr);
+            break;
+        case MIB_NWK_SKEY:
+            las_cmd_disp_byte_str(mibGet.Param.NwkSKey, LORA_KEY_LEN);
+            break;
+        case MIB_APP_SKEY:
+            las_cmd_disp_byte_str(mibGet.Param.AppSKey, LORA_KEY_LEN);
+            break;
+        case MIB_PUBLIC_NETWORK:
+            console_printf("%d\n", mibGet.Param.EnablePublicNetwork);
+            break;
+        case MIB_REPEATER_SUPPORT:
+            console_printf("%d\n", mibGet.Param.EnableRepeaterSupport);
+            break;
+        case MIB_CHANNELS:
+            //mibGet.Param.ChannelList;
+            break;
+        case MIB_RX2_CHANNEL:
+            //mibGet.Param.Rx2Channel;
+            break;
+        case MIB_RX2_DEFAULT_CHANNEL:
+            //mibGet.Param.Rx2Channel;
+            break;
+        case MIB_CHANNELS_DEFAULT_MASK:
+            las_cmd_disp_chan_mask(mibGet.Param.ChannelsDefaultMask);
+            break;
+        case MIB_CHANNELS_MASK:
+            las_cmd_disp_chan_mask(mibGet.Param.ChannelsMask);
+            break;
+        case MIB_CHANNELS_NB_REP:
+            console_printf("%u\n", mibGet.Param.ChannelNbRep);
+            break;
+        case MIB_MAX_RX_WINDOW_DURATION:
+            console_printf("%lu\n", mibGet.Param.MaxRxWindow);
+            break;
+        case MIB_RECEIVE_DELAY_1:
+            console_printf("%lu\n", mibGet.Param.ReceiveDelay1);
+            break;
+        case MIB_RECEIVE_DELAY_2:
+            console_printf("%lu\n", mibGet.Param.ReceiveDelay2);
+            break;
+        case MIB_JOIN_ACCEPT_DELAY_1:
+            console_printf("%lu\n", mibGet.Param.JoinAcceptDelay1);
+            break;
+        case MIB_JOIN_ACCEPT_DELAY_2:
+            console_printf("%lu\n", mibGet.Param.JoinAcceptDelay2);
+            break;
+        case MIB_CHANNELS_DEFAULT_DATARATE:
+            console_printf("%d\n", mibGet.Param.ChannelsDefaultDatarate);
+            break;
+        case MIB_CHANNELS_DATARATE:
+            console_printf("%d\n", mibGet.Param.ChannelsDatarate);
+            break;
+        case MIB_CHANNELS_DEFAULT_TX_POWER:
+            console_printf("%d\n", mibGet.Param.ChannelsDefaultTxPower);
+            break;
+        case MIB_CHANNELS_TX_POWER:
+            console_printf("%d\n", mibGet.Param.ChannelsTxPower);
+            break;
+        case MIB_UPLINK_COUNTER:
+            console_printf("%lu\n", mibGet.Param.UpLinkCounter);
+            break;
+        case MIB_DOWNLINK_COUNTER:
+            console_printf("%lu\n", mibGet.Param.DownLinkCounter);
+            break;
+        case MIB_MULTICAST_CHANNEL:
+            //mibGet.Param.MulticastList = MulticastChannels;
+            break;
+        default:
+            assert(0);
+            break;
+    }
+    return 0;
+
+rd_mib_err:
+    las_cmd_rd_mib_help();
+    return 0;
+}
+
+static int
+las_cmd_rd_dev_eui(int argc, char **argv)
+{
+    if (argc != 1) {
+        console_printf("Invalid # of arguments. Usage: las_rd_dev_eui\n");
+        return 0;
+    }
+
+    las_cmd_disp_byte_str(g_lora_dev_eui, LORA_EUI_LEN);
+    return 0;
+}
+
+static int
+las_cmd_wr_dev_eui(int argc, char **argv)
+{
+    int rc;
+    int plen;
+    uint8_t eui[LORA_EUI_LEN];
+
+    if (argc < 2) {
+        console_printf("Invalid # of arguments."
+                       " Usage: las_wr_dev_eui <xx:xx:xx:xx:xx:xx:xx:xx>\n");
+    }
+
+    rc = parse_byte_stream(argv[1], LORA_EUI_LEN, eui, &plen);
+    if (rc || (plen != LORA_EUI_LEN)) {
+        console_printf("EUI does not parse. Must be 8 bytes"
+                       " and separated by : or -\n");
+    } else {
+        memcpy(g_lora_dev_eui, eui, LORA_EUI_LEN);
+    }
+
+    return 0;
+}
+
+static int
+las_cmd_rd_app_eui(int argc, char **argv)
+{
+    if (argc != 1) {
+        console_printf("Invalid # of arguments. Usage: las_rd_app_eui\n");
+        return 0;
+    }
+
+    las_cmd_disp_byte_str(g_lora_app_eui, LORA_EUI_LEN);
+    return 0;
+}
+
+static int
+las_cmd_wr_app_eui(int argc, char **argv)
+{
+    int rc;
+    int plen;
+    uint8_t eui[LORA_EUI_LEN];
+
+    if (argc < 2) {
+        console_printf("Invalid # of arguments."
+                       " Usage: las_wr_app_eui <xx:xx:xx:xx:xx:xx:xx:xx>\n");
+    }
+
+    rc = parse_byte_stream(argv[1], LORA_EUI_LEN, eui, &plen);
+    if (rc || (plen != LORA_EUI_LEN)) {
+        console_printf("EUI does not parse. Must be 8 bytes"
+                       " and separated by : or -\n");
+    } else {
+        memcpy(g_lora_app_eui, eui, LORA_EUI_LEN);
+    }
+
+    return 0;
+}
+
+static int
+las_cmd_rd_app_key(int argc, char **argv)
+{
+    if (argc != 1) {
+        console_printf("Invalid # of arguments. Usage: las_rd_app_key\n");
+        return 0;
+    }
+
+    las_cmd_disp_byte_str(g_lora_app_key, LORA_KEY_LEN);
+    return 0;
+}
+
+static int
+las_cmd_wr_app_key(int argc, char **argv)
+{
+    int rc;
+    int plen;
+    uint8_t key[LORA_KEY_LEN];
+
+    if (argc < 2) {
+        console_printf("Invalid # of arguments."
+                       " Usage: las_wr_app_key <xx:xx:xx:xx:xx:xx:xx:xx:xx:xx"
+                       ":xx:xx:xx:xx:xx:xx\n");
+    }
+
+    rc = parse_byte_stream(argv[1], LORA_KEY_LEN, key, &plen);
+    if (rc || (plen != LORA_KEY_LEN)) {
+        console_printf("Key does not parse. Must be 16 bytes and separated by"
+                       " : or -\n");
+        return 0;
+    } else {
+        memcpy(g_lora_app_key, key, LORA_KEY_LEN);
+    }
+
+    return 0;
+}
+
+static int
+las_cmd_app_port(int argc, char **argv)
+{
+    int rc;
+    uint8_t port;
+    uint8_t retries;
+
+    if (argc < 3) {
+        console_printf("Invalid # of arguments.\n");
+        goto cmd_app_port_err;
+    }
+
+    port = parse_ull_bounds(argv[2], 1, 255, &rc);
+    if (rc != 0) {
+        console_printf("Invalid port %s. Must be 1 - 255\n", argv[2]);
+        return 0;
+    }
+
+    if (!strcmp(argv[1], "open")) {
+        rc = lora_app_port_open(port, lora_app_shell_txd_func,
+                                lora_app_shell_rxd_func);
+        if (rc == LORA_APP_STATUS_OK) {
+            console_printf("Opened app port %u\n", port);
+        } else {
+            console_printf("Failed to open app port %u err=%d\n", port, rc);
+        }
+    } else if (!strcmp(argv[1], "close")) {
+        rc = lora_app_port_close(port);
+        if (rc == LORA_APP_STATUS_OK) {
+            console_printf("Closed app port %u\n", port);
+        } else {
+            console_printf("Failed to close app port %u err=%d\n", port, rc);
+        }
+    } else if (!strcmp(argv[1], "cfg")) {
+        if (argc != 4) {
+            console_printf("Invalid # of arguments.\n");
+            goto cmd_app_port_err;
+        }
+        retries = parse_ull_bounds(argv[3], 1, MAX_ACK_RETRIES, &rc);
+        if (rc) {
+            console_printf("Invalid # of retries. Must be between 1 and "
+                           "%d (inclusve)\n", MAX_ACK_RETRIES);
+            return 0;
+        }
+
+        rc = lora_app_port_cfg(port, retries);
+        if (rc == LORA_APP_STATUS_OK) {
+            console_printf("App port %u configured w/retries=%u\n",
+                           port, retries);
+        } else {
+            console_printf("Cannot configure port %u err=%d\n", port, rc);
+        }
+    } else if (!strcmp(argv[1], "show")) {
+        if (rc == LORA_APP_STATUS_OK) {
+            console_printf("app port %u\n", port);
+            /* XXX: implement */
+        } else {
+            console_printf("Cannot show app port %u err=%d\n", port, rc);
+        }
+    } else {
+        console_printf("Invalid port command.\n");
+        goto cmd_app_port_err;
+    }
+
+    return 0;
+
+cmd_app_port_err:
+    console_printf("Usage:\n");
+    console_printf("\tlas_app_port open <port num>\n");
+    console_printf("\tlas_app_port close <port num>\n");
+    console_printf("\tlas_app_port cfg <port num> <retries>\n");
+    console_printf("\not implemented! las_app_port show <port num | all>\n");
+    return 0;
+}
+
+static int
+las_cmd_app_tx(int argc, char **argv)
+{
+    int rc;
+    uint8_t port;
+    uint8_t len;
+    uint8_t pkt_type;
+    struct os_mbuf *om;
+    Mcps_t mcps_type;
+
+    if (argc < 4) {
+        console_printf("Invalid # of arguments\n");
+        goto cmd_app_tx_err;
+    }
+
+    port = parse_ull_bounds(argv[1], 1, 255, &rc);
+    if (rc != 0) {
+        console_printf("Invalid port %s. Must be 1 - 255\n", argv[2]);
+        return 0;
+    }
+    len = parse_ull_bounds(argv[2], 1, LORA_APP_SHELL_MAX_APP_PAYLOAD, &rc);
+    if (rc != 0) {
+        console_printf("Invalid length. Must be 1 - %u\n",
+                       LORA_APP_SHELL_MAX_APP_PAYLOAD);
+        return 0;
+    }
+    pkt_type = parse_ull_bounds(argv[3], 0, 1, &rc);
+    if (rc != 0) {
+        console_printf("Invalid type. Must be 0 (unconfirmed) or 1 (confirmed)"
+                       "\n");
+        return 0;
+    }
+
+    if (lora_app_mtu() < len) {
+        console_printf("Can send at max %d bytes\n", lora_app_mtu());
+        return 0;
+    }
+
+    /* Attempt to allocate a mbuf */
+    om = lora_pkt_alloc();
+    if (!om) {
+        console_printf("Unable to allocate mbuf\n");
+        return 0;
+    }
+
+    /* Get correct packet type. */
+    if (pkt_type == 0) {
+        mcps_type = MCPS_UNCONFIRMED;
+    } else {
+        mcps_type = MCPS_CONFIRMED;
+    }
+
+    rc = os_mbuf_copyinto(om, 0, las_cmd_app_tx_buf, len);
+    assert(rc == 0);
+
+    rc = lora_app_port_send(port, mcps_type, om);
+    if (rc) {
+        console_printf("Failed to send to port %u err=%d\n", port, rc);
+        os_mbuf_free_chain(om);
+    } else {
+        console_printf("Packet sent on port %u\n", port);
+    }
+
+    return 0;
+
+cmd_app_tx_err:
+    console_printf("Usage:\n");
+    console_printf("\tlas_app_tx <port> <len> <type>\n");
+    console_printf("Where:\n");
+    console_printf("\tport = port number on which to send\n");
+    console_printf("\tlen = size n bytes of app data\n");
+    console_printf("\ttype = 0 for unconfirmed, 1 for confirmed\n");
+    console_printf("\tex: las_app_tx 10 20 1\n");
+
+    return 0;
+}
+
+static int
+las_cmd_link_chk(int argc, char **argv)
+{
+    int rc;
+
+    rc = lora_app_link_check();
+    if (rc) {
+        console_printf("Link check start failure err=%d\n", rc);
+    } else {
+        console_printf("Sending link check\n");
+    }
+    return 0;
+}
+
+static int
+las_cmd_join(int argc, char **argv)
+{
+    int rc;
+    uint8_t attempts;
+
+    /* Get the number of attempts */
+    if (argc != 2) {
+        console_printf("Invalid # of arguments\n");
+        goto cmd_join_err;
+    }
+
+    attempts = parse_ull_bounds(argv[1], 0, 255, &rc);
+    if (rc) {
+        console_printf("Error: could not parse attempts. Must be 0 - 255\n");
+
+    }
+
+    rc = lora_app_join(g_lora_dev_eui, g_lora_app_eui, g_lora_app_key,attempts);
+    if (rc) {
+        console_printf("Join attempt start failure err=%d\n", rc);
+    } else {
+        console_printf("Attempting to join...\n");
+    }
+    return 0;
+
+cmd_join_err:
+    console_printf("Usage:\n");
+    console_printf("\tlas_join <attempts>\n");
+    console_printf("Where:\n");
+    console_printf("\tattempts = # of join requests to send before failure"
+                   " (0 -255)�\n");
+    console_printf("\tex: las_join 10\n");
+    return 0;
+}
+
+void
+las_cmd_init(void)
+{
+    int i;
+    int rc;
+
+    /* Set the join callback */
+    lora_app_set_join_cb(lora_app_shell_join_cb);
+
+    /* Set link check callback */
+    lora_app_set_link_check_cb(lora_app_shell_link_chk_cb);
+
+    for (i = 0; i < LAS_NUM_CLI_CMDS; i++) {
+        rc = shell_cmd_register(las_cmds + i);
+        SYSINIT_PANIC_ASSERT_MSG(
+            rc == 0, "Failed to register lora app shell CLI commands");
+    }
+
+    /* Init app tx payload to incrementing pattern */
+    for (i = 0; i < LORA_APP_SHELL_MAX_APP_PAYLOAD; ++i) {
+        las_cmd_app_tx_buf[i] = i;
+    }
+}
diff --git a/apps/lora_app_shell/src/main.c b/apps/lora_app_shell/src/main.c
new file mode 100644
index 0000000000..13bb578afc
--- /dev/null
+++ b/apps/lora_app_shell/src/main.c
@@ -0,0 +1,158 @@
+/*
+ * 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 <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include "os/mynewt.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "bsp/bsp.h"
+#include "console/console.h"
+#include "shell/shell.h"
+#include "parse/parse.h"
+#include "node/lora_priv.h"
+#include "node/lora.h"
+#include "oic/oc_api.h"
+
+extern void las_cmd_init(void);
+extern void las_cmd_disp_byte_str(uint8_t *bytes, int len);
+
+/* XXX: should we count statistics for the app shell? You know, things
+   like transmitted, etc, etc. */
+void
+lora_app_shell_txd_func(uint8_t port, LoRaMacEventInfoStatus_t status,
+                        Mcps_t pkt_type, struct os_mbuf *om)
+{
+    struct lora_pkt_info *lpkt;
+
+    assert(om != NULL);
+    console_printf("Txd on port %u type=%s status=%d len=%u\n",
+                   port, pkt_type == MCPS_CONFIRMED ? "conf" : "unconf",
+                   status, OS_MBUF_PKTLEN(om));
+
+    lpkt = LORA_PKT_INFO_PTR(om);
+    console_printf("\tdr:%u\n", lpkt->txdinfo.datarate);
+    console_printf("\ttxpower (dbm):%d\n", lpkt->txdinfo.txpower);
+    console_printf("\ttries:%u\n", lpkt->txdinfo.retries);
+    console_printf("\tack_rxd:%u\n", lpkt->txdinfo.ack_rxd);
+    console_printf("\ttx_time_on_air:%lu\n", lpkt->txdinfo.tx_time_on_air);
+    console_printf("\tuplink_cntr:%lu\n", lpkt->txdinfo.uplink_cntr);
+    console_printf("\tuplink_chan:%lu\n", lpkt->txdinfo.uplink_chan);
+
+    os_mbuf_free_chain(om);
+}
+
+void
+lora_app_shell_rxd_func(uint8_t port, LoRaMacEventInfoStatus_t status,
+                        Mcps_t pkt_type, struct os_mbuf *om)
+{
+    int rc;
+    struct lora_pkt_info *lpkt;
+    uint16_t cur_len;
+    uint16_t len;
+    uint16_t cur_off;
+    uint8_t temp[16];
+
+    assert(om != NULL);
+    console_printf("Rxd on port %u type=%s status=%d len=%u\n",
+                   port, pkt_type == MCPS_CONFIRMED ? "conf" : "unconf",
+                   status, OS_MBUF_PKTLEN(om));
+
+    lpkt = LORA_PKT_INFO_PTR(om);
+    console_printf("\trxdr:%u\n", lpkt->rxdinfo.rxdatarate);
+    console_printf("\tsnr:%u\n", lpkt->rxdinfo.snr);
+    console_printf("\trssi:%d\n", lpkt->rxdinfo.rssi);
+    console_printf("\trxslot:%u\n", lpkt->rxdinfo.rxslot);
+    console_printf("\tack_rxd:%u\n", lpkt->rxdinfo.ack_rxd);
+    console_printf("\trxdata:%u\n", lpkt->rxdinfo.rxdata);
+    console_printf("\tmulticast:%u\n", lpkt->rxdinfo.multicast);
+    console_printf("\tfp:%u\n", lpkt->rxdinfo.frame_pending);
+    console_printf("\tdownlink_cntr:%lu\n", lpkt->rxdinfo.downlink_cntr);
+
+    /* Dump the bytes received */
+    len = OS_MBUF_PKTLEN(om);
+    if (len != 0) {
+        console_printf("Rxd data:\n");
+        cur_off = 0;
+        while (cur_off < len) {
+            cur_len = len - cur_off;
+            if (cur_len > 16) {
+                cur_len = 16;
+            }
+            rc = os_mbuf_copydata(om, cur_off, cur_len, temp);
+            if (rc) {
+                break;
+            }
+            cur_off += cur_len;
+            las_cmd_disp_byte_str(temp, cur_len);
+        }
+    }
+
+    os_mbuf_free_chain(om);
+}
+
+void
+lora_app_shell_join_cb(LoRaMacEventInfoStatus_t status, uint8_t attempts)
+{
+    console_printf("Join cb. status=%d attempts=%u\n", status, attempts);
+}
+
+void
+lora_app_shell_link_chk_cb(LoRaMacEventInfoStatus_t status, uint8_t num_gw,
+                           uint8_t demod_margin)
+{
+    console_printf("Link check cb. status=%d num_gw=%u demod_margin=%u\n",
+                   status, num_gw, demod_margin);
+}
+
+static void
+oic_app_init(void)
+{
+    oc_init_platform("MyNewt", NULL, NULL);
+    oc_add_device("/oic/d", "oic.d.light", "MynewtLed", "1.0", "1.0", NULL,
+                  NULL);
+}
+
+static const oc_handler_t omgr_oc_handler = {
+    .init = oic_app_init,
+};
+
+int
+main(void)
+{
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    console_printf("\n");
+    console_printf("lora_app_shell\n");
+    las_cmd_init();
+
+    oc_main_init((oc_handler_t *)&omgr_oc_handler);
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
diff --git a/apps/lora_app_shell/syscfg.yml b/apps/lora_app_shell/syscfg.yml
new file mode 100644
index 0000000000..70db38e9b4
--- /dev/null
+++ b/apps/lora_app_shell/syscfg.yml
@@ -0,0 +1,28 @@
+#
+# 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.
+#
+
+syscfg.vals:
+    STATS_CLI: 1
+    STATS_NAMES: 1
+    SHELL_TASK: 1
+    LORA_NODE_CLI: 0
+    SHELL_MAX_COMPAT_COMMANDS: 32
+    OC_SERVER: 1
+    OC_TRANSPORT_LORA: 1
+    LOG_SOFT_RESET: 0
diff --git a/apps/loraping/pkg.yml b/apps/loraping/pkg.yml
new file mode 100644
index 0000000000..bc6f0634c5
--- /dev/null
+++ b/apps/loraping/pkg.yml
@@ -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.
+#
+
+pkg.name: apps/loraping
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/boot/split"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/nmgr_shell"
+    - "@apache-mynewt-core/sys/config"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/id"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/test/flash_test"
+
+pkg.deps.CONFIG_NFFS:
+    - "@apache-mynewt-core/fs/nffs"
+
+pkg.deps.CONFIG_FCB:
+    - "@apache-mynewt-core/fs/fcb"
diff --git a/apps/loraping/src/loraping.h b/apps/loraping/src/loraping.h
new file mode 100644
index 0000000000..4b28e7a2ac
--- /dev/null
+++ b/apps/loraping/src/loraping.h
@@ -0,0 +1,27 @@
+/*
+ * 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 H_LORAPING_
+#define H_LORAPING_
+
+void loraping_rxinfo_print(void);
+void loraping_rxinfo_timeout(void);
+void loraping_rxinfo_rxed(int8_t rssi, int8_t snr);
+
+#endif
diff --git a/apps/loraping/src/main.c b/apps/loraping/src/main.c
new file mode 100644
index 0000000000..28ae433368
--- /dev/null
+++ b/apps/loraping/src/main.c
@@ -0,0 +1,277 @@
+/*
+Copyright (c) 2013, SEMTECH S.A.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of the Semtech corporation nor the
+      names of its contributors may be used to endorse or promote products
+      derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+DISCLAIMED. IN NO EVENT SHALL SEMTECH S.A. BE LIABLE FOR ANY
+DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+Description: Ping-Pong implementation.  Adapted to run in the MyNewt OS.
+*/
+
+#include <string.h>
+#include "os/mynewt.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "bsp/bsp.h"
+#include "radio/radio.h"
+#include "loraping.h"
+
+#define USE_BAND_915
+
+#if defined(USE_BAND_433)
+
+#define RF_FREQUENCY               434000000 /* Hz */
+
+#elif defined(USE_BAND_780)
+
+#define RF_FREQUENCY               780000000 /* Hz */
+
+#elif defined(USE_BAND_868)
+
+#define RF_FREQUENCY               868000000 /* Hz */
+
+#elif defined(USE_BAND_915)
+
+#define RF_FREQUENCY               915000000 /* Hz */
+
+#else
+    #error "Please define a frequency band in the compiler options."
+#endif
+
+#define LORAPING_TX_OUTPUT_POWER            14        /* dBm */
+
+#define LORAPING_BANDWIDTH                  0         /* [0: 125 kHz, */
+                                                  /*  1: 250 kHz, */
+                                                  /*  2: 500 kHz, */
+                                                  /*  3: Reserved] */
+#define LORAPING_SPREADING_FACTOR           7         /* [SF7..SF12] */
+#define LORAPING_CODINGRATE                 1         /* [1: 4/5, */
+                                                  /*  2: 4/6, */
+                                                  /*  3: 4/7, */
+                                                  /*  4: 4/8] */
+#define LORAPING_PREAMBLE_LENGTH            8         /* Same for Tx and Rx */
+#define LORAPING_SYMBOL_TIMEOUT             5         /* Symbols */
+#define LORAPING_FIX_LENGTH_PAYLOAD_ON      false
+#define LORAPING_IQ_INVERSION_ON            false
+
+#define LORAPING_TX_TIMEOUT_MS              3000    /* ms */
+#define LORAPING_RX_TIMEOUT_MS              1000    /* ms */
+#define LORAPING_BUFFER_SIZE                64
+
+const uint8_t loraping_ping_msg[] = "PING";
+const uint8_t loraping_pong_msg[] = "PONG";
+
+static uint8_t loraping_buffer[LORAPING_BUFFER_SIZE];
+static int loraping_rx_size;
+static int loraping_is_master = 1;
+
+struct {
+    int rx_timeout;
+    int rx_ping;
+    int rx_pong;
+    int rx_other;
+    int rx_error;
+    int tx_timeout;
+    int tx_success;
+} loraping_stats;
+
+static void loraping_tx(struct os_event *ev);
+static void loraping_rx(struct os_event *ev);
+
+static struct os_event loraping_ev_tx = {
+    .ev_cb = loraping_tx,
+};
+static struct os_event loraping_ev_rx = {
+    .ev_cb = loraping_rx,
+};
+
+static void
+send_once(int is_ping)
+{
+    int i;
+
+    if (is_ping) {
+        memcpy(loraping_buffer, loraping_ping_msg, 4);
+    } else {
+        memcpy(loraping_buffer, loraping_pong_msg, 4);
+    }
+    for (i = 4; i < sizeof loraping_buffer; i++) {
+        loraping_buffer[i] = i - 4;
+    }
+
+    Radio.Send(loraping_buffer, sizeof loraping_buffer);
+}
+
+static void
+loraping_tx(struct os_event *ev)
+{
+    /* Print information about last rx attempt. */
+    loraping_rxinfo_print();
+
+    if (loraping_rx_size == 0) {
+        /* Timeout. */
+    } else {
+        os_time_delay(1);
+        if (memcmp(loraping_buffer, loraping_pong_msg, 4) == 0) {
+            loraping_stats.rx_ping++;
+        } else if (memcmp(loraping_buffer, loraping_ping_msg, 4) == 0) {
+            loraping_stats.rx_pong++;
+
+            /* A master already exists.  Become a slave. */
+            loraping_is_master = 0;
+        } else {
+            /* Valid reception but neither a PING nor a PONG message. */
+            loraping_stats.rx_other++;
+            /* Set device as master and start again. */
+            loraping_is_master = 1;
+        }
+    }
+
+    loraping_rx_size = 0;
+    send_once(loraping_is_master);
+}
+
+static void
+loraping_rx(struct os_event *ev)
+{
+    Radio.Rx(LORAPING_RX_TIMEOUT_MS);
+}
+
+static void
+on_tx_done(void)
+{
+    loraping_stats.tx_success++;
+    Radio.Sleep();
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_rx);
+}
+
+static void
+on_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+    Radio.Sleep();
+
+    if (size > sizeof loraping_buffer) {
+        size = sizeof loraping_buffer;
+    }
+
+    loraping_rx_size = size;
+    memcpy(loraping_buffer, payload, size);
+
+    loraping_rxinfo_rxed(rssi, snr);
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_tx);
+}
+
+static void
+on_tx_timeout(void)
+{
+    Radio.Sleep();
+
+    loraping_stats.tx_timeout++;
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_rx);
+}
+
+static void
+on_rx_timeout(void)
+{
+    Radio.Sleep();
+
+    loraping_stats.rx_timeout++;
+    loraping_rxinfo_timeout();
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_tx);
+}
+
+static void
+on_rx_error(void)
+{
+    loraping_stats.rx_error++;
+    Radio.Sleep();
+
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_tx);
+}
+
+int
+main(void)
+{
+    RadioEvents_t radio_events;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    hal_timer_config(4, 1000000);
+
+    /* Radio initialization. */
+    radio_events.TxDone = on_tx_done;
+    radio_events.RxDone = on_rx_done;
+    radio_events.TxTimeout = on_tx_timeout;
+    radio_events.RxTimeout = on_rx_timeout;
+    radio_events.RxError = on_rx_error;
+
+    Radio.Init(&radio_events);
+
+    Radio.SetChannel(RF_FREQUENCY);
+
+    Radio.SetTxConfig(MODEM_LORA,
+                      LORAPING_TX_OUTPUT_POWER,
+                      0,        /* Frequency deviation; unused with LoRa. */
+                      LORAPING_BANDWIDTH,
+                      LORAPING_SPREADING_FACTOR,
+                      LORAPING_CODINGRATE,
+                      LORAPING_PREAMBLE_LENGTH,
+                      LORAPING_FIX_LENGTH_PAYLOAD_ON,
+                      true,     /* CRC enabled. */
+                      0,        /* Frequency hopping disabled. */
+                      0,        /* Hop period; N/A. */
+                      LORAPING_IQ_INVERSION_ON,
+                      LORAPING_TX_TIMEOUT_MS);
+
+    Radio.SetRxConfig(MODEM_LORA,
+                      LORAPING_BANDWIDTH,
+                      LORAPING_SPREADING_FACTOR,
+                      LORAPING_CODINGRATE,
+                      0,        /* AFC bandwisth; unused with LoRa. */
+                      LORAPING_PREAMBLE_LENGTH,
+                      LORAPING_SYMBOL_TIMEOUT,
+                      LORAPING_FIX_LENGTH_PAYLOAD_ON,
+                      0,        /* Fixed payload length; N/A. */
+                      true,     /* CRC enabled. */
+                      0,        /* Frequency hopping disabled. */
+                      0,        /* Hop period; N/A. */
+                      LORAPING_IQ_INVERSION_ON,
+                      true);    /* Continuous receive mode. */
+
+    /* Immediately receive on start up. */
+    os_eventq_put(os_eventq_dflt_get(), &loraping_ev_rx);
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
diff --git a/apps/loraping/src/rxinfo.c b/apps/loraping/src/rxinfo.c
new file mode 100644
index 0000000000..71c1de89bd
--- /dev/null
+++ b/apps/loraping/src/rxinfo.c
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+/**
+ * This file contains code to collect and print receive statistics to the
+ * console.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "console/console.h"
+#include "loraping.h"
+
+#define LORAPING_NUM_RXINFOS                10
+
+struct loraping_rxinfo {
+    int8_t rssi;
+    int8_t snr;
+
+    uint8_t rxed:1;
+};
+
+static struct loraping_rxinfo loraping_rxinfos[LORAPING_NUM_RXINFOS];
+static int loraping_rxinfo_idx;
+static int loraping_rxinfo_rollover;
+
+static void
+loraping_rxinfo_avg(struct loraping_rxinfo *out_info, int *out_pkt_loss)
+{
+    long long rssi_sum;
+    long long snr_sum;
+    int num_rxed;
+    int count;
+    int i;
+
+    if (!loraping_rxinfo_rollover) {
+        count = loraping_rxinfo_idx;
+    } else {
+        count = LORAPING_NUM_RXINFOS;
+    }
+
+    assert(count > 0);
+
+    rssi_sum = 0;
+    snr_sum = 0;
+    num_rxed = 0;
+    for (i = 0; i < count; i++) {
+        if (loraping_rxinfos[i].rxed) {
+            num_rxed++;
+            rssi_sum += loraping_rxinfos[i].rssi;
+            snr_sum += loraping_rxinfos[i].snr;
+        }
+    }
+
+    memset(out_info, 0, sizeof *out_info);
+    if (num_rxed > 0) {
+        out_info->rssi = rssi_sum / num_rxed;
+        out_info->snr = snr_sum / num_rxed;
+    }
+
+    *out_pkt_loss = (count - num_rxed) * 10000 / count;
+}
+
+static void
+loraping_rxinfo_inc_idx(void)
+{
+    loraping_rxinfo_idx++;
+    if (loraping_rxinfo_idx >= LORAPING_NUM_RXINFOS) {
+        loraping_rxinfo_idx = 0;
+        loraping_rxinfo_rollover = 1;
+    }
+}
+
+void
+loraping_rxinfo_print(void)
+{
+    const struct loraping_rxinfo *last;
+    struct loraping_rxinfo avg;
+    int last_idx;
+    int pkt_loss;
+    int width;
+
+    last_idx = loraping_rxinfo_idx - 1;
+    if (last_idx < 0) {
+        last_idx += LORAPING_NUM_RXINFOS;
+    }
+    last = loraping_rxinfos + last_idx;
+
+    loraping_rxinfo_avg(&avg, &pkt_loss);
+
+    if (last->rxed) {
+        width = console_printf("[LAST] rssi=%-4d snr=%-4d",
+                               last->rssi, last->snr);
+    } else {
+        width = console_printf("[LAST] TIMEOUT");
+    }
+
+    for (; width < 48; width++) {
+        console_printf(" ");
+    }
+
+    console_printf("[AVG-%d] rssi=%-4d snr=%-4d pkt_loss=%d.%02d%%\n",
+                   LORAPING_NUM_RXINFOS, avg.rssi, avg.snr,
+                   pkt_loss / 100, pkt_loss % 100);
+}
+
+void
+loraping_rxinfo_timeout(void)
+{
+    loraping_rxinfos[loraping_rxinfo_idx].rxed = 0;
+    loraping_rxinfo_inc_idx();
+}
+
+void
+loraping_rxinfo_rxed(int8_t rssi, int8_t snr)
+{
+    loraping_rxinfos[loraping_rxinfo_idx].rssi = rssi;
+    loraping_rxinfos[loraping_rxinfo_idx].snr = snr;
+    loraping_rxinfos[loraping_rxinfo_idx].rxed = 1;
+    loraping_rxinfo_inc_idx();
+}
diff --git a/apps/loraping/syscfg.yml b/apps/loraping/syscfg.yml
new file mode 100644
index 0000000000..60d294f48a
--- /dev/null
+++ b/apps/loraping/syscfg.yml
@@ -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.
+#
+
+syscfg.defs:
+    LORA_NODE:
+        description: >
+            Used by package management system to include mfrg firmware.
+        value: 1
+
+    LORA_MAC_TIMER_NUM:
+        description: Timer number used for lora mac and radio
+        value: -1
+
+syscfg.vals:
+    STATS_CLI: 1
+    STATS_NAMES: 1
+    SHELL_TASK: 1
+    SHELL_MAX_COMPAT_COMMANDS: 32
diff --git a/apps/lorashell/pkg.yml b/apps/lorashell/pkg.yml
new file mode 100644
index 0000000000..645fbeed2e
--- /dev/null
+++ b/apps/lorashell/pkg.yml
@@ -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.
+#
+
+pkg.name: apps/lorashell
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/lora/node"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/util/parse"
diff --git a/apps/lorashell/src/main.c b/apps/lorashell/src/main.c
new file mode 100644
index 0000000000..7069e2b215
--- /dev/null
+++ b/apps/lorashell/src/main.c
@@ -0,0 +1,512 @@
+/*
+ * 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.
+ */
+
+/**
+ * A simple app for LoRa phy testing.  A typical usage scenario is:
+ *
+ * ##### Receiver
+ * # Sit on a single channel.
+ * lora set_freq 915000000
+ *
+ * # Allow 250-byte packets.
+ * lora max_payload_len 1 250
+ *
+ * # Configure LoRa receiver (specify no arguments for usage).
+ * lora rx_cfg 1 0 7 1 0 8 5 0 0 1 0 0 0 1
+ *
+ * # Print message on each receive.
+ * lora_rx_verbose 1
+ *
+ * # Clear receive log
+ * lora_rx_info clear
+ *
+ * # Keep receiving 50-byte packets until manual stop.
+ * lora_rx_rpt 50
+ *
+ * # Display information about recent receives.
+ * lora_rx_info
+ *
+ * ##### Transmitter
+ * # Sit on a single channel.
+ * lora set_freq 915000000
+ *
+ * # Allow 250-byte packets.
+ * lora max_payload_len 1 250
+ *
+ * # Configure LoRa transceiver (specify no arguments for usage).
+ * lora tx_cfg 1 14 0 0 7 1 8 0 1 0 0 0 3000
+ *
+ * # Send; size=50, count=5, interval=100ms.
+ * lora_tx_rpt 50 5 100
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <limits.h>
+#include "os/mynewt.h"
+#include "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "bsp/bsp.h"
+#include "node/radio.h"
+#include "console/console.h"
+#include "shell/shell.h"
+#include "parse/parse.h"
+
+struct lorashell_rx_entry {
+    uint16_t size;
+    int16_t rssi;
+    int8_t snr;
+};
+
+static struct lorashell_rx_entry
+    lorashell_rx_entries[MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)];
+static int lorashell_rx_entry_idx;
+static int lorashell_rx_entry_cnt;
+
+static int lorashell_rx_rpt;
+static int lorashell_rx_size;
+static int lorashell_rx_verbose;
+static int lorashell_txes_pending;
+static uint8_t lorashell_tx_size;
+static uint32_t lorashell_tx_itvl; /* OS ticks. */
+
+static int lorashell_rx_info_cmd(int argc, char **argv);
+static int lorashell_rx_rpt_cmd(int argc, char **argv);
+static int lorashell_rx_verbose_cmd(int argc, char **argv);
+static int lorashell_tx_rpt_cmd(int argc, char **argv);
+
+static void lorashell_print_last_rx(struct os_event *ev);
+
+static struct shell_cmd lorashell_cli_cmds[] = {
+    {
+        .sc_cmd = "lora_rx_info",
+        .sc_cmd_func = lorashell_rx_info_cmd,
+    },
+    {
+        .sc_cmd = "lora_rx_rpt",
+        .sc_cmd_func = lorashell_rx_rpt_cmd,
+    },
+    {
+        .sc_cmd = "lora_rx_verbose",
+        .sc_cmd_func = lorashell_rx_verbose_cmd,
+    },
+    {
+        .sc_cmd = "lora_tx_rpt",
+        .sc_cmd_func = lorashell_tx_rpt_cmd,
+    },
+};
+#define LORASHELL_NUM_CLI_CMDS  \
+    (sizeof lorashell_cli_cmds / sizeof lorashell_cli_cmds[0])
+
+static struct os_event lorashell_print_last_rx_ev = {
+    .ev_cb = lorashell_print_last_rx,
+};
+static struct os_callout lorashell_tx_timer;
+
+static const uint8_t lorashell_payload[UINT8_MAX] = {
+          0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+    0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f,
+    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27,
+    0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f,
+    0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
+    0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f,
+    0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47,
+    0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f,
+    0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57,
+    0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f,
+    0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67,
+    0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f,
+    0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77,
+    0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f,
+    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+    0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
+    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
+    0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
+    0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
+    0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
+    0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
+    0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
+    0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
+    0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
+    0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
+    0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
+    0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
+    0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
+    0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
+    0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff,
+};
+
+static void
+lorashell_rx_rpt_begin(void)
+{
+    Radio.Rx(0);
+}
+
+static void
+lorashell_tx_timer_exp(struct os_event *ev)
+{
+    if (lorashell_txes_pending <= 0) {
+        Radio.Sleep();
+        return;
+    }
+    lorashell_txes_pending--;
+
+    Radio.Send((void *)lorashell_payload, lorashell_tx_size);
+}
+
+static const char *
+lorashell_rx_entry_str(const struct lorashell_rx_entry *entry)
+{
+    static char buf[32];
+
+    snprintf(buf, sizeof buf, "size=%-4d rssi=%-4d snr=%-4d",
+             entry->size, entry->rssi, entry->snr);
+    return buf;
+}
+
+static void
+lorashell_tx_timer_reset(void)
+{
+    int rc;
+
+    rc = os_callout_reset(&lorashell_tx_timer, lorashell_tx_itvl);
+    assert(rc == 0);
+}
+
+static void
+on_tx_done(void)
+{
+    if (lorashell_txes_pending <= 0) {
+        Radio.Sleep();
+    } else {
+        lorashell_tx_timer_reset();
+    }
+}
+
+static void
+on_rx_done(uint8_t *payload, uint16_t size, int16_t rssi, int8_t snr)
+{
+    struct lorashell_rx_entry *entry;
+
+    if (lorashell_rx_size != 0) {
+        if (size != lorashell_rx_size ||
+            memcmp(payload, lorashell_payload, size) != 0) {
+
+            /* Packet error. */
+            goto done;
+        }
+    }
+
+    entry = lorashell_rx_entries + lorashell_rx_entry_idx;
+    entry->size = size;
+    entry->rssi = rssi;
+    entry->snr = snr;
+
+    if (lorashell_rx_verbose) {
+        os_eventq_put(os_eventq_dflt_get(), &lorashell_print_last_rx_ev);
+    }
+
+    lorashell_rx_entry_idx++;
+    if (lorashell_rx_entry_idx >= MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+        lorashell_rx_entry_idx = 0;
+    }
+
+    if (lorashell_rx_entry_cnt < MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+        lorashell_rx_entry_cnt++;
+    }
+
+done:
+    Radio.Sleep();
+    if (lorashell_rx_rpt) {
+        lorashell_rx_rpt_begin();
+    }
+}
+
+static void
+on_tx_timeout(void)
+{
+    assert(0);
+    lorashell_tx_timer_reset();
+}
+
+static void
+on_rx_timeout(void)
+{
+    Radio.Sleep();
+}
+
+static void
+on_rx_error(void)
+{
+    Radio.Sleep();
+}
+
+static void
+lorashell_print_last_rx(struct os_event *ev)
+{
+    const struct lorashell_rx_entry *entry;
+    int idx;
+
+    idx = lorashell_rx_entry_idx - 1;
+    if (idx < 0) {
+        idx = lorashell_rx_entry_cnt - 1;
+    }
+
+    entry = lorashell_rx_entries + idx;
+    console_printf("rxed lora packet: %s\n", lorashell_rx_entry_str(entry));
+}
+
+static void
+lorashell_avg_rx_entry(struct lorashell_rx_entry *out_entry)
+{
+    long long rssi_sum;
+    long long size_sum;
+    long long snr_sum;
+    int i;
+
+    rssi_sum = 0;
+    size_sum = 0;
+    snr_sum = 0;
+    for (i = 0; i < lorashell_rx_entry_cnt; i++) {
+        rssi_sum += lorashell_rx_entries[i].rssi;
+        size_sum += lorashell_rx_entries[i].size;
+        snr_sum += lorashell_rx_entries[i].snr;
+    }
+
+    memset(out_entry, 0, sizeof *out_entry);
+    if (lorashell_rx_entry_cnt > 0) {
+        out_entry->size = size_sum / lorashell_rx_entry_cnt;
+        out_entry->rssi = rssi_sum / lorashell_rx_entry_cnt;
+        out_entry->snr = snr_sum / lorashell_rx_entry_cnt;
+    }
+}
+
+static int
+lorashell_rx_rpt_cmd(int argc, char **argv)
+{
+    const char *err;
+    int rc;
+
+    if (argc > 1) {
+        if (strcmp(argv[1], "stop") == 0) {
+            lorashell_rx_rpt = 0;
+            Radio.Sleep();
+            console_printf("lora rx stopped\n");
+            return 0;
+        }
+
+        lorashell_rx_size = parse_ull_bounds(argv[1], 0, UINT8_MAX, &rc);
+        if (rc != 0) {
+            err = "invalid size";
+            goto err;
+        }
+    } else {
+        lorashell_rx_size = 0;
+    }
+
+    lorashell_rx_rpt = 1;
+    lorashell_rx_rpt_begin();
+
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora_rx_rpt [size]\n"
+"    lora_rx_rpt stop\n");
+
+    return rc;
+}
+
+static int
+lorashell_rx_verbose_cmd(int argc, char **argv)
+{
+    int rc;
+
+    if (argc <= 1) {
+        console_printf("lora rx verbose: %d\n", lorashell_rx_verbose);
+        return 0;
+    }
+
+    lorashell_rx_verbose = parse_ull_bounds(argv[1], 0, 1, &rc);
+    if (rc != 0) {
+        console_printf("error: rc=%d\n", rc);
+        return rc;
+    }
+
+    return 0;
+}
+
+static int
+lorashell_rx_info_cmd(int argc, char **argv)
+{
+    const struct lorashell_rx_entry *entry;
+    struct lorashell_rx_entry avg;
+    int idx;
+    int i;
+
+    if (argc > 1 && argv[1][0] == 'c') {
+        lorashell_rx_entry_idx = 0;
+        lorashell_rx_entry_cnt = 0;
+        console_printf("lora rx info cleared\n");
+        return 0;
+    }
+
+    if (lorashell_rx_entry_cnt < MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+        idx = 0;
+    } else {
+        idx = lorashell_rx_entry_idx;
+    }
+
+    console_printf("entries in log: %d\n", lorashell_rx_entry_cnt);
+
+    for (i = 0; i < lorashell_rx_entry_cnt; i++) {
+        entry = lorashell_rx_entries + idx;
+        console_printf("%4d: %s\n", i + 1, lorashell_rx_entry_str(entry));
+
+        idx++;
+        if (idx >= MYNEWT_VAL(LORASHELL_NUM_RX_ENTRIES)) {
+            idx = 0;
+        }
+    }
+
+    if (lorashell_rx_entry_cnt > 0) {
+        lorashell_avg_rx_entry(&avg);
+        console_printf(" avg: %s\n", lorashell_rx_entry_str(&avg));
+    }
+
+    return 0;
+}
+
+static int
+lorashell_tx_rpt_cmd(int argc, char **argv)
+{
+    const char *err;
+    uint32_t itvl_ms;
+    int rc;
+
+    if (argc < 1) {
+        rc = 1;
+        err = NULL;
+        goto err;
+    }
+
+    if (strcmp(argv[1], "stop") == 0) {
+        lorashell_txes_pending = 0;
+        Radio.Sleep();
+        console_printf("lora tx stopped\n");
+        return 0;
+    }
+
+    lorashell_tx_size = parse_ull_bounds(argv[1], 0, UINT8_MAX, &rc);
+    if (rc != 0) {
+        err = "invalid size";
+        goto err;
+    }
+
+    if (argc >= 2) {
+        lorashell_txes_pending = parse_ull_bounds(argv[2], 0, INT_MAX, &rc);
+        if (rc != 0) {
+            err = "invalid count";
+            goto err;
+        }
+    } else {
+        lorashell_txes_pending = 1;
+    }
+
+    if (argc >= 3) {
+        itvl_ms = parse_ull_bounds(argv[3], 0, UINT32_MAX, &rc);
+        if (rc != 0) {
+            err = "invalid interval";
+            goto err;
+        }
+    } else {
+        itvl_ms = 1000;
+    }
+
+    rc = os_time_ms_to_ticks(itvl_ms, &lorashell_tx_itvl);
+    if (rc != 0) {
+        err = "invalid interval";
+        goto err;
+    }
+
+    lorashell_tx_timer_exp(NULL);
+
+    return 0;
+
+err:
+    if (err != NULL) {
+        console_printf("error: %s\n", err);
+    }
+
+    console_printf(
+"usage:\n"
+"    lora_tx_rpt <size> [count] [interval (ms)]\n"
+"    lora_tx_rpt stop\n");
+
+    return rc;
+}
+
+int
+main(void)
+{
+    RadioEvents_t radio_events;
+    int rc;
+    int i;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    for (i = 0; i < LORASHELL_NUM_CLI_CMDS; i++) {
+        rc = shell_cmd_register(lorashell_cli_cmds + i);
+        SYSINIT_PANIC_ASSERT_MSG(
+            rc == 0, "Failed to register lorashell CLI commands");
+    }
+
+    os_callout_init(&lorashell_tx_timer, os_eventq_dflt_get(),
+                    lorashell_tx_timer_exp, NULL);
+
+    /* Radio initialization. */
+    radio_events.TxDone = on_tx_done;
+    radio_events.RxDone = on_rx_done;
+    radio_events.TxTimeout = on_tx_timeout;
+    radio_events.RxTimeout = on_rx_timeout;
+    radio_events.RxError = on_rx_error;
+
+    Radio.Init(&radio_events);
+    Radio.SetMaxPayloadLength(MODEM_LORA, 250);
+
+    console_printf("lorashell\n");
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
diff --git a/apps/lorashell/syscfg.yml b/apps/lorashell/syscfg.yml
new file mode 100644
index 0000000000..a3953d0de4
--- /dev/null
+++ b/apps/lorashell/syscfg.yml
@@ -0,0 +1,29 @@
+#
+# 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.
+#
+
+syscfg.defs:
+    LORASHELL_NUM_RX_ENTRIES:
+        description: "The size of the receive log."
+        value: 10
+
+syscfg.vals:
+    STATS_CLI: 1
+    STATS_NAMES: 1
+    SHELL_TASK: 1
+    LORA_NODE_CLI: 1
diff --git a/apps/metrics/pkg.yml b/apps/metrics/pkg.yml
new file mode 100644
index 0000000000..c1445ad87a
--- /dev/null
+++ b/apps/metrics/pkg.yml
@@ -0,0 +1,29 @@
+# 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.
+#
+pkg.name: apps/metrics
+pkg.type: app
+pkg.description: 
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - kernel/os 
+    - sys/console/full
+    - sys/metrics 
+    - sys/sysinit
diff --git a/apps/metrics/src/main.c b/apps/metrics/src/main.c
new file mode 100755
index 0000000000..b5f9671a79
--- /dev/null
+++ b/apps/metrics/src/main.c
@@ -0,0 +1,156 @@
+/*
+ * 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 <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include "os/os.h"
+#include "sysinit/sysinit.h"
+#include "metrics/metrics.h"
+#include "tinycbor/cbor_mbuf_reader.h"
+#include "tinycbor/cbor.h"
+#include "log/log.h"
+#include "sysflash/sysflash.h"
+#include "fcb/fcb.h"
+
+/*
+ * XXX
+ * Metrics are numbered starting from 0 in order as defined. It may be good idea
+ * to define an enum with proper symbols to identify each metric so it's easy
+ * to rearrange them later. Or we may find some nice way to actually define
+ * these symbols automatically, not yet sure how though...
+ */
+
+/* Define symbols for metrics */
+enum {
+    MY_METRIC_VAL_S,
+    MY_METRIC_VAL_U,
+    MY_METRIC_VAL_SS16,
+    MY_METRIC_VAL_SU32,
+    MY_METRIC_VAL_SS32,
+};
+
+/* Define all metrics */
+METRICS_SECT_START(my_metrics)
+    METRICS_SECT_ENTRY(val_s, METRICS_TYPE_SINGLE_S)
+    METRICS_SECT_ENTRY(val_u, METRICS_TYPE_SINGLE_U)
+    METRICS_SECT_ENTRY(val_ss16, METRICS_TYPE_SERIES_S16)
+    METRICS_SECT_ENTRY(val_su32, METRICS_TYPE_SERIES_U32)
+    METRICS_SECT_ENTRY(val_ss32, METRICS_TYPE_SERIES_S32)
+METRICS_SECT_END;
+
+/* Declare event struct to accommodate all metrics */
+METRICS_EVENT_DECLARE(my_event, my_metrics);
+
+/* Sample event */
+struct my_event g_event;
+
+/* Target log instance */
+static struct log g_log;
+static struct fcb_log g_log_fcb;
+static struct flash_area g_log_fcb_fa;
+
+static void
+init_log_instance(void)
+{
+    const struct flash_area *fa;
+    int rc;
+
+    /* Temporarily just use reboot log fa */
+    rc = flash_area_open(FLASH_AREA_REBOOT_LOG, &fa);
+    assert(rc == 0);
+
+    g_log_fcb_fa = *fa;
+    g_log_fcb.fl_fcb.f_sectors = &g_log_fcb_fa;
+    g_log_fcb.fl_fcb.f_sector_cnt = 1;
+    g_log_fcb.fl_fcb.f_magic = 0xBABABABA;
+    g_log_fcb.fl_fcb.f_version = g_log_info.li_version;
+
+    g_log_fcb.fl_entries = 0;
+
+    rc = fcb_init(&g_log_fcb.fl_fcb);
+    if (rc) {
+        flash_area_erase(fa, 0, fa->fa_size);
+        rc = fcb_init(&g_log_fcb.fl_fcb);
+        assert(rc == 0);
+    }
+
+    log_register("my_metrics", &g_log, &log_fcb_handler, &g_log_fcb,
+                 LOG_SYSLEVEL);
+}
+
+int
+main(void)
+{
+    struct os_mbuf *om;
+    int i;
+
+    sysinit();
+
+    init_log_instance();
+
+    /* Initialize event internals and enable logging for all metrics */
+    metrics_event_init(&g_event.hdr, my_metrics, METRICS_SECT_COUNT(my_metrics), "myev");
+    metrics_event_register(&g_event.hdr);
+    metrics_set_state_mask(&g_event.hdr, 0xffffffff);
+
+    /* Start new event */
+    metrics_event_start(&g_event.hdr, os_cputime_get32());
+
+    /* Log some data to event */
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_S, -10);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_U, 10);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_SU32, 100);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_SU32, 101);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_SU32, 102);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_SU32, 103);
+
+    /* Serialize event to mbuf from metrics pool */
+    om = metrics_get_mbuf();
+    metrics_event_to_cbor(&g_event.hdr, om);
+    os_mbuf_free_chain(om);
+
+    /* Start new event */
+    metrics_event_start(&g_event.hdr, os_cputime_get32());
+    metrics_event_set_log(&g_event.hdr, &g_log, LOG_MODULE_DEFAULT, LOG_LEVEL_INFO);
+
+    /* Log some data to event */
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_S, -10);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_U, 10);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_U, 11);
+    metrics_set_value(&g_event.hdr, MY_METRIC_VAL_U, 12);
+    for (i = 32750; i < 32800; i++) {
+        metrics_set_value(&g_event.hdr, MY_METRIC_VAL_SS16, -i);
+        metrics_set_value(&g_event.hdr, MY_METRIC_VAL_SS32, -i);
+    }
+
+    /*
+     * event state can be dumped via shell:
+     *   select metrics
+     *   list-events 1
+     *   event-dump myev
+     */
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+
+    return 0;
+}
diff --git a/apps/metrics/syscfg.yml b/apps/metrics/syscfg.yml
new file mode 100644
index 0000000000..180753b60d
--- /dev/null
+++ b/apps/metrics/syscfg.yml
@@ -0,0 +1,24 @@
+#
+# 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.
+#
+
+syscfg.vals:
+    LOG_FCB: 1
+    LOG_CLI: 1
+    LOG_VERSION: 3
+    METRICS_CLI: 1
diff --git a/apps/ocf_sample/pkg.yml b/apps/ocf_sample/pkg.yml
index 6acc16bb59..e8882052a7 100644
--- a/apps/ocf_sample/pkg.yml
+++ b/apps/ocf_sample/pkg.yml
@@ -20,23 +20,24 @@
 pkg.name: apps/ocf_sample
 pkg.type: app
 pkg.description: Example application which uses OCF iotivity.
-pkg.author: "Apache Mynewt <de...@mynewt.incubator.apache.org>"
+pkg.author: "Apache Mynewt <de...@mynewt.apache.org>"
 pkg.homepage: "http://mynewt.apache.org/"
 pkg.keywords:
 
 pkg.deps:
-    - kernel/os
-    - net/oic
-    - encoding/cborattr
-    - sys/console/full
-    - sys/log/full
-    - sys/stats/full
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/net/oic"
+    - "@apache-mynewt-core/encoding/cborattr"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
 
 pkg.deps.OC_TRANSPORT_SERIAL:
-    - sys/shell
+    - "@apache-mynewt-core/sys/shell"
 
 pkg.deps.OC_TRANSPORT_GATT:
-    - net/nimble/controller
-    - net/nimble/host
-    - net/nimble/host/store/ram
-    - net/nimble/transport/ram
+    - "@apache-mynewt-core/net/nimble/controller"
+    - "@apache-mynewt-core/net/nimble/host"
+    - "@apache-mynewt-core/net/nimble/host/store/ram"
+    - "@apache-mynewt-core/net/nimble/transport/ram"
diff --git a/apps/ocf_sample/src/main.c b/apps/ocf_sample/src/main.c
index eb25cf13ed..3a3804e9c9 100644
--- a/apps/ocf_sample/src/main.c
+++ b/apps/ocf_sample/src/main.c
@@ -17,9 +17,7 @@
  * under the License.
  */
 #include <assert.h>
-#include "sysinit/sysinit.h"
-#include <os/os.h>
-#include <sysinit/sysinit.h>
+#include "os/mynewt.h"
 #include <bsp/bsp.h>
 #include <log/log.h>
 #include <oic/oc_api.h>
@@ -156,7 +154,7 @@ observe_light(oc_client_response_t *rsp)
     };
 
     len = coap_get_payload(rsp->packet, &m, &data_off);
-    if (cbor_read_mbuf_attrs(m, data_off, len, attrs)) {
+    if (!cbor_read_mbuf_attrs(m, data_off, len, attrs)) {
         printf("OBSERVE_light: %d\n", state);
         light_state = state;
     }
diff --git a/apps/ocf_sample/src/ocf_ble.c b/apps/ocf_sample/src/ocf_ble.c
index d93bdd9f68..2e6b23b1e0 100644
--- a/apps/ocf_sample/src/ocf_ble.c
+++ b/apps/ocf_sample/src/ocf_ble.c
@@ -17,14 +17,14 @@
  * under the License.
  */
 
-#include "syscfg/syscfg.h"
+#include "os/mynewt.h"
 
 #if MYNEWT_VAL(OC_TRANSPORT_GATT)
 
 #include <assert.h>
 #include <string.h>
 
-#include "log/log.h"
+#include "modlog/modlog.h"
 
 #include "oic/oc_gatt.h"
 
@@ -33,15 +33,6 @@
 #include "host/ble_hs.h"
 #include "services/gap/ble_svc_gap.h"
 
-struct log ocf_ble_log;
-
-/* ocf_ble uses the first "peruser" log module. */
-#define OCF_BLE_LOG_MODULE  (LOG_MODULE_PERUSER + 0)
-
-/* Convenience macro for logging to the ocf_ble module. */
-#define OCF_BLE_LOG(lvl, ...) \
-    LOG_ ## lvl(&ocf_ble_log, OCF_BLE_LOG_MODULE, __VA_ARGS__)
-
 static int ocf_ble_gap_event(struct ble_gap_event *event, void *arg);
 
 /**
@@ -53,7 +44,7 @@ print_bytes(const uint8_t *bytes, int len)
     int i;
 
     for (i = 0; i < len; i++) {
-        OCF_BLE_LOG(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
+        MODLOG_DFLT(INFO, "%s0x%02x", i != 0 ? ":" : "", bytes[i]);
     }
 }
 
@@ -63,7 +54,7 @@ print_addr(const void *addr)
     const uint8_t *u8p;
 
     u8p = addr;
-    OCF_BLE_LOG(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
+    MODLOG_DFLT(INFO, "%02x:%02x:%02x:%02x:%02x:%02x",
                 u8p[5], u8p[4], u8p[3], u8p[2], u8p[1], u8p[0]);
 }
 
@@ -73,20 +64,20 @@ print_addr(const void *addr)
 static void
 ocf_ble_print_conn_desc(struct ble_gap_conn_desc *desc)
 {
-    OCF_BLE_LOG(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
+    MODLOG_DFLT(INFO, "handle=%d our_ota_addr_type=%d our_ota_addr=",
                 desc->conn_handle, desc->our_ota_addr.type);
     print_addr(desc->our_ota_addr.val);
-    OCF_BLE_LOG(INFO, " our_id_addr_type=%d our_id_addr=",
+    MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
                 desc->our_id_addr.type);
     print_addr(desc->our_id_addr.val);
-    OCF_BLE_LOG(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
+    MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
                 desc->peer_ota_addr.type);
     print_addr(desc->peer_ota_addr.val);
-    OCF_BLE_LOG(INFO, " peer_id_addr_type=%d peer_id_addr=",
+    MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
                 desc->peer_id_addr.type);
     print_addr(desc->peer_id_addr.val);
-    OCF_BLE_LOG(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
-                "encrypted=%d authenticated=%d bonded=%d\n",
+    MODLOG_DFLT(INFO, " conn_itvl=%d conn_latency=%d supervision_timeout=%d "
+                      "encrypted=%d authenticated=%d bonded=%d\n",
                 desc->conn_itvl, desc->conn_latency,
                 desc->supervision_timeout,
                 desc->sec_state.encrypted,
@@ -137,7 +128,7 @@ ocf_ble_advertise(void)
 
     rc = ble_gap_adv_set_fields(&fields);
     if (rc != 0) {
-        OCF_BLE_LOG(ERROR, "error setting advertisement data; rc=%d\n", rc);
+        MODLOG_DFLT(ERROR, "error setting advertisement data; rc=%d\n", rc);
         return;
     }
 
@@ -148,7 +139,7 @@ ocf_ble_advertise(void)
     rc = ble_gap_adv_start(BLE_OWN_ADDR_PUBLIC, NULL, BLE_HS_FOREVER,
                            &adv_params, ocf_ble_gap_event, NULL);
     if (rc != 0) {
-        OCF_BLE_LOG(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
         return;
     }
 }
@@ -184,15 +175,15 @@ ocf_ble_gap_event(struct ble_gap_event *event, void *arg)
     switch (event->type) {
     case BLE_GAP_EVENT_CONNECT:
         /* A new connection was established or a connection attempt failed. */
-        OCF_BLE_LOG(INFO, "connection %s; status=%d ",
-                       event->connect.status == 0 ? "established" : "failed",
-                       event->connect.status);
+        MODLOG_DFLT(INFO, "connection %s; status=%d ",
+                    event->connect.status == 0 ? "established" : "failed",
+                    event->connect.status);
         if (event->connect.status == 0) {
             rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
             assert(rc == 0);
             ocf_ble_print_conn_desc(&desc);
         }
-        OCF_BLE_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
 
         if (event->connect.status != 0) {
             /* Connection failed; resume advertising. */
@@ -201,9 +192,9 @@ ocf_ble_gap_event(struct ble_gap_event *event, void *arg)
         return 0;
 
     case BLE_GAP_EVENT_DISCONNECT:
-        OCF_BLE_LOG(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
         ocf_ble_print_conn_desc(&event->disconnect.conn);
-        OCF_BLE_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
 
         /* Connection terminated; resume advertising. */
         ocf_ble_advertise();
@@ -211,26 +202,32 @@ ocf_ble_gap_event(struct ble_gap_event *event, void *arg)
 
     case BLE_GAP_EVENT_CONN_UPDATE:
         /* The central has updated the connection parameters. */
-        OCF_BLE_LOG(INFO, "connection updated; status=%d ",
+        MODLOG_DFLT(INFO, "connection updated; status=%d ",
                     event->conn_update.status);
         rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
         assert(rc == 0);
         ocf_ble_print_conn_desc(&desc);
-        OCF_BLE_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        MODLOG_DFLT(INFO, "advertise complete; reason=%d\n",
+                    event->adv_complete.reason);
+        ocf_ble_advertise();
         return 0;
 
     case BLE_GAP_EVENT_ENC_CHANGE:
         /* Encryption has been enabled or disabled for this connection. */
-        OCF_BLE_LOG(INFO, "encryption change event; status=%d ",
+        MODLOG_DFLT(INFO, "encryption change event; status=%d ",
                     event->enc_change.status);
         rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
         assert(rc == 0);
         ocf_ble_print_conn_desc(&desc);
-        OCF_BLE_LOG(INFO, "\n");
+        MODLOG_DFLT(INFO, "\n");
         return 0;
 
     case BLE_GAP_EVENT_SUBSCRIBE:
-        OCF_BLE_LOG(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
+        MODLOG_DFLT(INFO, "subscribe event; conn_handle=%d attr_handle=%d "
                           "reason=%d prevn=%d curn=%d previ=%d curi=%d\n",
                     event->subscribe.conn_handle,
                     event->subscribe.attr_handle,
@@ -242,7 +239,7 @@ ocf_ble_gap_event(struct ble_gap_event *event, void *arg)
         return 0;
 
     case BLE_GAP_EVENT_MTU:
-        OCF_BLE_LOG(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
+        MODLOG_DFLT(INFO, "mtu update event; conn_handle=%d cid=%d mtu=%d\n",
                     event->mtu.conn_handle,
                     event->mtu.channel_id,
                     event->mtu.value);
@@ -257,16 +254,9 @@ static const uint8_t ocf_ble_addr[6] = {1,2,3,4,5,6};
 void
 ocf_ble_init(void)
 {
-    /* Initialize the ocf_ble log. */
-    log_register("ocf_ble", &ocf_ble_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
     memcpy(g_dev_addr, ocf_ble_addr, sizeof(g_dev_addr));
 
     /* Initialize the BLE host. */
-    log_register("ble_hs", &ble_hs_log, &log_console_handler, NULL,
-                 LOG_SYSLEVEL);
-
     ble_hs_cfg.sync_cb = ocf_ble_on_sync;
 }
 
diff --git a/apps/pwm_test/pkg.yml b/apps/pwm_test/pkg.yml
new file mode 100644
index 0000000000..a5e73f30b9
--- /dev/null
+++ b/apps/pwm_test/pkg.yml
@@ -0,0 +1,31 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one

  (This diff was longer than 20,000 lines, and has been truncated...)


 

----------------------------------------------------------------
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