Merge pull request #67 from bethjonesbluesky/patch-1

Update blehci_project.rst, documented a missing step. 
diff --git a/docs/conf.py b/docs/conf.py
index fc8aed0..7fe78b3 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -185,3 +185,5 @@
     "default": ("apache/mynewt-documentation", "docs/")
 }
 edit_on_github_branch = 'master'
+
+slack_url = 'https://join.slack.com/t/mynewt/shared_invite/enQtNjA1MTg0NzgyNzg3LTZiYzgxNDQ3NmQ5ZWFkMTY4MjNjYTNmNGJjMDhiMZiMWFjNDdkMzBlNzZjOWY0YzljYTBhYTg1YmRjYzljZDg'
diff --git a/docs/themes/mynewt/footer.html b/docs/themes/mynewt/footer.html
index 3350810..94d26af 100644
--- a/docs/themes/mynewt/footer.html
+++ b/docs/themes/mynewt/footer.html
@@ -13,7 +13,7 @@
                 Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
                 registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
               </small>
-              <a href="https://join.slack.com/mynewt/shared_invite/MTkwMTg1ODM1NTg5LTE0OTYxNzQ4NzQtZTU1YmNhYjhkMg">
+              <a href="{{ slack_url }}">
                 <img src="{{pathto("_static/img/add_to_slack.png", 1)}}" alt="Slack Icon" title="Join our Slack Community" />
               </a>
           </div>
diff --git a/docs/themes/mynewt/main-banner.html b/docs/themes/mynewt/main-banner.html
index 1761e1a..8d3bbb4 100644
--- a/docs/themes/mynewt/main-banner.html
+++ b/docs/themes/mynewt/main-banner.html
@@ -8,7 +8,7 @@
         </div>
         <div class="news-cell">
             <div class="well">
-              <h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.5.0 </a> released (Nov 5, 2018)
+                <h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.6.0, Apache NimBLE 1.1.0 </a> released (April 9, 2019)
             </div>
         </div>
     </div>
diff --git a/docs/themes/mynewt/versions.html b/docs/themes/mynewt/versions.html
index 4890fb7..540ff2b 100644
--- a/docs/themes/mynewt/versions.html
+++ b/docs/themes/mynewt/versions.html
@@ -3,6 +3,9 @@
   <option value="/latest" selected>
     Version: latest
   </option>
+  <option value="/v1_5_0">
+    Version: 1.5.0
+  </option>
   <option value="/v1_4_0">
     Version: 1.4.0
   </option>
@@ -19,6 +22,6 @@
     Version: 1.0.0
   </option>
   <option value="/v0_9_0/os/introduction">
-    Version: 0_9_0
+    Version: 0.9.0
   </option>
-</select>
\ No newline at end of file
+</select>
diff --git a/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/footer.html b/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/footer.html
index 3350810..94d26af 100644
--- a/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/footer.html
+++ b/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/footer.html
@@ -13,7 +13,7 @@
                 Apache Mynewt, Mynewt, Apache, the Apache feather logo, and the Apache Mynewt project logo are either
                 registered trademarks or trademarks of the Apache Software Foundation in the United States and other countries.
               </small>
-              <a href="https://join.slack.com/mynewt/shared_invite/MTkwMTg1ODM1NTg5LTE0OTYxNzQ4NzQtZTU1YmNhYjhkMg">
+              <a href="{{ slack_url }}">
                 <img src="{{pathto("_static/img/add_to_slack.png", 1)}}" alt="Slack Icon" title="Join our Slack Community" />
               </a>
           </div>
diff --git a/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/main-banner.html b/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/main-banner.html
index 1761e1a..8d3bbb4 100644
--- a/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/main-banner.html
+++ b/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/main-banner.html
@@ -8,7 +8,7 @@
         </div>
         <div class="news-cell">
             <div class="well">
-              <h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.5.0 </a> released (Nov 5, 2018)
+                <h4>Latest News:</h4> <a href="/download">Apache Mynewt 1.6.0, Apache NimBLE 1.1.0 </a> released (April 9, 2019)
             </div>
         </div>
     </div>
diff --git a/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/versions.html b/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/versions.html
index 9475c0b..3c7b5dc 100644
--- a/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/versions.html
+++ b/versions/v1_4_0/mynewt-documentation/docs/themes/mynewt/versions.html
@@ -3,6 +3,9 @@
   <option value="/latest">
     Version: latest
   </option>
+  <option value="/v1_5_0">
+    Version: 1.5.0
+  </option>
   <option value="/v1_4_0" selected>
     Version: 1.4.0
   </option>
@@ -19,6 +22,6 @@
     Version: 1.0.0
   </option>
   <option value="/v0_9_0/os/introduction">
-    Version: 0_9_0
+    Version: 0.9.0
   </option>
-</select>
\ No newline at end of file
+</select>
diff --git a/versions/v1_4_0/mynewt-nimble/README.md b/versions/v1_4_0/mynewt-nimble/README.md
index b92f3f6..23d2f1a 100644
--- a/versions/v1_4_0/mynewt-nimble/README.md
+++ b/versions/v1_4_0/mynewt-nimble/README.md
@@ -112,7 +112,7 @@
 [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 IRC or #general channel on [Mynewt Slack](https://join.slack.com/mynewt/shared_invite/MTkwMTg1ODM1NTg5LTE0OTYxNzQ4NzQtZTU1YmNhYjhkMg)
+on the #mynewt channel on Freenode IRC or #general channel on [Mynewt Slack](https://join.slack.com/t/mynewt/shared_invite/enQtNjA1MTg0NzgyNzg3LTZiYzgxNDQ3NmQ5ZWFkMTY4MjNjYTNmNGJjMDhiMmZiMWFjNDdkMzBlNzZjOWY0YzljYTBhYTg1YmRjYzljZDg)
 
 Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers)
 for some help troubleshooting first.
diff --git a/versions/v1_5_0/mynewt-core/.gitignore b/versions/v1_5_0/mynewt-core/.gitignore
new file mode 100644
index 0000000..86f9312
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/.gitignore
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+.app.db
+.app
+bin
+obj
+tags
+.gdb_history
+.gdb_out
+.gdb_cmds
+.gdbinit
+*~
+.DS_Store
+*.swp
+*.swo
+*.bak
+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/versions/v1_5_0/mynewt-core/.mailmap b/versions/v1_5_0/mynewt-core/.mailmap
new file mode 100644
index 0000000..f90a088
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/.mailmap
@@ -0,0 +1,34 @@
+Aditi Hilbert <aditi@runtime.io>			<aditi@runtime.io>
+Alfred Schilken <alfred@schilken.de>			<alfred@schilken.de>
+Alvaro Prieto <alvaroprieto@verily.com>			<gitkraken@alvaroprieto.com>
+Alvaro Prieto <alvaroprieto@verily.com>			<source@alvaroprieto.com>
+Brian Giori <briangiori@gmail.com>			<bgiori@users.noreply.github.com>
+Christopher Collins <ccollins@apache.org>		<ccollins476ad@gmail.com>
+Christopher Collins <ccollins@apache.org>		<ccollins@iori.nightmare-heaven.no-ip.biz>
+David G. Simmons <santafen@mac.com>			<davidgs@users.noreply.github.com>
+David Lee <david@runtime.io>				<34385265+dlee-rt@users.noreply.github.com>
+David Lee <david@runtime.io>				<34385265+dlee-rt@users.noreply.github.com>
+Fabio Utzig <utzig@utzig.org>				<utzig@apache.org>
+Francois Berder <fberder@outlook.fr>			<fberder@outlook.fr>
+Gordon Klaus <gordon.klaus@gmail.com>			<gordon.klaus@telenordigital.com>
+Jacob Rosenthal <jakerosenthal@gmail.com>		<jacobrosenthal@gmail.com>
+Jacob Rosenthal <jakerosenthal@gmail.com>		<jacobrosenthal@localhost.localdomain>
+Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>		<kasjer@users.noreply.github.com>
+Julian Ingram <julian.ingram@imgtec.com>		<julian.ingram@imgtec.com>
+Julian Ingram <julian.ingram@imgtec.com>		<jjmingram@gmail.com>
+Julian Ingram <julian.ingram@imgtec.com>		<IMGJulian@users.noreply.github.com>
+Marko Kiiskila <marko@runtime.io>			<marko@runtime.io>
+Marko Kiiskila <marko@runtime.io>			<marko@Markos-MacBook-Pro-2.local>
+Matthew Warnes <matthewwarnes@outlook.com>		<36331729+matthewwarnes@users.noreply.github.com>
+Neel Natu <neel@nahannisys.com>				<neel@neels-Air.attlocal.net>
+Neel Natu <neel@nahannisys.com>				<neel@neels-MacBook-Air.local>
+Peter Snyder <peterfs@apache.org>			<git@peterfs.com>
+Sterling Hughes <sterling@apache.org>			<sterling@apache.org>
+Sterling Hughes <sterling@apache.org>			<sterling@micosa.net>
+Sterling Hughes <sterling@apache.org>			<sterling@runtime.io>
+Sterling Hughes <sterling@apache.org>			<sterlinghughes@users.noreply.github.com>
+Szymon Janc <szymon.janc@codecoup.pl>			<szymon.janc@gmail.com>
+Vipul Rahane <vipulrahane@apache.org>			<vipul@runtime.io>
+Vipul Rahane <vipulrahane@apache.org>			<vrahane@gmail.com>
+William San Filippo <wills@runtime.io>			<will@micosa.io>
+William San Filippo <wills@runtime.io>			<wills@runtime.io>
diff --git a/versions/v1_5_0/mynewt-core/.rat-excludes b/versions/v1_5_0/mynewt-core/.rat-excludes
new file mode 100644
index 0000000..af64bee
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/.rat-excludes
@@ -0,0 +1,448 @@
+# Can't easily add license to rat-excludes file.
+.rat-excludes
+
+# Temporary user files.
+.gdb_history
+.gdb_out
+tags
+
+# Non-source files
+RELEASE_NOTES.md
+repository.yml
+.gitignore
+00readme.txt
+uncrustify.cfg
+README.md
+.mailmap
+version.txt
+
+# unit tests executables
+bin
+
+# CRC16 - BSD License.
+crc16.*
+
+# Nordic nRF51 SDK - BSD License.
+nrf51dk_no_boot.ld
+system_nrf51.c
+gcc_startup_nrf51.s
+nrf51dk-16kbram_no_boot.ld
+boot-nrf51xxaa.ld
+nrf51xxaa.ld
+boot-nrf51xxac.ld
+nrf51xxac.ld
+split-nrf51dk.ld
+boot-nrf51xxac.ld
+nrf51xxac.ld
+split-nrf51dk.ld
+split-nrf51dk-16kbram.ld
+nrf51.ld
+nrf51.h
+nrf51_bitfields.h
+nrf51_deprecated.h
+system_nrf51.h
+gcc_startup_nrf51_split.s
+
+# Nordic nRF52 SDK - BSD License.
+nrf52dk_no_boot.ld
+bmd300eval_no_boot.ld
+boot-nrf52xxaa.ld
+nrf52xxaa.ld
+primo_no_boot.ld
+split-primo.ld
+split-bmd300eval.ld
+split-nrf52dk.ld
+rb-nano2_no_boot.ld
+split-rb-nano2.ld
+nrf52.ld
+ada_feather_nrf52_no_boot.ld
+split_ada_feather_nrf52.ld
+split-microbit.ld
+system_nrf52.c
+gcc_startup_nrf52.s
+nrf51_to_nrf52.h
+nrf52.h
+nrf52_bitfields.h
+system_nrf52.h
+gcc_startup_nrf52_split.s
+gcc_startup_nrf52840.s
+nrf51_to_nrf52840.h
+nrf52840.h
+nrf52840_bitfields.h
+nrf52840_peripherals.h
+nrf52_to_nrf52840.h
+system_nrf52840.c
+system_nrf52840.h
+
+# Nordic nRF51 SDK - BSD License.
+# Nordic nRF52 SDK - BSD License.
+compiler_abstraction.h
+nrf.h
+nrf52_name_change.h
+system_nrf51422.c
+arm_startup_nrf51.s
+arm_startup_nrf52.s
+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
+stm32_driver_mod_timer.c
+
+# STM32CubeF4  - BSD License.
+stm32f4xx_hal_conf.h
+system_stm32f4xx.c
+startup_STM32F40x.s
+stm32f407xx.h
+stm32f4xx.h
+stm32f4xx_hal.h
+stm32f4xx_hal_adc.h
+stm32f4xx_hal_adc_ex.h
+stm32f4xx_hal_can.h
+stm32f4xx_hal_cec.h
+stm32f4xx_hal_cortex.h
+stm32f4xx_hal_crc.h
+stm32f4xx_hal_cryp.h
+stm32f4xx_hal_cryp_ex.h
+stm32f4xx_hal_dac.h
+stm32f4xx_hal_dac_ex.h
+stm32f4xx_hal_dcmi.h
+stm32f4xx_hal_dcmi_ex.h
+stm32f4xx_hal_def.h
+stm32f4xx_hal_dma.h
+stm32f4xx_hal_dma2d.h
+stm32f4xx_hal_dma_ex.h
+stm32f4xx_hal_eth.h
+stm32f4xx_hal_flash.h
+stm32f4xx_hal_flash_ex.h
+stm32f4xx_hal_flash_ramfunc.h
+stm32f4xx_hal_fmpi2c.h
+stm32f4xx_hal_fmpi2c_ex.h
+stm32f4xx_hal_gpio.h
+stm32f4xx_hal_gpio_ex.h
+stm32f4xx_hal_hash.h
+stm32f4xx_hal_hash_ex.h
+stm32f4xx_hal_hcd.h
+stm32f4xx_hal_i2c.h
+stm32f4xx_hal_i2c_ex.h
+stm32f4xx_hal_i2s.h
+stm32f4xx_hal_i2s_ex.h
+stm32f4xx_hal_irda.h
+stm32f4xx_hal_iwdg.h
+stm32f4xx_hal_ltdc.h
+stm32f4xx_hal_nand.h
+stm32f4xx_hal_nor.h
+stm32f4xx_hal_pccard.h
+stm32f4xx_hal_pcd.h
+stm32f4xx_hal_pcd_ex.h
+stm32f4xx_hal_pwr.h
+stm32f4xx_hal_pwr_ex.h
+stm32f4xx_hal_qspi.h
+stm32f4xx_hal_rcc.h
+stm32f4xx_hal_rcc_ex.h
+stm32f4xx_hal_rng.h
+stm32f4xx_hal_rtc.h
+stm32f4xx_hal_rtc_ex.h
+stm32f4xx_hal_sai.h
+stm32f4xx_hal_sai_ex.h
+stm32f4xx_hal_sd.h
+stm32f4xx_hal_sdram.h
+stm32f4xx_hal_smartcard.h
+stm32f4xx_hal_spdifrx.h
+stm32f4xx_hal_spi.h
+stm32f4xx_hal_sram.h
+stm32f4xx_hal_tim.h
+stm32f4xx_hal_tim_ex.h
+stm32f4xx_hal_uart.h
+stm32f4xx_hal_usart.h
+stm32f4xx_hal_wwdg.h
+stm32f4xx_ll_fmc.h
+stm32f4xx_ll_fsmc.h
+stm32f4xx_ll_sdmmc.h
+stm32f4xx_ll_usb.h
+system_stm32f4xx.h
+stm32f4xx_hal_flash.c
+stm32f4xx_hal_flash_ex.c
+stm32f4xx_hal_gpio.c
+stm32f4xx_hal_rcc.c
+stm32f4xx_hal_uart.c
+
+# baselibc - BSD License.
+# tinyprintf - BSD License.
+# klibc - MIT License.
+baselibc
+
+# CMSIS-CORE - BSD License.
+core_ca9.h
+core_caFunc.h
+core_caInstr.h
+core_ca_mmu.h
+core_cm0.h
+core_cm0plus.h
+core_cm3.h
+core_cm4.h
+core_cm4_simd.h
+core_cmFunc.h
+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
+json_decode.c
+json_encode.c
+
+# queue.h - BSD License.
+queue.h
+
+# FreeBSD - BSD License.
+os_mbuf.c
+base64.c
+
+# tinycrypt - BSD License.
+tinycrypt
+
+# frdm-k64f clock configuration - BSD License.
+clock_config.c
+clock_config.h
+
+# CMSIS Cortex-M4, STM32f4 - BSD License.
+STM32F4xx
+STM32F4xx_HAL_Driver
+
+# NXP SDK - BSD License.
+sdk-2.0-frdm-k64f_b160321
+MK64FN1M0xxx12_flash.ld
+boot-MK64FN1M0xxx12_flash.ld
+startup_MK64F12.S
+
+# LWIP - BSD License.
+lwip_base
+
+# OIC - BSD License.
+oic
+
+# FATFS ChaN License
+diskio.h
+ff.h
+ffconf.h
+integer.h
+ff.c
+unicode.c
+00history.txt
+
+#Codesoucery License
+split-nrf52840pdk.ld
+nrf52840pdk_no_boot.ld
+
+# Freescale Semiconductor License
+boot-mkw41z512.ld
+mkw41z512.ld
+no-boot-mkw41z512.ld
+gcc_startup_mkw41z.s
+MKW41Z4.h
+fsl_device_registers.h
+system_MKW41Z4.h
+MKW41Z4_features.h
+system_MKW41Z4.c
+
+# 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
+
+# NUCLEO-F413ZH BSP - BSD License
+nucleo-f413zh
+
+# NUCLEO-L467rg BSP - BSD License
+nucleo-l476rg
+
+# 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
+nrf52xxx
+nrf52xxx-compat
+
+# 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
+
+# STM32L0xx SDK - BSD License
+stm32l0xx
+
+# STM32L4xx SDK - BSD License
+stm32l4xx
+
+# Fanstel EVBT840 BSP linker scripts - BSD License
+fanstel-ev-bt840_no_boot.ld
+split-fanstel-ev-bt840.ld
+
+# B-L072Z-LRWAN1 BSP - BSD License
+b-l072z-lrwan1
diff --git a/versions/v1_5_0/mynewt-core/.travis.yml b/versions/v1_5_0/mynewt-core/.travis.yml
new file mode 100644
index 0000000..a95d997
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/.travis.yml
@@ -0,0 +1,152 @@
+# 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.
+
+language: go
+
+_addons: &addon_conf
+  apt:
+    sources:
+      - ubuntu-toolchain-r-test
+    packages:
+      - gcc-7-multilib
+      - linux-libc-dev:i386
+
+go:
+  - "1.10"
+
+git:
+  depth: false
+
+matrix:
+  include:
+    # newt build <targets>
+    - os: linux
+      env:
+        - TEST=BUILD_TARGETS
+        - VM_AMOUNT=4
+        - TARGET_SET=1
+    - os: linux
+      env:
+        - TEST=BUILD_TARGETS
+        - VM_AMOUNT=4
+        - TARGET_SET=2
+    - os: linux
+      env:
+        - TEST=BUILD_TARGETS
+        - VM_AMOUNT=4
+        - TARGET_SET=3
+    - os: linux
+      env:
+        - TEST=BUILD_TARGETS
+        - VM_AMOUNT=4
+        - TARGET_SET=4
+
+    # newt build <blinky-for-BSP>
+    - os: linux
+      env:
+        - TEST=BUILD_BLINKY
+        - VM_AMOUNT=4
+        - TARGET_SET=1
+    - os: linux
+      env:
+        - TEST=BUILD_BLINKY
+        - VM_AMOUNT=4
+        - TARGET_SET=2
+    - os: linux
+      env:
+        - TEST=BUILD_BLINKY
+        - VM_AMOUNT=4
+        - TARGET_SET=3
+    - os: linux
+      env:
+        - TEST=BUILD_BLINKY
+        - VM_AMOUNT=4
+        - TARGET_SET=4
+
+    # newt test all (Linux)
+    - os: linux
+      addons: *addon_conf
+      env:
+        - TEST=TEST_ALL
+        - VM_AMOUNT=3
+        - TARGET_SET=1
+    - os: linux
+      addons: *addon_conf
+      env:
+        - TEST=TEST_ALL
+        - VM_AMOUNT=3
+        - TARGET_SET=2
+    - os: linux
+      addons: *addon_conf
+      env:
+        - TEST=TEST_ALL
+        - VM_AMOUNT=3
+        - TARGET_SET=3
+
+    # newt test all (osx)
+    - os: osx
+      osx_image: xcode9.2
+      env:
+        - TEST=TEST_ALL
+        - VM_AMOUNT=3
+        - TARGET_SET=1
+    - os: osx
+      osx_image: xcode9.2
+      env:
+        - TEST=TEST_ALL
+        - VM_AMOUNT=3
+        - TARGET_SET=2
+    - os: osx
+      osx_image: xcode9.2
+      env:
+        - TEST=TEST_ALL
+        - VM_AMOUNT=3
+        - TARGET_SET=3
+
+before_install:
+  - printenv
+  - export GOPATH=$HOME/gopath
+  - go version
+
+install:
+  - git clone https://github.com/runtimeco/mynewt-travis-ci $HOME/ci
+  - chmod +x $HOME/ci/*.sh
+  - $HOME/ci/${TRAVIS_OS_NAME}_travis_install.sh
+
+before_script:
+  - newt version
+  - gcc --version
+  - if [ "${TEST}" != "TEST_ALL" ]; then arm-none-eabi-gcc --version; fi
+  - cp -R $HOME/ci/mynewt-core-project.yml project.yml
+  - cp -R $HOME/ci/mynewt-core-targets targets
+  - newt install
+    # pass in the number of target sets
+  - $HOME/ci/prepare_test.sh $VM_AMOUNT
+
+script:
+  # the following list of targets are known to fail building blinky, or
+  # might have extra dependencies hard to provide, non-common toolchains, etc
+  # NOTE: "native" is here to avoid having to install gcc-multilib
+  - export IGNORED_BSPS="ci40 embarc_emsk hifive1 native-armv7 native-mips
+                         pic32mx470_6lp_clicker pic32mz2048_wi-fire sensorhub
+                         native"
+  - $HOME/ci/run_test.sh
+
+cache:
+  directories:
+  - $HOME/TOOLCHAIN
+  - $HOME/Library/Caches/Homebrew
diff --git a/versions/v1_5_0/mynewt-core/CODING_STANDARDS.md b/versions/v1_5_0/mynewt-core/CODING_STANDARDS.md
new file mode 100644
index 0000000..d5e58c9
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/CODING_STANDARDS.md
@@ -0,0 +1,262 @@
+# Coding Style for Apache Mynewt Core
+
+This document is meant to define the coding style for Apache Mynewt, and 
+all subprojects of Apache Mynewt.  This covers C and Assembly coding 
+conventions, *only*.  Other languages (such as Go), have their own 
+coding conventions.
+
+## Headers
+
+* All files that are newly written, should have the Apache License clause
+at the top of them.
+
+* For files that are copied from another source, but contain an Apache 
+compatible license, the original license header shall be maintained.
+
+* For more information on applying the Apache license, the definitive 
+source is here: http://www.apache.org/dev/apply-license.html
+
+* The Apache License clause for the top of files is as follows:
+
+```no-highlight
+/*
+ * 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.
+ */
+```
+
+## Whitespace and Braces
+
+* Code must be indented to 4 spaces, tabs should not be used.
+
+* Do not add whitespace at the end of a line.
+
+* Put space after keywords (for, if, return, switch, while).
+
+* for, else, if, while statements must have braces around their 
+code blocks, i.e., do: 
+
+```
+    if (x) {
+        assert(0);
+    } else {
+        assert(0);
+    }
+```
+
+Not: 
+
+```
+    if (x) 
+        assert(0);
+    else
+        assert(0);
+```
+
+* Braces for statements must be on the same line as the statement.  Good:
+
+```
+    for (i = 0; i < 10; i++) {
+        if (i == 5) {
+            break;
+        } else {
+            continue;
+        }
+    }
+```
+
+Not:
+
+```
+    for (i = 0; i < 10; i++) 
+    { <-- brace must be on same line as for
+        if (i == 5) {
+            break;
+        } <-- no new line between else
+        else {
+            continue;
+        }
+    }
+```
+
+* After a function declaration, the braces should be on a newline, i.e. do:
+
+```
+    static void *
+    function(int var1, int var2)
+    {
+```
+
+not: 
+
+```
+    static void *
+    function(int var1, int var2) {
+```
+
+## Line Length and Wrap
+
+* Line length should never exceed 79 columns.
+
+* When you have to wrap a long statement, put the operator at the end of the 
+  line.  i.e.:
+
+```
+    if (x &&
+        y == 10 &&
+        b)
+```
+
+Not:
+
+```
+    if (x
+        && y == 10
+        && b)
+```
+
+## Comments
+
+* No C++ style comments allowed.
+
+* When using a single line comment, put it above the line of code that you 
+intend to comment, i.e., do:
+
+```
+    /* check variable */
+    if (a) {
+```
+
+Not:
+
+```
+    if (a) { /* check variable */
+```
+
+
+* All public APIs should be commented with Doxygen style comments describing 
+purpose, parameters and return values.  Private APIs need not be documented.
+
+
+## Header files
+
+* Header files must contain the following structure:
+    * Apache License (see above)
+    * ```#ifdef``` aliasing, to prevent multiple includes
+    * ```#include``` directives for other required header files
+    * ```#ifdef __cplusplus``` wrappers to maintain C++ friendly APIs
+    * Contents of the header file
+
+* ```#ifdef``` aliasing, shall be in the following format, where
+the package name is "os" and the file name is "callout.h": 
+
+```no-highlight
+#ifndef _OS_CALLOUT_H
+#define _OS_CALLOUT_H
+```
+
+* ```#include``` directives must happen prior to the cplusplus 
+wrapper.
+
+* The cplusplus wrapper must have the following format, and precedes
+any contents of the header file:
+
+```no-highlight
+#ifdef __cplusplus
+#extern "C" {
+##endif
+```
+
+## Naming
+
+* Names of functions, structures and variables must be in all lowercase.  
+
+* Names should be as short as possible, but no shorter.  
+
+* Globally visible names must be prefixed with the name of the module, 
+followed by the '_' character, i.e.: 
+
+```
+    os_callout_init(&c)
+```
+
+Not:
+
+```
+    callout_init(c)
+```
+
+## Functions
+
+* No spaces after function names when calling a function, i.e, do:
+
+```
+    rc = function(a)
+```
+
+Not: 
+
+```
+    rc = function (a)
+```
+
+
+* Arguments to function calls should have spaces between the comma, i.e. do:
+
+```
+    rc = function(a, b)
+```
+
+Not: 
+
+```
+    rc = function(a,b)
+```
+
+* The function type must be on a line by itself preceding the function, i.e. do: 
+
+```
+    static void *
+    function(int var1, int var2)
+    {
+```
+
+Not: 
+
+```
+    static void *function(int var1, int var2)
+    {
+```
+
+* In general, for functions that return values that denote success or error, 0
+shall be success, and non-zero shall be the failure code.
+
+## Variables and Macros
+
+* Do not use typedefs for structures.  This makes it impossible for 
+applications to use pointers to those structures opaquely.  
+
+* typedef may be used for non-structure types, where it is beneficial to 
+hide or alias the underlying type used (e.g. ```os_time_t```.)   Indicate
+typedefs by applying the ```_t``` marker to them.
+
+* Place all function-local variable definitions at the top of the function body, before any statements.
+
+## Compiler Directives
+
+* Code must compile cleanly with -Wall enabled.
+
diff --git a/versions/v1_5_0/mynewt-core/LICENSE b/versions/v1_5_0/mynewt-core/LICENSE
new file mode 100644
index 0000000..8d8a09b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/LICENSE
@@ -0,0 +1,444 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "{}"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright {yyyy} {name of copyright owner}
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+
+This product bundles crc16, which is available under the "3-clause BSD"
+license.  For details, see:
+    * util/crc/include/crc/crc16.h
+    * util/crc/src/crc16.c
+
+This product bundles queue.h 8.5, which is available under the "3-clause BSD"
+license.  For details, see kernel/os/include/os/queue.h
+
+This product partly derives from FreeBSD, which is available under the
+"3-clause BSD" license.  For details, see:
+    * kernel/os/include/os/os_time.h
+    * kernel/os/src/os_mbuf.c
+    * encoding/base64/src/base64.c
+    * time/datetime/src/datetime.c
+
+This product bundles baselibc, which is available under the "3-clause BSD"
+license. Baselibc bundles tinyprintf and is based on klibc for details see:
+libc/baselibc/LICENSE
+
+This product bundles tinyprintf, which is available under the "3-clause BSD"
+license.  For details, see libc/baselibc/src/tinyprintf.c
+
+This product contains code based on klibc, which is available under the MIT
+license.  For details, see libc/baselibc/LICENSE
+
+This product bundles microjson, which is available under the "3-clause BSD"
+license.  For details, see encoding/json/
+
+This product bundles and partly derives from parts of the Nordic nRF52 SDK,
+which are available under a BSD style license.  Relevant files are:
+    * hw/bsp/nrf51dk/src/arch/cortex_m0/gcc_startup_nrf51.s
+    * hw/bsp/nrf51dk/src/arch/cortex_m0/gcc_startup_nrf51_split.s
+    * hw/bsp/nrf52840pdk/src/arch/cortex_m4/gcc_startup_nrf52840.s
+    * hw/bsp/nrf52840pdk/src/arch/cortex_m4/gcc_startup_nrf52_split.s
+    * hw/bsp/nrf52dk/src/arch/cortex_m4/gcc_startup_nrf52.s
+    * hw/bsp/nrf52dk/src/arch/cortex_m4/gcc_startup_nrf52_split.s
+    * 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.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
+
+This product bundles Gary S. Brown's CRC32 implementation, which is available under the following license:
+    COPYRIGHT (C) 1986 Gary S. Brown.  You may use this program, or
+    code or tables extracted from it, as desired without restriction.
+
+This product bundles parts of CMSIS-CORE, which is available under the
+"3-clause BSD" license.  Bundled files are:
+    * hw/cmsis-core/
+    * kernel/os/src/arch/cortex_m0/m0/HAL_CM0.s
+    * kernel/os/src/arch/cortex_m0/m0/SVC_Table.s
+    * kernel/os/src/arch/cortex_m4/m4/HAL_CM4.s
+    * kernel/os/src/arch/cortex_m4/m4/SVC_Table.s
+
+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/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:
+    * hw/mcu/stm/stm32f4xx/src/ext
+    * hw/bsp/nucleo-f401re/src/arch/cortex_m4/startup_STM32F40x.s
+    * hw/bsp/nucleo-f401re/include/bsp/stm32f4xx_hal_conf.h
+    * hw/bsp/nucleo-f401re/src/system_stm32f4xx.c
+    * hw/bsp/olimex_stm32-e407_devboard/src/arch/cortex_m4/startup_STM32F40x.s
+    * hw/bsp/olimex_stm32-e407_devboard/include/bsp/stm32f4xx_hal_conf.h
+    * hw/bsp/olimex_stm32-e407_devboard/src/system_stm32f4xx.c
+    * hw/bsp/stm32f4discovery/src/arch/cortex_m4/startup_STM32F40x.s
+    * hw/bsp/stm32f4discovery/include/bsp/stm32f4xx_hal_conf.h
+    * hw/bsp/stm32f4discovery/src/system_stm32f4xx.c
+
+This product bundles parts of STM32CubeF7, which is available under the
+"3-clause BSD" license.  Bundled files are:
+    * hw/mcu/stm/stm32f7xx/src/ext
+    * hw/bsp/stm32f767-nucleo/include/bsp/stm32f7xx_hal_conf.h
+    * hw/bsp/stm32f767-nucleo/src/system_stm32f7xx.c
+    * hw/bsp/stm32f767-nucleo/src/arch/cortex_m7/startup_stm32f767xx.s
+
+This product bundles parts of STM32CubeF3, which is available under the
+"3-clause BSD" license.  Bundled files are:
+    * 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:
+    * fs/fatfs/include/fatfs/diskio.h
+    * fs/fatfs/include/fatfs/ff.h
+    * fs/fatfs/include/fatfs/ffconf.h
+    * fs/fatfs/include/fatfs/integer.h
+    * fs/fatfs/src/ff.c
+    * fs/fatfs/src/option/unicode.c
+
+This product bundles part of linker scripts Nordic Semiconductor nRF5 devices, which is available under the
+"modified Tcl/Tk" license.  Bundled files are:
+    * hw/bsp/nrf52840pdk/split-nrf52840pdk.ld
+    * hw/bsp/nrf52840pdk/nrf52840pdk_no_boot.ld
+    * hw/bsp/bmd300eval/bmd300eval_no_boot.ld
+    * hw/bsp/nrf51dk-16kbram/nrf51dk-16kbram_no_boot.ld
+    * hw/bsp/nrf51dk/nrf51dk_no_boot.ld
+    * 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:
+    * hw/mcu/nxp/src/ext
+
+This product bundles part of NXP mkw41z, which is available under the
+"3-clause BSD" license.  Bundled files are:
+    * hw/mcu/nxp/mkw41z/include/mcu/MKW41Z4.h
+    * hw/mcu/nxp/mkw41z/include/mcu/MKW41Z4_features.h
+    * hw/mcu/nxp/mkw41z/include/mcu/fsl_device_registers.h
+    * hw/mcu/nxp/mkw41z/include/mcu/system_MKW41Z4.h
+    * hw/mcu/nxp/mkw41z/src/system_MKW41Z4.c
+    * hw/bsp/usbmkw41z/boot-mkw41z512.ld
+    * hw/bsp/usbmkw41z/mkw41z512.ld
+    * hw/bsp/usbmkw41z/no-boot-mkw41z512.ld
+    * hw/bsp/usbmkw41z/src/arch/cortex_m0/gcc_startup_mkw41z.s
+
+This product bundles part of mips architecture and ci40, which is available
+under the "3-clause BSD" license.  Bundled files are:
+    * kernel/os/src/arch/mips/asm/ctx.S
+    * kernel/os/src/arch/mips/asm/excpt_isr.S
+    * hw/bsp/ci40/uhi32.ld
+
+This product bundles LwIP, which is available under the "3-clause BSD"
+license. For details, and bundled files see:
+    * net/ip/lwip_base/COPYING
+    * net/ip/lwip_base
+
+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/versions/v1_5_0/mynewt-core/NOTICE b/versions/v1_5_0/mynewt-core/NOTICE
new file mode 100644
index 0000000..4ba7354
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/NOTICE
@@ -0,0 +1,8 @@
+Apache Mynewt
+Copyright 2015-2017 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of this software were developed at
+Runtime Inc, copyright 2015.
diff --git a/versions/v1_5_0/mynewt-core/README.md b/versions/v1_5_0/mynewt-core/README.md
new file mode 100644
index 0000000..b82480a
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/README.md
@@ -0,0 +1,245 @@
+<!--
+#
+# 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.
+#
+-->
+
+<img src="http://mynewt.apache.org/img/logo.svg" width="250" alt="Apache Mynewt">
+
+## Overview
+
+[![Build/Test](https://travis-ci.org/apache/mynewt-core.svg?branch=master)][travis]
+
+[travis]: https://travis-ci.org/apache/mynewt-core
+
+Apache Mynewt is an open-source operating system for tiny embedded devices.
+Its goal is to make it easy to develop applications for microcontroller
+environments where power and cost are driving factors.
+
+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)
+* Arduino Zero Pro (Cortex-M0)
+* Arduino M0 Pro (Cortex-M0)
+* 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/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 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
+* JSON and CBOR encoding
+* Bootloader support
+* Remote Software Upgrade
+* HAL and BSP infrastructure designed to abstract microcontroller specifics
+* Shell and Console support
+* Statistics and Logging Infrastructure
+* OIC Client and Server
+
+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/).
+
+## 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/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/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/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/mynewt-nimble)
+is a full Bluetooth host and controller implementation, that is written
+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/mynewt-core/tree/master/hw/bsp),
+and the MCU specific definitions they rely on are located in
+[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/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/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/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.
+The fs directory also contains [fcb](http://mynewt.apache.org/latest/os/modules/fcb/fcb/), a flash circular buffer implementation.
+
+## Sample Applications
+
+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/mynewt-core/tree/master/apps/boot):
+  Project to build the bootloader for test platforms.
+* [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/mynewt-core/tree/master/apps/slinky): A
+  slightly more complex project that includes the console and shell libraries.
+* [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/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/mynewt-core/tree/master/apps/bleprph): An
+  implementation of a minimal BLE peripheral.
+* [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/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.
+
+# Getting Help
+
+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.apache.org).
+
+Although not a formal channel, you can also find a number of core developers
+on the #mynewt channel on Freenode.
+
+Also, be sure to checkout the [Frequently Asked Questions](https://mynewt.apache.org/faq/answers)
+for some help troubleshooting first.
+
+# Contributing
+
+Anybody who works with Apache Mynewt can be a contributing member of the
+community that develops and deploys it.  The process of releasing an operating
+system for microcontrollers is never done: and we welcome your contributions
+to that effort.
+
+More information can be found at the Community section of the Apache Mynewt
+website, located [here](https://mynewt.apache.org/community).
+
+## Pull Requests
+
+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.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.
+
+We do not merge pull requests directly on Github, all PRs will be pulled and
+pushed through https://git.apache.org/.
+
+## Filing Bugs
+
+Bugs can be filed on the
+[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://github.com/apache/mynewt-core/issues).
+Please label the issue as a "Feature" or "Enhancement" depending on the scope.
+
+## Writing Tests
+
+We love getting newt tests!  Apache Mynewt is a huge undertaking, and improving
+code coverage is a win for every Apache Mynewt user.
+
+## Writing Documentation
+
+Contributing to documentation (in addition to writing tests), is a great way
+to get involved with the Apache Mynewt project.
+
+The Mynewt core OS documentation is found in [/docs](/docs).
+
+# License
+
+The code in this repository is all under either the Apache 2 license, or a
+license compatible with the Apache 2 license.  See the LICENSE file for more
+information.
+
+# Export restrictions
+
+This distribution includes cryptographic software. The country in which you
+currently reside may have restrictions on the import, possession, use, and/or
+re-export to another country, of encryption software. BEFORE using any encryption
+software, please check your country's laws, regulations and policies concerning
+the import, possession, or use, and re-export of encryption software, to see if
+this is permitted. See <http://www.wassenaar.org/> for more information.
+
+The U.S. Government Department of Commerce, Bureau of Industry and Security (BIS),
+has classified this software as Export Commodity Control Number (ECCN) 5D002.C.1,
+which includes information security software using or performing cryptographic
+functions with asymmetric algorithms. The form and manner of this Apache Software
+Foundation distribution makes it eligible for export under the License Exception ENC
+Technology Software Unrestricted (TSU) exception (see the BIS Export Administration
+Regulations, Section 740.13) for both object code and source code.
+
+The following provides more details on the included cryptographic software:
+https://tls.mbed.org/supported-ssl-ciphersuites.
diff --git a/versions/v1_5_0/mynewt-core/RELEASE_NOTES.md b/versions/v1_5_0/mynewt-core/RELEASE_NOTES.md
new file mode 100644
index 0000000..6c531ff
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/RELEASE_NOTES.md
@@ -0,0 +1,25 @@
+# RELEASE NOTES
+
+18 October 2018 - Apache Mynewt v1.5.0
+
+For full release notes, please visit the
+[Apache Mynewt Wiki](https://cwiki.apache.org/confluence/display/MYNEWT/Release+Notes).
+
+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/).
+
+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
+requests are in
+[JIRA](https://issues.apache.org/jira/browse/MYNEWT/?selectedTab=com.atlassian.jira.jira-projects-plugin:roadmap-panel).
+
+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.apache.org).
diff --git a/versions/v1_5_0/mynewt-core/apps/blecent/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blecent/pkg.yml
new file mode 100644
index 0000000..ce259c2
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blecent/pkg.yml
@@ -0,0 +1,20 @@
+# 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: transient
+pkg.link: "@apache-mynewt-nimble/apps/blecent"
diff --git a/versions/v1_5_0/mynewt-core/apps/blecsc/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blecsc/pkg.yml
new file mode 100644
index 0000000..2ebb3db
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blecsc/pkg.yml
@@ -0,0 +1,21 @@
+# 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/blecsc
+pkg.type: transient
+pkg.link: "@apache-mynewt-nimble/apps/blecsc"
diff --git a/versions/v1_5_0/mynewt-core/apps/blehci/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blehci/pkg.yml
new file mode 100644
index 0000000..112148b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blehci/pkg.yml
@@ -0,0 +1,20 @@
+# 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: transient
+pkg.link: "@apache-mynewt-nimble/apps/blehci"
diff --git a/versions/v1_5_0/mynewt-core/apps/blehr/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blehr/pkg.yml
new file mode 100644
index 0000000..6571298
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blehr/pkg.yml
@@ -0,0 +1,21 @@
+# 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/blehr
+pkg.type: transient
+pkg.link: "@apache-mynewt-nimble/apps/blehr"
diff --git a/versions/v1_5_0/mynewt-core/apps/blemesh/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blemesh/pkg.yml
new file mode 100644
index 0000000..3a2905f
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blemesh/pkg.yml
@@ -0,0 +1,20 @@
+# 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/blemesh
+pkg.type: transient
+pkg.link: "@apache-mynewt-nimble/apps/blemesh"
diff --git a/versions/v1_5_0/mynewt-core/apps/blemesh_light/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blemesh_light/pkg.yml
new file mode 100644
index 0000000..97be83a
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blemesh_light/pkg.yml
@@ -0,0 +1,20 @@
+# 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/blemesh_light
+pkg.type: transient
+pkg.link: "@apache-mynewt-nimble/apps/blemesh_light"
diff --git a/versions/v1_5_0/mynewt-core/apps/blemesh_shell/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blemesh_shell/pkg.yml
new file mode 100644
index 0000000..ed17d11
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blemesh_shell/pkg.yml
@@ -0,0 +1,20 @@
+# 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/blemesh_shell
+pkg.type: transient
+pkg.link: "@apache-mynewt-nimble/apps/blemesh_shell"
diff --git a/versions/v1_5_0/mynewt-core/apps/bleprph/pkg.yml b/versions/v1_5_0/mynewt-core/apps/bleprph/pkg.yml
new file mode 100644
index 0000000..d8c22e6
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph/pkg.yml
@@ -0,0 +1,20 @@
+# 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: transient
+pkg.link: "@apache-mynewt-nimble/apps/bleprph"
diff --git a/versions/v1_5_0/mynewt-core/apps/bleprph_oic/pkg.yml b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/pkg.yml
new file mode 100644
index 0000000..56f44a3
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/pkg.yml
@@ -0,0 +1,41 @@
+# 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_oic
+pkg.type: app
+pkg.description: Simple BLE peripheral application.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps: 
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/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/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/bleprph.h b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/bleprph.h
new file mode 100644
index 0000000..d14b53a
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/bleprph.h
@@ -0,0 +1,53 @@
+/*
+ * 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 "os/mynewt.h"
+#include "modlog/modlog.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct ble_hs_cfg;
+struct ble_gatt_register_ctxt;
+
+extern struct log bleprph_log;
+
+/** 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/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/gatt_svr.c b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/gatt_svr.c
new file mode 100644
index 0000000..03791d3
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/gatt_svr.c
@@ -0,0 +1,57 @@
+/*
+ * 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 "bleprph.h"
+
+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;
+    }
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/main.c b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/main.c
new file mode 100644
index 0000000..fa62684
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/main.c
@@ -0,0 +1,397 @@
+/*
+ * 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 <mgmt/mgmt.h>
+
+#include <oic/oc_api.h>
+#include <oic/oc_gatt.h>
+#include <cborattr/cborattr.h>
+
+/* BLE */
+#include <nimble/ble.h>
+#include <host/ble_hs.h>
+#include <services/gap/ble_svc_gap.h>
+
+/* Application-specified header. */
+#include "bleprph.h"
+
+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)
+{
+    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 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 service UUID.
+     */
+
+    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;
+
+#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_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) {
+        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_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) {
+        MODLOG_DFLT(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. */
+        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);
+        }
+        MODLOG_DFLT(INFO, "\n");
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            bleprph_advertise();
+        } else {
+            oc_ble_coap_conn_new(event->connect.conn_handle);
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        bleprph_print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        oc_ble_coap_conn_del(event->disconnect.conn.conn_handle);
+
+        /* Connection terminated; resume advertising. */
+        bleprph_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);
+        bleprph_print_conn_desc(&desc);
+        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. */
+        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);
+        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);
+        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;
+
+    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;
+}
+
+static void
+bleprph_on_reset(int reason)
+{
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
+}
+
+static void
+bleprph_on_sync(void)
+{
+    /* Begin advertising. */
+    bleprph_advertise();
+}
+
+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);
+
+}
+
+static const oc_handler_t omgr_oc_handler = {
+    .init = omgr_app_init,
+};
+
+/**
+ * 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, 0xfa, 0xcf, 0xac, 0xfa, 0xc0}, 6);
+
+    /* Initialize OS */
+    sysinit();
+
+    /* Initialize the OIC  */
+    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("c5");
+    assert(rc == 0);
+
+    /* Our light resource */
+    hal_gpio_init_out(LED_BLINK_PIN, 1);
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* Never exit */
+
+    return 0;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/misc.c b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/src/misc.c
new file mode 100644
index 0000000..6ed205e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/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 "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++) {
+        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/versions/v1_5_0/mynewt-core/apps/bleprph_oic/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/syscfg.yml
new file mode 100644
index 0000000..bfa3b2a
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleprph_oic/syscfg.yml
@@ -0,0 +1,73 @@
+# 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:
+    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
+
+    BLE_GATT_WRITE_MAX_ATTRS: 6
+    BLE_HCI_EVT_HI_BUF_COUNT: 4
+    BLE_HCI_EVT_LO_BUF_COUNT: 3
+
+    # Disable central and observer roles.
+    BLE_ROLE_BROADCASTER: 1
+    BLE_ROLE_CENTRAL: 0
+    BLE_ROLE_OBSERVER: 0
+    BLE_ROLE_PERIPHERAL: 1
+
+    # Disable security manager
+    BLE_SM: 0
+    BLE_LL_CFG_FEAT_LE_ENCRYPTION: 0
+    BLE_LL_CFG_FEAT_LL_PRIVACY: 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
+
+    # OC server, with bluetooth transport.
+    OC_SERVER: 1
+    OC_TRANSPORT_GATT: 1
+
+    SHELL_TASK: 1
+    STATS_CLI: 1
+    LOG_CLI: 1
+    STATS_NAMES: 1
+
+    # Default task settings
+    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/versions/v1_5_0/mynewt-core/apps/blesplit/README.md b/versions/v1_5_0/mynewt-core/apps/blesplit/README.md
new file mode 100644
index 0000000..8be3e25
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blesplit/README.md
@@ -0,0 +1,55 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+
+<img src="http://mynewt.apache.org/img/logo.svg" width="250" alt="Apache Mynewt">
+
+## Overview
+
+`apps/splitty` is an example split application.  It can be paired with slinky to form an application.
+
+## Split Image
+
+Split applications allow the user to build the application content separate from the library content by splitting an application into two pieces:
+
+* A "loader" which contains a separate application that can perform upgrades and manage split images
+* A "split app" which contains the main application content and references the libraries in the loader by static linkage
+
+See [split image architecture](http://mynewt.apache.org/latest/os/modules/split/split/) for the details of split image design.
+
+## Contents
+
+splitty is just a simply app that has newtmgr, shell and blinkys the LED at a differernt rate than slinky, so its visually evident that its running.
+
+## Usage
+
+You can use splitty as part of a split app by setting up your target.
+
+```
+targets/app
+    app=@apache-mynewt-core/apps/splitty
+    loader=@apache-mynewt-core/apps/slinky
+    bsp=@apache-mynewt-core/hw/bsp/nordic_pca10040
+    build_profile=optimized
+```
+
+
+
diff --git a/versions/v1_5_0/mynewt-core/apps/blesplit/pkg.yml b/versions/v1_5_0/mynewt-core/apps/blesplit/pkg.yml
new file mode 100644
index 0000000..467a41b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blesplit/pkg.yml
@@ -0,0 +1,47 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#  http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+
+pkg.name: apps/blesplit
+pkg.type: app
+pkg.description: "Example BLE application which runs as a split app."
+pkg.author: "Apache Mynewt <dev@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/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-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/util"
+    - "@apache-mynewt-nimble/nimble/host/services/ans"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/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/versions/v1_5_0/mynewt-core/apps/blesplit/src/blesplit.h b/versions/v1_5_0/mynewt-core/apps/blesplit/src/blesplit.h
new file mode 100644
index 0000000..6b17c9b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blesplit/src/blesplit.h
@@ -0,0 +1,51 @@
+/*
+ * 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_BLESPLIT_
+#define H_BLESPLIT_
+
+#include "os/mynewt.h"
+#include "modlog/modlog.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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/versions/v1_5_0/mynewt-core/apps/blesplit/src/main.c b/versions/v1_5_0/mynewt-core/apps/blesplit/src/main.c
new file mode 100644
index 0000000..b4d8caa
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blesplit/src/main.c
@@ -0,0 +1,310 @@
+/*
+ * 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 "host/util/util.h"
+#include "services/gap/ble_svc_gap.h"
+
+/* Application-specified header. */
+#include "blesplit.h"
+
+static int blesplit_gap_event(struct ble_gap_event *event, void *arg);
+
+/**
+ * Logs information about a connection to the console.
+ */
+static void
+blesplit_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 Undirected connectable mode.
+ */
+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).
+     *     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_UND;
+    adv_params.disc_mode = BLE_GAP_DISC_MODE_GEN;
+    rc = ble_gap_adv_start(own_addr_type, NULL, BLE_HS_FOREVER,
+                           &adv_params, blesplit_gap_event, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(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.
+ * blesplit 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
+ *                                  blesplit.
+ *
+ * @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
+blesplit_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);
+            blesplit_print_conn_desc(&desc);
+        }
+        MODLOG_DFLT(INFO, "\n");
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            blesplit_advertise();
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        blesplit_print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        /* Connection terminated; resume advertising. */
+        blesplit_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);
+        blesplit_print_conn_desc(&desc);
+        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. */
+        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);
+        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);
+        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;
+
+    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;
+}
+
+static void
+blesplit_on_reset(int 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();
+}
+
+/**
+ * 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();
+
+    /* Initialize the NimBLE host configuration. */
+    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);
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    return 0;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/blesplit/src/misc.c b/versions/v1_5_0/mynewt-core/apps/blesplit/src/misc.c
new file mode 100644
index 0000000..3c11d91
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blesplit/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 "blesplit.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/versions/v1_5_0/mynewt-core/apps/blesplit/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/blesplit/syscfg.yml
new file mode 100644
index 0000000..8e5ca9e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/blesplit/syscfg.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.
+#
+
+# Package: apps/blesplit
+
+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
+
+    # 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: 468
diff --git a/versions/v1_5_0/mynewt-core/apps/bletest/pkg.yml b/versions/v1_5_0/mynewt-core/apps/bletest/pkg.yml
new file mode 100644
index 0000000..eb9eba1
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bletest/pkg.yml
@@ -0,0 +1,22 @@
+#
+# 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: transient
+pkg.link: "@apache-mynewt-nimble/apps/bletest"
diff --git a/versions/v1_5_0/mynewt-core/apps/bleuart/pkg.yml b/versions/v1_5_0/mynewt-core/apps/bleuart/pkg.yml
new file mode 100644
index 0000000..1ce5d5d
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleuart/pkg.yml
@@ -0,0 +1,41 @@
+# 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/bleuart
+pkg.type: app
+pkg.description: Simple BLE uart application.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/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-nimble/nimble/host/services/bleuart"
diff --git a/versions/v1_5_0/mynewt-core/apps/bleuart/src/main.c b/versions/v1_5_0/mynewt-core/apps/bleuart/src/main.c
new file mode 100644
index 0000000..d9b5d88
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleuart/src/main.c
@@ -0,0 +1,227 @@
+/*
+ * 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 <imgmgr/imgmgr.h>
+
+/* BLE */
+#include "nimble/ble.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_l2cap.h"
+#include "host/ble_sm.h"
+#include "controller/ble_ll.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"
+
+/* Newtmgr include */
+#include "newtmgr/newtmgr.h"
+#include "nmgrble/newtmgr_ble.h"
+#include "bleuart/bleuart.h"
+
+static int bleuart_gap_event(struct ble_gap_event *event, void *arg);
+
+/**
+ * Enables advertising with the following parameters:
+ *     o General discoverable mode.
+ *     o Undirected connectable mode.
+ */
+static void
+bleuart_advertise(void)
+{
+    struct ble_gap_adv_params adv_params;
+    struct ble_hs_adv_fields fields;
+    int rc;
+
+    /*
+     *  Set the advertisement data included in our advertisements:
+     *     o Flags (indicates advertisement type and other general info).
+     *     o Advertising tx power.
+     *     o 128 bit UUID
+     */
+
+    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;
+
+    fields.uuids128 = BLE_UUID128(&gatt_svr_svc_uart_uuid.u);
+    fields.num_uuids128 = 1;
+    fields.uuids128_is_complete = 1;
+
+    rc = ble_gap_adv_set_fields(&fields);
+    if (rc != 0) {
+        return;
+    }
+
+    memset(&fields, 0, sizeof fields);
+    fields.name = (uint8_t *)ble_svc_gap_device_name();
+    fields.name_len = strlen((char *)fields.name);
+    fields.name_is_complete = 1;
+
+    rc = ble_gap_adv_rsp_set_fields(&fields);
+    if (rc != 0) {
+        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, bleuart_gap_event, NULL);
+    if (rc != 0) {
+        return;
+    }
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that forms.
+ * bleuart 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
+ *                                  bleuart.
+ *
+ * @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
+bleuart_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) {
+            rc = ble_gap_conn_find(event->connect.conn_handle, &desc);
+            assert(rc == 0);
+            bleuart_set_conn_handle(event->connect.conn_handle);
+        }
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            bleuart_advertise();
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        /* 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;
+}
+
+static void
+bleuart_on_sync(void)
+{
+    /* Begin advertising. */
+    bleuart_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();
+
+    /* Initialize the BLE host. */
+    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);
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set("Mynewt_BLEuart");
+    assert(rc == 0);
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* Never exit */
+
+    return 0;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/bleuart/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/bleuart/syscfg.yml
new file mode 100644
index 0000000..054fb42
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/bleuart/syscfg.yml
@@ -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.
+#
+
+# Package: apps/bleuart
+
+syscfg.vals:
+    # Disable unused roles; bleuart is a peripheral-only app.
+    BLE_ROLE_OBSERVER: 0
+    BLE_ROLE_CENTRAL: 0
+
+    # Default task settings
+    OS_MAIN_STACK_SIZE: 336
diff --git a/versions/v1_5_0/mynewt-core/apps/boot/pkg.yml b/versions/v1_5_0/mynewt-core/apps/boot/pkg.yml
new file mode 100644
index 0000000..7d07516
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/boot/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/boot
+pkg.type: app
+pkg.description: Boot loader application.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - loader
+
+pkg.deps:
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/console/stub"
+
+pkg.deps.BOOT_SERIAL:
+    - "@apache-mynewt-core/boot/boot_serial"
diff --git a/versions/v1_5_0/mynewt-core/apps/boot/src/boot.c b/versions/v1_5_0/mynewt-core/apps/boot/src/boot.c
new file mode 100644
index 0000000..22dded3
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/boot/src/boot.c
@@ -0,0 +1,56 @@
+/*
+ * 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 <stddef.h>
+#include <inttypes.h>
+#include "os/mynewt.h"
+#include <flash_map/flash_map.h>
+
+#include <hal/hal_bsp.h>
+#include <hal/hal_system.h>
+#include <hal/hal_flash.h>
+#include <console/console.h>
+#include "bootutil/image.h"
+#include "bootutil/bootutil.h"
+
+#define BOOT_AREA_DESC_MAX  (256)
+#define AREA_DESC_MAX       (BOOT_AREA_DESC_MAX)
+
+int
+main(void)
+{
+    struct boot_rsp rsp;
+    int rc;
+
+    hal_bsp_init();
+
+#if MYNEWT_VAL(BOOT_SERIAL)
+    sysinit();
+#else
+    flash_map_init();
+#endif
+
+    rc = boot_go(&rsp);
+    assert(rc == 0);
+
+    hal_system_start((void *)(rsp.br_image_addr + rsp.br_hdr->ih_hdr_size));
+
+    return 0;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/boot/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/boot/syscfg.yml
new file mode 100644
index 0000000..47bd1c5
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/boot/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.
+#
+
+# Package: apps/boot
+
+syscfg.defs:
+    BOOT_LOADER:
+        description: 'Set to indicate that this app is a bootloader.'
+        value: 1
+    BOOT_SERIAL:
+        description: 'Support image upgrade over serial within bootloader'
+        value: 0
+
+syscfg.vals:
+    SYSINIT_CONSTRAIN_INIT: 0
+    OS_SCHEDULING: 0
+    MSYS_1_BLOCK_COUNT: 0
diff --git a/versions/v1_5_0/mynewt-core/apps/bsncent/pkg.yml b/versions/v1_5_0/mynewt-core/apps/bsncent/pkg.yml
new file mode 100644
index 0000000..28748c2
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/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/versions/v1_5_0/mynewt-core/apps/bsncent/src/bsncent.h b/versions/v1_5_0/mynewt-core/apps/bsncent/src/bsncent.h
new file mode 100644
index 0000000..8363f5e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsncent/src/main.c b/versions/v1_5_0/mynewt-core/apps/bsncent/src/main.c
new file mode 100644
index 0000000..bb9d4bd
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsncent/src/misc.c b/versions/v1_5_0/mynewt-core/apps/bsncent/src/misc.c
new file mode 100644
index 0000000..7b00273
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsncent/src/peer.c b/versions/v1_5_0/mynewt-core/apps/bsncent/src/peer.c
new file mode 100644
index 0000000..0993e05
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsncent/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/bsncent/syscfg.yml
new file mode 100644
index 0000000..2324068
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsnprph/pkg.yml b/versions/v1_5_0/mynewt-core/apps/bsnprph/pkg.yml
new file mode 100644
index 0000000..f344c72
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@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-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/services/ans"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/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/versions/v1_5_0/mynewt-core/apps/bsnprph/src/bsnprph.h b/versions/v1_5_0/mynewt-core/apps/bsnprph/src/bsnprph.h
new file mode 100644
index 0000000..e305ac7
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsnprph/src/gatt_svr.c b/versions/v1_5_0/mynewt-core/apps/bsnprph/src/gatt_svr.c
new file mode 100644
index 0000000..eefb57b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsnprph/src/main.c b/versions/v1_5_0/mynewt-core/apps/bsnprph/src/main.c
new file mode 100644
index 0000000..64c6526
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsnprph/src/misc.c b/versions/v1_5_0/mynewt-core/apps/bsnprph/src/misc.c
new file mode 100644
index 0000000..6b2e584
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/bsnprph/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/bsnprph/syscfg.yml
new file mode 100644
index 0000000..a20c1e8
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/btshell/pkg.yml b/versions/v1_5_0/mynewt-core/apps/btshell/pkg.yml
new file mode 100644
index 0000000..2be1744
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/btshell/pkg.yml
@@ -0,0 +1,20 @@
+# 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/btshell
+pkg.type: transient
+pkg.link: "@apache-mynewt-nimble/apps/btshell"
diff --git a/versions/v1_5_0/mynewt-core/apps/ffs2native/pkg.yml b/versions/v1_5_0/mynewt-core/apps/ffs2native/pkg.yml
new file mode 100644
index 0000000..3345cdc
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ffs2native/pkg.yml
@@ -0,0 +1,33 @@
+#
+# 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/ffs2native
+pkg.type: app
+pkg.description: Support application for debugging the Newtron Flash File System.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@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/versions/v1_5_0/mynewt-core/apps/ffs2native/src/main.c b/versions/v1_5_0/mynewt-core/apps/ffs2native/src/main.c
new file mode 100644
index 0000000..2a7323c
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ffs2native/src/main.c
@@ -0,0 +1,716 @@
+/*
+ * 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 <inttypes.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <string.h>
+#include "os/mynewt.h"
+#include "../src/nffs_priv.h"
+#include <fs/fs.h>
+#include <bsp/bsp.h>
+#include <nffs/nffs.h>
+#include <hal/hal_flash.h>
+#include <flash_map/flash_map.h>
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+struct log nffs_log;
+static const char *copy_in_dir;
+static const char *progname;
+static int print_verbose;
+
+char *file_flash_area;
+size_t file_flash_size;
+int file_scratch_idx;
+
+#define MAX_AREAS    16
+static struct nffs_area_desc area_descs[MAX_AREAS];
+int nffs_version;
+int force_version;
+
+/** On-disk representation of a version 0 inode (file or directory). */
+struct nffs_disk_V0inode {
+    uint32_t ndi_magic;         /* NFFS_INODE_MAGIC */
+    uint32_t ndi_id;            /* Unique object ID. */
+    uint32_t ndi_seq;           /* Sequence number; greater supersedes
+                                   lesser. */
+    uint32_t ndi_parent_id;     /* Object ID of parent directory inode. */
+    uint8_t reserved8;
+    uint8_t ndi_filename_len;   /* Length of filename, in bytes. */
+    uint16_t ndi_crc16;         /* Covers rest of header and filename. */
+    /* Followed by filename. */
+};
+#define NFFS_DISK_V0INODE_OFFSET_CRC  18
+
+/** On-disk representation of a version 0 data block. */
+struct nffs_disk_V0block {
+    uint32_t ndb_magic;     /* NFFS_BLOCK_MAGIC */
+    uint32_t ndb_id;        /* Unique object ID. */
+    uint32_t ndb_seq;       /* Sequence number; greater supersedes lesser. */
+    uint32_t ndb_inode_id;  /* Object ID of owning inode. */
+    uint32_t ndb_prev_id;   /* Object ID of previous block in file;
+                               NFFS_ID_NONE if this is the first block. */
+    uint16_t ndb_data_len;  /* Length of data contents, in bytes. */
+    uint16_t ndb_crc16;     /* Covers rest of header and data. */
+    /* Followed by 'ndb_data_len' bytes of data. */
+};
+#define NFFS_DISK_V0BLOCK_OFFSET_CRC  22
+
+struct nffs_disk_V0object {
+    int ndo_type;
+    uint8_t ndo_area_idx;
+    uint32_t ndo_offset;
+    union {
+        struct nffs_disk_V0inode ndo_disk_V0inode;
+        struct nffs_disk_V0block ndo_disk_V0block;
+    } ndo_un_V0obj;
+};
+
+#define ndo_disk_V0inode    ndo_un_V0obj.ndo_disk_V0inode
+#define ndo_disk_V0block    ndo_un_V0obj.ndo_disk_V0block
+
+static void usage(int rc);
+
+static void
+copyfs(FILE *fp)
+{
+    uint32_t dst_addr;
+    int rc;
+    int c;
+
+    dst_addr = area_descs[0].nad_offset;
+    while (1) {
+        c = getc(fp);
+        if (c == EOF) {
+            return;
+        }
+
+        rc = hal_flash_write(area_descs[0].nad_flash_id, dst_addr, &c, 1);
+        assert(rc == 0);
+
+        dst_addr++;
+    }
+}
+
+static void
+print_inode_entry(struct nffs_inode_entry *inode_entry, int indent)
+{
+    struct nffs_inode inode;
+    char name[NFFS_FILENAME_MAX_LEN + 1];
+    uint32_t area_offset;
+    uint8_t area_idx;
+    int rc;
+
+    rc = nffs_inode_from_entry(&inode, inode_entry);
+    /*
+     * Dummy inode
+     */
+    if (rc == FS_ENOENT) {
+        printf("    DUMMY %d\n", rc);
+        return;
+    }
+    assert(rc == 0);
+
+    nffs_flash_loc_expand(inode_entry->nie_hash_entry.nhe_flash_loc,
+                         &area_idx, &area_offset);
+
+    rc = nffs_flash_read(area_idx,
+                         area_offset + sizeof (struct nffs_disk_inode),
+                         name, inode.ni_filename_len);
+    assert(rc == 0);
+
+    name[inode.ni_filename_len] = '\0';
+
+    printf("%*s%s\n", indent, "", name[0] == '\0' ? "/" : name);
+}
+
+static void
+process_inode_entry(struct nffs_inode_entry *inode_entry, int indent)
+{
+    struct nffs_inode_entry *child;
+
+    print_inode_entry(inode_entry, indent);
+
+    if (nffs_hash_id_is_dir(inode_entry->nie_hash_entry.nhe_id)) {
+        SLIST_FOREACH(child, &inode_entry->nie_child_list, nie_sibling_next) {
+            process_inode_entry(child, indent + 2);
+        }
+    }
+}
+
+static int
+print_nffs_inode(struct nffs_disk_inode *ndi, int idx, uint32_t off)
+{
+    char filename[128];
+    int len;
+    int rc;
+
+    memset(filename, 0, sizeof(filename));
+    len = min(sizeof(filename) - 1, ndi->ndi_filename_len);
+    rc = nffs_flash_read(idx, off + sizeof(struct nffs_disk_inode),
+                         filename, len);
+    printf("      %x-%d inode %d/%d",
+      off, ndi->ndi_filename_len, ndi->ndi_id, ndi->ndi_seq);
+    if (rc == 0)
+        printf(" %s\n", filename);
+    else
+        printf("\n");
+    return (sizeof(struct nffs_disk_inode) + ndi->ndi_filename_len);
+}
+
+static int
+print_nffs_block(struct nffs_disk_block *ndb, int idx, uint32_t off)
+{
+    printf("      %x-%d block %u/%u belongs to %u\n",
+      off, ndb->ndb_data_len, ndb->ndb_id, ndb->ndb_seq, ndb->ndb_inode_id);
+    return sizeof(struct nffs_disk_block) + ndb->ndb_data_len;
+}
+
+static int
+print_nffs_object(int idx, uint32_t off)
+{
+    struct nffs_disk_object dobj;
+    int rc;
+
+    rc = nffs_flash_read(idx, off, &dobj.ndo_un_obj, sizeof(dobj.ndo_un_obj));
+    assert(rc == 0);
+
+    if (nffs_hash_id_is_inode(dobj.ndo_disk_inode.ndi_id)) {
+        return print_nffs_inode(&dobj.ndo_disk_inode, idx, off);
+
+    } else if (nffs_hash_id_is_block(dobj.ndo_disk_inode.ndi_id)) {
+        return print_nffs_block(&dobj.ndo_disk_block, idx, off);
+
+    } else if (dobj.ndo_disk_inode.ndi_id == NFFS_ID_NONE) {
+        assert(0);
+        return 0;
+
+    } else {
+        printf("      %x Corruption\n", off);
+        return 1;
+    }
+}
+
+static void
+print_nffs_darea(struct nffs_disk_area *darea)
+{
+    printf("\tdarea: len %d ver %d gc_seq %d id %x\n",
+           darea->nda_length, darea->nda_ver,
+           darea->nda_gc_seq, darea->nda_id);
+}
+
+static void
+print_nffs_area(int idx)
+{
+    struct nffs_area *area;
+    struct nffs_disk_area darea;
+    int off;
+    int rc;
+
+    area = &nffs_areas[idx];
+    rc = nffs_flash_read(idx, 0, &darea, sizeof(darea));
+    assert(rc == 0);
+    print_nffs_darea(&darea);
+    if (!nffs_area_magic_is_set(&darea)) {
+        printf("Area header corrupt!\n");
+        return;
+    }
+    /*
+     * XXX Enhance to print but not restore unsupported formats
+     */
+    if (!nffs_area_is_current_version(&darea)) {
+        printf("Area format is not supported!\n");
+        return;
+    }
+    off = sizeof (struct nffs_disk_area);
+    while (off < area->na_cur) {
+        off += print_nffs_object(idx, off);
+    }
+}
+
+static void
+print_nffs_areas(void)
+{
+    int i;
+    struct nffs_area *area;
+
+    for (i = 0; i < nffs_num_areas; i++) {
+        if (nffs_scratch_area_idx == i) {
+            printf(" sc ");
+        } else {
+            printf("    ");
+        }
+
+        area = &nffs_areas[i];
+        printf("%d: cur:%d id:%d 0x%x-0x%x\n",
+          i, area->na_cur, area->na_id,
+          area->na_offset, area->na_offset + area->na_length);
+        print_nffs_area(i);
+    }
+} 
+
+static int
+copy_in_file(char *src, char *dst)
+{
+    struct fs_file *nf;
+    FILE *fp;
+    int rc;
+    char data[2048];
+    int ret = 0;
+
+    rc = fs_open(dst, FS_ACCESS_WRITE, &nf);
+    assert(rc == 0);
+
+    fp = fopen(src, "r");
+    if (!fp) {
+        perror("fopen()");
+        assert(0);
+    }
+    while ((rc = fread(data, 1, sizeof(data), fp))) {
+        rc = fs_write(nf, data, rc);
+        if (rc) {
+            ret = rc;
+            break;
+        }
+    }
+    rc = fs_close(nf);
+    assert(rc == 0);
+    fclose(fp);
+    return ret;
+}
+
+void
+copy_in_directory(const char *src, const char *dst)
+{
+    DIR *dr;
+    struct dirent *entry;
+    char src_name[1024];
+    char dst_name[1024];
+    int rc;
+
+    dr = opendir(src);
+    if (!dr) {
+        perror("opendir");
+        usage(1);
+    }
+    while ((entry = readdir(dr))) {
+        snprintf(src_name, sizeof(src_name), "%s/%s", src, entry->d_name);
+        snprintf(dst_name, sizeof(dst_name), "%s/%s", dst, entry->d_name);
+        if (entry->d_type == DT_DIR &&
+          strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) {
+            rc = fs_mkdir(dst_name);
+            copy_in_directory(src_name, dst_name);
+            assert(rc == 0);
+        } else if (entry->d_type == DT_REG) {
+            printf("Copying %s\n", dst_name);
+            rc = copy_in_file(src_name, dst_name);
+            if (rc) {
+                if (print_verbose) {
+                    printf("  error code %d ", rc);
+                }
+                switch (rc) {
+                case FS_ENOMEM:
+                    printf("out of memory\n");
+                    break;
+                case FS_EFULL:
+                    printf("disk is full\n");
+                    break;
+                default:
+                    printf("\n");
+                }
+                break;
+            }
+        } else {
+            if (print_verbose) {
+                printf("Skipping %s\n", src_name);
+            }
+        }
+    }
+    closedir(dr);
+}
+
+static int
+file_flash_read(uint32_t addr, void *dst, int byte_cnt)
+{
+    memcpy(dst, (void*)file_flash_area + addr, byte_cnt);
+    return 0;
+}
+
+/*
+ * Print NFFS V0 structures
+ * XXX could check for CRC errors
+ */
+static int
+print_nffs_flash_V0inode(struct nffs_area_desc *area, uint32_t off)
+{
+    struct nffs_disk_V0inode ndi;
+    char filename[128];
+    int len;
+    int rc;
+
+    rc = file_flash_read(area->nad_offset + off, &ndi, sizeof(ndi));
+    assert(rc == 0);
+    assert(nffs_hash_id_is_inode(ndi.ndi_id));
+
+    memset(filename, 0, sizeof(filename));
+    len = min(sizeof(filename) - 1, ndi.ndi_filename_len);
+    rc = file_flash_read(area->nad_offset + off + sizeof(ndi), filename, len);
+    filename[len] = '\0';
+    assert(rc == 0);
+
+    printf("   %s off %d id %x flen %d seq %d prnt %x %s\n",
+           (nffs_hash_id_is_file(ndi.ndi_id) ? "File" :
+            (nffs_hash_id_is_dir(ndi.ndi_id) ? "Dir" : "???")),
+           off, ndi.ndi_id, ndi.ndi_filename_len,
+           ndi.ndi_seq, ndi.ndi_parent_id, filename);
+    return sizeof(struct nffs_disk_V0inode) + ndi.ndi_filename_len;
+}
+
+static int
+print_nffs_flash_V0block(struct nffs_area_desc *area, uint32_t off)
+{
+    struct nffs_disk_V0block ndb;
+    int rc;
+
+    rc = file_flash_read(area->nad_offset + off, &ndb, sizeof(ndb));
+    assert(rc == 0);
+    assert(nffs_hash_id_is_block(ndb.ndb_id));
+    assert(!nffs_hash_id_is_inode(ndb.ndb_id));
+
+    printf("   Block off %d id %x len %d seq %d prev %x ino %x\n",
+           off, ndb.ndb_id, ndb.ndb_data_len, ndb.ndb_seq,
+           ndb.ndb_prev_id, ndb.ndb_inode_id);
+    return sizeof(struct nffs_disk_V0block) + ndb.ndb_data_len;
+}
+
+static int
+print_nffs_flash_V0object(struct nffs_area_desc *area, uint32_t off)
+{
+    uint32_t magic;
+    int rc;
+
+    printf("print_nffs_flash_V0object(area:%d off%d)\n", area->nad_flash_id, off);
+    rc = file_flash_read(area->nad_offset + off, &magic, sizeof magic);
+    assert(rc == 0);
+
+    switch (magic) {
+    case NFFS_INODE_MAGIC:
+        return print_nffs_flash_V0inode(area, off);
+
+    case NFFS_BLOCK_MAGIC:
+        return print_nffs_flash_V0block(area, off);
+
+    case 0xffffffff:
+        return area->nad_length;
+
+    default:
+        return 1;
+    }
+}
+
+static int
+print_nffs_flash_inode(struct nffs_area_desc *area, uint32_t off)
+{
+    struct nffs_disk_inode ndi;
+    char filename[128];
+    int len;
+    int rc;
+    uint16_t crc16;
+    int badcrc = 0;
+
+    rc = file_flash_read(area->nad_offset + off, &ndi, sizeof(ndi));
+    assert(rc == 0);
+
+    crc16 = crc16_ccitt(0, (void*)&ndi, NFFS_DISK_INODE_OFFSET_CRC);
+
+    memset(filename, 0, sizeof(filename));
+    len = min(sizeof(filename) - 1, ndi.ndi_filename_len);
+    rc = file_flash_read(area->nad_offset + off + sizeof(ndi), filename, len);
+
+    crc16 = crc16_ccitt(crc16, filename, ndi.ndi_filename_len);
+    if (crc16 != ndi.ndi_crc16) {
+        badcrc = 1;
+    }
+
+    printf("  off %x %s id %x flen %d seq %d last %x prnt %x flgs %x %s%s\n",
+           off,
+           (nffs_hash_id_is_file(ndi.ndi_id) ? "File" :
+            nffs_hash_id_is_dir(ndi.ndi_id) ? "Dir" : "???"),
+           ndi.ndi_id,
+           ndi.ndi_filename_len,
+           ndi.ndi_seq,
+           ndi.ndi_lastblock_id,
+           ndi.ndi_parent_id,
+           ndi.ndi_flags,
+           filename,
+           badcrc ? " (Bad CRC!)" : "");
+    return sizeof(ndi) + ndi.ndi_filename_len;
+}
+
+static int
+print_nffs_flash_block(struct nffs_area_desc *area, uint32_t off)
+{
+    struct nffs_disk_block ndb;
+    int rc;
+    uint16_t crc16;
+    int badcrc = 0;
+    int dataover = 0;
+
+    rc = file_flash_read(area->nad_offset + off, &ndb, sizeof(ndb));
+    assert(rc == 0);
+
+    if (off + ndb.ndb_data_len > area->nad_length) {
+        dataover++;
+    } else {
+        crc16 = crc16_ccitt(0, (void*)&ndb, NFFS_DISK_BLOCK_OFFSET_CRC);
+        crc16 = crc16_ccitt(crc16,
+            (void*)(file_flash_area + area->nad_offset + off + sizeof(ndb)),
+            ndb.ndb_data_len);
+        if (crc16 != ndb.ndb_crc16) {
+            badcrc++;
+        }
+    }
+
+    printf("  off %x Block id %x len %d seq %d prev %x own ino %x%s%s\n",
+           off,
+           ndb.ndb_id,
+           ndb.ndb_data_len,
+           ndb.ndb_seq,
+           ndb.ndb_prev_id,
+           ndb.ndb_inode_id,
+           dataover ? " (Bad data length)" : "",
+           badcrc ? " (Bad CRC!)" : "");
+    if (dataover) {
+        return 1;
+    }
+    return sizeof(ndb) + ndb.ndb_data_len;
+}
+
+static int
+print_nffs_flash_object(struct nffs_area_desc *area, uint32_t off)
+{
+    struct nffs_disk_inode *ndi;
+    struct nffs_disk_block *ndb;
+
+    ndi = (struct nffs_disk_inode*)(file_flash_area + area->nad_offset + off);
+    ndb = (struct nffs_disk_block*)ndi;
+
+    if (nffs_hash_id_is_inode(ndi->ndi_id)) {
+        return print_nffs_flash_inode(area, off);
+
+    } else if (nffs_hash_id_is_block(ndb->ndb_id)) {
+        return print_nffs_flash_block(area, off);
+
+    } else if (ndb->ndb_id == 0xffffffff) {
+        return area->nad_length;
+
+    } else {
+        return 1;
+    }
+}
+
+static void
+print_nffs_file_flash(char *flash_area, size_t size)
+{
+    char *daptr;        /* Disk Area Pointer */
+    char *eoda;            /* End Of Disk Area */
+    struct nffs_disk_area *nda;
+    int nad_cnt = 0;    /* Nffs Area Descriptor count */
+    int off;
+    int objsz;
+
+    daptr = flash_area;
+    eoda = flash_area + size;
+    printf("\nNFFS Flash Areas:\n");
+    while (daptr < eoda) {
+        if (nffs_area_magic_is_set((struct nffs_disk_area*)daptr)) {
+            nda = (struct nffs_disk_area*)daptr;
+            area_descs[nad_cnt].nad_offset = (daptr - flash_area);
+            area_descs[nad_cnt].nad_length = nda->nda_length;
+            area_descs[nad_cnt].nad_flash_id = nda->nda_id;
+            if (force_version >= 0) {
+                nffs_version = force_version;
+            } else {
+                nffs_version = nda->nda_ver;
+            }
+
+            if (nda->nda_id == 0xff)
+                file_scratch_idx = nad_cnt;
+
+            printf("Area %d: off %x-%x len %d flshid %x gcseq %d ver %d id %x%s%s\n",
+                   nad_cnt,
+                   area_descs[nad_cnt].nad_offset,
+                   area_descs[nad_cnt].nad_offset +
+                                 area_descs[nad_cnt].nad_length,
+                   area_descs[nad_cnt].nad_length,
+                   area_descs[nad_cnt].nad_flash_id,
+                   nda->nda_gc_seq,
+                   nda->nda_ver,
+                   nda->nda_id,
+                   nda->nda_ver != NFFS_AREA_VER ? " (V0)" : "",
+                   nad_cnt == file_scratch_idx ? " (Scratch)" : "");
+
+            if (nffs_version == 0) {
+                objsz = sizeof (struct nffs_disk_V0object);
+            } else {
+                objsz = sizeof (struct nffs_disk_object);
+            }
+            off = sizeof (struct nffs_disk_area);
+            while (off + objsz < area_descs[nad_cnt].nad_length) {
+                if (nffs_version == 0) {
+                    off += print_nffs_flash_V0object(&area_descs[nad_cnt], off);
+                } else if (nffs_version == NFFS_AREA_VER) {
+                    off += print_nffs_flash_object(&area_descs[nad_cnt], off);
+                }
+            }
+            printf("\n");
+
+            nad_cnt++;
+            daptr = daptr + nda->nda_length;
+        } else {
+            daptr++;
+        }
+    }
+    nffs_num_areas = nad_cnt;
+}
+
+static void
+printfs(void)
+{
+    printf("\nNFFS directory:\n");
+    process_inode_entry(nffs_root_dir, print_verbose);
+
+    printf("\nNFFS areas:\n");
+    print_nffs_areas();
+
+}
+
+static void
+usage(int rc)
+{
+    printf("%s [-v][-c]|[-d dir][-s][-f flash_file]\n", progname);
+    printf("  Tool for operating on simulator flash image file\n");
+    printf("   -c: ...\n");
+    printf("   -v: verbose\n");
+    printf("   -d: use dir as root for NFFS portion and create flash image\n");
+    printf("   -f: flash_file is the name of the flash image file\n");
+    printf("   -s: use flash area layout in flash image file\n");
+    exit(rc);
+}
+
+int
+main(int argc, char **argv)
+{
+    FILE *fp;
+    int fd;
+    int rc;
+    int ch;
+    int cnt;
+    struct stat st;
+    int standalone = 0;
+
+    progname = argv[0];
+    force_version = -1;
+
+    while ((ch = getopt(argc, argv, "c:d:f:sv01")) != -1) {
+        switch (ch) {
+        case 'c':
+            fp = fopen(optarg, "rb");
+            assert(fp != NULL);
+            copyfs(fp);
+            fclose(fp);
+            break;
+        case 'd':
+            copy_in_dir = optarg;
+            break;
+        case 's':
+            standalone++;
+            break;
+        case 'f':
+            native_flash_file = optarg;
+            break;
+        case 'v':
+            print_verbose++;
+            break;
+        case '0':
+            force_version = 0;
+            break;
+        case '1':
+            force_version = 1;
+            break;
+        case '?':
+        default:
+            usage(0);
+        }
+    }
+
+    sysinit();
+
+    log_register("nffs-log", &nffs_log, &log_console_handler, NULL, LOG_SYSLEVEL);
+
+    file_scratch_idx = MAX_AREAS + 1;
+
+    if (standalone) {
+        fd = open(native_flash_file, O_RDWR);
+        if ((rc = fstat(fd, &st)))
+            perror("fstat failed");
+        file_flash_size = st.st_size;
+        if ((file_flash_area = mmap(0, (size_t)8192, PROT_READ,
+                               MAP_FILE|MAP_SHARED, fd, 0)) == MAP_FAILED) {
+            perror("%s mmap failed");
+        }
+
+        print_nffs_file_flash(file_flash_area, file_flash_size);
+
+        return 0;
+    }
+
+    rc = nffs_misc_desc_from_flash_area(MYNEWT_VAL(NFFS_FLASH_AREA), &cnt,
+      area_descs);
+    assert(rc == 0);
+
+    if (copy_in_dir) {
+        /*
+         * Build filesystem from contents of directory
+         */
+        rc = nffs_format(area_descs);
+        assert(rc == 0);
+        copy_in_directory(copy_in_dir, "");
+    } else {
+        rc = nffs_detect(area_descs);
+        if (rc) {
+            printf("nffs_detect() failed\n");
+            exit(0);
+        }
+    }
+    printfs();
+
+    return 0;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/iptest/pkg.yml b/versions/v1_5_0/mynewt-core/apps/iptest/pkg.yml
new file mode 100644
index 0000000..311887f
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@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/versions/v1_5_0/mynewt-core/apps/iptest/src/main.c b/versions/v1_5_0/mynewt-core/apps/iptest/src/main.c
new file mode 100644
index 0000000..f56fe5e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/iptest/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/iptest/syscfg.yml
new file mode 100644
index 0000000..b24891c
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/lora_app_shell/pkg.yml b/versions/v1_5_0/mynewt-core/apps/lora_app_shell/pkg.yml
new file mode 100644
index 0000000..0bed1eb
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@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/versions/v1_5_0/mynewt-core/apps/lora_app_shell/src/las_cmd.c b/versions/v1_5_0/mynewt-core/apps/lora_app_shell/src/las_cmd.c
new file mode 100644
index 0000000..289071b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/lora_app_shell/src/main.c b/versions/v1_5_0/mynewt-core/apps/lora_app_shell/src/main.c
new file mode 100644
index 0000000..13bb578
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/lora_app_shell/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/lora_app_shell/syscfg.yml
new file mode 100644
index 0000000..70db38e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/loraping/pkg.yml b/versions/v1_5_0/mynewt-core/apps/loraping/pkg.yml
new file mode 100644
index 0000000..bc6f063
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@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/versions/v1_5_0/mynewt-core/apps/loraping/src/loraping.h b/versions/v1_5_0/mynewt-core/apps/loraping/src/loraping.h
new file mode 100644
index 0000000..4b28e7a
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/loraping/src/main.c b/versions/v1_5_0/mynewt-core/apps/loraping/src/main.c
new file mode 100644
index 0000000..28ae433
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/loraping/src/rxinfo.c b/versions/v1_5_0/mynewt-core/apps/loraping/src/rxinfo.c
new file mode 100644
index 0000000..71c1de8
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/loraping/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/loraping/syscfg.yml
new file mode 100644
index 0000000..be3ca0d
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/loraping/syscfg.yml
@@ -0,0 +1,30 @@
+#
+# 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
+
+syscfg.vals:
+    STATS_CLI: 1
+    STATS_NAMES: 1
+    SHELL_TASK: 1
+    SHELL_MAX_COMPAT_COMMANDS: 32
diff --git a/versions/v1_5_0/mynewt-core/apps/lorashell/pkg.yml b/versions/v1_5_0/mynewt-core/apps/lorashell/pkg.yml
new file mode 100644
index 0000000..645fbee
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@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/versions/v1_5_0/mynewt-core/apps/lorashell/src/main.c b/versions/v1_5_0/mynewt-core/apps/lorashell/src/main.c
new file mode 100644
index 0000000..98aad07
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 "radio/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/versions/v1_5_0/mynewt-core/apps/lorashell/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/lorashell/syscfg.yml
new file mode 100644
index 0000000..a3953d0
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/metrics/pkg.yml b/versions/v1_5_0/mynewt-core/apps/metrics/pkg.yml
new file mode 100644
index 0000000..c1445ad
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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 <dev@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/versions/v1_5_0/mynewt-core/apps/metrics/src/main.c b/versions/v1_5_0/mynewt-core/apps/metrics/src/main.c
new file mode 100755
index 0000000..b5f9671
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/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/versions/v1_5_0/mynewt-core/apps/metrics/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/metrics/syscfg.yml
new file mode 100644
index 0000000..0732833
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/metrics/syscfg.yml
@@ -0,0 +1,25 @@
+#
+# 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
+    SHELL_TASK: 1
diff --git a/versions/v1_5_0/mynewt-core/apps/ocf_sample/pkg.yml b/versions/v1_5_0/mynewt-core/apps/ocf_sample/pkg.yml
new file mode 100644
index 0000000..dc6c7eb
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ocf_sample/pkg.yml
@@ -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.
+#
+
+pkg.name: apps/ocf_sample
+pkg.type: app
+pkg.description: Example application which uses OCF iotivity.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@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:
+    - "@apache-mynewt-core/sys/shell"
+
+pkg.deps.OC_TRANSPORT_GATT:
+    - "@apache-mynewt-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/nimble/transport/ram"
diff --git a/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/main.c b/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/main.c
new file mode 100644
index 0000000..3a3804e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/main.c
@@ -0,0 +1,265 @@
+/*
+ * 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 "os/mynewt.h"
+#include <bsp/bsp.h>
+#include <log/log.h>
+#include <oic/oc_api.h>
+#include <cborattr/cborattr.h>
+#if (MYNEWT_VAL(OC_TRANSPORT_SERIAL) == 1)
+#include <console/console.h>
+#include <console/prompt.h>
+#include <shell/shell.h>
+#endif
+
+#if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1)
+#include "host/ble_hs.h"
+#include "ocf_sample.h"
+#endif
+
+#if (MYNEWT_VAL(OC_CLIENT) == 1)
+static void issue_requests(void);
+#endif
+
+#if (MYNEWT_VAL(OC_SERVER) == 1)
+static bool light_state = false;
+
+static void
+get_light(oc_request_t *request, oc_interface_mask_t interface)
+{
+    printf("GET_light:\n");
+    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, light_state);
+        break;
+    default:
+        break;
+    }
+    oc_rep_end_root_object();
+    oc_send_response(request, OC_STATUS_OK);
+    printf("Light state %d\n", light_state);
+}
+
+static void
+put_light(oc_request_t *request, oc_interface_mask_t interface)
+{
+    bool state;
+    int len;
+    uint16_t data_off;
+    struct os_mbuf *m;
+    struct cbor_attr_t attrs[] = {
+        [0] = {
+            .attribute = "state",
+            .type = CborAttrBooleanType,
+            .addr.boolean = &state,
+            .dflt.boolean = false
+        },
+        [1] = {
+        }
+    };
+
+    printf("PUT_light:\n");
+
+    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 {
+        printf("value: %d\n", state);
+        light_state = state;
+        oc_send_response(request, OC_STATUS_CHANGED);
+    }
+}
+
+static void
+register_resources(void)
+{
+    oc_resource_t *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_set_discoverable(res);
+    oc_resource_set_periodic_observable(res, 1);
+    oc_resource_set_request_handler(res, OC_GET, get_light);
+    oc_resource_set_request_handler(res, OC_PUT, put_light);
+    oc_add_resource(res);
+}
+#endif
+
+#if (MYNEWT_VAL(OC_CLIENT) == 1)
+#define MAX_URI_LENGTH (30)
+static char light_1[MAX_URI_LENGTH];
+static oc_server_handle_t light_server;
+static bool light_state = false;
+static struct os_callout callout;
+
+static void
+set_device_custom_property(void *data)
+{
+    oc_set_custom_device_property(purpose, "operate mynewt-light");
+}
+
+static void
+stop_observe(struct os_event *ev)
+{
+    printf("Stopping OBSERVE\n");
+    oc_stop_observe(light_1, &light_server);
+}
+
+static void
+put_light(oc_client_response_t *data)
+{
+    printf("PUT_light:\n");
+    if (data->code == OC_STATUS_CHANGED)
+        printf("PUT response OK\n");
+    else
+        printf("PUT response code %d\n", data->code);
+}
+
+static void
+observe_light(oc_client_response_t *rsp)
+{
+    bool state;
+    int len;
+    uint16_t data_off;
+    struct os_mbuf *m;
+    struct cbor_attr_t attrs[] = {
+        [0] = {
+            .attribute = "state",
+            .type = CborAttrBooleanType,
+            .addr.boolean = &state,
+            .dflt.boolean = false
+        },
+        [1] = {
+        }
+    };
+
+    len = coap_get_payload(rsp->packet, &m, &data_off);
+    if (!cbor_read_mbuf_attrs(m, data_off, len, attrs)) {
+        printf("OBSERVE_light: %d\n", state);
+        light_state = state;
+    }
+
+    if (oc_init_put(light_1, &light_server, NULL, &put_light, LOW_QOS)) {
+        oc_rep_start_root_object();
+        oc_rep_set_boolean(root, state, !light_state);
+        oc_rep_end_root_object();
+        if (oc_do_put() == true) {
+            printf("Sent PUT request\n");
+        } else {
+            printf("Could not send PUT\n");
+        }
+    } else {
+        printf("Could not init PUT\n");
+    }
+}
+
+static oc_discovery_flags_t
+discovery(const char *di, const char *uri, oc_string_array_t types,
+          oc_interface_mask_t interfaces, oc_server_handle_t *server)
+{
+    int i;
+    int uri_len = strlen(uri);
+    uri_len = (uri_len >= MAX_URI_LENGTH) ? MAX_URI_LENGTH - 1 : uri_len;
+
+    for (i = 0; i < oc_string_array_get_allocated_size(types); i++) {
+        char *t = oc_string_array_get_item(types, i);
+        if (strlen(t) == 11 && strncmp(t, "oic.r.light", 11) == 0) {
+            memcpy(&light_server, server, sizeof(oc_server_handle_t));
+
+            strncpy(light_1, uri, uri_len);
+            light_1[uri_len] = '\0';
+
+            oc_do_observe(light_1, &light_server, NULL, &observe_light,
+                          LOW_QOS);
+            os_callout_reset(&callout, 30 * OS_TICKS_PER_SEC);
+            return OC_STOP_DISCOVERY;
+        }
+    }
+    return OC_CONTINUE_DISCOVERY;
+}
+
+static void
+issue_requests(void)
+{
+    oc_do_ip_discovery("oic.r.light", &discovery);
+}
+#endif
+
+static void
+app_init(void)
+{
+    oc_init_platform("Mynewt", NULL, NULL);
+#if (MYNEWT_VAL(OC_CLIENT) == 1)
+    oc_add_device("/oic/d", "oic.d.light", "MynewtClient", "1.0", "1.0",
+                  set_device_custom_property, NULL);
+#endif
+
+#if (MYNEWT_VAL(OC_SERVER) == 1)
+    oc_add_device("/oic/d", "oic.d.light", "MynewtServer", "1.0", "1.0", NULL,
+                  NULL);
+#endif
+}
+
+oc_handler_t ocf_handler = {
+    .init = app_init,
+#if (MYNEWT_VAL(OC_SERVER) == 1)
+    .register_resources = register_resources,
+#endif
+#if (MYNEWT_VAL(OC_CLIENT) == 1)
+    .requests_entry = issue_requests,
+#endif
+ };
+
+static void
+ocf_init_tasks(void)
+{
+#if (MYNEWT_VAL(OC_CLIENT) == 1)
+    os_callout_init(&callout, os_eventq_dflt_get(), stop_observe, NULL);
+#endif
+    oc_main_init(&ocf_handler);
+}
+
+int
+main(int argc, char **argv)
+{
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    /* Initialize OS */
+    sysinit();
+
+#if (MYNEWT_VAL(OC_TRANSPORT_GATT) == 1)
+    ocf_ble_init();
+#endif
+
+    ocf_init_tasks();
+
+    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);
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/ocf_ble.c b/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/ocf_ble.c
new file mode 100644
index 0000000..2e6b23b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/ocf_ble.c
@@ -0,0 +1,263 @@
+/**
+ * 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"
+
+#if MYNEWT_VAL(OC_TRANSPORT_GATT)
+
+#include <assert.h>
+#include <string.h>
+
+#include "modlog/modlog.h"
+
+#include "oic/oc_gatt.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+
+static int ocf_ble_gap_event(struct ble_gap_event *event, void *arg);
+
+/**
+ * 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]);
+}
+
+/**
+ * Logs information about a connection to the console.
+ */
+static void
+ocf_ble_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 Undirected connectable mode.
+ */
+static void
+ocf_ble_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.
+     */
+
+    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;
+
+    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_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, ocf_ble_gap_event, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        return;
+    }
+}
+
+static void
+ocf_ble_on_sync(void)
+{
+    /* Begin advertising. */
+    ocf_ble_advertise();
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that forms.
+ * ocf_ble 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
+ *                                  ocf_ble.
+ *
+ * @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
+ocf_ble_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);
+            ocf_ble_print_conn_desc(&desc);
+        }
+        MODLOG_DFLT(INFO, "\n");
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            ocf_ble_advertise();
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        ocf_ble_print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        /* Connection terminated; resume advertising. */
+        ocf_ble_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);
+        ocf_ble_print_conn_desc(&desc);
+        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. */
+        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);
+        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);
+        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 const uint8_t ocf_ble_addr[6] = {1,2,3,4,5,6};
+
+void
+ocf_ble_init(void)
+{
+    memcpy(g_dev_addr, ocf_ble_addr, sizeof(g_dev_addr));
+
+    /* Initialize the BLE host. */
+    ble_hs_cfg.sync_cb = ocf_ble_on_sync;
+}
+
+#endif /* MYNEWT_VAL(OC_TRANSPORT_GATT) */
diff --git a/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/ocf_sample.h b/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/ocf_sample.h
new file mode 100644
index 0000000..b2327f1
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ocf_sample/src/ocf_sample.h
@@ -0,0 +1,35 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_OCF_BLE_
+#define H_OCF_BLE_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if MYNEWT_VAL(OC_TRANSPORT_GATT)
+void ocf_ble_init(void);
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/versions/v1_5_0/mynewt-core/apps/ocf_sample/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/ocf_sample/syscfg.yml
new file mode 100644
index 0000000..f18b757
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/ocf_sample/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:
+    SHELL_TASK: 1
+
+    # Default task settings
+    OS_MAIN_STACK_SIZE: 512
diff --git a/versions/v1_5_0/mynewt-core/apps/pwm_test/pkg.yml b/versions/v1_5_0/mynewt-core/apps/pwm_test/pkg.yml
new file mode 100644
index 0000000..a5e73f3
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/pwm_test/pkg.yml
@@ -0,0 +1,31 @@
+#
+# 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/pwm_test
+pkg.type: app
+pkg.description: Basic example application which drives an LED using PWM.
+pkg.author: "Apache Mynewt <dev@mynewt.incubator.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/hw/drivers/pwm"
+    - "@apache-mynewt-core/util/easing"
diff --git a/versions/v1_5_0/mynewt-core/apps/pwm_test/src/main.c b/versions/v1_5_0/mynewt-core/apps/pwm_test/src/main.c
new file mode 100644
index 0000000..dc0a715
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/pwm_test/src/main.c
@@ -0,0 +1,177 @@
+/**
+ * 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 <pwm/pwm.h>
+#include <bsp/bsp.h>
+#include <easing/easing.h>
+#include <console/console.h>
+
+#if (defined NUCLEO_F767ZI)
+#   define  PWM_TEST_CH_CFG_PIN  MCU_AFIO_GPIO(LED_BLINK_PIN, 2)
+#   define  PWM_TEST_CH_CFG_INV  false 
+#   define  PWM_TEST_CH_NUM      2
+#   define  PWM_TEST_IRQ_PRIO    0
+#elif (defined NUCLEO_F303RE)
+#   define  PWM_TEST_CH_CFG_PIN  MCU_AFIO_GPIO(LED_BLINK_PIN, 1)
+#   define  PWM_TEST_CH_CFG_INV  false 
+#   define  PWM_TEST_CH_NUM      0
+#   define  PWM_TEST_IRQ_PRIO    0
+#elif (defined NUCLEO_F303K8)
+#   define  PWM_TEST_CH_CFG_PIN  MCU_AFIO_GPIO(LED_BLINK_PIN, 1)
+#   define  PWM_TEST_CH_CFG_INV  false 
+#   define  PWM_TEST_CH_NUM      1
+#   define  PWM_TEST_IRQ_PRIO    0
+#else
+#   define  PWM_TEST_CH_CFG_PIN  LED_BLINK_PIN
+#   define  PWM_TEST_CH_CFG_INV  true 
+#   define  PWM_TEST_CH_NUM      0
+#   define  PWM_TEST_IRQ_PRIO    3
+#endif
+
+#if MYNEWT_VAL(SOFT_PWM)
+#   define PWM_TEST_DEV   "spwm0"
+#else
+#   define PWM_TEST_DEV   "pwm0"
+#endif
+
+struct pwm_dev *pwm;
+static uint32_t pwm_freq = 200;
+static uint32_t max_steps = 200; /* two seconds motion up/down */
+static uint16_t top_val;
+static volatile uint32_t step = 0;
+static volatile bool up = false;
+static volatile int func_num = 1;
+static easing_int_func_t easing_funct = sine_int_io;
+
+static void
+pwm_cycle_handler(void* unused)
+{
+    int16_t eased;
+    eased = easing_funct(step, max_steps, top_val);
+    pwm_set_duty_cycle(pwm, PWM_TEST_CH_NUM, eased);
+    if (step >= max_steps || step <= 0) {
+        up = !up;
+    }
+
+    step += (up) ? 1 : -1;
+}
+
+static void
+pwm_end_seq_handler(void* unused)
+{
+    int rc;
+    step = 0;
+    up = false;
+
+    switch (func_num)
+    {
+    case 0:
+        easing_funct = sine_int_io;
+        console_printf ("Easing: sine io\n");
+        break;
+    case 1:
+        easing_funct = bounce_int_io;
+        console_printf ("Easing: bounce io\n");
+        break;
+    case 2:
+        easing_funct = circular_int_io;
+        console_printf ("Easing: circular io\n");
+        break;
+    case 3:
+        easing_funct = quadratic_int_io;
+        console_printf ("Easing: quadratic io\n");
+        break;
+    case 4:
+        easing_funct = cubic_int_io;
+        console_printf ("Easing: cubic io\n");
+        break;
+    case 5:
+        easing_funct = quartic_int_io;
+        console_printf ("Easing: quartic io\n");
+        break;
+    default:
+        easing_funct = quintic_int_io;
+        console_printf ("Easing: quintic io\n");
+    }
+
+    if (func_num > 5) {
+        func_num = 0;
+    } else {
+        func_num++;
+    }
+    rc = pwm_disable(pwm); /* Not needed but used for testing purposes. */
+    assert(rc == 0);
+
+    rc = pwm_enable(pwm);
+    assert(rc == 0);
+}
+
+int
+pwm_init(void)
+{
+    struct pwm_chan_cfg chan_conf = {
+        .pin = PWM_TEST_CH_CFG_PIN,
+        .inverted = PWM_TEST_CH_CFG_INV,
+        .data = NULL,
+    };
+    struct pwm_dev_cfg dev_conf = {
+        .n_cycles = pwm_freq * 6, /* 6 seconds cycles */
+        .int_prio = PWM_TEST_IRQ_PRIO,
+        .cycle_handler = pwm_cycle_handler, /* this won't work on soft_pwm */
+        .seq_end_handler = pwm_end_seq_handler, /* this won't work on soft_pwm */
+        .cycle_data = NULL,
+        .seq_end_data = NULL,
+        .data = NULL
+    };
+    int rc;
+
+    pwm = (struct pwm_dev *) os_dev_open(PWM_TEST_DEV, 0, NULL);
+
+    pwm_configure_device(pwm, &dev_conf);
+
+    /* set the PWM frequency */
+    pwm_set_frequency(pwm, pwm_freq);
+    top_val = (uint16_t) pwm_get_top_value(pwm);
+
+    /* setup led */
+    rc = pwm_configure_channel(pwm, PWM_TEST_CH_NUM, &chan_conf);
+    assert(rc == 0);
+
+    /* console_printf ("Easing: sine io\n"); */
+    rc = pwm_set_duty_cycle(pwm, PWM_TEST_CH_NUM, top_val);
+    rc = pwm_enable(pwm);
+    assert(rc == 0);
+
+    return rc;
+}
+
+int
+main(int argc, char **argv)
+{
+    sysinit();
+
+    pwm_init();
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    assert(0);
+    return(0);
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/sensors_test/pkg.yml b/versions/v1_5_0/mynewt-core/apps/sensors_test/pkg.yml
new file mode 100644
index 0000000..42ec83b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/sensors_test/pkg.yml
@@ -0,0 +1,58 @@
+#
+# 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/sensors_test
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/hw/sensor"
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@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/hw/sensor/creator"
+    - "@apache-mynewt-core/sys/reboot"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/ble"
+    - "@apache-mynewt-core/sys/id"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/test/flash_test"
+    - "@apache-mynewt-core/test/i2c_scan"
+
+pkg.deps.SENSOR_OIC:
+   #- mgmt/oicmgr
+
+pkg.deps.SENSOR_BLE:
+    - "@apache-mynewt-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/nimble/transport/ram"
+
+pkg.deps.CONFIG_NFFS:
+    - "@apache-mynewt-core/fs/nffs"
+
+pkg.deps.CONFIG_FCB:
+    - "@apache-mynewt-core/fs/fcb"
diff --git a/versions/v1_5_0/mynewt-core/apps/sensors_test/src/bleprph.h b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/bleprph.h
new file mode 100644
index 0000000..cacca93
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/bleprph.h
@@ -0,0 +1,50 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#ifndef H_BLEPRPH_
+#define H_BLEPRPH_
+
+#include "modlog/modlog.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);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/versions/v1_5_0/mynewt-core/apps/sensors_test/src/gatt_svr.c b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/gatt_svr.c
new file mode 100644
index 0000000..130e4df
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/gatt_svr.c
@@ -0,0 +1,63 @@
+/*
+ * 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"
+
+#if MYNEWT_VAL(SENSOR_BLE)
+
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include "bsp/bsp.h"
+#include "host/ble_hs.h"
+#include "bleprph.h"
+
+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;
+    }
+}
+
+#endif
diff --git a/versions/v1_5_0/mynewt-core/apps/sensors_test/src/main.c b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/main.c
new file mode 100644
index 0000000..7783d74
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/main.c
@@ -0,0 +1,526 @@
+/*
+ * 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 <log/log.h>
+#include <sensor/sensor.h>
+#include "flash_map/flash_map.h"
+#include <hal/hal_system.h>
+#include <assert.h>
+#include <string.h>
+#include <reboot/log_reboot.h>
+#include <id/id.h>
+
+#ifndef LED_BLINK_PIN
+#define LED_BLINK_PIN 15
+#endif
+
+#if MYNEWT_VAL(BNO055_CLI)
+#include <bno055/bno055.h>
+#endif
+#if MYNEWT_VAL(TCS34725_CLI)
+#include <tcs34725/tcs34725.h>
+#endif
+#if MYNEWT_VAL(TSL2561_CLI)
+#include <tsl2561/tsl2561.h>
+#endif
+#if MYNEWT_VAL(BMA253_CLI)
+#include <bma253/bma253.h>
+#endif
+#if MYNEWT_VAL(BMA2XX_CLI)
+#include <bma2xx/bma2xx.h>
+#endif
+#if MYNEWT_VAL(BME280_CLI)
+#include <bme280/bme280.h>
+#endif
+#if MYNEWT_VAL(BMP280_CLI)
+#include <bmp280/bmp280.h>
+#endif
+#if MYNEWT_VAL(DRV2605_CLI)
+#include <drv2605/drv2605.h>
+#endif
+#if MYNEWT_VAL(LIS2DS12_CLI)
+#include <lis2ds12/lis2ds12.h>
+#endif
+#if MYNEWT_VAL(LIS2DW12_CLI)
+#include <lis2dw12/lis2dw12.h>
+#endif
+
+#if MYNEWT_VAL(SENSOR_OIC)
+#include <oic/oc_api.h>
+#include <oic/oc_gatt.h>
+
+extern int oc_stack_errno;
+
+static const oc_handler_t sensor_oic_handler = {
+    .init = sensor_oic_init,
+};
+
+#endif
+
+#if MYNEWT_VAL(SENSOR_BLE)
+/* BLE */
+#include <nimble/ble.h>
+#include <host/ble_hs.h>
+#include <services/gap/ble_svc_gap.h>
+/* Application-specified header. */
+#include "bleprph.h"
+
+#if MYNEWT_VAL(SENSOR_OIC)
+static int sensor_oic_gap_event(struct ble_gap_event *event, void *arg);
+#endif
+
+#endif
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+/* Task 1 */
+#define TASK1_PRIO (8)
+#define TASK1_STACK_SIZE    OS_STACK_ALIGN(192)
+#define MAX_CBMEM_BUF 600
+static struct os_task task1;
+static volatile int g_task1_loops;
+
+/* Task 2 */
+#define TASK2_PRIO (9)
+#define TASK2_STACK_SIZE    OS_STACK_ALIGN(64)
+static struct os_task task2;
+static volatile int g_task2_loops;
+
+/* Global test semaphore */
+static struct os_sem g_test_sem;
+
+/* For LED toggling */
+static int g_led_pin;
+
+#if MYNEWT_VAL(SENSOR_OIC) && MYNEWT_VAL(SENSOR_BLE)
+
+/**
+ * Logs information about a connection to the console.
+ */
+static void
+sensor_oic_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 Undirected connectable mode.
+ */
+static void
+sensor_oic_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.uuids128 = (ble_uuid128_t []) {
+        BLE_UUID128_INIT(OC_GATT_UNSEC_SVC_UUID)
+    };
+    fields.num_uuids128 = 1;
+    fields.uuids128_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_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, sensor_oic_gap_event, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(ERROR, "error enabling advertisement; rc=%d\n", rc);
+        return;
+    }
+}
+
+
+static void
+sensor_oic_on_reset(int reason)
+{
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
+}
+
+static void
+sensor_oic_on_sync(void)
+{
+    /* Begin advertising. */
+    sensor_oic_advertise();
+}
+
+/**
+ * The nimble host executes this callback when a GAP event occurs.  The
+ * application associates a GAP event callback with each connection that forms.
+ * sensor_oic 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
+ *                                  sensor_oic.
+ *
+ * @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
+sensor_oic_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);
+            sensor_oic_print_conn_desc(&desc);
+        }
+        MODLOG_DFLT(INFO, "\n");
+
+        if (event->connect.status != 0) {
+            /* Connection failed; resume advertising. */
+            sensor_oic_advertise();
+        } else {
+            oc_ble_coap_conn_new(event->connect.conn_handle);
+        }
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        sensor_oic_print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        oc_ble_coap_conn_del(event->disconnect.conn.conn_handle);
+
+        /* Connection terminated; resume advertising. */
+        sensor_oic_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);
+        sensor_oic_print_conn_desc(&desc);
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+
+    case BLE_GAP_EVENT_DISC_COMPLETE:
+        MODLOG_DFLT(INFO, "discovery complete; reason=%d\n",
+                    event->disc_complete.reason);
+        return 0;
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        MODLOG_DFLT(INFO, "advertise complete; reason=%d\n",
+                    event->adv_complete.reason);
+        sensor_oic_advertise();
+        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);
+        sensor_oic_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);
+        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;
+}
+#endif
+
+static void
+task1_handler(void *arg)
+{
+    struct os_task *t;
+
+    /* Set the led pin for the E407 devboard */
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    console_printf("\nSensors Test App\n");
+
+    while (1) {
+        t = os_sched_get_current_task();
+        assert(t->t_func == task1_handler);
+
+        ++g_task1_loops;
+
+        /* Wait one second */
+        os_time_delay(OS_TICKS_PER_SEC * MYNEWT_VAL(SENSOR_OIC_OBS_RATE));
+
+        /* Toggle the LED */
+        (void)hal_gpio_toggle(g_led_pin);
+
+        /* Release semaphore to task 2 */
+        os_sem_release(&g_test_sem);
+    }
+}
+
+static void
+task2_handler(void *arg)
+{
+    struct os_task *t;
+
+    while (1) {
+        /* just for debug; task 2 should be the running task */
+        t = os_sched_get_current_task();
+        assert(t->t_func == task2_handler);
+
+        /* Increment # of times we went through task loop */
+        ++g_task2_loops;
+
+        /* Wait for semaphore from ISR */
+        os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
+    }
+}
+
+/**
+ * init_tasks
+ *
+ * Called by main.c after sysinit(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static void
+init_tasks(void)
+{
+    os_stack_t *pstack;
+
+    /* Initialize global test semaphore */
+    os_sem_init(&g_test_sem, 0);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "task1", task1_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task2, "task2", task2_handler, NULL,
+            TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
+}
+
+static void
+sensors_dev_shell_init(void)
+{
+
+#if MYNEWT_VAL(TCS34725_CLI)
+    tcs34725_shell_init();
+#endif
+
+#if MYNEWT_VAL(TSL2561_CLI)
+    tsl2561_shell_init();
+#endif
+
+#if MYNEWT_VAL(BNO055_CLI)
+    bno055_shell_init();
+#endif
+
+#if MYNEWT_VAL(BMA253_CLI)
+    bma253_shell_init();
+#endif
+#if MYNEWT_VAL(BMA2XX_CLI)
+    bma2xx_shell_init();
+#endif
+
+#if MYNEWT_VAL(BME280_CLI)
+    bme280_shell_init();
+#endif
+
+#if MYNEWT_VAL(BMP280_CLI)
+    bmp280_shell_init();
+#endif
+
+#if MYNEWT_VAL(DRV2605_CLI)
+    drv2605_shell_init();
+#endif
+
+#if MYNEWT_VAL(LIS2DS12_CLI)
+    lis2ds12_shell_init();
+#endif
+
+#if MYNEWT_VAL(LIS2DW12_CLI)
+    lis2dw12_shell_init();
+#endif
+}
+
+static void
+sensor_ble_oic_server_init(void)
+{
+#if MYNEWT_VAL(SENSOR_BLE) && MYNEWT_VAL(SENSOR_OIC)
+    int rc;
+
+    /* Set initial BLE device address. */
+    memcpy(g_dev_addr, (uint8_t[6]){0x0a, 0xfa, 0xcf, 0xac, 0xfa, 0xc0}, 6);
+
+    oc_ble_coap_gatt_srv_init();
+
+    ble_hs_cfg.reset_cb = sensor_oic_on_reset;
+    ble_hs_cfg.sync_cb = sensor_oic_on_sync;
+    ble_hs_cfg.gatts_register_cb = gatt_svr_register_cb;
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set("sn");
+    assert(rc == 0);
+
+    rc = oc_main_init((oc_handler_t *)&sensor_oic_handler);
+    assert(!rc);
+
+    oc_init_platform("MyNewt", NULL, NULL);
+    oc_add_device("/oic/d", "oic.d.sensy", "sensy", "1.0", "1.0", NULL,
+                  NULL);
+    assert(!oc_stack_errno);
+#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
+    /* Initialize OS */
+    sysinit();
+
+    /* Initialize tasks */
+    init_tasks();
+
+    /* Sensor device shell init */
+    sensors_dev_shell_init();
+
+    /* Initialize BLE OIC GATT Server */
+    sensor_ble_oic_server_init();
+
+    /* log reboot */
+    reboot_start(hal_reset_cause());
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+
+    return (0);
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/sensors_test/src/misc.c b/versions/v1_5_0/mynewt-core/apps/sensors_test/src/misc.c
new file mode 100644
index 0000000..6ed205e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/sensors_test/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 "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++) {
+        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/versions/v1_5_0/mynewt-core/apps/sensors_test/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/sensors_test/syscfg.yml
new file mode 100644
index 0000000..87a449b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/sensors_test/syscfg.yml
@@ -0,0 +1,71 @@
+# 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/sensors_test
+
+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
+
+    CONFIG_CLI: 1
+
+    # Enable shell commands.
+    STATS_CLI: 1
+    LOG_CLI: 1
+
+    # Enable newtmgr commands.
+    STATS_NEWTMGR: 0
+    LOG_NEWTMGR: 0
+    CONFIG_NEWTMGR: 0
+
+    TSL2561_CLI: 0
+    BNO055_CLI: 0
+    TCS34725_CLI: 0
+    BME280_CLI: 0
+    BMA2XX_CLI: 0
+
+    # Setup Sensor BLE OIC GATT Server
+    SENSOR_OIC: 1
+    BLE_ROLE_CENTRAL: 0
+    BLE_ROLE_OBSERVER: 0
+    OC_SERVER: 1
+
+    OC_TRANSPORT_GATT: 1
+    OC_APP_RESOURCES : 20
+
+    FLOAT_USER: 1
+    SENSOR_OIC_PERIODIC: 1
+
+syscfg.defs:
+    SENSOR_BLE:
+        description: 'BLE transport is used for sensor data'
+        value : 1
+        restrictions:
+        - BLE_ROLE_BROADCASTER
+        - '!BLE_ROLE_CENTRAL'
+        - '!BLE_ROLE_OBSERVER'
+        - BLE_ROLE_PERIPHERAL
diff --git a/versions/v1_5_0/mynewt-core/apps/slinky/pkg.yml b/versions/v1_5_0/mynewt-core/apps/slinky/pkg.yml
new file mode 100644
index 0000000..ee25b7b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/slinky/pkg.yml
@@ -0,0 +1,51 @@
+#
+# 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/slinky
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/test/flash_test"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr"
+    - "@apache-mynewt-core/mgmt/newtmgr/transport/nmgr_shell"
+    - "@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/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/boot/split"
+
+pkg.deps.I2C_0: test/i2c_scan
+pkg.deps.I2C_1: test/i2c_scan
+pkg.deps.I2C_2: test/i2c_scan
+
+pkg.deps.CONFIG_NFFS:
+    - "@apache-mynewt-core/fs/nffs"
+
+pkg.deps.CONFIG_FCB:
+    - "@apache-mynewt-core/fs/fcb"
diff --git a/versions/v1_5_0/mynewt-core/apps/slinky/src/main.c b/versions/v1_5_0/mynewt-core/apps/slinky/src/main.c
new file mode 100644
index 0000000..3cf9716
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/slinky/src/main.c
@@ -0,0 +1,291 @@
+/*
+ * 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 <shell/shell.h>
+#include <log/log.h>
+#include <stats/stats.h>
+#include <config/config.h>
+#include "flash_map/flash_map.h"
+#include <hal/hal_system.h>
+#if MYNEWT_VAL(SPLIT_LOADER)
+#include "split/split.h"
+#endif
+#include <newtmgr/newtmgr.h>
+#include <bootutil/image.h>
+#include <bootutil/bootutil.h>
+#include <imgmgr/imgmgr.h>
+#include <assert.h>
+#include <string.h>
+#include <reboot/log_reboot.h>
+#include <id/id.h>
+#include "modlog/modlog.h"
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+/* Task 1 */
+#define TASK1_PRIO (8)
+#define TASK1_STACK_SIZE    OS_STACK_ALIGN(192)
+#define MAX_CBMEM_BUF 600
+static struct os_task task1;
+static volatile int g_task1_loops;
+
+/* Task 2 */
+#define TASK2_PRIO (9)
+#define TASK2_STACK_SIZE    OS_STACK_ALIGN(64)
+static struct os_task task2;
+
+static struct log my_log;
+
+static volatile int g_task2_loops;
+
+/* Global test semaphore */
+static struct os_sem g_test_sem;
+
+/* For LED toggling */
+static int g_led_pin;
+
+STATS_SECT_START(gpio_stats)
+STATS_SECT_ENTRY(toggles)
+STATS_SECT_END
+
+static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle;
+
+static STATS_NAME_START(gpio_stats)
+STATS_NAME(gpio_stats, toggles)
+STATS_NAME_END(gpio_stats)
+
+static char *test_conf_get(int argc, char **argv, char *val, int max_len);
+static int test_conf_set(int argc, char **argv, char *val);
+static int test_conf_commit(void);
+static int test_conf_export(void (*export_func)(char *name, char *val),
+  enum conf_export_tgt tgt);
+
+static struct conf_handler test_conf_handler = {
+    .ch_name = "test",
+    .ch_get = test_conf_get,
+    .ch_set = test_conf_set,
+    .ch_commit = test_conf_commit,
+    .ch_export = test_conf_export
+};
+
+static uint8_t test8;
+static uint8_t test8_shadow;
+static char test_str[32];
+static uint32_t cbmem_buf[MAX_CBMEM_BUF];
+static struct cbmem cbmem;
+
+static char *
+test_conf_get(int argc, char **argv, char *buf, int max_len)
+{
+    if (argc == 1) {
+        if (!strcmp(argv[0], "8")) {
+            return conf_str_from_value(CONF_INT8, &test8, buf, max_len);
+        } else if (!strcmp(argv[0], "str")) {
+            return test_str;
+        }
+    }
+    return NULL;
+}
+
+static int
+test_conf_set(int argc, char **argv, char *val)
+{
+    if (argc == 1) {
+        if (!strcmp(argv[0], "8")) {
+            return CONF_VALUE_SET(val, CONF_INT8, test8_shadow);
+        } else if (!strcmp(argv[0], "str")) {
+            return CONF_VALUE_SET(val, CONF_STRING, test_str);
+        }
+    }
+    return OS_ENOENT;
+}
+
+static int
+test_conf_commit(void)
+{
+    test8 = test8_shadow;
+
+    return 0;
+}
+
+static int
+test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt)
+{
+    char buf[4];
+
+    conf_str_from_value(CONF_INT8, &test8, buf, sizeof(buf));
+    func("test/8", buf);
+    func("test/str", test_str);
+    return 0;
+}
+
+static void
+task1_handler(void *arg)
+{
+    struct os_task *t;
+    int prev_pin_state, curr_pin_state;
+    struct image_version ver;
+
+    /* Set the led pin for the E407 devboard */
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    if (imgr_my_version(&ver) == 0) {
+        console_printf("\nSlinky %u.%u.%u.%u\n",
+          ver.iv_major, ver.iv_minor, ver.iv_revision,
+          (unsigned int)ver.iv_build_num);
+    } else {
+        console_printf("\nSlinky\n");
+    }
+
+    while (1) {
+        t = os_sched_get_current_task();
+        assert(t->t_func == task1_handler);
+
+        ++g_task1_loops;
+
+        /* Wait one second */
+        os_time_delay(OS_TICKS_PER_SEC);
+
+        /* Toggle the LED */
+        prev_pin_state = hal_gpio_read(g_led_pin);
+        curr_pin_state = hal_gpio_toggle(g_led_pin);
+        MODLOG_DFLT(INFO, "GPIO toggle from %u to %u",
+                    prev_pin_state, curr_pin_state);
+        STATS_INC(g_stats_gpio_toggle, toggles);
+
+        /* Release semaphore to task 2 */
+        os_sem_release(&g_test_sem);
+    }
+}
+
+static void
+task2_handler(void *arg)
+{
+    struct os_task *t;
+
+    while (1) {
+        /* just for debug; task 2 should be the running task */
+        t = os_sched_get_current_task();
+        assert(t->t_func == task2_handler);
+
+        /* Increment # of times we went through task loop */
+        ++g_task2_loops;
+
+        /* Wait for semaphore from ISR */
+        os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
+    }
+}
+
+/**
+ * init_tasks
+ *
+ * Called by main.c after sysinit(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static void
+init_tasks(void)
+{
+    os_stack_t *pstack;
+
+    /* Initialize global test semaphore */
+    os_sem_init(&g_test_sem, 0);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "task1", task1_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task2, "task2", task2_handler, NULL,
+            TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
+}
+
+/**
+ * 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)
+{
+    int rc;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    rc = conf_register(&test_conf_handler);
+    assert(rc == 0);
+
+    cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
+    log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
+
+    /* Point the default module at the cbmem log just registered. */
+    rc = modlog_register(LOG_MODULE_DEFAULT, &my_log, LOG_LEVEL_DEBUG, NULL);
+    assert(rc == 0);
+
+    stats_init(STATS_HDR(g_stats_gpio_toggle),
+               STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32),
+               STATS_NAME_INIT_PARMS(gpio_stats));
+
+    stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle));
+
+    reboot_start(hal_reset_cause());
+
+    init_tasks();
+
+    /* 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_restart(entry);
+        }
+    }
+#endif
+
+    /*
+     * As the last thing, process events from default event queue.
+     */
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/slinky/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/slinky/syscfg.yml
new file mode 100644
index 0000000..5661efe
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/slinky/syscfg.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.
+#
+
+# Package: apps/slinky
+syscfg.defs:
+    SLINKY_LOG_MODULE_GPIO:
+        description: The log module to use for slinky GPIO messages.
+        value: 64
+
+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
+
+    # Enable newtmgr commands.
+    STATS_NEWTMGR: 1
+    LOG_NEWTMGR: 1
+    CONFIG_NEWTMGR: 1
diff --git a/versions/v1_5_0/mynewt-core/apps/slinky_oic/pkg.yml b/versions/v1_5_0/mynewt-core/apps/slinky_oic/pkg.yml
new file mode 100644
index 0000000..7442e69
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/slinky_oic/pkg.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.
+#
+
+pkg.name: apps/slinky_oic
+pkg.type: app
+pkg.description: "Example application which uses a variety of mynewt features."
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/oicmgr"
+    - "@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/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/boot/split"
+
+pkg.deps.CONFIG_NFFS:
+    - "@apache-mynewt-core/fs/nffs"
+
+pkg.deps.CONFIG_FCB:
+    - "@apache-mynewt-core/fs/fcb"
diff --git a/versions/v1_5_0/mynewt-core/apps/slinky_oic/src/main.c b/versions/v1_5_0/mynewt-core/apps/slinky_oic/src/main.c
new file mode 100644
index 0000000..25d6214
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/slinky_oic/src/main.c
@@ -0,0 +1,301 @@
+/**
+ * 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 <log/log.h>
+#include <stats/stats.h>
+#include <config/config.h>
+#if MYNEWT_VAL(SPLIT_LOADER)
+#include "split/split.h"
+#endif
+#include <bootutil/image.h>
+#include <imgmgr/imgmgr.h>
+#include <mgmt/mgmt.h>
+#include <oic/oc_api.h>
+#include <assert.h>
+#include <string.h>
+#include <reboot/log_reboot.h>
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+/* Task 1 */
+#define TASK1_PRIO (8)
+#define TASK1_STACK_SIZE    OS_STACK_ALIGN(192)
+#define MAX_CBMEM_BUF 600
+static struct os_task task1;
+static volatile int g_task1_loops;
+
+/* Task 2 */
+#define TASK2_PRIO (9)
+#define TASK2_STACK_SIZE    OS_STACK_ALIGN(64)
+static struct os_task task2;
+
+static struct log my_log;
+
+static volatile int g_task2_loops;
+
+/* Global test semaphore */
+static struct os_sem g_test_sem;
+
+/* For LED toggling */
+static int g_led_pin;
+
+STATS_SECT_START(gpio_stats)
+STATS_SECT_ENTRY(toggles)
+STATS_SECT_END
+
+static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle;
+
+static STATS_NAME_START(gpio_stats)
+STATS_NAME(gpio_stats, toggles)
+STATS_NAME_END(gpio_stats)
+
+static char *test_conf_get(int argc, char **argv, char *val, int max_len);
+static int test_conf_set(int argc, char **argv, char *val);
+static int test_conf_commit(void);
+static int test_conf_export(void (*export_func)(char *name, char *val),
+  enum conf_export_tgt tgt);
+
+static struct conf_handler test_conf_handler = {
+    .ch_name = "test",
+    .ch_get = test_conf_get,
+    .ch_set = test_conf_set,
+    .ch_commit = test_conf_commit,
+    .ch_export = test_conf_export
+};
+
+static uint8_t test8;
+static uint8_t test8_shadow;
+static char test_str[32];
+static uint32_t cbmem_buf[MAX_CBMEM_BUF];
+static struct cbmem cbmem;
+
+static char *
+test_conf_get(int argc, char **argv, char *buf, int max_len)
+{
+    if (argc == 1) {
+        if (!strcmp(argv[0], "8")) {
+            return conf_str_from_value(CONF_INT8, &test8, buf, max_len);
+        } else if (!strcmp(argv[0], "str")) {
+            return test_str;
+        }
+    }
+    return NULL;
+}
+
+static int
+test_conf_set(int argc, char **argv, char *val)
+{
+    if (argc == 1) {
+        if (!strcmp(argv[0], "8")) {
+            return CONF_VALUE_SET(val, CONF_INT8, test8_shadow);
+        } else if (!strcmp(argv[0], "str")) {
+            return CONF_VALUE_SET(val, CONF_STRING, test_str);
+        }
+    }
+    return OS_ENOENT;
+}
+
+static int
+test_conf_commit(void)
+{
+    test8 = test8_shadow;
+
+    return 0;
+}
+
+static int
+test_conf_export(void (*func)(char *name, char *val), enum conf_export_tgt tgt)
+{
+    char buf[4];
+
+    conf_str_from_value(CONF_INT8, &test8, buf, sizeof(buf));
+    func("test/8", buf);
+    func("test/str", test_str);
+    return 0;
+}
+
+void
+task1_handler(void *arg)
+{
+    struct os_task *t;
+    int prev_pin_state, curr_pin_state;
+    struct image_version ver;
+
+    /* Set the led pin for the E407 devboard */
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    if (imgr_my_version(&ver) == 0) {
+        console_printf("\nSlinky_OIC %u.%u.%u.%u\n",
+          ver.iv_major, ver.iv_minor, ver.iv_revision,
+          (unsigned int)ver.iv_build_num);
+    } else {
+        console_printf("\nSlinky\n");
+    }
+
+    while (1) {
+        t = os_sched_get_current_task();
+        assert(t->t_func == task1_handler);
+
+        ++g_task1_loops;
+
+        /* Wait one second */
+        os_time_delay(OS_TICKS_PER_SEC);
+
+        /* Toggle the LED */
+        prev_pin_state = hal_gpio_read(g_led_pin);
+        curr_pin_state = hal_gpio_toggle(g_led_pin);
+        MODLOG_DFLT(INFO, "GPIO toggle from %u to %u",
+                    prev_pin_state, curr_pin_state);
+        STATS_INC(g_stats_gpio_toggle, toggles);
+
+        /* Release semaphore to task 2 */
+        os_sem_release(&g_test_sem);
+    }
+}
+
+void
+task2_handler(void *arg)
+{
+    struct os_task *t;
+
+    while (1) {
+        /* just for debug; task 2 should be the running task */
+        t = os_sched_get_current_task();
+        assert(t->t_func == task2_handler);
+
+        /* Increment # of times we went through task loop */
+        ++g_task2_loops;
+
+        /* Wait for semaphore from ISR */
+        os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
+    }
+}
+
+/*
+ * OIC platform/resource registration.
+ */
+static void
+omgr_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 = omgr_app_init,
+};
+
+/**
+ * init_tasks
+ *
+ * Called by main.c after sysinit(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static void
+init_tasks(void)
+{
+    os_stack_t *pstack;
+    /* Initialize global test semaphore */
+    os_sem_init(&g_test_sem, 0);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "task1", task1_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task2, "task2", task2_handler, NULL,
+            TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
+
+    oc_main_init((oc_handler_t *)&omgr_oc_handler);
+}
+
+/**
+ * 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)
+{
+    int rc;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    rc = conf_register(&test_conf_handler);
+    assert(rc == 0);
+
+    cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
+    log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
+
+    /* Point the default module at the cbmem log just registered. */
+    rc = modlog_register(LOG_MODULE_DEFAULT, &my_log, LOG_LEVEL_DEBUG, NULL);
+    assert(rc == 0);
+
+    stats_init(STATS_HDR(g_stats_gpio_toggle),
+               STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32),
+               STATS_NAME_INIT_PARMS(gpio_stats));
+
+    stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle));
+
+    reboot_start(hal_reset_cause());
+
+#if MYNEWT_VAL(SPLIT_LOADER)
+    {
+        void *entry;
+        rc = split_app_go(&entry, true);
+        if(rc == 0) {
+            hal_system_start(entry);
+        }
+    }
+#endif
+
+    init_tasks();
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* Never returns */
+
+    return rc;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/slinky_oic/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/slinky_oic/syscfg.yml
new file mode 100644
index 0000000..209ba27
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/slinky_oic/syscfg.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.
+#
+
+# Package: apps/slinky
+
+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
+
+    # Enable newtmgr commands.
+    STATS_NEWTMGR: 1
+    LOG_NEWTMGR: 1
+    OC_SERVER: 1
+    OC_TRANSPORT_IP: 1
+    OC_TRANSPORT_SERIAL: 1
+
+    # Default task settings
+    OS_MAIN_STACK_SIZE: 512
diff --git a/versions/v1_5_0/mynewt-core/apps/spitest/pkg.yml b/versions/v1_5_0/mynewt-core/apps/spitest/pkg.yml
new file mode 100644
index 0000000..a59f5cc
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/spitest/pkg.yml
@@ -0,0 +1,33 @@
+#
+# 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/spitest
+pkg.type: app
+pkg.description: A board to board test for hal spi master/slave.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/config"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/stats/full"
diff --git a/versions/v1_5_0/mynewt-core/apps/spitest/src/main.c b/versions/v1_5_0/mynewt-core/apps/spitest/src/main.c
new file mode 100644
index 0000000..3374078
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/spitest/src/main.c
@@ -0,0 +1,448 @@
+/*
+ * 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 "hal/hal_gpio.h"
+#include "hal/hal_spi.h"
+#include "stats/stats.h"
+#include "config/config.h"
+#include <console/console.h>
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+/* The spi txrx callback */
+struct sblinky_spi_cb_arg
+{
+    int transfers;
+    int txlen;
+    uint32_t tx_rx_bytes;
+};
+struct sblinky_spi_cb_arg spi_cb_obj;
+void *spi_cb_arg;
+
+/* Task 1 */
+#define TASK1_PRIO (1)
+#define TASK1_STACK_SIZE    OS_STACK_ALIGN(1024)
+struct os_task task1;
+
+/* Global test semaphore */
+struct os_sem g_test_sem;
+
+/* For LED toggling */
+int g_led_pin;
+
+#define SPI_BAUDRATE 500
+
+#if MYNEWT_VAL(SPI_0_MASTER) || MYNEWT_VAL(SPI_1_MASTER) || MYNEWT_VAL(SPI_2_MASTER)
+#define SPI_MASTER 1
+#define SPI_SS_PIN  (MYNEWT_VAL(SPITEST_SS_PIN))
+#if SPI_SS_PIN < 0
+#error "SPITEST_SS_PIN must be set in the target config."
+#endif
+#define SPI_M_NUM  (MYNEWT_VAL(SPITEST_M_NUM))
+#endif
+
+#if MYNEWT_VAL(SPI_0_SLAVE) || MYNEWT_VAL(SPI_1_SLAVE) || MYNEWT_VAL(SPI_2_SLAVE)
+#define SPI_SLAVE 1
+#define SPI_S_NUM  (MYNEWT_VAL(SPITEST_S_NUM))
+#endif
+
+#if defined(SPI_MASTER) && defined(SPI_SLAVE)
+#if SPI_M_NUM == SPI_S_NUM
+#error "SPI_M_NUM and SPI_S_NUM cannot be the same."
+#endif
+#endif
+
+#ifdef SPI_MASTER
+uint8_t g_spi_tx_buf[32];
+uint8_t g_spi_last_tx_buf[32];
+uint8_t g_spi_rx_buf[32];
+uint32_t g_spi_xfr_num;
+uint8_t g_spi_null_rx;
+uint8_t g_last_tx_len;
+
+static
+void spitest_validate_last(int len)
+{
+    int i;
+    int curlen;
+    int remlen;
+    int curindex;
+    uint8_t expval;
+
+    if (g_spi_null_rx == 0) {
+        expval = 0xaa;
+        if (g_last_tx_len < len) {
+            curlen = g_last_tx_len;
+            remlen = len - g_last_tx_len;
+        } else {
+            curlen = len;
+            remlen = 0;
+        }
+        for (i = 0; i < curlen; ++i) {
+            if (g_spi_rx_buf[i] != g_spi_last_tx_buf[i]) {
+                assert(0);
+            }
+        }
+        curindex = curlen;
+        for (i = 0; i < remlen; ++i) {
+            if (g_spi_rx_buf[curindex + i] != expval) {
+                assert(0);
+            }
+        }
+    }
+}
+
+void
+sblinky_spi_irqm_handler(void *arg, int len)
+{
+    int i;
+    struct sblinky_spi_cb_arg *cb;
+
+    hal_gpio_write(SPI_SS_PIN, 1);
+
+    assert(arg == spi_cb_arg);
+    if (spi_cb_arg) {
+        cb = (struct sblinky_spi_cb_arg *)arg;
+        assert(len == cb->txlen);
+        ++cb->transfers;
+    }
+
+    /* Make sure we get back the data we expect! */
+    if (g_spi_xfr_num == 1) {
+        /* The first time we expect entire buffer to be filled with 0x88 */
+        for (i = 0; i < len; ++i) {
+            if (g_spi_rx_buf[i] != 0x88) {
+                assert(0);
+            }
+        }
+
+        /* copy current tx buf to last */
+        memcpy(g_spi_last_tx_buf, g_spi_tx_buf, len);
+    } else {
+        /* Check that we received what we last sent */
+        spitest_validate_last(len);
+    }
+    ++g_spi_xfr_num;
+}
+
+void
+sblinky_spim_cfg(int spi_num)
+{
+    struct hal_spi_settings my_spi;
+
+    my_spi.data_order = HAL_SPI_MSB_FIRST;
+    my_spi.data_mode = HAL_SPI_MODE0;
+    my_spi.baudrate = SPI_BAUDRATE;
+    my_spi.word_size = HAL_SPI_WORD_SIZE_8BIT;
+    assert(hal_spi_config(spi_num, &my_spi) == 0);
+}
+#endif
+
+#ifdef SPI_SLAVE
+uint8_t g_spi_tx_buf[32];
+uint8_t g_spi_rx_buf[32];
+uint32_t g_spi_xfr_num;
+
+void
+sblinky_spi_irqs_handler(void *arg, int len)
+{
+    struct sblinky_spi_cb_arg *cb;
+
+    assert(arg == spi_cb_arg);
+    if (spi_cb_arg) {
+        cb = (struct sblinky_spi_cb_arg *)arg;
+        ++cb->transfers;
+        cb->tx_rx_bytes += len;
+        cb->txlen = len;
+    }
+
+    /* Post semaphore to task waiting for SPI slave */
+    os_sem_release(&g_test_sem);
+}
+
+void
+sblinky_spis_cfg(int spi_num)
+{
+    struct hal_spi_settings my_spi;
+
+    my_spi.data_order = HAL_SPI_MSB_FIRST;
+    my_spi.data_mode = HAL_SPI_MODE0;
+    my_spi.baudrate =  SPI_BAUDRATE;
+    my_spi.word_size = HAL_SPI_WORD_SIZE_8BIT;
+    assert(hal_spi_config(spi_num, &my_spi) == 0);
+    hal_spi_set_txrx_cb(spi_num, sblinky_spi_irqs_handler, spi_cb_arg);
+}
+#endif
+
+#ifdef SPI_MASTER
+void
+spim_task_handler(void *arg)
+{
+    int i;
+    int rc;
+    uint16_t rxval;
+    uint8_t last_val;
+    uint8_t spi_nb_cntr;
+    uint8_t spi_b_cntr;
+
+    /* Set the led pin */
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    /* Use SS pin for testing */
+    hal_gpio_init_out(SPI_SS_PIN, 1);
+    sblinky_spim_cfg(SPI_M_NUM);
+    hal_spi_set_txrx_cb(SPI_M_NUM, NULL, NULL);
+    hal_spi_enable(SPI_M_NUM);
+
+    /*
+     * Send some bytes in a non-blocking manner to SPI using tx val. The
+     * slave should send back 0x77.
+     */
+    g_spi_tx_buf[0] = 0xde;
+    g_spi_tx_buf[1] = 0xad;
+    g_spi_tx_buf[2] = 0xbe;
+    g_spi_tx_buf[3] = 0xef;
+    hal_gpio_write(SPI_SS_PIN, 0);
+    for (i = 0; i < 4; ++i) {
+        rxval = hal_spi_tx_val(SPI_M_NUM, g_spi_tx_buf[i]);
+        assert(rxval == 0x77);
+        g_spi_rx_buf[i] = (uint8_t)rxval;
+    }
+    hal_gpio_write(SPI_SS_PIN, 1);
+    ++g_spi_xfr_num;
+
+    /* Set up the callback to use when non-blocking API used */
+    hal_spi_disable(SPI_M_NUM);
+    spi_cb_arg = &spi_cb_obj;
+    spi_cb_obj.txlen = 32;
+    hal_spi_set_txrx_cb(SPI_M_NUM, sblinky_spi_irqm_handler, spi_cb_arg);
+    hal_spi_enable(SPI_M_NUM);
+    spi_nb_cntr = 0;
+    spi_b_cntr = 0;
+
+    while (1) {
+        /* Wait one second */
+        os_time_delay(OS_TICKS_PER_SEC);
+
+        /* Toggle the LED */
+        hal_gpio_toggle(g_led_pin);
+
+        /* Get random length to send */
+        g_last_tx_len = spi_cb_obj.txlen;
+        spi_cb_obj.txlen = (rand() & 0x1F) + 1;
+        memcpy(g_spi_last_tx_buf, g_spi_tx_buf, g_last_tx_len);
+        last_val = g_spi_last_tx_buf[g_last_tx_len - 1];
+        for (i= 0; i < spi_cb_obj.txlen; ++i) {
+            g_spi_tx_buf[i] = (uint8_t)(last_val + i);
+        }
+
+        if (g_spi_xfr_num & 1) {
+            /* Send non-blocking */
+            ++spi_nb_cntr;
+            assert(hal_gpio_read(SPI_SS_PIN) == 1);
+            hal_gpio_write(SPI_SS_PIN, 0);
+#if 0
+            if (spi_nb_cntr == 7) {
+                g_spi_null_rx = 1;
+                rc = hal_spi_txrx_noblock(SPI_M_NUM, g_spi_tx_buf, NULL, 32);
+            } else {
+                g_spi_null_rx = 0;
+                rc = hal_spi_txrx_noblock(SPI_M_NUM, g_spi_tx_buf, g_spi_rx_buf, 32);
+            }
+            assert(!rc);
+#else
+            g_spi_null_rx = 0;
+            rc = hal_spi_txrx_noblock(SPI_M_NUM, g_spi_tx_buf, g_spi_rx_buf,
+                                      spi_cb_obj.txlen);
+            assert(!rc);
+            console_printf("a transmitted: ");
+            for (i = 0; i < spi_cb_obj.txlen; i++) {
+                console_printf("%2x ", g_spi_tx_buf[i]);
+            }
+            console_printf("\n");
+            console_printf("received: ");
+            for (i = 0; i < spi_cb_obj.txlen; i++) {
+                console_printf("%2x ", g_spi_rx_buf[i]);
+            }
+            console_printf("\n");
+#endif
+        } else {
+            /* Send blocking */
+            ++spi_b_cntr;
+            assert(hal_gpio_read(SPI_SS_PIN) == 1);
+            hal_gpio_write(SPI_SS_PIN, 0);
+#if 0
+            if (spi_b_cntr == 7) {
+                g_spi_null_rx = 1;
+                rc = hal_spi_txrx(SPI_M_NUM, g_spi_tx_buf, NULL, 32);
+                spi_b_cntr = 0;
+            } else {
+                g_spi_null_rx = 0;
+                rc = hal_spi_txrx(SPI_M_NUM, g_spi_tx_buf, g_spi_rx_buf, 32);
+            }
+            assert(!rc);
+            hal_gpio_write(SPI_SS_PIN, 1);
+            spitest_validate_last(spi_cb_obj.txlen);
+#else
+            rc = hal_spi_txrx(SPI_M_NUM, g_spi_tx_buf, g_spi_rx_buf, spi_cb_obj.txlen);
+            assert(!rc);
+            hal_gpio_write(SPI_SS_PIN, 1);
+            console_printf("b transmitted: ");
+            for (i = 0; i < spi_cb_obj.txlen; i++) {
+                console_printf("%2x ", g_spi_tx_buf[i]);
+            }
+            console_printf("\n");
+            console_printf("received: ");
+            for (i = 0; i < spi_cb_obj.txlen; i++) {
+                console_printf("%2x ", g_spi_rx_buf[i]);
+            }
+            console_printf("\n");
+            spitest_validate_last(spi_cb_obj.txlen);
+            ++g_spi_xfr_num;
+#endif
+        }
+    }
+}
+#endif
+
+#ifdef SPI_SLAVE
+int prev_len;
+uint8_t prev_buf[32];
+
+void
+spis_task_handler(void *arg)
+{
+    int rc;
+
+    /* Set the led pin for the E407 devboard */
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    spi_cb_arg = &spi_cb_obj;
+    sblinky_spis_cfg(SPI_S_NUM);
+    hal_spi_enable(SPI_S_NUM);
+
+    /* Make the default character 0x77 */
+    hal_spi_slave_set_def_tx_val(SPI_S_NUM, 0x77);
+
+    /*
+     * Fill buffer with 0x77 for first transfer. This should be a 0xdeadbeef
+     * transfer from master to start things off
+     */
+    memset(g_spi_tx_buf, 0x77, 32);
+    rc = hal_spi_txrx_noblock(SPI_S_NUM, g_spi_tx_buf, g_spi_rx_buf, 32);
+
+    while (1) {
+        /* Wait for semaphore from ISR */
+        os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
+
+        if (g_spi_xfr_num == 0) {
+            /* Since we dont know what master will send, we fill 0x88 */
+            memset(g_spi_tx_buf, 0x88, 32);
+            rc = hal_spi_txrx_noblock(SPI_S_NUM, g_spi_tx_buf, g_spi_rx_buf,
+                                      32);
+            assert(rc == 0);
+        } else {
+            /* transmit back what we just received */
+            memcpy(prev_buf, g_spi_tx_buf, 32);
+            memset(g_spi_tx_buf, 0xaa, 32);
+            memcpy(g_spi_tx_buf, g_spi_rx_buf, spi_cb_obj.txlen);
+            rc = hal_spi_txrx_noblock(SPI_S_NUM, g_spi_tx_buf, g_spi_rx_buf,
+                                      32);
+            assert(rc == 0);
+        }
+        ++g_spi_xfr_num;
+
+        /* Toggle the LED */
+        hal_gpio_toggle(g_led_pin);
+    }
+}
+#endif
+
+/**
+ * init_tasks
+ *
+ * Called by main.c after sysinit(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static void
+init_tasks(void)
+{
+    os_stack_t *pstack;
+
+    (void)pstack;
+
+    /* Initialize global test semaphore */
+    os_sem_init(&g_test_sem, 0);
+
+#if defined(SPI_MASTER)
+    pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "spim", spim_task_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+#endif
+
+#if defined(SPI_SLAVE)
+    pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "spis", spis_task_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+#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)
+{
+    int rc;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+    init_tasks();
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* Never returns */
+    assert(0);
+
+    return rc;
+}
+
diff --git a/versions/v1_5_0/mynewt-core/apps/spitest/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/spitest/syscfg.yml
new file mode 100644
index 0000000..f1de4b3
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/spitest/syscfg.yml
@@ -0,0 +1,38 @@
+# 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/spitest
+
+syscfg.defs:
+    SPITEST_SS_PIN:
+        description: 'SPI slave select pin number'
+        value:  -1
+
+    SPITEST_M_NUM:
+        description: 'SPI peripheral number to use for master'
+        value: 0
+
+    SPITEST_S_NUM:
+        description: 'SPI peripheral number to use for slave'
+        value: 0
+
+syscfg.vals:
+    SHELL_TASK: 0
+
+    # Default task settings
+    OS_MAIN_STACK_SIZE: 512
diff --git a/versions/v1_5_0/mynewt-core/apps/splitty/README.md b/versions/v1_5_0/mynewt-core/apps/splitty/README.md
new file mode 100644
index 0000000..8be3e25
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/splitty/README.md
@@ -0,0 +1,55 @@
+<!--
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+#  KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+-->
+
+
+<img src="http://mynewt.apache.org/img/logo.svg" width="250" alt="Apache Mynewt">
+
+## Overview
+
+`apps/splitty` is an example split application.  It can be paired with slinky to form an application.
+
+## Split Image
+
+Split applications allow the user to build the application content separate from the library content by splitting an application into two pieces:
+
+* A "loader" which contains a separate application that can perform upgrades and manage split images
+* A "split app" which contains the main application content and references the libraries in the loader by static linkage
+
+See [split image architecture](http://mynewt.apache.org/latest/os/modules/split/split/) for the details of split image design.
+
+## Contents
+
+splitty is just a simply app that has newtmgr, shell and blinkys the LED at a differernt rate than slinky, so its visually evident that its running.
+
+## Usage
+
+You can use splitty as part of a split app by setting up your target.
+
+```
+targets/app
+    app=@apache-mynewt-core/apps/splitty
+    loader=@apache-mynewt-core/apps/slinky
+    bsp=@apache-mynewt-core/hw/bsp/nordic_pca10040
+    build_profile=optimized
+```
+
+
+
diff --git a/versions/v1_5_0/mynewt-core/apps/splitty/pkg.yml b/versions/v1_5_0/mynewt-core/apps/splitty/pkg.yml
new file mode 100644
index 0000000..06602f2
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/splitty/pkg.yml
@@ -0,0 +1,41 @@
+#
+# 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/splitty
+pkg.type: app
+pkg.description: "Example application which runs as a split app."
+pkg.author: "Apache Mynewt <dev@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/boot/split_app"
+    - "@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/log/modlog"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/stats/full"
diff --git a/versions/v1_5_0/mynewt-core/apps/splitty/src/main.c b/versions/v1_5_0/mynewt-core/apps/splitty/src/main.c
new file mode 100644
index 0000000..04eab29
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/splitty/src/main.c
@@ -0,0 +1,208 @@
+/*
+ * 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 <hal/hal_gpio.h>
+#include <hal/hal_flash.h>
+#include <console/console.h>
+#include <shell/shell.h>
+#include <modlog/modlog.h>
+#include <stats/stats.h>
+#include <config/config.h>
+#include <flash_map/flash_map.h>
+#include <hal/hal_system.h>
+#include <newtmgr/newtmgr.h>
+#include <bootutil/image.h>
+#include <bootutil/bootutil.h>
+#include <imgmgr/imgmgr.h>
+#include <reboot/log_reboot.h>
+#include <id/id.h>
+
+#ifdef ARCH_sim
+#include <mcu/mcu_sim.h>
+#endif
+
+/* Task 1 */
+#define TASK1_PRIO (8)
+#define TASK1_STACK_SIZE    OS_STACK_ALIGN(128)
+#define MAX_CBMEM_BUF 300
+static struct os_task task1;
+static volatile int g_task1_loops;
+
+/* Task 2 */
+#define TASK2_PRIO (9)
+#define TASK2_STACK_SIZE    OS_STACK_ALIGN(32)
+static struct os_task task2;
+
+static struct log my_log;
+
+static volatile int g_task2_loops;
+
+/* Global test semaphore */
+static struct os_sem g_test_sem;
+
+/* For LED toggling */
+static int g_led_pin;
+
+STATS_SECT_START(gpio_stats)
+STATS_SECT_ENTRY(toggles)
+STATS_SECT_END
+
+static STATS_SECT_DECL(gpio_stats) g_stats_gpio_toggle;
+
+STATS_NAME_START(gpio_stats)
+STATS_NAME(gpio_stats, toggles)
+STATS_NAME_END(gpio_stats)
+
+static uint32_t cbmem_buf[MAX_CBMEM_BUF];
+static struct cbmem cbmem;
+
+static void
+task1_handler(void *arg)
+{
+    struct os_task *t;
+    int prev_pin_state, curr_pin_state;
+    struct image_version ver;
+
+    /* Set the led pin for the E407 devboard */
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    if (imgr_my_version(&ver) == 0) {
+        console_printf("\nSplitty %u.%u.%u.%u\n",
+          ver.iv_major, ver.iv_minor, ver.iv_revision,
+          (unsigned int)ver.iv_build_num);
+    } else {
+        console_printf("\nSplitty\n");
+    }
+
+    while (1) {
+        t = os_sched_get_current_task();
+        assert(t->t_func == task1_handler);
+
+        ++g_task1_loops;
+
+        /* Wait one second */
+        os_time_delay(OS_TICKS_PER_SEC/4);
+
+        /* Toggle the LED */
+        prev_pin_state = hal_gpio_read(g_led_pin);
+        curr_pin_state = hal_gpio_toggle(g_led_pin);
+        MODLOG_INFO(LOG_MODULE_DEFAULT, "GPIO toggle from %u to %u",
+                    prev_pin_state, curr_pin_state);
+        STATS_INC(g_stats_gpio_toggle, toggles);
+
+        /* Release semaphore to task 2 */
+        os_sem_release(&g_test_sem);
+    }
+}
+
+static void
+task2_handler(void *arg)
+{
+    struct os_task *t;
+
+    while (1) {
+        /* just for debug; task 2 should be the running task */
+        t = os_sched_get_current_task();
+        assert(t->t_func == task2_handler);
+
+        /* Increment # of times we went through task loop */
+        ++g_task2_loops;
+
+        /* Wait for semaphore from ISR */
+        os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
+    }
+}
+
+/**
+ * init_tasks
+ *
+ * Called by main.c after sysinit(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static void
+init_tasks(void)
+{
+    os_stack_t *pstack;
+
+    /* Initialize global test semaphore */
+    os_sem_init(&g_test_sem, 0);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "task1", task1_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+
+    pstack = malloc(sizeof(os_stack_t)*TASK2_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task2, "task2", task2_handler, NULL,
+            TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
+
+}
+
+/**
+ * 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)
+{
+    int rc;
+
+#ifdef ARCH_sim
+    mcu_sim_parse_args(argc, argv);
+#endif
+
+    sysinit();
+
+    cbmem_init(&cbmem, cbmem_buf, MAX_CBMEM_BUF);
+    log_register("log", &my_log, &log_cbmem_handler, &cbmem, LOG_SYSLEVEL);
+
+    rc = modlog_register(LOG_MODULE_DEFAULT, &my_log, LOG_LEVEL_DEBUG, NULL);
+    assert(rc == 0);
+
+    stats_init(STATS_HDR(g_stats_gpio_toggle),
+               STATS_SIZE_INIT_PARMS(g_stats_gpio_toggle, STATS_SIZE_32),
+               STATS_NAME_INIT_PARMS(gpio_stats));
+
+    stats_register("gpio_toggle", STATS_HDR(g_stats_gpio_toggle));
+
+    reboot_start(hal_reset_cause());
+
+    init_tasks();
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* Never exit */
+    return rc;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/splitty/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/splitty/syscfg.yml
new file mode 100644
index 0000000..cd2ece7
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/splitty/syscfg.yml
@@ -0,0 +1,30 @@
+# 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/splitty
+
+syscfg.vals:
+    # Enable the shell task.
+    SHELL_TASK: 1
+
+    # Include names for statistics.
+    STATS_NAMES: 1
+
+    # Log reboot messages to a flash circular buffer.
+    LOG_FCB: 1
+    REBOOT_LOG_FCB: 1
diff --git a/versions/v1_5_0/mynewt-core/apps/testbench/pkg.yml b/versions/v1_5_0/mynewt-core/apps/testbench/pkg.yml
new file mode 100644
index 0000000..b2237e9
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/testbench/pkg.yml
@@ -0,0 +1,61 @@
+#
+# 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/testbench
+pkg.type: app
+pkg.description: target test suite for high-level mynewt OS functionality
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/boot/bootutil"
+    - "@apache-mynewt-core/boot/split_app"
+    - "@apache-mynewt-core/encoding/json/test"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/kernel/os/test"
+    - "@apache-mynewt-core/mgmt/imgmgr"
+    - "@apache-mynewt-core/mgmt/oicmgr"
+    - "@apache-mynewt-core/sys/config"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/sys/flash_map"
+    - "@apache-mynewt-core/sys/flash_map/test"
+    - "@apache-mynewt-core/sys/id"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/log/modlog"
+    - "@apache-mynewt-core/sys/stats/full"
+    - "@apache-mynewt-core/test/crash_test"
+    - "@apache-mynewt-core/test/runtest"
+    - "@apache-mynewt-core/test/testutil"
+
+pkg.deps.TESTBENCH_BLE:
+    - "@apache-mynewt-nimble/nimble/controller"
+    - "@apache-mynewt-nimble/nimble/host"
+    - "@apache-mynewt-nimble/nimble/host/services/gap"
+    - "@apache-mynewt-nimble/nimble/host/services/gatt"
+    - "@apache-mynewt-nimble/nimble/host/store/ram"
+    - "@apache-mynewt-nimble/nimble/transport/ram"
+
+pkg.deps.CONFIG_NFFS:
+    - "@apache-mynewt-core/fs/nffs"
+    - "@apache-mynewt-core/fs/nffs/test"
+
+pkg.deps.CONFIG_FCB:
+    - "@apache-mynewt-core/fs/fcb"
+    - "@apache-mynewt-core/fs/fcb/test"
diff --git a/versions/v1_5_0/mynewt-core/apps/testbench/src/tbb.c b/versions/v1_5_0/mynewt-core/apps/testbench/src/tbb.c
new file mode 100644
index 0000000..eb1fc9a
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/testbench/src/tbb.c
@@ -0,0 +1,277 @@
+/*
+ * 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.
+ */
+
+/** tbb - test bench BLE. */
+
+#include "os/mynewt.h"
+
+#if MYNEWT_VAL(TESTBENCH_BLE)
+
+#include <assert.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include "bsp/bsp.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"
+#include "modlog/modlog.h"
+
+/* BLE */
+#include "nimble/ble.h"
+#include "host/ble_hs.h"
+#include "services/gap/ble_svc_gap.h"
+
+#include "oic/oc_gatt.h"
+
+#include "tbb.h"
+
+static int tbb_gap_event(struct ble_gap_event *event, void *arg);
+
+void
+tbb_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]);
+}
+
+/**
+ * Logs information about a connection to the console.
+ */
+static void
+tbb_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);
+    tbb_print_addr(desc->our_ota_addr.val);
+    MODLOG_DFLT(INFO, " our_id_addr_type=%d our_id_addr=",
+                desc->our_id_addr.type);
+    tbb_print_addr(desc->our_id_addr.val);
+    MODLOG_DFLT(INFO, " peer_ota_addr_type=%d peer_ota_addr=",
+                desc->peer_ota_addr.type);
+    tbb_print_addr(desc->peer_ota_addr.val);
+    MODLOG_DFLT(INFO, " peer_id_addr_type=%d peer_id_addr=",
+                desc->peer_id_addr.type);
+    tbb_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 Undirected connectable mode.
+ */
+static void
+tbb_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(OC_GATT_SEC_SVC_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_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, tbb_gap_event, NULL);
+    if (rc != 0) {
+        MODLOG_DFLT(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.
+ * tbb 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
+ *                                  tbb.
+ *
+ * @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
+tbb_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);
+            tbb_print_conn_desc(&desc);
+        }
+        MODLOG_DFLT(INFO, "\n");
+
+        /* Try to advertise again. */
+        tbb_advertise();
+
+        return 0;
+
+    case BLE_GAP_EVENT_DISCONNECT:
+        MODLOG_DFLT(INFO, "disconnect; reason=%d ", event->disconnect.reason);
+        tbb_print_conn_desc(&event->disconnect.conn);
+        MODLOG_DFLT(INFO, "\n");
+
+        /* Connection terminated; resume advertising. */
+        tbb_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);
+        tbb_print_conn_desc(&desc);
+        MODLOG_DFLT(INFO, "\n");
+        return 0;
+
+    case BLE_GAP_EVENT_ADV_COMPLETE:
+        MODLOG_DFLT(INFO, "advertise complete; reason=%d\n",
+                    event->adv_complete.reason);
+        tbb_advertise();
+        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);
+        tbb_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);
+        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
+tbb_on_reset(int reason)
+{
+    MODLOG_DFLT(ERROR, "Resetting state; reason=%d\n", reason);
+}
+
+static void
+tbb_on_sync(void)
+{
+    /* Begin advertising. */
+    tbb_advertise();
+}
+
+void
+tbb_init(void)
+{
+    int rc;
+
+    /* Initialize the NimBLE host configuration. */
+    ble_hs_cfg.reset_cb = tbb_on_reset;
+    ble_hs_cfg.sync_cb = tbb_on_sync;
+
+    /* Set the default device name. */
+    rc = ble_svc_gap_device_name_set(MYNEWT_VAL(TESTBENCH_BLE_NAME));
+    assert(rc == 0);
+}
+
+#endif
diff --git a/versions/v1_5_0/mynewt-core/apps/testbench/src/tbb.h b/versions/v1_5_0/mynewt-core/apps/testbench/src/tbb.h
new file mode 100644
index 0000000..3d59124
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/testbench/src/tbb.h
@@ -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.
+ */
+
+#ifndef H_TBB_
+#define H_TBB_
+
+#include "os/mynewt.h"
+
+#if MYNEWT_VAL(TESTBENCH_BLE)
+
+#include "nimble/ble.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+void tbb_init(void);
+
+#else
+#define tbb_init()
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/versions/v1_5_0/mynewt-core/apps/testbench/src/testbench.c b/versions/v1_5_0/mynewt-core/apps/testbench/src/testbench.c
new file mode 100644
index 0000000..452bd4e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/testbench/src/testbench.c
@@ -0,0 +1,180 @@
+/**
+ * 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>
+#if MYNEWT_VAL(SHELL_TASK)
+#include <shell/shell.h>
+#endif
+#include <log/log.h>
+#include <modlog/modlog.h>
+#include <stats/stats.h>
+#include <config/config.h>
+#include "flash_map/flash_map.h"
+#include <hal/hal_system.h>
+#if MYNEWT_VAL(SPLIT_LOADER)
+#include "split/split.h"
+#endif
+#include <bootutil/image.h>
+#include <bootutil/bootutil.h>
+#include <imgmgr/imgmgr.h>
+#include <assert.h>
+#include <string.h>
+#include <json/json.h>
+#include <reboot/log_reboot.h>
+#include <id/id.h>
+#include <oic/oc_api.h>
+#include <oic/oc_gatt.h>
+#include "json_test/json_test.h"
+#include "os_test/os_test.h"
+
+#include "testutil/testutil.h"
+
+#if MYNEWT_VAL(CONFIG_NFFS)
+#include <fs/fs.h>
+#include <nffs/nffs.h>
+#include "nffs/nffs_test.h"
+#endif /* NFFS */
+
+#if MYNEWT_VAL(CONFIG_FCB)
+#include <fcb/fcb.h>
+/*#include "../fcb/fcb_test.h"*/
+#endif /* FCB */
+
+#include "bootutil/bootutil_test.h"
+
+#include <stddef.h>
+#include <config/config_file.h>
+#include "mbedtls/mbedtls_test.h"
+
+#if MYNEWT_VAL(RUNTEST_CLI)
+#include "runtest/runtest.h"
+#endif
+#include "tbb.h"
+
+struct os_timeval tv;
+struct os_timezone tz;
+
+/* Test Task */
+#define TESTTASK_PRIO (1)
+#define TESTTASK_STACK_SIZE    OS_STACK_ALIGN(256)
+static struct os_task testtask;
+
+/* For LED toggling */
+int g_led_pin;
+
+int blinky_blink;
+
+#define BLINKY_DUTYCYCLE_SUCCESS 1
+#define BLINKY_DUTYCYCLE_FAIL 16
+
+OS_TASK_STACK_DEFINE(teststack, TESTTASK_STACK_SIZE);
+
+void
+testbench_test_init(void)
+{
+    blinky_blink = BLINKY_DUTYCYCLE_SUCCESS;
+}
+
+/*
+ * Run the tests
+ * If any tests fail, blink the LED BLINKY_DUTYCYCLE_FAIL (16) times a second
+ */
+static void
+testtask_handler(void *arg)
+{
+    os_gettimeofday(&tv, &tz);
+
+    g_led_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led_pin, 1);
+
+    while (1) {
+        /*
+         * if any test fails, blinky the LED more rapidly to
+         * provide visual feedback from physical device.
+         */
+        if (runtest_total_fails_get() > 0) {
+            blinky_blink = BLINKY_DUTYCYCLE_FAIL;
+        }
+
+        /* Wait one second */
+        os_time_delay(OS_TICKS_PER_SEC / blinky_blink);
+
+        /* Toggle the LED */
+        hal_gpio_toggle(g_led_pin);
+    }
+}
+
+static void
+omgr_app_init(void)
+{ }
+
+static const oc_handler_t omgr_oc_handler = {
+    .init = omgr_app_init,
+};
+
+/*
+ * main()
+ * Keep this app simple, just run the tests and then report success or failure.
+ * Complexity is pushed down to the individual test suites and component test cases.
+ */
+int
+main(int argc, char **argv)
+{
+    int rc;
+
+    sysinit();
+
+    /* Initialize the OIC  */
+    oc_main_init((oc_handler_t *)&omgr_oc_handler);
+
+#if MYNEWT_VAL(TESTBENCH_BLE)
+    tbb_init();
+    oc_ble_coap_gatt_srv_init();
+#endif
+
+    reboot_start(hal_reset_cause());
+
+    /*
+     * Register the tests that can be run by lookup
+     * - each test is added to the ts_suites slist
+     */
+    TEST_SUITE_REGISTER(os_mempool_test_suite);
+    TEST_SUITE_REGISTER(os_mutex_test_suite);
+    TEST_SUITE_REGISTER(os_sem_test_suite);
+    TEST_SUITE_REGISTER(test_json_suite);
+
+    testbench_test_init(); /* initialize globals include blink duty cycle */
+
+    os_task_init(&testtask, "testtask", testtask_handler, NULL,
+                 TESTTASK_PRIO, OS_WAIT_FOREVER, teststack,
+                 TESTTASK_STACK_SIZE);
+
+    MODLOG_INFO(LOG_MODULE_TEST, "testbench app initialized");
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    assert(0);
+
+    return rc;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/testbench/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/testbench/syscfg.yml
new file mode 100644
index 0000000..80e5616
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/testbench/syscfg.yml
@@ -0,0 +1,73 @@
+# 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/testbench
+
+syscfg.defs:
+    TESTBENCH_BLE:
+        description: Enables BLE support in the testbench app.
+        value: 0
+
+    TESTBENCH_BLE_NAME:
+        description: The BLE name to use.
+        value: '"testbench-ble"'
+
+syscfg.vals:
+    # Enable the shell task.
+    SHELL_TASK: 1
+
+    # Include names for statistics.
+    STATS_NAMES: 1
+    STATS_CLI: 1
+    STATS_NEWTMGR: 1
+
+    # Log reboot messages to a flash circular buffer.
+    REBOOT_LOG_FCB: 1
+    LOG_FCB: 1
+
+    # Enable coredump
+    OS_COREDUMP: 1
+    IMGMGR_COREDUMP: 1
+
+    CONFIG_FCB: 1
+
+    # Enable shell commands.
+    LOG_CLI: 1
+    CONFIG_CLI: 1
+
+    # Enable newtmgr commands.
+    LOG_NEWTMGR: 1
+    CONFIG_NEWTMGR: 1
+
+    RUNTEST_LOG: 1
+    RUNTEST_CLI: 1
+    RUNTEST_NEWTMGR: 1
+
+    CRASH_TEST_CLI: 1
+    IMGMGR_CLI: 1
+
+    # Default task settings
+    OS_MAIN_STACK_SIZE: 768
+
+    # OC server, with serial transport.
+    OC_SERVER: 1
+    OC_TRANSPORT_SERIAL: 1
+
+    # Optionally add OC BLE transport.
+syscfg.vals.TESTBENCH_BLE:
+    OC_TRANSPORT_GATT: 1
diff --git a/versions/v1_5_0/mynewt-core/apps/timtest/pkg.yml b/versions/v1_5_0/mynewt-core/apps/timtest/pkg.yml
new file mode 100644
index 0000000..706343b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/timtest/pkg.yml
@@ -0,0 +1,33 @@
+#
+# 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/timtest
+pkg.type: app
+pkg.description: board test code for hal timer.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/shell"
+    - "@apache-mynewt-core/sys/config"
+    - "@apache-mynewt-core/sys/log/full"
+    - "@apache-mynewt-core/sys/stats/full"
diff --git a/versions/v1_5_0/mynewt-core/apps/timtest/src/main.c b/versions/v1_5_0/mynewt-core/apps/timtest/src/main.c
new file mode 100644
index 0000000..fe9d0be
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/timtest/src/main.c
@@ -0,0 +1,207 @@
+/*
+ * 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 "hal/hal_gpio.h"
+#include "hal/hal_timer.h"
+#include "stats/stats.h"
+#include "config/config.h"
+
+/* Task 1 */
+#define TASK1_PRIO (1)
+#define TASK1_STACK_SIZE    OS_STACK_ALIGN(64)
+struct os_task task1;
+
+#define TASK1_TIMER_NUM     (1)
+#define TASK1_TIMER_FREQ    (4000000)
+
+/* Task 2 */
+#define TASK2_PRIO (2)
+#define TASK2_STACK_SIZE    OS_STACK_ALIGN(64)
+struct os_task task2;
+
+#define TASK2_TIMER_NUM     (2)
+#define TASK2_TIMER_FREQ    (31250)
+
+/* For LED toggling */
+int g_led1_pin;
+int g_led2_pin;
+struct os_sem g_test_sem;
+
+struct hal_timer g_task1_timer;
+uint32_t task1_timer_arg = 0xdeadc0de;
+uint32_t g_task1_loops;
+
+void
+task1_timer_cb(void *arg)
+{
+    uint32_t timer_arg_val;
+
+    timer_arg_val = *(uint32_t *)arg;
+    assert(timer_arg_val == 0xdeadc0de);
+
+    os_sem_release(&g_test_sem);
+}
+
+void
+task1_handler(void *arg)
+{
+    int rc;
+    uint32_t timer_cntr;
+
+    /* Task 1 toggles LED 1 (LED_BLINK_PIN) */
+    g_led1_pin = LED_BLINK_PIN;
+    hal_gpio_init_out(g_led1_pin, 1);
+
+    hal_timer_set_cb(TASK1_TIMER_NUM, &g_task1_timer, task1_timer_cb,
+                     &task1_timer_arg);
+
+    g_task1_loops = 0;
+    rc = hal_timer_start(&g_task1_timer, TASK1_TIMER_FREQ);
+    assert(rc == 0);
+
+    while (1) {
+        /* Wait for semaphore from ISR */
+        os_sem_pend(&g_test_sem, OS_TIMEOUT_NEVER);
+
+        /* Toggle the LED */
+        hal_gpio_toggle(g_led1_pin);
+
+        ++g_task1_loops;
+        if (g_task1_loops & 1) {
+            timer_cntr = hal_timer_read(TASK1_TIMER_NUM);
+            hal_timer_start_at(&g_task1_timer, timer_cntr + TASK1_TIMER_FREQ);
+            if ((g_task1_loops % 10) == 0) {
+                hal_timer_stop(&g_task1_timer);
+                os_sem_release(&g_test_sem);
+            }
+        } else {
+            hal_timer_start(&g_task1_timer, TASK1_TIMER_FREQ);
+            if ((g_task1_loops % 10) == 0) {
+                hal_timer_stop(&g_task1_timer);
+                os_sem_release(&g_test_sem);
+            }
+        }
+    }
+}
+
+void
+task2_handler(void *arg)
+{
+    int cntr;
+    int32_t delta;
+    uint32_t tval1;
+    uint32_t tval2;
+
+    g_led2_pin = LED_2;
+    hal_gpio_init_out(g_led2_pin, 1);
+
+    cntr = 8;
+    while (1) {
+        /* Read timer, block for 500 msecs, make sure timer counter counts! */
+        tval1 = hal_timer_read(TASK2_TIMER_NUM);
+        hal_timer_delay(TASK2_TIMER_NUM, TASK2_TIMER_FREQ / 2);
+        tval2 = hal_timer_read(TASK2_TIMER_NUM);
+        delta = (int32_t)(tval2 - tval1);
+        assert(delta > (int)(TASK2_TIMER_FREQ / 2));
+
+        /* Toggle LED2 */
+        hal_gpio_toggle(g_led2_pin);
+
+        /* We want to wait to hit watchdog so delay every now and then */
+        --cntr;
+        if (cntr == 0) {
+            os_time_delay(OS_TICKS_PER_SEC);
+            cntr = 8;
+        }
+    }
+}
+
+/**
+ * init_tasks
+ *
+ * Called by main.c after sysinit(). This function performs initializations
+ * that are required before tasks are running.
+ *
+ * @return int 0 success; error otherwise.
+ */
+static void
+init_tasks(void)
+{
+    int rc;
+    uint32_t res;
+    os_stack_t *pstack;
+
+    /* Initialize global test semaphore */
+    os_sem_init(&g_test_sem, 0);
+
+    /* Initialize timer 0 to count at 1 MHz */
+    rc = hal_timer_config(TASK1_TIMER_NUM, TASK1_TIMER_FREQ);
+    assert(rc == 0);
+
+    res = hal_timer_get_resolution(TASK1_TIMER_NUM);
+    assert(res == (1000000000 / TASK1_TIMER_FREQ));
+
+    /* Initialize timer 1 to count at 250 kHz */
+    rc = hal_timer_config(TASK2_TIMER_NUM, TASK2_TIMER_FREQ);
+    assert(rc == 0);
+
+    res = hal_timer_get_resolution(TASK2_TIMER_NUM);
+    assert(res == (1000000000 / TASK2_TIMER_FREQ));
+
+    pstack = malloc(sizeof(os_stack_t) * TASK1_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task1, "task1", task1_handler, NULL,
+            TASK1_PRIO, OS_WAIT_FOREVER, pstack, TASK1_STACK_SIZE);
+
+    pstack = malloc(sizeof(os_stack_t) * TASK2_STACK_SIZE);
+    assert(pstack);
+
+    os_task_init(&task2, "task2", task2_handler, NULL,
+            TASK2_PRIO, OS_WAIT_FOREVER, pstack, TASK2_STACK_SIZE);
+}
+
+/**
+ * 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)
+{
+    int rc;
+
+    sysinit();
+    init_tasks();
+
+    while (1) {
+        os_eventq_run(os_eventq_dflt_get());
+    }
+    /* Never exit */
+    return rc;
+}
+
diff --git a/versions/v1_5_0/mynewt-core/apps/timtest/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/timtest/syscfg.yml
new file mode 100644
index 0000000..ed8f912
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/timtest/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.
+#
+
+# Package: apps/timtest
+
+syscfg.vals:
+    SHELL_TASK: 0
+    TIMER_1: 1
+    TIMER_2: 1
diff --git a/versions/v1_5_0/mynewt-core/apps/trng_test/pkg.yml b/versions/v1_5_0/mynewt-core/apps/trng_test/pkg.yml
new file mode 100644
index 0000000..3da3f2b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/trng_test/pkg.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.
+#
+pkg.name: apps/trng_test
+pkg.type: app
+pkg.description: 
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+
+pkg.deps:
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/sys/console/full"
+    - "@apache-mynewt-core/hw/drivers/trng"
diff --git a/versions/v1_5_0/mynewt-core/apps/trng_test/src/main.c b/versions/v1_5_0/mynewt-core/apps/trng_test/src/main.c
new file mode 100755
index 0000000..55939b3
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/trng_test/src/main.c
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+#include <stddef.h>
+#include <stdint.h>
+#include "sysinit/sysinit.h"
+#include "os/os.h"
+#include "console/console.h"
+#include "trng/trng.h"
+
+static uint8_t buf[128];
+
+static void
+print_buffer(void *ptr, size_t size)
+{
+    while (size) {
+        console_printf("%02x", *((uint8_t *) ptr));
+
+        size--;
+        ptr++;
+    }
+
+    console_printf("\n");
+}
+
+int
+main(void)
+{
+    struct trng_dev *trng;
+
+    sysinit();
+
+    trng = (struct trng_dev *) os_dev_open(MYNEWT_VAL(APP_TRNG_DEV),
+                                           OS_TIMEOUT_NEVER, NULL);
+    assert(trng);
+
+    os_time_delay(OS_TICKS_PER_SEC);
+
+    trng_read(trng, buf, sizeof(buf));
+    console_printf("%d bytes from os_dev:\n", sizeof(buf));
+    print_buffer(buf, sizeof(buf));
+
+    while (1) {
+        console_printf("os_dev -> %08x\n", (unsigned) trng_get_u32(trng));
+
+        os_time_delay(OS_TICKS_PER_SEC / 4);
+    }
+
+    return 0;
+}
diff --git a/versions/v1_5_0/mynewt-core/apps/trng_test/syscfg.yml b/versions/v1_5_0/mynewt-core/apps/trng_test/syscfg.yml
new file mode 100644
index 0000000..945e48e
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/apps/trng_test/syscfg.yml
@@ -0,0 +1,26 @@
+#
+# 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:
+    APP_TRNG_DEV:
+        description: TRNG device name
+        value: '"trng"'
+
+syscfg.vals:
+    TRNG: 1
diff --git a/versions/v1_5_0/mynewt-core/boot/boot_serial/include/boot_serial/boot_serial.h b/versions/v1_5_0/mynewt-core/boot/boot_serial/include/boot_serial/boot_serial.h
new file mode 100644
index 0000000..b93c28f
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/boot/boot_serial/include/boot_serial/boot_serial.h
@@ -0,0 +1,38 @@
+/*
+ * 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 __BOOT_SERIAL_H__
+#define __BOOT_SERIAL_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * Start processing newtmgr commands for uploading image0 over serial.
+ *
+ * Open console serial port and wait for download command.
+ */
+void boot_serial_start(int max_input);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  __BOOT_SERIAL_H__ */
diff --git a/versions/v1_5_0/mynewt-core/boot/boot_serial/pkg.yml b/versions/v1_5_0/mynewt-core/boot/boot_serial/pkg.yml
new file mode 100644
index 0000000..8211eb4
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/boot/boot_serial/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: boot/boot_serial
+pkg.description: The boot_serial library is used when downloading image over serial port.
+pkg.author: "Apache Mynewt <dev@mynewt.apache.org>"
+pkg.homepage: "http://mynewt.apache.org/"
+pkg.keywords:
+    - boot
+    - bootloader
+
+pkg.deps:
+    - "@apache-mynewt-core/hw/hal"
+    - "@apache-mynewt-core/kernel/os"
+    - "@apache-mynewt-core/encoding/tinycbor"
+    - "@apache-mynewt-core/encoding/base64"
+    - "@apache-mynewt-core/sys/flash_map"
+    - "@apache-mynewt-core/util/crc"
+
+pkg.req_apis:
+    - bootloader
+
+pkg.cflags.SELFTEST:
+    - -DBOOT_SERIAL_DETECT_PIN=0
+    - -DBOOT_SERIAL_DETECT_PIN_VAL=1
+    - -DBOOT_SERIAL_DETECT_PIN_CFG=0
+
+pkg.init:
+    boot_serial_os_dev_init: 0
+    boot_serial_pkg_init: 200
diff --git a/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_serial.c b/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_serial.c
new file mode 100644
index 0000000..176798d
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_serial.c
@@ -0,0 +1,705 @@
+/*
+ * 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 <stddef.h>
+#include <inttypes.h>
+#include <ctype.h>
+#include <stdio.h>
+
+#include "os/mynewt.h"
+#include <bsp/bsp.h>
+
+#include <flash_map/flash_map.h>
+#include <hal/hal_flash.h>
+#include <hal/hal_system.h>
+#include <hal/hal_gpio.h>
+#include <hal/hal_watchdog.h>
+#include <hal/hal_nvreg.h>
+
+#include <tinycbor/cbor.h>
+#include <tinycbor/cbor_buf_reader.h>
+#include <base64/base64.h>
+#include <crc/crc16.h>
+
+#include <bootutil/image.h>
+
+#include "boot_serial/boot_serial.h"
+#include "boot_serial_priv.h"
+
+#if MYNEWT_VAL(OS_CPUTIME_TIMER_NUM) < 0
+#error "Boot serial needs OS_CPUTIME timer"
+#endif
+
+#define BOOT_SERIAL_INPUT_MAX   512
+#define BOOT_SERIAL_OUT_MAX     80
+#define BOOT_SERIAL_REPORT_DUR  \
+    (MYNEWT_VAL(OS_CPUTIME_FREQ) / MYNEWT_VAL(BOOT_SERIAL_REPORT_FREQ))
+
+static uint32_t curr_off;
+static uint32_t img_size;
+static struct nmgr_hdr *bs_hdr;
+
+static char bs_obuf[BOOT_SERIAL_OUT_MAX];
+
+static int bs_cbor_writer(struct cbor_encoder_writer *, const char *data,
+  int len);
+static void boot_serial_output(void);
+
+static struct cbor_encoder_writer bs_writer = {
+    .write = bs_cbor_writer
+};
+static CborEncoder bs_root;
+static CborEncoder bs_rsp;
+
+int
+bs_cbor_writer(struct cbor_encoder_writer *cew, const char *data, int len)
+{
+    if (cew->bytes_written + len > sizeof(bs_obuf)) {
+        return CborErrorOutOfMemory;
+    }
+
+    memcpy(&bs_obuf[cew->bytes_written], data, len);
+    cew->bytes_written += len;
+
+    return 0;
+}
+
+/*
+ * Convert version into string without use of snprintf().
+ */
+static int
+u32toa(char *tgt, uint32_t val)
+{
+    char *dst;
+    uint32_t d = 1;
+    uint32_t dgt;
+    int n = 0;
+
+    dst = tgt;
+    while (val / d >= 10) {
+        d *= 10;
+    }
+    while (d) {
+        dgt = val / d;
+        val %= d;
+        d /= 10;
+        if (n || dgt > 0 || d == 0) {
+            *dst++ = dgt + '0';
+            ++n;
+        }
+    }
+    *dst = '\0';
+
+    return dst - tgt;
+}
+
+/*
+ * dst has to be able to fit "255.255.65535.4294967295" (25 characters).
+ */
+static void
+bs_list_img_ver(char *dst, int maxlen, struct image_version *ver)
+{
+    int off;
+
+    off = u32toa(dst, ver->iv_major);
+    dst[off++] = '.';
+    off += u32toa(dst + off, ver->iv_minor);
+    dst[off++] = '.';
+    off += u32toa(dst + off, ver->iv_revision);
+    dst[off++] = '.';
+    off += u32toa(dst + off, ver->iv_build_num);
+}
+
+/*
+ * List images.
+ */
+static void
+bs_list(char *buf, int len)
+{
+    CborEncoder images;
+    CborEncoder image;
+    struct image_header hdr;
+    uint8_t tmpbuf[64];
+    int i, area_id;
+    const struct flash_area *fap;
+
+    cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
+    cbor_encode_text_stringz(&bs_rsp, "images");
+    cbor_encoder_create_array(&bs_rsp, &images, CborIndefiniteLength);
+    for (i = 0; i < 2; i++) {
+        area_id = flash_area_id_from_image_slot(i);
+        if (flash_area_open(area_id, &fap)) {
+            continue;
+        }
+
+        flash_area_read(fap, 0, &hdr, sizeof(hdr));
+
+        if (hdr.ih_magic != IMAGE_MAGIC ||
+          bootutil_img_validate(&hdr, fap, tmpbuf, sizeof(tmpbuf),
+                                NULL, 0, NULL)) {
+            flash_area_close(fap);
+            continue;
+        }
+        flash_area_close(fap);
+
+        cbor_encoder_create_map(&images, &image, CborIndefiniteLength);
+        cbor_encode_text_stringz(&image, "slot");
+        cbor_encode_int(&image, i);
+        cbor_encode_text_stringz(&image, "version");
+
+        bs_list_img_ver((char *)tmpbuf, sizeof(tmpbuf), &hdr.ih_ver);
+        cbor_encode_text_stringz(&image, (char *)tmpbuf);
+        cbor_encoder_close_container(&images, &image);
+    }
+    cbor_encoder_close_container(&bs_rsp, &images);
+    cbor_encoder_close_container(&bs_root, &bs_rsp);
+    boot_serial_output();
+}
+
+/*
+ * Image upload request.
+ */
+static void
+bs_upload(char *buf, int len)
+{
+    CborParser parser;
+    struct cbor_buf_reader reader;
+    struct CborValue root_value;
+    struct CborValue value;
+    uint8_t img_data[512];
+    long long int off = UINT_MAX;
+    size_t img_blen = 0;
+    uint8_t rem_bytes;
+    long long int data_len = UINT_MAX;
+    size_t slen;
+    char name_str[8];
+    const struct flash_area *fap = NULL;
+    int rc;
+
+    memset(img_data, 0, sizeof(img_data));
+
+    cbor_buf_reader_init(&reader, (uint8_t *)buf, len);
+    cbor_parser_init(&reader.r, 0, &parser, &root_value);
+
+    /*
+     * Expected data format.
+     * {
+     *    "data":<img_data>
+     *    "len":<image len>
+     *    "off":<current offset of image data>
+     * }
+     */
+
+    /*
+     * Object comes within { ... }
+     */
+    if (!cbor_value_is_container(&root_value)) {
+        goto out_invalid_data;
+    }
+    if (cbor_value_enter_container(&root_value, &value)) {
+        goto out_invalid_data;
+    }
+    while (cbor_value_is_valid(&value)) {
+        /*
+         * Decode key.
+         */
+        if (cbor_value_calculate_string_length(&value, &slen)) {
+            goto out_invalid_data;
+        }
+        if (!cbor_value_is_text_string(&value) ||
+            slen >= sizeof(name_str) - 1) {
+            goto out_invalid_data;
+        }
+        if (cbor_value_copy_text_string(&value, name_str, &slen, &value)) {
+            goto out_invalid_data;
+        }
+        name_str[slen] = '\0';
+        if (!strcmp(name_str, "data")) {
+            /*
+             * Image data
+             */
+            if (value.type != CborByteStringType) {
+                goto out_invalid_data;
+            }
+            if (cbor_value_calculate_string_length(&value, &slen) ||
+                slen >= sizeof(img_data)) {
+                goto out_invalid_data;
+            }
+            if (cbor_value_copy_byte_string(&value, img_data, &slen, &value)) {
+                goto out_invalid_data;
+            }
+            img_blen = slen;
+        } else if (!strcmp(name_str, "off")) {
+            /*
+             * Offset of the data.
+             */
+            if (value.type != CborIntegerType) {
+                goto out_invalid_data;
+            }
+            if (cbor_value_get_int64(&value, &off)) {
+                goto out_invalid_data;
+            }
+            if (cbor_value_advance(&value)) {
+                goto out_invalid_data;
+            }
+        } else if (!strcmp(name_str, "len")) {
+            /*
+             * Length of the image. This should only be present in the first
+             * block of data; when offset is 0.
+             */
+            if (value.type != CborIntegerType) {
+                goto out_invalid_data;
+            }
+            if (cbor_value_get_int64(&value, &data_len)) {
+                goto out_invalid_data;
+            }
+            if (cbor_value_advance(&value)) {
+                goto out_invalid_data;
+            }
+        } else {
+            /*
+             * Skip unknown keys.
+             */
+            if (cbor_value_advance(&value)) {
+                goto out_invalid_data;
+            }
+        }
+    }
+    if (off == UINT_MAX) {
+        /*
+         * Offset must be set in every block.
+         */
+        goto out_invalid_data;
+    }
+
+    rc = flash_area_open(flash_area_id_from_image_slot(0), &fap);
+    if (rc) {
+        rc = MGMT_ERR_EINVAL;
+        goto out;
+    }
+
+    if (off == 0) {
+        curr_off = 0;
+        if (data_len > fap->fa_size) {
+            goto out_invalid_data;
+        }
+        rc = flash_area_erase(fap, 0, fap->fa_size);
+        if (rc) {
+            rc = MGMT_ERR_EINVAL;
+            goto out;
+        }
+        img_size = data_len;
+    }
+    if (off != curr_off) {
+        rc = 0;
+        goto out;
+    }
+    if (curr_off + img_blen < img_size) {
+        rem_bytes = img_blen % flash_area_align(fap);
+        if (rem_bytes) {
+            img_blen -= rem_bytes;
+        }
+    }
+    rc = flash_area_write(fap, curr_off, img_data, img_blen);
+    if (rc == 0) {
+        curr_off += img_blen;
+    } else {
+out_invalid_data:
+        rc = MGMT_ERR_EINVAL;
+    }
+
+out:
+    cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
+    cbor_encode_text_stringz(&bs_rsp, "rc");
+    cbor_encode_int(&bs_rsp, rc);
+    if (rc == 0) {
+        cbor_encode_text_stringz(&bs_rsp, "off");
+        cbor_encode_uint(&bs_rsp, curr_off);
+    }
+    cbor_encoder_close_container(&bs_root, &bs_rsp);
+
+    boot_serial_output();
+    flash_area_close(fap);
+}
+
+/*
+ * Console echo control/image erase. Send empty response, don't do anything.
+ */
+static void
+bs_empty_rsp(char *buf, int len)
+{
+    cbor_encoder_create_map(&bs_root, &bs_rsp, CborIndefiniteLength);
+    cbor_encode_text_stringz(&bs_rsp, "rc");
+    cbor_encode_int(&bs_rsp, 0);
+    cbor_encoder_close_container(&bs_root, &bs_rsp);
+    boot_serial_output();
+}
+
+/*
+ * Reset, and (presumably) boot to newly uploaded image. Flush console
+ * before restarting.
+ */
+static int
+bs_reset(char *buf, int len)
+{
+    bs_empty_rsp(buf, len);
+    os_cputime_delay_usecs(250000);
+    hal_system_reset();
+}
+
+/*
+ * Parse incoming line of input from console.
+ * Expect newtmgr protocol with serial transport.
+ */
+void
+boot_serial_input(char *buf, int len)
+{
+    struct nmgr_hdr *hdr;
+
+    hdr = (struct nmgr_hdr *)buf;
+    if (len < sizeof(*hdr) ||
+      (hdr->nh_op != NMGR_OP_READ && hdr->nh_op != NMGR_OP_WRITE) ||
+      (ntohs(hdr->nh_len) < len - sizeof(*hdr))) {
+        return;
+    }
+    bs_hdr = hdr;
+    hdr->nh_group = ntohs(hdr->nh_group);
+
+    buf += sizeof(*hdr);
+    len -= sizeof(*hdr);
+
+    bs_writer.bytes_written = 0;
+    cbor_encoder_init(&bs_root, &bs_writer, 0);
+
+    /*
+     * Limited support for commands.
+     */
+    if (hdr->nh_group == MGMT_GROUP_ID_IMAGE) {
+        switch (hdr->nh_id) {
+        case IMGMGR_NMGR_ID_STATE:
+            bs_list(buf, len);
+            break;
+        case IMGMGR_NMGR_ID_UPLOAD:
+            bs_upload(buf, len);
+            break;
+        default:
+            bs_empty_rsp(buf, len);
+            break;
+        }
+    } else if (hdr->nh_group == MGMT_GROUP_ID_DEFAULT) {
+        switch (hdr->nh_id) {
+        case NMGR_ID_CONS_ECHO_CTRL:
+            bs_empty_rsp(buf, len);
+            break;
+        case NMGR_ID_RESET:
+            bs_reset(buf, len);
+            break;
+        default:
+            break;
+        }
+    }
+}
+
+static void
+boot_serial_output(void)
+{
+    char *data;
+    int len;
+    uint16_t crc;
+    uint16_t totlen;
+    char pkt_start[2] = { SHELL_NLIP_PKT_START1, SHELL_NLIP_PKT_START2 };
+    char buf[BOOT_SERIAL_OUT_MAX];
+    char encoded_buf[BASE64_ENCODE_SIZE(BOOT_SERIAL_OUT_MAX)];
+
+    data = bs_obuf;
+    len = bs_writer.bytes_written;
+
+    bs_hdr->nh_op++;
+    bs_hdr->nh_flags = 0;
+    bs_hdr->nh_len = htons(len);
+    bs_hdr->nh_group = htons(bs_hdr->nh_group);
+
+    crc = crc16_ccitt(CRC16_INITIAL_CRC, bs_hdr, sizeof(*bs_hdr));
+    crc = crc16_ccitt(crc, data, len);
+    crc = htons(crc);
+
+    boot_serial_uart_write(pkt_start, sizeof(pkt_start));
+
+    totlen = len + sizeof(*bs_hdr) + sizeof(crc);
+    totlen = htons(totlen);
+
+    memcpy(buf, &totlen, sizeof(totlen));
+    totlen = sizeof(totlen);
+    memcpy(&buf[totlen], bs_hdr, sizeof(*bs_hdr));
+    totlen += sizeof(*bs_hdr);
+    memcpy(&buf[totlen], data, len);
+    totlen += len;
+    memcpy(&buf[totlen], &crc, sizeof(crc));
+    totlen += sizeof(crc);
+    totlen = base64_encode(buf, totlen, encoded_buf, 1);
+    boot_serial_uart_write(encoded_buf, totlen);
+    boot_serial_uart_write("\n\r", 2);
+}
+
+/*
+ * Returns 1 if full packet has been received.
+ */
+static int
+boot_serial_in_dec(char *in, int inlen, char *out, int *out_off, int maxout)
+{
+    int rc;
+    uint16_t crc;
+    uint16_t len;
+
+    if (*out_off + base64_decode_len(in) >= maxout) {
+        return -1;
+    }
+    rc = base64_decode(in, &out[*out_off]);
+    if (rc < 0) {
+        return -1;
+    }
+    *out_off += rc;
+
+    if (*out_off > sizeof(uint16_t)) {
+        len = ntohs(*(uint16_t *)out);
+
+        len = min(len, *out_off - sizeof(uint16_t));
+        out += sizeof(uint16_t);
+        crc = crc16_ccitt(CRC16_INITIAL_CRC, out, len);
+        if (crc || len <= sizeof(crc)) {
+            return 0;
+        }
+        *out_off -= sizeof(crc);
+        out[*out_off] = '\0';
+
+        return 1;
+    }
+    return 0;
+}
+
+#if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
+
+/** Don't include null-terminator in comparison. */
+#define BOOT_SERIAL_DETECT_STRING_LEN \
+    (sizeof MYNEWT_VAL(BOOT_SERIAL_DETECT_STRING) - 1)
+
+/**
+ * Listens on the UART for the management string.  Blocks for up to
+ * BOOT_SERIAL_DETECT_TIMEOUT milliseconds.
+ *
+ * @return                      true if the management string was received;
+ *                              false if the management string was not received
+ *                                  before the UART listen timeout expired.
+ */
+static bool
+boot_serial_detect_uart_string(void)
+{
+    uint32_t start_tick;
+    char buf[BOOT_SERIAL_DETECT_STRING_LEN] = { 0 };
+    char ch;
+    int newline;
+    int rc;
+
+    /* Calculate the timeout duration in OS cputime ticks. */
+    static const uint32_t timeout_dur =
+        MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) /
+        (1000.0 / MYNEWT_VAL(OS_CPUTIME_FREQ));
+
+    rc = boot_serial_uart_open();
+    assert(rc == 0);
+
+    start_tick = os_cputime_get32();
+
+    while (1) {
+        /* Read a single character from the UART. */
+        rc = boot_serial_uart_read(&ch, 1, &newline);
+        if (rc > 0) {
+            /* Eliminate the oldest character in the buffer to make room for
+             * the new one.
+             */
+            memmove(buf, buf + 1, BOOT_SERIAL_DETECT_STRING_LEN - 1);
+            buf[BOOT_SERIAL_DETECT_STRING_LEN - 1] = ch;
+
+            /* If the full management string has been received, indicate that
+             * the serial boot loader should start.
+             */
+            rc = memcmp(buf,
+                        MYNEWT_VAL(BOOT_SERIAL_DETECT_STRING),
+                        BOOT_SERIAL_DETECT_STRING_LEN);
+            if (rc == 0) {
+                boot_serial_uart_close();
+                return true;
+            }
+        }
+
+        /* Abort the listen on timeout. */
+        if (os_cputime_get32() >= start_tick + timeout_dur) {
+            boot_serial_uart_close();
+            return false;
+        }
+    }
+}
+#endif
+
+/*
+ * Task which waits reading console, expecting to get image over
+ * serial port.
+ */
+void
+boot_serial_start(int max_input)
+{
+    int rc;
+    int off;
+    char *buf;
+    char *dec;
+    int dec_off;
+    int full_line;
+#if MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN) != -1
+    uint32_t tick;
+#endif
+
+#if 0
+    /*
+     * This is commented out, as it includes divide operation, bloating
+     * the bootloader 10%.
+     * Note that there are calls to hal_watchdog_tickle() in the subsequent
+     * code.
+     */
+    rc = hal_watchdog_init(MYNEWT_VAL(WATCHDOG_INTERVAL));
+    assert(rc == 0);
+#endif
+#if MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN) != -1
+    /*
+     * Configure GPIO line as output. This is a pin we toggle at the
+     * given frequency.
+     */
+    hal_gpio_init_out(MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN), 0);
+    tick = os_cputime_get32();
+#endif
+
+    rc = boot_serial_uart_open();
+    assert(rc == 0);
+
+    buf = os_malloc(max_input);
+    dec = os_malloc(max_input);
+    assert(buf && dec);
+
+    off = 0;
+    while (1) {
+        hal_watchdog_tickle();
+#if MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN) != -1
+        if (os_cputime_get32() - tick > BOOT_SERIAL_REPORT_DUR) {
+            hal_gpio_toggle(MYNEWT_VAL(BOOT_SERIAL_REPORT_PIN));
+            tick = os_cputime_get32();
+        }
+#endif
+        rc = boot_serial_uart_read(buf + off, max_input - off, &full_line);
+        if (rc <= 0 && !full_line) {
+            continue;
+        }
+        off += rc;
+        if (!full_line) {
+            if (off == max_input) {
+                /*
+                 * Full line, no newline yet. Reset the input buffer.
+                 */
+                off = 0;
+            }
+            continue;
+        }
+        if (buf[0] == SHELL_NLIP_PKT_START1 &&
+          buf[1] == SHELL_NLIP_PKT_START2) {
+            dec_off = 0;
+            rc = boot_serial_in_dec(&buf[2], off - 2, dec, &dec_off, max_input);
+        } else if (buf[0] == SHELL_NLIP_DATA_START1 &&
+          buf[1] == SHELL_NLIP_DATA_START2) {
+            rc = boot_serial_in_dec(&buf[2], off - 2, dec, &dec_off, max_input);
+        }
+        if (rc == 1) {
+            boot_serial_input(&dec[2], dec_off - 2);
+        }
+        off = 0;
+    }
+}
+
+/*
+ * os_init() will not be called with bootloader, so we need to initialize
+ * devices created by hal_bsp_init() here.
+ */
+void
+boot_serial_os_dev_init(void)
+{
+    os_dev_initialize_all(OS_DEV_INIT_PRIMARY);
+    os_dev_initialize_all(OS_DEV_INIT_SECONDARY);
+
+    /*
+     * Configure GPIO line as input. This is read later to see if
+     * we should stay and keep waiting for input.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN) != -1
+    hal_gpio_init_in(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN),
+                     MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_CFG));
+#endif
+}
+
+void
+boot_serial_pkg_init(void)
+{
+
+    /*
+     * Read retained register and compare with expected magic value.
+     * If it matches, await for download commands from serial.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX) != -1
+    if (hal_nvreg_read(MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX)) ==
+        MYNEWT_VAL(BOOT_SERIAL_NVREG_MAGIC)) {
+
+        hal_nvreg_write(MYNEWT_VAL(BOOT_SERIAL_NVREG_INDEX), 0);
+
+        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
+        assert(0);
+    }
+
+#endif
+
+    /*
+     * Configure a GPIO as input, and compare it against expected value.
+     * If it matches, await for download commands from serial.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN) != -1
+    if (hal_gpio_read(MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN)) ==
+        MYNEWT_VAL(BOOT_SERIAL_DETECT_PIN_VAL)) {
+
+        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
+        assert(0);
+    }
+#endif
+
+    /*
+     * Listen for management pattern in UART input.  If detected, await for
+     * download commands from serial.
+     */
+#if MYNEWT_VAL(BOOT_SERIAL_DETECT_TIMEOUT) != 0
+    if (boot_serial_detect_uart_string()) {
+        boot_serial_start(BOOT_SERIAL_INPUT_MAX);
+        assert(0);
+    }
+#endif
+}
diff --git a/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_serial_priv.h b/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_serial_priv.h
new file mode 100644
index 0000000..bb236ee
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_serial_priv.h
@@ -0,0 +1,84 @@
+/*
+ * 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 __BOOTUTIL_SERIAL_PRIV_H__
+#define __BOOTUTIL_SERIAL_PRIV_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * From shell.h
+ */
+#define SHELL_NLIP_PKT_START1   6
+#define SHELL_NLIP_PKT_START2   9
+
+#define SHELL_NLIP_DATA_START1  4
+#define SHELL_NLIP_DATA_START2  20
+
+/*
+ * From newtmgr.h
+ */
+#define MGMT_ERR_EINVAL         3
+
+#define NMGR_OP_READ            0
+#define NMGR_OP_WRITE           2
+
+#define MGMT_GROUP_ID_DEFAULT   0
+#define MGMT_GROUP_ID_IMAGE     1
+
+#define NMGR_ID_CONS_ECHO_CTRL  1
+#define NMGR_ID_RESET           5
+
+struct nmgr_hdr {
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+    uint8_t  nh_op:3;           /* NMGR_OP_XXX */
+    uint8_t  _res1:5;
+#endif
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+    uint8_t  _res1:5;
+    uint8_t  nh_op:3;           /* NMGR_OP_XXX */
+#endif
+    uint8_t  nh_flags;
+    uint16_t nh_len;            /* length of the payload */
+    uint16_t nh_group;          /* NMGR_GROUP_XXX */
+    uint8_t  nh_seq;            /* sequence number */
+    uint8_t  nh_id;             /* message ID within group */
+};
+
+/*
+ * From imgmgr.h
+ */
+#define IMGMGR_NMGR_ID_STATE            0
+#define IMGMGR_NMGR_ID_UPLOAD           1
+#define IMGMGR_NMGR_ID_ERASE            5
+
+void boot_serial_input(char *buf, int len);
+
+int boot_serial_uart_open(void);
+void boot_serial_uart_close(void);
+int boot_serial_uart_read(char *str, int cnt, int *newline);
+void boot_serial_uart_write(char *ptr, int cnt);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*  __BOOTUTIL_SERIAL_PRIV_H__ */
diff --git a/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_uart.c b/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_uart.c
new file mode 100644
index 0000000..6ee151b
--- /dev/null
+++ b/versions/v1_5_0/mynewt-core/boot/boot_serial/src/boot_uart.c
@@ -0,0 +1,173 @@
+/*
+ * 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 <stddef.h>
+#include <inttypes.h>
+#include "os/mynewt.h"
+#include <uart/uart.h>
+
+/*
+ * RX is a ring buffer, which gets drained constantly.
+ * TX blocks until buffer has been completely transmitted.
+ */
+#define CONSOLE_HEAD_INC(cr) (((cr)->head + 1) & (sizeof((cr)->buf) - 1))
+#define CONSOLE_TAIL_INC(cr) (((cr)->tail + 1) & (sizeof((cr)->buf) - 1))
+
+struct {
+    uint8_t head;
+    uint8_t tail;
+    uint8_t buf[16];
+} bs_uart_rx;
+
+struct {
+    uint8_t *ptr;
+    int cnt;
+} volatile bs_uart_tx;
+
+static struct uart_dev *bs_uart;
+
+static int bs_rx_char(void *arg, uint8_t byte);
+static int bs_tx_char(void *arg);
+
+int
+boot_serial_uart_open(void)
+{
+    struct uart_conf uc = {
+        .uc_speed = MYNEWT_VAL(CONSOLE_UART_BAUD),
+        .uc_databits = 8,
+        .uc_stopbits = 1,
+        .uc_parity = UART_PARITY_NONE,
+        .uc_flow_ctl = MYNEWT_VAL(CONSOLE_UART_FLOW_CONTROL),
+        .uc_tx_char = bs_tx_char,
+        .uc_rx_char = bs_rx_char,
+    };
+
+    bs_uart = (struct uart_dev *)os_dev_open(MYNEWT_VAL(CONSOLE_UART_DEV),
+      OS_TIMEOUT_NEVER, &uc);
+    if (!bs_uart) {
+        return -1;
+    }
+    return 0;
+}
+
+void
+boot_serial_uart_close(void)
+{
+    os_dev_close(&bs_uart->ud_dev);
+    bs_uart_rx.head = 0;
+    bs_uart_rx.tail = 0;
+    bs_uart_tx.cnt = 0;
+}
+
+static int
+bs_rx_char(void *arg, uint8_t byte)
+{
+    if (CONSOLE_HEAD_INC(&bs_uart_rx) == bs_uart_rx.tail) {
+        /*
+         * RX queue full. Reader must drain this.
+         */
+        return -1;
+    }
+    bs_uart_rx.buf[bs_uart_rx.head] = byte;
+    bs_uart_rx.head = CONSOLE_HEAD_INC(&bs_uart_rx);
+    return 0;
+}
+
+static uint8_t
+bs_pull_char(void)
+{
+    uint8_t ch;
+
+    ch = bs_uart_rx.buf[bs_uart_rx.tail];
+    bs_uart_rx.tail = CONSOLE_TAIL_INC(&bs_uart_rx);
+    return ch;
+}
+
+int
+boot_serial_uart_read(char *str, int cnt, int *newline)
+{
+    int i;
+    int sr;
+    uint8_t ch;
+
+    *newline = 0;
+    OS_ENTER_CRITICAL(sr);
+    for (i = 0; i < cnt; i++) {
+        if (bs_uart_rx.head == bs_uart_rx.tail) {
+            break;
+        }
+
+        ch = bs_pull_char();
+        if (ch == '\n') {
+            *str = '\0';
+            *newline = 1;
+            break;
+        }
+        *str++ = ch;
+    }
+    OS_EXIT_CRITICAL(sr);
+    if (i > 0 || *newline) {
+        uart_start_rx(bs_uart);
+    }
+    return i;
+}
+
+static int
+bs_tx_char(void *arg)
+{
+    uint8_t ch;
+
+    if (!bs_uart_tx.cnt) {
+        return -1;
+    }
+
+    bs_uart_tx.cnt--;
+    ch = *bs_uart_tx.ptr;
+    bs_uart_tx.ptr++;
+    return ch;
+}
+
+#if MYNEWT_VAL(SELFTEST)
+/*
+ * OS is not running, so native uart 'driver' cannot run either.
+ * At the moment unit tests don't check the responses to messages it
+ * sends, so we can drop the outgoing data here.
+ */
+void
+boot_serial_uart_write(char *ptr, int cnt)
+{
+}
+
+#else
+
+void
+boot_serial_uart_write(char *ptr, int cnt)
+{
+    int sr;
+
+    OS_ENTER_CRITICAL(sr);
+