You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by st...@apache.org on 2016/07/27 23:13:54 UTC

[25/51] [partial] incubator-mynewt-core git commit: add stm32 and nordic sdks based on new structure

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.c
new file mode 100644
index 0000000..6180c40
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.c
@@ -0,0 +1,192 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include "dfu_app_handler.h"
+#include <string.h>
+#include "bootloader_util.h"
+#include "nrf.h"
+#include "nrf_sdm.h"
+#include "ble_gatt.h"
+#include "ble_gatts.h"
+#include "app_error.h"
+#include "dfu_ble_svc.h"
+#include "device_manager.h"
+#include "nrf_delay.h"
+
+#define IRQ_ENABLED            0x01                                     /**< Field that identifies if an interrupt is enabled. */
+#define MAX_NUMBER_INTERRUPTS  32                                       /**< Maximum number of interrupts available. */
+
+static void                    dfu_app_reset_prepare(void);             /**< Forward declaration of default reset handler. */
+static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare; /**< Callback function to application to prepare for system reset. Allows application to clean up service and memory before reset. */
+static dfu_ble_peer_data_t     m_peer_data;                             /**< Peer data to be used for data exchange when resetting into DFU mode. */
+static dm_handle_t             m_dm_handle;                             /**< Device Manager handle with instance IDs of current BLE connection. */
+
+
+/**@brief Function for reset_prepare handler if the application has not registered a handler.
+ */
+static void dfu_app_reset_prepare(void)
+{
+    // Reset prepare should be handled by application.
+    // This function can be extended to include default handling if application does not implement
+    // own handler.
+}
+
+
+/**@brief Function for disabling all interrupts before jumping from bootloader to application.
+ */
+static void interrupts_disable(void)
+{
+    uint32_t interrupt_setting_mask;
+    uint32_t irq;
+
+    // Fetch the current interrupt settings.
+    interrupt_setting_mask = NVIC->ISER[0];
+
+    // Loop from interrupt 0 for disabling of all interrupts.
+    for (irq = 0; irq < MAX_NUMBER_INTERRUPTS; irq++)
+    {
+        if (interrupt_setting_mask & (IRQ_ENABLED << irq))
+        {
+            // The interrupt was enabled, hence disable it.
+            NVIC_DisableIRQ((IRQn_Type)irq);
+        }
+    }
+}
+
+
+/**@brief Function for providing peer information to DFU for re-establishing a bonded connection in
+ *        DFU mode.
+ *
+ * @param[in] conn_handle   Connection handle for the connection requesting DFU mode.
+ */
+static void dfu_app_peer_data_set(uint16_t conn_handle)
+{
+    uint32_t                 err_code;
+    dm_sec_keyset_t          key_set;
+    uint32_t                 app_context_data = 0;
+    dm_application_context_t app_context;
+
+
+/** [DFU bond sharing] */
+    err_code = dm_handle_get(conn_handle, &m_dm_handle);
+    if (err_code == NRF_SUCCESS)
+    {
+        err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
+        if (err_code == NRF_SUCCESS)
+        {
+            APP_ERROR_CHECK(err_code);
+
+            m_peer_data.addr              = key_set.keys_central.p_id_key->id_addr_info;
+            m_peer_data.irk               = key_set.keys_central.p_id_key->id_info;
+            m_peer_data.enc_key.enc_info  = key_set.keys_periph.enc_key.p_enc_key->enc_info;
+            m_peer_data.enc_key.master_id = key_set.keys_periph.enc_key.p_enc_key->master_id;
+
+            err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
+            APP_ERROR_CHECK(err_code);
+
+            app_context_data   = (DFU_APP_ATT_TABLE_CHANGED << DFU_APP_ATT_TABLE_POS);
+            app_context.len    = sizeof(app_context_data);
+            app_context.p_data = (uint8_t *)&app_context_data;
+            app_context.flags  = 0;
+
+            err_code = dm_application_context_set(&m_dm_handle, &app_context);
+            APP_ERROR_CHECK(err_code);
+        }
+        else
+        {
+            // Keys were not available, thus we have a non-encrypted connection.
+            err_code = dm_peer_addr_get(&m_dm_handle, &m_peer_data.addr);
+            APP_ERROR_CHECK(err_code);
+
+            err_code = dfu_ble_svc_peer_data_set(&m_peer_data);
+            APP_ERROR_CHECK(err_code);
+        }
+    }
+/** [DFU bond sharing] */
+}
+
+
+/**@brief Function for preparing the reset, disabling SoftDevice, and jumping to the bootloader.
+ *
+ * @param[in] conn_handle Connection handle for peer requesting to enter DFU mode.
+ */
+static void bootloader_start(uint16_t conn_handle)
+{
+    uint32_t err_code;
+    uint16_t sys_serv_attr_len = sizeof(m_peer_data.sys_serv_attr);
+
+    err_code = sd_ble_gatts_sys_attr_get(conn_handle,
+                                         m_peer_data.sys_serv_attr,
+                                         &sys_serv_attr_len,
+                                         BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+    if (err_code != NRF_SUCCESS)
+    {
+        // Any error at this stage means the system service attributes could not be fetched.
+        // This means the service changed indication cannot be sent in DFU mode, but connection
+        // is still possible to establish.
+    }
+
+    m_reset_prepare();
+
+    err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = sd_softdevice_disable();
+    APP_ERROR_CHECK(err_code);
+
+    err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);
+    APP_ERROR_CHECK(err_code);
+
+    dfu_app_peer_data_set(conn_handle);
+
+    NVIC_ClearPendingIRQ(SWI2_IRQn);
+    interrupts_disable();
+    bootloader_util_app_start(NRF_UICR->NRFFW[0]);
+}
+
+
+void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
+{
+    switch (p_evt->ble_dfu_evt_type)
+    {
+        case BLE_DFU_START:
+            // Starting the bootloader - will cause reset.
+            bootloader_start(p_dfu->conn_handle);
+            break;
+
+        default:
+            {
+                // Unsupported event received from DFU Service. 
+                // Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
+                uint32_t err_code = ble_dfu_response_send(p_dfu,
+                                                          BLE_DFU_START_PROCEDURE,
+                                                          BLE_DFU_RESP_VAL_NOT_SUPPORTED);
+                APP_ERROR_CHECK(err_code);
+            }
+            break;
+    }
+}
+
+
+void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
+{
+    m_reset_prepare = reset_prepare_func;
+}
+
+
+void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance)
+{
+    uint32_t err_code;
+    
+    err_code = dm_application_instance_set(&app_instance, &m_dm_handle);
+    APP_ERROR_CHECK(err_code);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.h
new file mode 100644
index 0000000..b93bd26
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_app_handler.h
@@ -0,0 +1,86 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+  
+/** @file
+ *
+ * @defgroup nrf_dfu_app_handler DFU BLE packet handling in application
+ * @{
+ *
+ * @brief Handling of DFU BLE packets in the application.
+ *
+ * @details This module implements the handling of DFU packets for switching 
+ *          from an application to the bootloader and start DFU mode. The DFU
+ *          packets are transmitted over BLE. 
+ *          This module handles only the StartDFU packet, which allows a BLE 
+ *          application to expose support for the DFU Service.
+ *          The actual DFU Service runs in a dedicated environment after a BLE 
+ *          disconnect and reset of the \nRFXX device. 
+ *          The host must reconnect and continue the update procedure with 
+ *          access to the full DFU Service.
+ *
+ * @note The application must propagate DFU events to this module by calling
+ *       @ref dfu_app_on_dfu_evt from the @ref ble_dfu_evt_handler_t callback.
+ */
+ 
+#ifndef DFU_APP_HANDLER_H__
+#define DFU_APP_HANDLER_H__
+
+#include "ble_dfu.h"
+#include "nrf_svc.h"
+#include "bootloader_types.h"
+#include "device_manager.h"
+
+#define DFU_APP_ATT_TABLE_POS     0                     /**< Position for the ATT table changed setting. */
+#define DFU_APP_ATT_TABLE_CHANGED 1                     /**< Value indicating that the ATT table might have changed. This value will be set in the application-specific context in Device Manager when entering DFU mode. */
+
+/**@brief DFU application reset_prepare function. This function is a callback that allows the 
+ *        application to prepare for an upcoming application reset. 
+ */
+typedef void (*dfu_app_reset_prepare_t)(void);
+
+/**@brief   Function for handling events from the DFU Service. 
+ *
+ * @details The application must inject this function into the DFU Service or propagate DFU events 
+ *          to the dfu_app_handler module by calling this function in the application-specific DFU event 
+ *          handler.
+ * 
+ * @param[in] p_dfu  Pointer to the DFU Service structure to which the include event relates.
+ * @param[in] p_evt  Pointer to the DFU event.
+ */
+void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt);
+
+/**@brief Function for registering a function to prepare a reset.
+ *
+ * @details The provided function is executed before resetting the system into bootloader/DFU
+ *          mode. By registering this function, the caller is notified before the reset and can
+ *          thus prepare the application for reset. For example, the application can gracefully
+ *          disconnect any peers on BLE, turn of LEDS, ensure that all pending flash operations
+ *          have completed, and so on.
+ *
+ * @param[in] reset_prepare_func  Function to be executed before a reset.
+ */
+void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func);
+
+/**@brief Function for setting the Device Manager application instance.
+ *
+ * @details This function allows to set the @ref dm_application_instance_t value that is returned by the 
+ *          Device Manager when the application registers using @ref dm_register.
+ *          If this function is not called, it is not be possible to share bonding information
+ *          from the application to the bootloader/DFU when entering DFU mode.
+ *
+ * @param[in] app_instance Value for the application instance in use.
+ */
+void dfu_app_dm_appl_instance_set(dm_application_instance_t app_instance);
+
+#endif // DFU_APP_HANDLER_H__
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_bank_internal.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_bank_internal.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_bank_internal.h
new file mode 100644
index 0000000..4e524b4
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_bank_internal.h
@@ -0,0 +1,87 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+ 
+/**@file
+ *
+ * @defgroup dfu_bank_internal Device Firmware Update internal header for bank handling in DFU.
+ * @{     
+ *
+ * @brief Device Firmware Update Bank handling module interface.
+ *
+ * @details This header is intended for shared definition and functions between single and dual bank 
+ *         implementations used for DFU support. It is not supposed to be used for external access 
+ *         to the DFU module.
+ *  
+ */
+#ifndef DFU_BANK_INTERNAL_H__
+#define DFU_BANK_INTERNAL_H__
+
+#include <dfu_types.h>
+
+/**@brief States of the DFU state machine. */
+typedef enum
+{
+    DFU_STATE_INIT_ERROR,                                                           /**< State for: dfu_init(...) error. */
+    DFU_STATE_IDLE,                                                                 /**< State for: idle. */
+    DFU_STATE_PREPARING,                                                            /**< State for: preparing, indicates that the flash is being erased and no data packets can be processed. */
+    DFU_STATE_RDY,                                                                  /**< State for: ready. */
+    DFU_STATE_RX_INIT_PKT,                                                          /**< State for: receiving initialization packet. */
+    DFU_STATE_RX_DATA_PKT,                                                          /**< State for: receiving data packet. */
+    DFU_STATE_VALIDATE,                                                             /**< State for: validate. */
+    DFU_STATE_WAIT_4_ACTIVATE                                                       /**< State for: waiting for dfu_image_activate(). */
+} dfu_state_t;
+
+#define APP_TIMER_PRESCALER         0                                               /**< Value of the RTC1 PRESCALER register. */
+#define DFU_TIMEOUT_INTERVAL        APP_TIMER_TICKS(120000, APP_TIMER_PRESCALER)    /**< DFU timeout interval in units of timer ticks. */     
+
+#define IS_UPDATING_SD(START_PKT)   ((START_PKT).dfu_update_mode & DFU_UPDATE_SD)   /**< Macro for determining if a SoftDevice update is ongoing. */
+#define IS_UPDATING_BL(START_PKT)   ((START_PKT).dfu_update_mode & DFU_UPDATE_BL)   /**< Macro for determining if a Bootloader update is ongoing. */
+#define IS_UPDATING_APP(START_PKT)  ((START_PKT).dfu_update_mode & DFU_UPDATE_APP)  /**< Macro for determining if a Application update is ongoing. */
+#define IMAGE_WRITE_IN_PROGRESS()   (m_data_received > 0)                           /**< Macro for determining if an image write is in progress. */
+#define IS_WORD_SIZED(SIZE)         ((SIZE & (sizeof(uint32_t) - 1)) == 0)          /**< Macro for checking that the provided is word sized. */
+
+/**@cond NO_DOXYGEN */
+static uint32_t                     m_data_received;                                /**< Amount of received data. */
+/**@endcond */
+
+/**@brief     Type definition of function used for preparing of the bank before receiving of a
+ *            software image.
+ *
+ * @param[in] image_size  Size of software image being received.
+ */
+typedef void (*dfu_bank_prepare_t)(uint32_t image_size);
+
+/**@brief     Type definition of function used for handling clear complete of the bank before 
+ *            receiving of a software image.
+ */
+typedef void (*dfu_bank_cleared_t)(void);
+
+/**@brief    Type definition of function used for activating of the software image received.
+ *
+ * @return  NRF_SUCCESS If the image has been successfully activated any other NRF_ERROR code in
+ *          case of a failure.
+ */
+typedef uint32_t (*dfu_bank_activate_t)(void);
+
+/**@brief Structure for holding of function pointers for needed prepare and activate procedure for
+ *        the requested update procedure. 
+ */
+typedef struct
+{
+    dfu_bank_prepare_t  prepare;                                                    /**< Function pointer to the prepare function called on start of update procedure. */
+    dfu_bank_cleared_t  cleared;                                                    /**< Function pointer to the cleared function called after prepare function completes. */
+    dfu_bank_activate_t activate;                                                   /**< Function pointer to the activate function called on finalizing the update procedure. */
+} dfu_bank_func_t;
+
+#endif // DFU_BANK_INTERNAL_H__
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc.h
new file mode 100644
index 0000000..5e5ae4b
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc.h
@@ -0,0 +1,80 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+  
+/** @file
+ *
+ * @defgroup nrf_dfu_ble_svc DFU BLE SVC 
+ * @{
+ *
+ * @brief DFU BLE SVC in bootloader. The DFU BLE SuperVisor Calls allow an application to execute
+ *        functions in the installed bootloader. 
+ *
+ * @details This module implements handling of SuperVisor Calls in the bootloader. 
+ *          SuperVisor Calls allow for an application to execute calls into the bootloader.
+ *          Currently, it is possible to exchange bonding information (like keys) from the 
+ *          application to a bootloader supporting DFU OTA using BLE, so the update process can be 
+ *          done through an already existing bond.
+ *
+ * @note The application must make sure that all SuperVisor Calls (SVC) are forwarded to the 
+ *       bootloader to ensure correct behavior. Forwarding of SVCs to the bootloader is 
+ *       done using the SoftDevice SVC @ref sd_softdevice_vector_table_base_set with the value 
+ *       present in @c NRF_UICR->NRFFW[0].
+ */
+ 
+#ifndef DFU_BLE_SVC_H__
+#define DFU_BLE_SVC_H__
+
+#include "nrf_svc.h"
+#include <stdint.h>
+#include "ble_gap.h"
+#include "nrf.h"
+#include "nrf_soc.h"
+#include "nrf_error_sdm.h"
+
+#define BOOTLOADER_SVC_BASE     0x0     /**< The number of the lowest SVC number reserved for the bootloader. */
+#define SYSTEM_SERVICE_ATT_SIZE 8       /**< Size of the system service attribute length including CRC-16 at the end. */  
+
+/**@brief The SVC numbers used by the SVC functions in the SoC library. */
+enum BOOTLOADER_SVCS
+{
+    DFU_BLE_SVC_PEER_DATA_SET = BOOTLOADER_SVC_BASE,    /**< SVC number for the setting of peer data call. */
+    BOOTLOADER_SVC_LAST
+};
+
+/**@brief   DFU Peer data structure.
+ *
+ * @details This structure contains peer data needed for connection to a bonded device during DFU.
+ *          The peer data must be provided by the application to the bootloader during buttonless
+ *          update. See @ref dfu_ble_svc_peer_data_set. It contains bond information about the
+ *          desired DFU peer.
+ */
+typedef struct
+{
+    ble_gap_addr_t      addr;                                   /**< BLE GAP address of the device that initiated the DFU process. */
+    ble_gap_irk_t       irk;                                    /**< IRK of the device that initiated the DFU process if this device uses Private Resolvable Addresses. */
+    ble_gap_enc_key_t   enc_key;                                /**< Encryption key structure containing encrypted diversifier and LTK for re-establishing the bond. */
+    uint8_t             sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */
+} dfu_ble_peer_data_t;
+
+/**@brief   SVC Function for setting peer data containing address, IRK, and LTK to establish bonded
+ *          connection in DFU mode.
+ *
+ * @param[in] p_peer_data  Pointer to the peer data containing keys for the connection.
+ *
+ * @retval NRF_ERROR_NULL If a NULL pointer was provided as argument.
+ * @retval NRF_SUCCESS    If the function completed successfully.
+ */
+SVCALL(DFU_BLE_SVC_PEER_DATA_SET, uint32_t, dfu_ble_svc_peer_data_set(dfu_ble_peer_data_t * p_peer_data));
+
+#endif // DFU_BLE_SVC_H__
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h
new file mode 100644
index 0000000..0b6e5d4
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_ble_svc_internal.h
@@ -0,0 +1,43 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+  
+/** @file
+ *
+ * @defgroup nrf_dfu_ble_svc_internal DFU BLE SVC internal
+ * @{
+ *
+ * @brief DFU BLE SVC internal functions in bootloader. The DFU BLE SuperVisor Calls allow an 
+ *        application to execute functions in the installed bootloader. This interface provides 
+ *        internal Bootloader DFU functions for retrieving data exchanged through SuperVisor Calls.
+ *
+ */
+
+#ifndef DFU_BLE_SVC_INTERNAL_H__
+#define DFU_BLE_SVC_INTERNAL_H__
+
+#include <stdint.h>
+#include "dfu_ble_svc.h"
+#include "ble_gap.h"
+
+/**@brief Internal bootloader/DFU function for retrieving peer data provided from application.
+ *
+ * @param[out] p_peer_data Peer data set by application to be used for DFU connection.
+ *
+ * @retval NRF_SUCCESS            If peer data is valid and can be used for connection.
+ * @retval NRF_ERROR_NULL         If p_peer_data is a NULL pointer.
+ * @retval NRF_ERROR_INVALID_DATA If peer data is not available or invalid.
+ */
+uint32_t dfu_ble_peer_data_get(dfu_ble_peer_data_t * p_peer_data);
+
+#endif // DFU_BLE_SVC_INTERNAL_H__
+
+/** @} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_dual_bank.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_dual_bank.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_dual_bank.c
new file mode 100644
index 0000000..fecbdf3
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_dual_bank.c
@@ -0,0 +1,834 @@
+/* Copyright (c) 2013 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+#include <stddef.h>
+#include "dfu.h"
+#include <dfu_types.h>
+#include "dfu_bank_internal.h"
+#include "nrf.h"
+#include "nrf_sdm.h"
+#include "app_error.h"
+#include "app_timer.h"
+#include "bootloader.h"
+#include "bootloader_types.h"
+#include "pstorage.h"
+#include "nrf_mbr.h"
+#include "dfu_init.h"
+#include "sdk_common.h"
+
+static dfu_state_t                  m_dfu_state;                /**< Current DFU state. */
+static uint32_t                     m_image_size;               /**< Size of the image that will be transmitted. */
+
+static dfu_start_packet_t           m_start_packet;             /**< Start packet received for this update procedure. Contains update mode and image sizes information to be used for image transfer. */
+static uint8_t                      m_init_packet[128];         /**< Init packet, can hold CRC, Hash, Signed Hash and similar, for image validation, integrety check and authorization checking. */ 
+static uint8_t                      m_init_packet_length;       /**< Length of init packet received. */
+static uint16_t                     m_image_crc;                /**< Calculated CRC of the image received. */
+
+APP_TIMER_DEF(m_dfu_timer_id);                                  /**< Application timer id. */
+static bool                         m_dfu_timed_out = false;    /**< Boolean flag value for tracking DFU timer timeout state. */
+
+static pstorage_handle_t            m_storage_handle_swap;      /**< Pstorage handle for the swap area (bank 1). Bank used when updating an application or bootloader without SoftDevice. */
+static pstorage_handle_t            m_storage_handle_app;       /**< Pstorage handle for the application area (bank 0). Bank used when updating a SoftDevice w/wo bootloader. Handle also used when swapping received application from bank 1 to bank 0. */
+static pstorage_handle_t          * mp_storage_handle_active;   /**< Pointer to the pstorage handle for the active bank for receiving of data packets. */
+
+static dfu_callback_t               m_data_pkt_cb;              /**< Callback from DFU Bank module for notification of asynchronous operation such as flash prepare. */
+static dfu_bank_func_t              m_functions;                /**< Structure holding operations for the selected update process. */
+
+
+/**@brief Function for handling callbacks from pstorage module.
+ *
+ * @details Handles pstorage results for clear and storage operation. For detailed description of
+ *          the parameters provided with the callback, please refer to \ref pstorage_ntf_cb_t.
+ */
+static void pstorage_callback_handler(pstorage_handle_t * p_handle,
+                                      uint8_t             op_code,
+                                      uint32_t            result,
+                                      uint8_t           * p_data,
+                                      uint32_t            data_len)
+{
+    switch (op_code)
+    {
+        case PSTORAGE_STORE_OP_CODE:
+            if ((m_dfu_state == DFU_STATE_RX_DATA_PKT) && (m_data_pkt_cb != NULL))
+            {
+                m_data_pkt_cb(DATA_PACKET, result, p_data);
+            }
+            break;
+
+        case PSTORAGE_CLEAR_OP_CODE:
+            if (m_dfu_state == DFU_STATE_PREPARING)
+            {
+                m_functions.cleared();
+                m_dfu_state = DFU_STATE_RDY;
+                if (m_data_pkt_cb != NULL)
+                {
+                    m_data_pkt_cb(START_PACKET, result, p_data);
+                }
+            }
+            break;
+
+        default:
+            break;
+    }
+    APP_ERROR_CHECK(result);
+}
+
+
+/**@brief Function for handling the DFU timeout.
+ *
+ * @param[in] p_context The timeout context.
+ */
+static void dfu_timeout_handler(void * p_context)
+{
+    UNUSED_PARAMETER(p_context);
+    dfu_update_status_t update_status;
+
+    m_dfu_timed_out           = true;
+    update_status.status_code = DFU_TIMEOUT;
+
+    bootloader_dfu_update_process(update_status);
+}
+
+
+/**@brief   Function for restarting the DFU Timer.
+ *
+ * @details This function will stop and restart the DFU timer. This function will be called by the
+ *          functions handling any DFU packet received from the peer that is transferring a firmware
+ *          image.
+ */
+static uint32_t dfu_timer_restart(void)
+{
+    if (m_dfu_timed_out)
+    {
+        // The DFU timer had already timed out.
+        return NRF_ERROR_INVALID_STATE;
+    }
+
+    uint32_t err_code = app_timer_stop(m_dfu_timer_id);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
+    APP_ERROR_CHECK(err_code);
+
+    return err_code;
+}
+
+
+/**@brief   Function for preparing of flash before receiving SoftDevice image.
+ *
+ * @details This function will erase current application area to ensure sufficient amount of
+ *          storage for the SoftDevice image. Upon erase complete a callback will be done.
+ *          See \ref dfu_bank_prepare_t for further details.
+ */
+static void dfu_prepare_func_app_erase(uint32_t image_size)
+{
+    uint32_t err_code;
+
+    mp_storage_handle_active = &m_storage_handle_app;
+
+    // Doing a SoftDevice update thus current application must be cleared to ensure enough space
+    // for new SoftDevice.
+    m_dfu_state = DFU_STATE_PREPARING;
+    err_code    = pstorage_clear(&m_storage_handle_app, m_image_size);
+    APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief   Function for preparing swap before receiving application or bootloader image.
+ *
+ * @details This function will erase current swap area to ensure flash is ready for storage of the
+ *          Application or Bootloader image. Upon erase complete a callback will be done.
+ *          See \ref dfu_bank_prepare_t for further details.
+ */
+static void dfu_prepare_func_swap_erase(uint32_t image_size)
+{
+    uint32_t err_code;
+
+    mp_storage_handle_active = &m_storage_handle_swap;
+
+    m_dfu_state = DFU_STATE_PREPARING;
+    err_code    = pstorage_clear(&m_storage_handle_swap, DFU_IMAGE_MAX_SIZE_BANKED);
+    APP_ERROR_CHECK(err_code);
+}
+
+
+/**@brief   Function for handling behaviour when clear operation has completed.
+ */
+static void dfu_cleared_func_swap(void)
+{
+    // Do nothing.
+}
+
+
+/**@brief   Function for handling behaviour when clear operation has completed.
+ */
+static void dfu_cleared_func_app(void)
+{
+    dfu_update_status_t update_status = {DFU_BANK_0_ERASED, };
+    bootloader_dfu_update_process(update_status);
+}
+
+
+/**@brief   Function for calculating storage offset for receiving SoftDevice image.
+ *
+ * @details When a new SoftDevice is received it will be temporary stored in flash before moved to
+ *          address 0x0. In order to succesfully validate transfer and relocation it is important
+ *          that temporary image and final installed image does not ovwerlap hence an offset must
+ *          be calculated in case new image is larger than currently installed SoftDevice.
+ */
+uint32_t offset_calculate(uint32_t sd_image_size)
+{
+    uint32_t offset = 0;
+    
+    if (m_start_packet.sd_image_size > DFU_BANK_0_REGION_START)
+    {
+        uint32_t page_mask = (CODE_PAGE_SIZE - 1);
+        uint32_t diff = m_start_packet.sd_image_size - DFU_BANK_0_REGION_START;
+        
+        offset = diff & ~page_mask;
+        
+        // Align offset to next page if image size is not page sized.
+        if ((diff & page_mask) > 0)
+        {
+            offset += CODE_PAGE_SIZE;
+        }
+    }
+
+    return offset;
+}
+
+
+/**@brief Function for activating received SoftDevice image.
+ *
+ *  @note This function will not move the SoftDevice image.
+ *        The bootloader settings will be marked as SoftDevice update complete and the swapping of
+ *        current SoftDevice will occur after system reset.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+static uint32_t dfu_activate_sd(void)
+{
+    dfu_update_status_t update_status;
+
+    update_status.status_code    = DFU_UPDATE_SD_COMPLETE;
+    update_status.app_crc        = m_image_crc;
+    update_status.sd_image_start = DFU_BANK_0_REGION_START;
+    update_status.sd_size        = m_start_packet.sd_image_size;
+    update_status.bl_size        = m_start_packet.bl_image_size;
+    update_status.app_size       = m_start_packet.app_image_size;
+
+    bootloader_dfu_update_process(update_status);
+
+    return NRF_SUCCESS;
+}
+
+
+/**@brief Function for activating received Application image.
+ *
+ *  @details This function will move the received application image fram swap (bank 1) to
+ *           application area (bank 0).
+ *
+ * @return NRF_SUCCESS on success. Error code otherwise.
+ */
+static uint32_t dfu_activate_app(void)
+{
+    uint32_t err_code;
+
+    // Erase BANK 0.
+    err_code = pstorage_clear(&m_storage_handle_app, m_start_packet.app_image_size);
+    APP_ERROR_CHECK(err_code);
+
+    err_code = pstorage_store(&m_storage_handle_app,
+                                  (uint8_t *)m_storage_handle_swap.block_id,
+                                  m_start_packet.app_image_size,
+                                  0);
+
+    if (err_code == NRF_SUCCESS)
+    {
+        dfu_update_status_t update_status;
+
+        memset(&update_status, 0, sizeof(dfu_update_status_t ));
+        update_status.status_code = DFU_UPDATE_APP_COMPLETE;
+        update_status.app_crc     = m_image_crc;
+        update_status.app_size    = m_start_packet.app_image_size;
+
+        bootloader_dfu_update_process(update_status);
+    }
+
+    return err_code;
+}
+
+
+/**@brief Function for activating received Bootloader image.
+ *
+ *  @note This function will not move the bootloader image.
+ *        The bootloader settings will be marked as Bootloader update complete and the swapping of
+ *        current bootloader will occur after system reset.
+ *
+ * @return NRF_SUCCESS on success.
+ */
+static uint32_t dfu_activate_bl(void)
+{
+    dfu_update_status_t update_status;
+
+    update_status.status_code = DFU_UPDATE_BOOT_COMPLETE;
+    update_status.app_crc     = m_image_crc;
+    update_status.sd_size     = m_start_packet.sd_image_size;
+    update_status.bl_size     = m_start_packet.bl_image_size;
+    update_status.app_size    = m_start_packet.app_image_size;
+
+    bootloader_dfu_update_process(update_status);
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t dfu_init(void)
+{
+    uint32_t                err_code;
+    pstorage_module_param_t storage_module_param = {.cb = pstorage_callback_handler};
+
+    m_init_packet_length = 0;
+    m_image_crc          = 0;
+
+    err_code = pstorage_register(&storage_module_param, &m_storage_handle_app);
+    if (err_code != NRF_SUCCESS)
+    {
+        m_dfu_state = DFU_STATE_INIT_ERROR;
+        return err_code;
+    }
+
+    m_storage_handle_app.block_id  = DFU_BANK_0_REGION_START;
+    m_storage_handle_swap          = m_storage_handle_app;
+    m_storage_handle_swap.block_id = DFU_BANK_1_REGION_START;
+
+    // Create the timer to monitor the activity by the peer doing the firmware update.
+    err_code = app_timer_create(&m_dfu_timer_id,
+                                APP_TIMER_MODE_SINGLE_SHOT,
+                                dfu_timeout_handler);
+    APP_ERROR_CHECK(err_code);
+
+    // Start the DFU timer.
+    err_code = app_timer_start(m_dfu_timer_id, DFU_TIMEOUT_INTERVAL, NULL);
+    APP_ERROR_CHECK(err_code);
+
+    m_data_received = 0;
+    m_dfu_state     = DFU_STATE_IDLE;
+
+    return NRF_SUCCESS;
+}
+
+
+void dfu_register_callback(dfu_callback_t callback_handler)
+{
+    m_data_pkt_cb = callback_handler;
+}
+
+
+uint32_t dfu_start_pkt_handle(dfu_update_packet_t * p_packet)
+{
+    uint32_t err_code;
+
+    m_start_packet = *(p_packet->params.start_packet);
+
+    // Check that the requested update procedure is supported.
+    // Currently the following combinations are allowed:
+    // - Application
+    // - SoftDevice
+    // - Bootloader
+    // - SoftDevice with Bootloader
+    if (IS_UPDATING_APP(m_start_packet) && 
+        (IS_UPDATING_SD(m_start_packet) || IS_UPDATING_BL(m_start_packet)))
+    {
+        // App update is only supported independently.
+        return NRF_ERROR_NOT_SUPPORTED;
+    }
+
+    if (!(IS_WORD_SIZED(m_start_packet.sd_image_size) &&
+          IS_WORD_SIZED(m_start_packet.bl_image_size) &&
+          IS_WORD_SIZED(m_start_packet.app_image_size)))
+    {
+        // Image_sizes are not a multiple of 4 (word size).
+        return NRF_ERROR_NOT_SUPPORTED;
+    }
+
+    m_image_size = m_start_packet.sd_image_size + m_start_packet.bl_image_size +
+                   m_start_packet.app_image_size;
+    
+    if (m_start_packet.bl_image_size > DFU_BL_IMAGE_MAX_SIZE)
+    {
+        return NRF_ERROR_DATA_SIZE;
+    }
+
+    if (IS_UPDATING_SD(m_start_packet))
+    {
+        if (m_image_size > (DFU_IMAGE_MAX_SIZE_FULL))
+        {
+            return NRF_ERROR_DATA_SIZE;
+        }
+        m_functions.prepare  = dfu_prepare_func_app_erase;
+        m_functions.cleared  = dfu_cleared_func_app;
+        m_functions.activate = dfu_activate_sd;
+    }
+    else
+    {
+        if (m_image_size > DFU_IMAGE_MAX_SIZE_BANKED)
+        {
+            return NRF_ERROR_DATA_SIZE;
+        }
+
+        m_functions.prepare = dfu_prepare_func_swap_erase;
+        m_functions.cleared = dfu_cleared_func_swap;
+        if (IS_UPDATING_BL(m_start_packet))
+        {
+            m_functions.activate = dfu_activate_bl;
+        }
+        else
+        {
+            m_functions.activate = dfu_activate_app;
+        }
+    }
+
+    switch (m_dfu_state)
+    {
+        case DFU_STATE_IDLE:
+            // Valid peer activity detected. Hence restart the DFU timer.
+            err_code = dfu_timer_restart();
+            VERIFY_SUCCESS(err_code);
+            m_functions.prepare(m_image_size);
+
+            break;
+
+        default:
+            err_code = NRF_ERROR_INVALID_STATE;
+            break;
+    }
+
+    return err_code;
+}
+
+
+uint32_t dfu_data_pkt_handle(dfu_update_packet_t * p_packet)
+{
+    uint32_t   data_length;
+    uint32_t   err_code;
+    uint32_t * p_data;
+
+    VERIFY_PARAM_NOT_NULL(p_packet);
+
+    // Check pointer alignment.
+    if (!is_word_aligned(p_packet->params.data_packet.p_data_packet))
+    {
+        // The p_data_packet is not word aligned address.
+        return NRF_ERROR_INVALID_ADDR;
+    }
+
+    switch (m_dfu_state)
+    {
+        case DFU_STATE_RDY:
+        case DFU_STATE_RX_INIT_PKT:
+            return NRF_ERROR_INVALID_STATE;
+
+        case DFU_STATE_RX_DATA_PKT:
+            data_length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);
+
+            if ((m_data_received + data_length) > m_image_size)
+            {
+                // The caller is trying to write more bytes into the flash than the size provided to
+                // the dfu_image_size_set function. This is treated as a serious error condition and
+                // an unrecoverable one. Hence point the variable mp_app_write_address to the top of
+                // the flash area. This will ensure that all future application data packet writes
+                // will be blocked because of the above check.
+                m_data_received = 0xFFFFFFFF;
+
+                return NRF_ERROR_DATA_SIZE;
+            }
+
+            // Valid peer activity detected. Hence restart the DFU timer.
+            err_code = dfu_timer_restart();
+            VERIFY_SUCCESS(err_code);
+
+            p_data = (uint32_t *)p_packet->params.data_packet.p_data_packet;
+
+            err_code = pstorage_store(mp_storage_handle_active,
+                                          (uint8_t *)p_data,
+                                          data_length,
+                                          m_data_received);
+            VERIFY_SUCCESS(err_code);
+
+            m_data_received += data_length;
+
+            if (m_data_received != m_image_size)
+            {
+                // The entire image is not received yet. More data is expected.
+                err_code = NRF_ERROR_INVALID_LENGTH;
+            }
+            else
+            {
+                // The entire image has been received. Return NRF_SUCCESS.
+                err_code = NRF_SUCCESS;
+            }
+            break;
+
+        default:
+            err_code = NRF_ERROR_INVALID_STATE;
+            break;
+    }
+
+    return err_code;
+}
+
+
+uint32_t dfu_init_pkt_complete(void)
+{
+    uint32_t err_code = NRF_ERROR_INVALID_STATE;
+    
+    // DFU initialization has been done and a start packet has been received.
+    if (IMAGE_WRITE_IN_PROGRESS())
+    {
+        // Image write is already in progress. Cannot handle an init packet now.
+        return NRF_ERROR_INVALID_STATE;
+    }
+    
+    if (m_dfu_state == DFU_STATE_RX_INIT_PKT)
+    {
+        err_code = dfu_init_prevalidate(m_init_packet, m_init_packet_length);
+        if (err_code == NRF_SUCCESS)
+        {
+            m_dfu_state = DFU_STATE_RX_DATA_PKT;
+        }
+        else
+        {
+            m_init_packet_length = 0;
+        }
+    }
+    return err_code;
+}
+
+
+uint32_t dfu_init_pkt_handle(dfu_update_packet_t * p_packet)
+{
+    uint32_t err_code = NRF_SUCCESS;
+    uint32_t length;
+
+    switch (m_dfu_state)
+    {
+        case DFU_STATE_RDY:
+            m_dfu_state = DFU_STATE_RX_INIT_PKT;
+            // When receiving init packet in state ready just update and fall through this case.         
+
+        case DFU_STATE_RX_INIT_PKT:
+            // DFU initialization has been done and a start packet has been received.
+            if (IMAGE_WRITE_IN_PROGRESS())
+            {
+                // Image write is already in progress. Cannot handle an init packet now.
+                return NRF_ERROR_INVALID_STATE;
+            }
+
+            // Valid peer activity detected. Hence restart the DFU timer.
+            err_code = dfu_timer_restart();
+            VERIFY_SUCCESS(err_code);
+
+            length = p_packet->params.data_packet.packet_length * sizeof(uint32_t);
+            if ((m_init_packet_length + length) > sizeof(m_init_packet))
+            {
+                return NRF_ERROR_INVALID_LENGTH;
+            }
+            
+            memcpy(&m_init_packet[m_init_packet_length],
+                   &p_packet->params.data_packet.p_data_packet[0],
+                   length);
+            m_init_packet_length += length;
+            break;
+
+        default:
+            // Either the start packet was not received or dfu_init function was not called before.
+            err_code = NRF_ERROR_INVALID_STATE;
+            break;
+    }
+
+    return err_code;
+}
+
+
+uint32_t dfu_image_validate()
+{
+    uint32_t err_code;
+
+    switch (m_dfu_state)
+    {
+        case DFU_STATE_RX_DATA_PKT:
+            // Check if the application image write has finished.
+            if (m_data_received != m_image_size)
+            {
+                // Image not yet fully transfered by the peer or the peer has attempted to write
+                // too much data. Hence the validation should fail.
+                err_code = NRF_ERROR_INVALID_STATE;
+            }
+            else
+            {
+                m_dfu_state = DFU_STATE_VALIDATE;
+
+                // Valid peer activity detected. Hence restart the DFU timer.
+                err_code = dfu_timer_restart();
+                if (err_code == NRF_SUCCESS)
+                {
+                    err_code = dfu_init_postvalidate((uint8_t *)mp_storage_handle_active->block_id,
+                                                     m_image_size);
+                    VERIFY_SUCCESS(err_code);
+
+                    m_dfu_state = DFU_STATE_WAIT_4_ACTIVATE;
+                }
+            }
+            break;
+
+        default:
+            err_code = NRF_ERROR_INVALID_STATE;
+            break;
+    }
+
+    return err_code;
+}
+
+
+uint32_t dfu_image_activate()
+{
+    uint32_t err_code;
+
+    switch (m_dfu_state)
+    {
+        case DFU_STATE_WAIT_4_ACTIVATE:
+
+            // Stop the DFU Timer because the peer activity need not be monitored any longer.
+            err_code = app_timer_stop(m_dfu_timer_id);
+            APP_ERROR_CHECK(err_code);
+
+            err_code = m_functions.activate();
+            break;
+
+        default:
+            err_code = NRF_ERROR_INVALID_STATE;
+            break;
+    }
+
+    return err_code;
+}
+
+
+void dfu_reset(void)
+{
+    dfu_update_status_t update_status;
+
+    update_status.status_code = DFU_RESET;
+
+    bootloader_dfu_update_process(update_status);
+}
+
+
+static uint32_t dfu_compare_block(uint32_t * ptr1, uint32_t * ptr2, uint32_t len)
+{
+    sd_mbr_command_t sd_mbr_cmd;
+
+    sd_mbr_cmd.command             = SD_MBR_COMMAND_COMPARE;
+    sd_mbr_cmd.params.compare.ptr1 = ptr1;
+    sd_mbr_cmd.params.compare.ptr2 = ptr2;
+    sd_mbr_cmd.params.compare.len  = len / sizeof(uint32_t);
+
+    return sd_mbr_command(&sd_mbr_cmd);
+}
+
+
+static uint32_t dfu_copy_sd(uint32_t * src, uint32_t * dst, uint32_t len)
+{
+    sd_mbr_command_t sd_mbr_cmd;
+
+    sd_mbr_cmd.command            = SD_MBR_COMMAND_COPY_SD;
+    sd_mbr_cmd.params.copy_sd.src = src;
+    sd_mbr_cmd.params.copy_sd.dst = dst;
+    sd_mbr_cmd.params.copy_sd.len = len / sizeof(uint32_t);
+
+    return sd_mbr_command(&sd_mbr_cmd);
+}
+
+
+static uint32_t dfu_sd_img_block_swap(uint32_t * src, 
+                                      uint32_t * dst, 
+                                      uint32_t len, 
+                                      uint32_t block_size)
+{
+    // It is neccesarry to swap the new SoftDevice in 3 rounds to ensure correct copy of data
+    // and verifucation of data in case power reset occurs during write to flash. 
+    // To ensure the robustness of swapping the images are compared backwards till start of
+    // image swap. If the back is identical everything is swapped.
+    uint32_t err_code = dfu_compare_block(src, dst, len);
+    if (err_code == NRF_SUCCESS)
+    {
+        return err_code;
+    }
+
+    if ((uint32_t)dst > SOFTDEVICE_REGION_START)
+    {
+        err_code = dfu_sd_img_block_swap((uint32_t *)((uint32_t)src - block_size), 
+                                         (uint32_t *)((uint32_t)dst - block_size), 
+                                         block_size, 
+                                         block_size);
+        VERIFY_SUCCESS(err_code);
+    }
+
+    err_code = dfu_copy_sd(src, dst, len);
+    VERIFY_SUCCESS(err_code);
+
+    return dfu_compare_block(src, dst, len);
+}
+
+
+uint32_t dfu_sd_image_swap(void)
+{
+    bootloader_settings_t boot_settings;
+
+    bootloader_settings_get(&boot_settings);
+
+    if (boot_settings.sd_image_size == 0)
+    {
+        return NRF_SUCCESS;
+    }
+    
+    if ((SOFTDEVICE_REGION_START + boot_settings.sd_image_size) > boot_settings.sd_image_start)
+    {
+        uint32_t err_code;
+        uint32_t sd_start        = SOFTDEVICE_REGION_START;
+        uint32_t block_size      = (boot_settings.sd_image_start - sd_start) / 2;
+        uint32_t image_end       = boot_settings.sd_image_start + boot_settings.sd_image_size;
+
+        uint32_t img_block_start = boot_settings.sd_image_start + 2 * block_size;
+        uint32_t sd_block_start  = sd_start + 2 * block_size;
+        
+        if (SD_SIZE_GET(MBR_SIZE) < boot_settings.sd_image_size)
+        {
+            // This will clear a page thus ensuring the old image is invalidated before swapping.
+            err_code = dfu_copy_sd((uint32_t *)(sd_start + block_size), 
+                                   (uint32_t *)(sd_start + block_size), 
+                                   sizeof(uint32_t));
+            VERIFY_SUCCESS(err_code);
+
+            err_code = dfu_copy_sd((uint32_t *)sd_start, (uint32_t *)sd_start, sizeof(uint32_t));
+            VERIFY_SUCCESS(err_code);
+        }
+        
+        return dfu_sd_img_block_swap((uint32_t *)img_block_start, 
+                                     (uint32_t *)sd_block_start, 
+                                     image_end - img_block_start, 
+                                     block_size);
+    }
+    else
+    {
+        if (boot_settings.sd_image_size != 0)
+        {
+            return dfu_copy_sd((uint32_t *)boot_settings.sd_image_start,
+                               (uint32_t *)SOFTDEVICE_REGION_START, 
+                               boot_settings.sd_image_size);
+        }
+    }
+
+    return NRF_SUCCESS;
+}
+
+
+uint32_t dfu_bl_image_swap(void)
+{
+    bootloader_settings_t bootloader_settings;
+    sd_mbr_command_t      sd_mbr_cmd;
+
+    bootloader_settings_get(&bootloader_settings);
+
+    if (bootloader_settings.bl_image_size != 0)
+    {
+        uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ?
+                                  DFU_BANK_1_REGION_START :
+                                  bootloader_settings.sd_image_start + 
+                                  bootloader_settings.sd_image_size;
+
+        sd_mbr_cmd.command               = SD_MBR_COMMAND_COPY_BL;
+        sd_mbr_cmd.params.copy_bl.bl_src = (uint32_t *)(bl_image_start);
+        sd_mbr_cmd.params.copy_bl.bl_len = bootloader_settings.bl_image_size / sizeof(uint32_t);
+
+        return sd_mbr_command(&sd_mbr_cmd);
+    }
+    return NRF_SUCCESS;
+}
+
+
+uint32_t dfu_bl_image_validate(void)
+{
+    bootloader_settings_t bootloader_settings;
+    sd_mbr_command_t      sd_mbr_cmd;
+
+    bootloader_settings_get(&bootloader_settings);
+
+    if (bootloader_settings.bl_image_size != 0)
+    {
+        uint32_t bl_image_start = (bootloader_settings.sd_image_size == 0) ?
+                                  DFU_BANK_1_REGION_START :
+                                  bootloader_settings.sd_image_start +
+                                  bootloader_settings.sd_image_size;
+
+        sd_mbr_cmd.command             = SD_MBR_COMMAND_COMPARE;
+        sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)BOOTLOADER_REGION_START;
+        sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)(bl_image_start);
+        sd_mbr_cmd.params.compare.len  = bootloader_settings.bl_image_size / sizeof(uint32_t);
+
+        return sd_mbr_command(&sd_mbr_cmd);
+    }
+    return NRF_SUCCESS;
+}
+
+
+uint32_t dfu_sd_image_validate(void)
+{
+    bootloader_settings_t bootloader_settings;
+    sd_mbr_command_t      sd_mbr_cmd;
+
+    bootloader_settings_get(&bootloader_settings);
+
+    if (bootloader_settings.sd_image_size == 0)
+    {
+        return NRF_SUCCESS;
+    }
+    
+    if ((SOFTDEVICE_REGION_START + bootloader_settings.sd_image_size) > bootloader_settings.sd_image_start)
+    {
+        uint32_t sd_start        = SOFTDEVICE_REGION_START;
+        uint32_t block_size      = (bootloader_settings.sd_image_start - sd_start) / 2;
+        uint32_t image_end       = bootloader_settings.sd_image_start + 
+                                   bootloader_settings.sd_image_size;
+
+        uint32_t img_block_start = bootloader_settings.sd_image_start + 2 * block_size;
+        uint32_t sd_block_start  = sd_start + 2 * block_size;
+
+        if (SD_SIZE_GET(MBR_SIZE) < bootloader_settings.sd_image_size)
+        {
+            return NRF_ERROR_NULL;
+        }
+
+        return dfu_sd_img_block_swap((uint32_t *)img_block_start, 
+                                     (uint32_t *)sd_block_start, 
+                                     image_end - img_block_start, 
+                                     block_size);
+    }
+    
+    sd_mbr_cmd.command             = SD_MBR_COMMAND_COMPARE;
+    sd_mbr_cmd.params.compare.ptr1 = (uint32_t *)SOFTDEVICE_REGION_START;
+    sd_mbr_cmd.params.compare.ptr2 = (uint32_t *)bootloader_settings.sd_image_start;
+    sd_mbr_cmd.params.compare.len  = bootloader_settings.sd_image_size / sizeof(uint32_t);
+
+    return sd_mbr_command(&sd_mbr_cmd);
+}

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init.h
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init.h b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init.h
new file mode 100644
index 0000000..059ad0d
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init.h
@@ -0,0 +1,134 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/**@file
+ *
+ * @defgroup nrf_dfu_init Init packet handling in DFU
+ * @{
+ *
+ * @brief Device Firmware Update module type and function declaration for init packet handling.
+ *
+ * @details This header contains basic functionality for performing safety checks on software 
+ *          updates for \nRFXX based devices. It provides a skeleton for pre-checking an init packet
+ *          to ensure the following image is compatible with this device. A safety check should 
+ *          always be performed to prevent accidental flashing of unsupported applications or a
+ *          wrong combination of application and SoftDevice.
+ *          The device information contains information such as:
+ *          - Device type (2 bytes), for example Heart Rate. The device type is a number defined by
+ *            the customer. It can be located in UICR or FICR.
+ *          - Device revision (2 bytes), for example major revision 1, minor revision 0. The device
+ *            revision is a number defined by the customer. It can be located in UICR or FICR.
+ *          - List of SoftDevices supported by this application, for example 
+ *              0x0049 = S110v6_0_0 
+ *              0xFFFE = S110 development (any SoftDevice accepted),
+ *          - CRC or hash of firmware image
+ *
+ * @note This module does not support security features such as image signing, but the corresponding
+ *       implementation allows for such extensions.
+ *       If the init packet is signed by a trusted source, it must be decrypted before it can be 
+ *       processed.
+ */
+
+#ifndef DFU_INIT_H__
+#define DFU_INIT_H__
+
+#include <stdint.h>
+#include "nrf.h"
+
+/**@brief Structure contained in an init packet. Contains information on device type, revision, and 
+ *        supported SoftDevices.
+ */
+typedef struct
+{
+    uint16_t device_type;                                                                   /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+    uint16_t device_rev;                                                                    /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+    uint32_t app_version;                                                                   /**< Application version for the image software. This field allows for additional checking, for example ensuring that a downgrade is not allowed. */
+    uint16_t softdevice_len;                                                                /**< Number of different SoftDevice revisions compatible with this application. The list of SoftDevice firmware IDs is defined in @ref softdevice. */
+    uint16_t softdevice[1];                                                                 /**< Variable length array of SoftDevices compatible with this application. The length of the array is specified in the length field. SoftDevice firmware id 0xFFFE indicates any SoftDevice. */
+} dfu_init_packet_t;
+
+/**@brief Structure holding basic device information settings.
+ */
+typedef struct
+{
+    uint16_t device_type;                                                                   /**< Device type (2 bytes), for example Heart Rate. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+    uint16_t device_rev;                                                                    /**< Device revision (2 bytes), for example major revision 1, minor revision 0. This number must be defined by the customer before production. It can be located in UICR or FICR. */
+} dfu_device_info_t;
+
+/** The device info offset can be modified to place the device info settings at a different location.
+  * If the customer reserved UICR location is used for other application specific data, the offset
+  * must be updated to avoid collision with that data.
+  */
+/** [DFU UICR DEV offset] */
+#define UICR_CUSTOMER_DEVICE_INFO_OFFSET    0x0                                             /**< Device info offset inside the customer UICR reserved area. Customers may change this value to place the device information in a user-preferred location. */
+/** [DFU UICR DEV offset] */
+
+#define UICR_CUSTOMER_RESERVED_OFFSET       0x80                                            /**< Customer reserved area in the UICR. The area from UICR + 0x80 is reserved for customer usage. */
+#define DFU_DEVICE_INFO_BASE                (NRF_UICR_BASE + \
+                                             UICR_CUSTOMER_RESERVED_OFFSET + \
+                                             UICR_CUSTOMER_DEVICE_INFO_OFFSET)              /**< The device information base address inside of UICR. */
+#define DFU_DEVICE_INFO                     ((dfu_device_info_t *)DFU_DEVICE_INFO_BASE)     /**< The memory mapped structure for device information data. */
+
+#define DFU_DEVICE_TYPE_EMPTY               ((uint16_t)0xFFFF)                              /**< Mask indicating no device type is present in UICR. 0xFFFF is default flash pattern when not written with data. */
+#define DFU_DEVICE_REVISION_EMPTY           ((uint16_t)0xFFFF)                              /**< Mask indicating no device revision is present in UICR. 0xFFFF is default flash pattern when not written with data. */
+#define DFU_SOFTDEVICE_ANY                  ((uint16_t)0xFFFE)                              /**< Mask indicating that any SoftDevice is allowed for updating this application. Allows for easy development. Not to be used in production images. */
+
+
+/**@brief DFU prevalidate call for pre-checking the received init packet.
+ *
+ * @details  Pre-validation will safety check the firmware image to be transfered in second stage.
+ *           The function currently checks the device type, device revision, application firmware 
+ *           version, and supported SoftDevices. More checks should be added according to 
+ *           customer-specific requirements.
+ * 
+ * @param[in] p_init_data    Pointer to the init packet. If the init packet is encrypted or signed,
+ *                           it must first be decrypted before being checked.
+ * @param[in] init_data_len  Length of the init data.
+ *
+ * @retval NRF_SUCCESS              If the pre-validation succeeded, that means the image is 
+ *                                  supported by the device and it is considered to come from a 
+ *                                  trusted source (signing).
+ * @retval NRF_ERROR_INVALID_DATA   If the pre-validation failed, that means the image is not 
+ *                                  supported by the device or comes from an un-trusted source 
+ *                                  (signing).
+ * @retval NRF_ERROR_INVALID_LENGTH If the size of the init packet is not within the limits of 
+ *                                  the init packet handler.
+ */
+uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len);
+
+/**@brief DFU postvalidate call for post-checking the received image using the init packet.
+ *
+ * @details  Post-validation can verify the integrity check the firmware image received before 
+ *           activating the image.
+ *           Checks performed can be: 
+ *           - A simple CRC as shown in the corresponding implementation of this API in the file
+ *             dfu_init_template.c
+ *           - A hash for better verification of the image.
+ *           - A signature to ensure the image originates from a trusted source.
+ *           Checks are intended to be expanded for customer-specific requirements.
+ * 
+ * @param[in] p_image    Pointer to the received image. The init data provided in the call 
+ *                       \ref dfu_init_prevalidate will be used for validating the image.
+ * @param[in] image_len  Length of the image data.
+ *
+ * @retval NRF_SUCCESS             If the post-validation succeeded, that meant the integrity of the
+ *                                 image has been verified and the image originates from a trusted 
+ *                                 source (signing).
+ * @retval NRF_ERROR_INVALID_DATA  If the post-validation failed, that meant the post check of the 
+ *                                 image failed such as the CRC is not matching the image transfered
+ *                                 or the verification of the image fails (signing).
+ */
+uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len);
+
+#endif // DFU_INIT_H__
+
+/**@} */

http://git-wip-us.apache.org/repos/asf/incubator-mynewt-core/blob/f06c2d2b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init_template.c
----------------------------------------------------------------------
diff --git a/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init_template.c b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init_template.c
new file mode 100644
index 0000000..0d582e1
--- /dev/null
+++ b/hw/mcu/nordic/src/ext/nRF5_SDK_11.0.0_89a8197/components/libraries/bootloader_dfu/dfu_init_template.c
@@ -0,0 +1,155 @@
+/* Copyright (c) 2014 Nordic Semiconductor. All Rights Reserved.
+ *
+ * The information contained herein is property of Nordic Semiconductor ASA.
+ * Terms and conditions of usage are described in detail in NORDIC
+ * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
+ *
+ * Licensees are granted free, non-transferable use of the information. NO
+ * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
+ * the file.
+ *
+ */
+
+/**@file
+ *
+ * @defgroup nrf_dfu_init_template Template file with an DFU init packet handling example.
+ * @{
+ *
+ * @ingroup nrf_dfu
+ *
+ * @brief This file contains a template on how to implement DFU init packet handling.
+ *
+ * @details The template shows how device type and revision can be used for a safety check of the 
+ *          received image. It shows how validation can be performed in two stages:
+ *          - Stage 1: Pre-check of firmware image before transfer to ensure the firmware matches:
+ *                     - Device Type.
+ *                     - Device Revision.
+ *                     Installed SoftDevice.
+ *                     This template can be extended with additional checks according to needs.
+ *                     For example, such a check could be the origin of the image (trusted source) 
+ *                     based on a signature scheme.
+ *          - Stage 2: Post-check of the image after image transfer but before installing firmware.
+ *                     For example, such a check could be an integrity check in form of hashing or 
+ *                     verification of a signature.
+ *                     In this template, a simple CRC check is carried out.
+ *                     The CRC check can be replaced with other mechanisms, like signing.
+ *
+ * @note This module does not support security features such as image signing, but the 
+ *       implementation allows for such extension.
+ *       If the init packet is signed by a trusted source, it must be decrypted before it can be
+ *       processed.
+ */
+
+#include "dfu_init.h"
+#include <stdint.h>
+#include <string.h>
+#include <dfu_types.h>
+#include "nrf_error.h"
+#include "crc16.h"
+
+#define DFU_INIT_PACKET_EXT_LENGTH_MIN      2                       //< Minimum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a minimum value of two in order to hold a CRC. */
+#define DFU_INIT_PACKET_EXT_LENGTH_MAX      10                      //< Maximum length of the extended init packet. The extended init packet may contain a CRC, a HASH, or other data. This value must be changed according to the requirements of the system. The template uses a maximum value of 10 in order to hold a CRC and any padded data on transport layer without overflow. */
+
+static uint8_t m_extended_packet[DFU_INIT_PACKET_EXT_LENGTH_MAX];   //< Data array for storage of the extended data received. The extended data follows the normal init data of type \ref dfu_init_packet_t. Extended data can be used for a CRC, hash, signature, or other data. */
+static uint8_t m_extended_packet_length;                            //< Length of the extended data received with init packet. */
+
+
+uint32_t dfu_init_prevalidate(uint8_t * p_init_data, uint32_t init_data_len)
+{
+    uint32_t i = 0;
+    
+    // In order to support signing or encryption then any init packet decryption function / library
+    // should be called from here or implemented at this location.
+
+    // Length check to ensure valid data are parsed.
+    if (init_data_len < sizeof(dfu_init_packet_t))
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    // Current template uses clear text data so they can be casted for pre-check.
+    dfu_init_packet_t * p_init_packet = (dfu_init_packet_t *)p_init_data;
+
+    m_extended_packet_length = ((uint32_t)p_init_data + init_data_len) -
+                               (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len];
+    if (m_extended_packet_length < DFU_INIT_PACKET_EXT_LENGTH_MIN)
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    if (((uint32_t)p_init_data + init_data_len) < 
+        (uint32_t)&p_init_packet->softdevice[p_init_packet->softdevice_len])
+    {
+        return NRF_ERROR_INVALID_LENGTH;
+    }
+
+    memcpy(m_extended_packet,
+           &p_init_packet->softdevice[p_init_packet->softdevice_len],
+           m_extended_packet_length);
+
+/** [DFU init application version] */
+    // To support application versioning, this check should be updated.
+    // This template allows for any application to be installed. However, 
+    // customers can place a revision number at the bottom of the application 
+    // to be verified by the bootloader. This can be done at a location 
+    // relative to the application, for example the application start 
+    // address + 0x0100.
+/** [DFU init application version] */
+    
+    // First check to verify the image to be transfered matches the device type.
+    // If no Device type is present in DFU_DEVICE_INFO then any image will be accepted.
+    if ((DFU_DEVICE_INFO->device_type != DFU_DEVICE_TYPE_EMPTY) &&
+        (p_init_packet->device_type != DFU_DEVICE_INFO->device_type))
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+    
+    // Second check to verify the image to be transfered matches the device revision.
+    // If no Device revision is present in DFU_DEVICE_INFO then any image will be accepted.
+    if ((DFU_DEVICE_INFO->device_rev != DFU_DEVICE_REVISION_EMPTY) &&
+        (p_init_packet->device_rev != DFU_DEVICE_INFO->device_rev))
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    // Third check: Check the array of supported SoftDevices by this application.
+    //              If the installed SoftDevice does not match any SoftDevice in the list then an
+    //              error is returned.
+    while (i < p_init_packet->softdevice_len)
+    {
+        if (p_init_packet->softdevice[i]   == DFU_SOFTDEVICE_ANY ||
+            p_init_packet->softdevice[i++] == SD_FWID_GET(MBR_SIZE))
+        {
+            return NRF_SUCCESS;
+        }
+    }
+    
+    // No matching SoftDevice found - Return NRF_ERROR_INVALID_DATA.
+    return NRF_ERROR_INVALID_DATA;
+}
+
+
+uint32_t dfu_init_postvalidate(uint8_t * p_image, uint32_t image_len)
+{
+    uint16_t image_crc;
+    uint16_t received_crc;
+    
+    // In order to support hashing (and signing) then the (decrypted) hash should be fetched and
+    // the corresponding hash should be calculated over the image at this location.
+    // If hashing (or signing) is added to the system then the CRC validation should be removed.
+
+    // calculate CRC from active block.
+    image_crc = crc16_compute(p_image, image_len, NULL);
+
+    // Decode the received CRC from extended data.    
+    received_crc = uint16_decode((uint8_t *)&m_extended_packet[0]);
+
+    // Compare the received and calculated CRC.
+    if (image_crc != received_crc)
+    {
+        return NRF_ERROR_INVALID_DATA;
+    }
+
+    return NRF_SUCCESS;
+}
+