aboutsummaryrefslogtreecommitdiff
path: root/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader
diff options
context:
space:
mode:
Diffstat (limited to 'thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader')
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c1238
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h93
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h95
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options3
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c116
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h213
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto66
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c100
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h85
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h132
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c61
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h124
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h90
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c855
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h345
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h173
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c185
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c86
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c222
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c91
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c237
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h74
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h302
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c259
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h167
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c745
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h127
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c241
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h58
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c394
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c77
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h92
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c256
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c126
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h87
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c436
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h96
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c59
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h188
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c134
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h79
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c265
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h109
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c235
-rw-r--r--thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c370
50 files changed, 10316 insertions, 0 deletions
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
new file mode 100644
index 0000000..44b0072
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c
@@ -0,0 +1,1238 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_ble.h"
+
+#include <stddef.h>
+#include "sdk_common.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+#include "nrf_sdm.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_bootloader_info.h"
+#include "ble.h"
+#include "ble_srv_common.h"
+#include "ble_hci.h"
+#include "nrf_sdh.h"
+#include "nrf_sdh_ble.h"
+#include "nrf_balloc.h"
+#include "nrf_delay.h"
+#include "nrf_dfu_settings.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_ble
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#define APP_BLE_CONN_CFG_TAG 1 /**< A tag identifying the SoftDevice BLE configuration. */
+
+#define APP_ADV_DATA_HEADER_SIZE 9 /**< Size of encoded advertisement data header (not including device name). */
+#define APP_ADV_DURATION BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED /**< The advertising duration in units of 10 milliseconds. This is set to @ref BLE_GAP_ADV_TIMEOUT_GENERAL_UNLIMITED so that the advertisement is done as long as there there is a call to @ref dfu_transport_close function.*/
+#define APP_ADV_INTERVAL MSEC_TO_UNITS(25, UNIT_0_625_MS) /**< The advertising interval (25 ms.). */
+
+#define GATT_HEADER_LEN 3 /**< GATT header length. */
+#define GATT_PAYLOAD(mtu) ((mtu) - GATT_HEADER_LEN) /**< Length of the ATT payload for a given ATT MTU. */
+#define MAX_DFU_PKT_LEN (NRF_SDH_BLE_GATT_MAX_MTU_SIZE - GATT_HEADER_LEN) /**< Maximum length (in bytes) of the DFU Packet characteristic (3 bytes are used for the GATT opcode and handle). */
+#define MAX_RESPONSE_LEN 17 /**< Maximum length (in bytes) of the response to a Control Point command. */
+#define RESPONSE_HEADER_LEN 3 /**< The length of the header of a response. I.E. the index of the opcode-specific payload. */
+
+#define DFU_BLE_FLAG_INITIALIZED (1 << 0) /**< Flag to check if the DFU service was initialized by the application.*/
+#define DFU_BLE_FLAG_USE_ADV_NAME (1 << 1) /**< Flag to indicate that advertisement name is to be used. */
+#define DFU_BLE_RESETTING_SOON (1 << 2) /**< Flag to indicate that the device will reset soon. */
+
+#define BLE_OBSERVER_PRIO 2 /**< BLE observer priority. Controls the priority for BLE event handler. */
+
+#if (NRF_DFU_BLE_BUFFERS_OVERRIDE)
+/* If selected, use the override value. */
+#define MAX_DFU_BUFFERS NRF_DFU_BLE_BUFFERS
+#else
+#define MAX_DFU_BUFFERS ((CODE_PAGE_SIZE / MAX_DFU_PKT_LEN) + 1)
+#endif
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS) && (!NRF_SDH_BLE_SERVICE_CHANGED)
+#error NRF_DFU_BLE_REQUIRES_BONDS requires NRF_SDH_BLE_SERVICE_CHANGED. \
+ Please update the SoftDevice BLE stack configuration in sdk_config.h
+#endif
+
+#if (MAX_DFU_PKT_LEN % 4)
+#error Payload length should be a multiple of four. \
+ Payload length is set to NRF_SDH_BLE_GATT_MAX_MTU_SIZE - 3.
+#endif
+
+
+static uint32_t ble_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t ble_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const ble_dfu_transport) =
+{
+ .init_func = ble_dfu_transport_init,
+ .close_func = ble_dfu_transport_close,
+};
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+static nrf_dfu_peer_data_t m_peer_data;
+#else
+static nrf_dfu_adv_name_t m_adv_name;
+#endif
+
+static uint32_t m_flags;
+static ble_dfu_t m_dfu; /**< Structure used to identify the Device Firmware Update service. */
+static uint16_t m_pkt_notif_target; /**< Number of packets of firmware data to be received before transmitting the next Packet Receipt Notification to the DFU Controller. */
+static uint16_t m_pkt_notif_target_cnt; /**< Number of packets of firmware data received after sending last Packet Receipt Notification or since the receipt of a @ref BLE_DFU_PKT_RCPT_NOTIF_ENABLED event from the DFU service, which ever occurs later.*/
+static uint16_t m_conn_handle = BLE_CONN_HANDLE_INVALID; /**< Handle of the current connection. */
+static uint8_t m_adv_handle = BLE_GAP_ADV_SET_HANDLE_NOT_SET; /**< Advertising handle used to identify an advertising set. */
+static nrf_dfu_observer_t m_observer; /**< Observer function called on certain events. */
+
+static ble_gap_conn_params_t const m_gap_conn_params =
+{
+ .min_conn_interval = NRF_DFU_BLE_MIN_CONN_INTERVAL,
+ .max_conn_interval = NRF_DFU_BLE_MAX_CONN_INTERVAL,
+ /* This value is expressed in units of 10 ms, rather than 1 ms. */
+ .conn_sup_timeout = NRF_DFU_BLE_CONN_SUP_TIMEOUT_MS / 10,
+ .slave_latency = 0,
+};
+
+NRF_BALLOC_DEF(m_buffer_pool, MAX_DFU_PKT_LEN, MAX_DFU_BUFFERS);
+
+
+/**@brief Function for the Advertising functionality initialization.
+ *
+ * @details Encodes the required advertising data and passes it to the stack.
+ * The advertising data encoded here is specific for DFU.
+ */
+static uint32_t advertising_init(uint8_t adv_flags, ble_gap_adv_params_t const * const p_adv_params)
+{
+ uint32_t err_code;
+ uint16_t actual_device_name_length = BLE_GAP_ADV_SET_DATA_SIZE_MAX - APP_ADV_DATA_HEADER_SIZE;
+
+ /* This needs to be static because of SoftDevice API requirements. */
+ static uint8_t m_enc_advdata[BLE_GAP_ADV_SET_DATA_SIZE_MAX];
+
+ ble_gap_adv_data_t m_adv_data =
+ {
+ .adv_data =
+ {
+ .p_data = m_enc_advdata,
+ .len = APP_ADV_DATA_HEADER_SIZE,
+ }
+ };
+
+ /* Encode flags. */
+ m_enc_advdata[0] = 0x2;
+ m_enc_advdata[1] = BLE_GAP_AD_TYPE_FLAGS;
+ m_enc_advdata[2] = adv_flags;
+
+ /* Encode 'more available' UUID list. */
+ m_enc_advdata[3] = 0x3;
+ m_enc_advdata[4] = BLE_GAP_AD_TYPE_16BIT_SERVICE_UUID_MORE_AVAILABLE;
+ m_enc_advdata[5] = LSB_16(BLE_DFU_SERVICE_UUID);
+ m_enc_advdata[6] = MSB_16(BLE_DFU_SERVICE_UUID);
+
+ /* Get GAP device name and length. */
+ err_code = sd_ble_gap_device_name_get(&m_enc_advdata[9], &actual_device_name_length);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ // Set GAP device in advertising data.
+ m_enc_advdata[7] = actual_device_name_length + 1; // (actual_length + ADV_AD_TYPE_FIELD_SIZE(1))
+ m_enc_advdata[8] = BLE_GAP_AD_TYPE_COMPLETE_LOCAL_NAME;
+
+ m_adv_data.adv_data.len += actual_device_name_length;
+
+ return sd_ble_gap_adv_set_configure(&m_adv_handle, &m_adv_data, p_adv_params);
+}
+
+
+/**@brief Function for starting advertising.
+ */
+static uint32_t advertising_start(void)
+{
+ uint32_t err_code;
+ uint8_t adv_flag = BLE_GAP_ADV_FLAGS_LE_ONLY_GENERAL_DISC_MODE;
+
+ ble_gap_adv_params_t adv_params =
+ {
+ .properties.type = BLE_GAP_ADV_TYPE_CONNECTABLE_SCANNABLE_UNDIRECTED,
+ .p_peer_addr = NULL,
+ .filter_policy = BLE_GAP_ADV_FP_ANY,
+ .interval = APP_ADV_INTERVAL,
+ .duration = APP_ADV_DURATION,
+ .primary_phy = BLE_GAP_PHY_1MBPS,
+ };
+
+ NRF_LOG_DEBUG("Advertising...");
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+ ble_gap_irk_t empty_irk = {{0}};
+
+ if (memcmp(m_peer_data.ble_id.id_info.irk, empty_irk.irk, sizeof(ble_gap_irk_t)) == 0)
+ {
+ NRF_LOG_DEBUG("No IRK found, general discovery");
+ }
+ else
+ {
+ NRF_LOG_DEBUG("IRK Found, setting up whitelist");
+
+ adv_flag = BLE_GAP_ADV_FLAG_BR_EDR_NOT_SUPPORTED;
+ adv_params.filter_policy = BLE_GAP_ADV_FP_FILTER_CONNREQ;
+
+ ble_gap_addr_t const * const p_gap_addr = &m_peer_data.ble_id.id_addr_info;
+ ble_gap_id_key_t const * const p_gap_id_key = &m_peer_data.ble_id;
+
+ err_code = sd_ble_gap_whitelist_set(&p_gap_addr, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("sd_ble_gap_whitelist_set() returned %s",
+ NRF_LOG_ERROR_STRING_GET(err_code));
+ }
+
+ err_code = sd_ble_gap_device_identities_set(&p_gap_id_key, NULL, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("sd_ble_gap_device_identities_set() returned %s",
+ NRF_LOG_ERROR_STRING_GET(err_code));
+ }
+ }
+#endif /* NRF_DFU_BLE_REQUIRES_BONDS */
+
+ err_code = advertising_init(adv_flag, &adv_params);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ UNUSED_RETURN_VALUE(err_code);
+
+ return sd_ble_gap_adv_start(m_adv_handle, APP_BLE_CONN_CFG_TAG);
+}
+
+
+static bool is_cccd_configured(ble_dfu_t * p_dfu)
+{
+ uint8_t cccd_val_buf[BLE_CCCD_VALUE_LEN];
+
+ ble_gatts_value_t gatts_value =
+ {
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = cccd_val_buf
+ };
+
+ /* Check the CCCD Value of DFU Control Point. */
+ uint32_t err_code = sd_ble_gatts_value_get(m_conn_handle,
+ p_dfu->dfu_ctrl_pt_handles.cccd_handle,
+ &gatts_value);
+ VERIFY_SUCCESS(err_code);
+
+ return ble_srv_is_notification_enabled(cccd_val_buf);
+}
+
+
+static ret_code_t response_send(uint8_t * p_buf, uint16_t len)
+{
+ ble_gatts_hvx_params_t hvx_params =
+ {
+ .handle = m_dfu.dfu_ctrl_pt_handles.value_handle,
+ .type = BLE_GATT_HVX_NOTIFICATION,
+ .p_data = (uint8_t *)(p_buf),
+ .p_len = &len,
+ };
+
+ return sd_ble_gatts_hvx(m_conn_handle, &hvx_params);
+}
+
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+static uint32_t service_changed_send(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_DEBUG("Sending Service Changed indication");
+
+ err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
+ m_peer_data.sys_serv_attr,
+ sizeof(m_peer_data.sys_serv_attr),
+ BLE_GATTS_SYS_ATTR_FLAG_SYS_SRVCS);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gatts_sys_attr_set(m_conn_handle,
+ NULL,
+ 0,
+ BLE_GATTS_SYS_ATTR_FLAG_USR_SRVCS);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gatts_service_changed(m_conn_handle, m_dfu.service_handle, 0xFFFF);
+
+ if ( (err_code == BLE_ERROR_INVALID_CONN_HANDLE)
+ || (err_code == NRF_ERROR_INVALID_STATE)
+ || (err_code == NRF_ERROR_BUSY))
+ {
+ /* These errors can be expected when trying to send a Service Changed indication */
+ /* if the CCCD is not set to indicate. Thus, set the returning error code to success. */
+ NRF_LOG_WARNING("Client did not have the Service Changed indication set to enabled."
+ "Error: 0x%08x", err_code);
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
+#endif
+
+
+/**@brief Function for encoding the beginning of a response.
+ *
+ * @param[inout] p_buffer The buffer to encode into.
+ * @param[in] op_code The opcode of the response.
+ * @param[in] result The result of the operation.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_prepare(uint8_t * p_buffer, uint8_t op_code, uint8_t result)
+{
+ ASSERT(p_buffer);
+ p_buffer[0] = NRF_DFU_OP_RESPONSE;
+ p_buffer[1] = op_code;
+ p_buffer[2] = result;
+ return RESPONSE_HEADER_LEN;
+}
+
+
+/**@brief Function for encoding a select object response into a buffer.
+ *
+ * The select object response consists of a maximum object size, a firmware offset, and a CRC value.
+ *
+ * @param[inout] p_buffer The buffer to encode the response into.
+ * @param[in] max_size The maximum object size value to encode.
+ * @param[in] fw_offset The firmware offset value to encode.
+ * @param[in] crc The CRC value to encode.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_select_obj_add(uint8_t * p_buffer,
+ uint32_t max_size,
+ uint32_t fw_offset,
+ uint32_t crc)
+{
+ uint16_t offset = uint32_encode(max_size, &p_buffer[RESPONSE_HEADER_LEN]);
+ offset += uint32_encode(fw_offset, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ offset += uint32_encode(crc, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ return offset;
+}
+
+
+/**@brief Function for encoding a CRC response into a buffer.
+ *
+ * The CRC response consists of a firmware offset and a CRC value.
+ *
+ * @param[inout] p_buffer The buffer to encode the response into.
+ * @param[in] fw_offset The firmware offset value to encode.
+ * @param[in] crc The CRC value to encode.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_crc_add(uint8_t * p_buffer, uint32_t fw_offset, uint32_t crc)
+{
+ uint16_t offset = uint32_encode(fw_offset, &p_buffer[RESPONSE_HEADER_LEN]);
+ offset += uint32_encode(crc, &p_buffer[RESPONSE_HEADER_LEN + offset]);
+ return offset;
+}
+
+
+/**@brief Function for appending an extended error code to the response buffer.
+ *
+ * @param[inout] p_buffer The buffer to append the extended error code to.
+ * @param[in] result The error code to append.
+ * @param[in] buf_offset The current length of the buffer.
+ *
+ * @return The length added to the buffer.
+ */
+static uint32_t response_ext_err_payload_add(uint8_t * p_buffer, uint8_t result, uint32_t buf_offset)
+{
+ p_buffer[buf_offset] = ext_error_get();
+ (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+ return 1;
+}
+
+
+static void ble_dfu_req_handler_callback(nrf_dfu_response_t * p_res, void * p_context)
+{
+ ASSERT(p_res);
+ ASSERT(p_context);
+
+ uint8_t len = 0;
+ uint8_t buffer[MAX_RESPONSE_LEN] = {0};
+
+ if (p_res->request == NRF_DFU_OP_OBJECT_WRITE)
+ {
+ --m_pkt_notif_target_cnt;
+ if ((m_pkt_notif_target == 0) || (m_pkt_notif_target_cnt && m_pkt_notif_target > 0))
+ {
+ return;
+ }
+
+ /* Reply with a CRC message and reset the packet counter. */
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+
+ p_res->request = NRF_DFU_OP_CRC_GET;
+ }
+
+ len += response_prepare(buffer, p_res->request, p_res->result);
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_WARNING("DFU request %d failed with error: 0x%x", p_res->request, p_res->result);
+
+ if (p_res->result == NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ len += response_ext_err_payload_add(buffer, p_res->result, len);
+ }
+
+ (void) response_send(buffer, len);
+ return;
+ }
+
+ switch (p_res->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ len += response_select_obj_add(buffer,
+ p_res->select.max_size,
+ p_res->select.offset,
+ p_res->select.crc);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ len += response_crc_add(buffer, p_res->write.offset, p_res->write.crc);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ len += response_crc_add(buffer, p_res->crc.offset, p_res->crc.crc);
+ } break;
+
+ default:
+ {
+ // No action.
+ } break;
+ }
+
+ (void) response_send(buffer, len);
+}
+
+
+/**@brief Function for handling a Write event on the Control Point characteristic.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_write_evt Pointer to the write event received from BLE stack.
+ *
+ * @return NRF_SUCCESS on successful processing of control point write. Otherwise an error code.
+ */
+static uint32_t on_ctrl_pt_write(ble_dfu_t * p_dfu, ble_gatts_evt_write_t const * p_ble_write_evt)
+{
+ //lint -save -e415 -e416 : Out-of-bounds access on p_ble_write_evt->data
+ nrf_dfu_request_t request =
+ {
+ .request = (nrf_dfu_op_t)(p_ble_write_evt->data[0]),
+ .p_context = p_dfu,
+ .callback.response = ble_dfu_req_handler_callback,
+ };
+
+ switch (request.request)
+ {
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ /* Set object type to read info about */
+ request.select.object_type = p_ble_write_evt->data[1];
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ /* Activity on the current transport. Close all except the current one. */
+ (void) nrf_dfu_transports_close(&ble_dfu_transport);
+
+ /* Reset the packet receipt notification on create object */
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+
+ request.create.object_type = p_ble_write_evt->data[1];
+ request.create.object_size = uint32_decode(&(p_ble_write_evt->data[2]));
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ NRF_LOG_DEBUG("Set receipt notif");
+
+ m_pkt_notif_target = uint16_decode(&(p_ble_write_evt->data[1]));
+ m_pkt_notif_target_cnt = m_pkt_notif_target;
+ } break;
+
+ default:
+ break;
+ }
+ //lint -restore : Out-of-bounds access
+
+ return nrf_dfu_req_handler_on_req(&request);
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST event from the
+ * SoftDevice.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static bool on_rw_authorize_req(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt)
+{
+ uint32_t err_code;
+
+ ble_gatts_evt_rw_authorize_request_t const * p_authorize_request;
+ ble_gatts_evt_write_t const * p_ble_write_evt;
+
+ p_authorize_request = &(p_ble_evt->evt.gatts_evt.params.authorize_request);
+ p_ble_write_evt = &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write);
+
+ if ( (p_authorize_request->type != BLE_GATTS_AUTHORIZE_TYPE_WRITE)
+ || (p_authorize_request->request.write.handle != p_dfu->dfu_ctrl_pt_handles.value_handle)
+ || (p_authorize_request->request.write.op != BLE_GATTS_OP_WRITE_REQ))
+ {
+ return false;
+ }
+
+ ble_gatts_rw_authorize_reply_params_t auth_reply =
+ {
+ .type = BLE_GATTS_AUTHORIZE_TYPE_WRITE,
+ .params.write.update = 1,
+ .params.write.offset = p_ble_write_evt->offset,
+ .params.write.len = p_ble_write_evt->len,
+ .params.write.p_data = p_ble_write_evt->data,
+ };
+
+ if (!is_cccd_configured(p_dfu))
+ {
+ /* Send an error response to the peer indicating that the CCCD is improperly configured. */
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_ATTERR_CPS_CCCD_CONFIG_ERROR;
+
+ /* Ignore response of auth reply */
+ (void) sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply);
+ return false;
+ }
+ else
+ {
+ auth_reply.params.write.gatt_status = BLE_GATT_STATUS_SUCCESS;
+
+ err_code = sd_ble_gatts_rw_authorize_reply(m_conn_handle, &auth_reply);
+ return err_code == NRF_SUCCESS ? true : false;
+ }
+}
+
+
+static void on_flash_write(void * p_buf)
+{
+ NRF_LOG_DEBUG("Freeing buffer %p", p_buf);
+ nrf_balloc_free(&m_buffer_pool, p_buf);
+}
+
+
+/**@brief Function for handling the @ref BLE_GATTS_EVT_WRITE event from the SoftDevice.
+ *
+ * @param[in] p_dfu DFU Service Structure.
+ * @param[in] p_ble_evt Pointer to the event received from BLE stack.
+ */
+static void on_write(ble_dfu_t * p_dfu, ble_evt_t const * p_ble_evt)
+{
+ ble_gatts_evt_write_t const * const p_write_evt = &p_ble_evt->evt.gatts_evt.params.write;
+
+ if (p_write_evt->handle != p_dfu->dfu_pkt_handles.value_handle)
+ {
+ return;
+ }
+
+ /* Allocate a buffer to receive data. */
+ uint8_t * p_balloc_buf = nrf_balloc_alloc(&m_buffer_pool);
+ if (p_balloc_buf == NULL)
+ {
+ /* Operations are retried by the host; do not give up here. */
+ NRF_LOG_WARNING("cannot allocate memory buffer!");
+ return;
+ }
+
+ NRF_LOG_DEBUG("Buffer %p acquired, len %d (%d)",
+ p_balloc_buf, p_write_evt->len, MAX_DFU_PKT_LEN);
+
+ /* Copy payload into buffer. */
+ memcpy(p_balloc_buf, p_write_evt->data, p_write_evt->len);
+
+ /* Set up the request. */
+ nrf_dfu_request_t request =
+ {
+ .request = NRF_DFU_OP_OBJECT_WRITE,
+ .p_context = p_dfu,
+ .callback =
+ {
+ .response = ble_dfu_req_handler_callback,
+ .write = on_flash_write,
+ }
+ };
+
+ /* Set up the request buffer. */
+ request.write.p_data = p_balloc_buf;
+ request.write.len = p_write_evt->len;
+
+ /* Schedule handling of the request. */
+ ret_code_t rc = nrf_dfu_req_handler_on_req(&request);
+ if (rc != NRF_SUCCESS)
+ {
+ /* The error is logged in nrf_dfu_req_handler_on_req().
+ * Free the buffer.
+ */
+ (void) nrf_balloc_free(&m_buffer_pool, p_balloc_buf);
+ }
+}
+
+
+/**@brief Function for the Application's SoftDevice event handler.
+ *
+ * @param[in] p_ble_evt SoftDevice event.
+ */
+static void ble_evt_handler(ble_evt_t const * p_ble_evt, void * p_context)
+{
+ uint32_t err_code;
+ ble_gap_evt_t const * const p_gap = &p_ble_evt->evt.gap_evt;
+
+ switch (p_ble_evt->header.evt_id)
+ {
+ case BLE_GAP_EVT_CONNECTED:
+ {
+ NRF_LOG_DEBUG("Connected");
+
+ m_conn_handle = p_gap->conn_handle;
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+
+ err_code = sd_ble_gap_conn_param_update(m_conn_handle, &m_gap_conn_params);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failure to update connection parameters: 0x%x", err_code);
+ }
+ } break;
+
+ case BLE_GAP_EVT_DISCONNECTED:
+ {
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ /* Restart advertising so that the DFU Controller can reconnect if possible. */
+ if (!(m_flags & DFU_BLE_RESETTING_SOON))
+ {
+ err_code = advertising_start();
+ APP_ERROR_CHECK(err_code);
+ }
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_DEACTIVATED);
+ }
+ } break;
+
+ case BLE_GATTS_EVT_WRITE:
+ {
+ on_write(&m_dfu, p_ble_evt);
+ } break;
+
+ case BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST:
+ {
+ uint16_t const mtu_requested =
+ p_ble_evt->evt.gatts_evt.params.exchange_mtu_request.client_rx_mtu;
+
+ /* If the requested MTU is smaller than the maximum, we can accept with the given
+ * stack configuration, and the payload is not word-aligned, reply with a smaller MTU
+ * that has a word-aligned payload. This ensures that the length of data we write to
+ * flash is a multiple of the word size.
+ */
+ uint16_t mtu_reply;
+
+ if (mtu_requested < NRF_SDH_BLE_GATT_MAX_MTU_SIZE)
+ {
+ /* Round the payload size down to a multiple of 4 so it is word-aligned. */
+ if (GATT_PAYLOAD(mtu_requested) % 4)
+ {
+ mtu_reply = GATT_PAYLOAD(mtu_requested) - 4;
+ mtu_reply = ALIGN_NUM(4, mtu_reply);
+ /* Add the header len to the MTU. */
+ mtu_reply += GATT_HEADER_LEN;
+ }
+ else
+ {
+ mtu_reply = mtu_requested;
+ }
+ }
+ else
+ {
+ mtu_reply = NRF_SDH_BLE_GATT_MAX_MTU_SIZE;
+ }
+
+ NRF_LOG_DEBUG("Received BLE_GATTS_EVT_EXCHANGE_MTU_REQUEST (request: %d, reply: %d).",
+ mtu_requested, mtu_reply);
+
+ err_code = sd_ble_gatts_exchange_mtu_reply(m_conn_handle, mtu_reply);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_DATA_LENGTH_UPDATE_REQUEST.");
+
+ ble_gap_data_length_params_t const dlp =
+ {
+ .max_rx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+ .max_tx_octets = BLE_GAP_DATA_LENGTH_AUTO,
+ };
+
+ err_code = sd_ble_gap_data_length_update(p_ble_evt->evt.gatts_evt.conn_handle,
+ &dlp, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+
+ case BLE_GAP_EVT_DATA_LENGTH_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_DATA_LENGTH_UPDATE (%u, max_rx_time %u).",
+ p_gap->params.data_length_update.effective_params.max_rx_octets,
+ p_gap->params.data_length_update.effective_params.max_rx_time_us);
+ } break;
+
+ case BLE_GAP_EVT_SEC_PARAMS_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_SEC_PARAMS_REQUEST");
+
+ uint16_t cccd;
+ ble_gatts_value_t gatts_value =
+ {
+ .len = BLE_CCCD_VALUE_LEN,
+ .p_value = (uint8_t*)&cccd
+ };
+
+ err_code = sd_ble_gatts_value_get(m_conn_handle,
+ BLE_UUID_GATT_CHARACTERISTIC_SERVICE_CHANGED,
+ &gatts_value);
+ APP_ERROR_CHECK(err_code);
+
+ NRF_LOG_DEBUG("CCCD for service changed is 0x%04x", cccd);
+
+ err_code = sd_ble_gap_sec_params_reply(m_conn_handle,
+ BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP,
+ NULL,
+ NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_CONN_PARAM_UPDATE");
+
+ ble_gap_conn_params_t const * p_conn =
+ &p_gap->params.conn_param_update.conn_params;
+
+ NRF_LOG_DEBUG("max_conn_interval: %d", p_conn->max_conn_interval);
+ NRF_LOG_DEBUG("min_conn_interval: %d", p_conn->min_conn_interval);
+ NRF_LOG_DEBUG("slave_latency: %d", p_conn->slave_latency);
+ NRF_LOG_DEBUG("conn_sup_timeout: %d", p_conn->conn_sup_timeout);
+ } break;
+
+ case BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_CONN_PARAM_UPDATE_REQUEST");
+
+ err_code = sd_ble_gap_conn_param_update(m_conn_handle,
+ &p_gap->params.conn_param_update_request.conn_params);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failure to update connection parameter request: 0x%x", err_code);
+ }
+
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_PHY_UPDATE:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_PHY_UPDATE (RX:%d, TX:%d, status:%d)",
+ p_gap->params.phy_update.rx_phy,
+ p_gap->params.phy_update.tx_phy,
+ p_gap->params.phy_update.status);
+ break;
+ }
+
+ case BLE_GAP_EVT_PHY_UPDATE_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_PHY_UPDATE_REQUEST.");
+
+ ble_gap_phys_t const phys =
+ {
+ .rx_phys = BLE_GAP_PHY_AUTO,
+ .tx_phys = BLE_GAP_PHY_AUTO,
+ };
+
+ err_code = sd_ble_gap_phy_update(p_gap->conn_handle, &phys);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GATTS_EVT_TIMEOUT:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.timeout.src == BLE_GATT_TIMEOUT_SRC_PROTOCOL)
+ {
+ err_code = sd_ble_gap_disconnect(m_conn_handle,
+ BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ APP_ERROR_CHECK(err_code);
+ }
+ } break;
+
+ case BLE_EVT_USER_MEM_REQUEST:
+ {
+ err_code = sd_ble_user_mem_reply(m_conn_handle, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GATTS_EVT_RW_AUTHORIZE_REQUEST:
+ {
+ if (p_ble_evt->evt.gatts_evt.params.authorize_request.type
+ != BLE_GATTS_AUTHORIZE_TYPE_INVALID)
+ {
+ if (on_rw_authorize_req(&m_dfu, p_ble_evt))
+ {
+ err_code = on_ctrl_pt_write(&m_dfu,
+ &(p_ble_evt->evt.gatts_evt.params.authorize_request.request.write));
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not handle on_ctrl_pt_write. err_code: 0x%04x", err_code);
+ }
+ }
+ }
+ } break;
+
+ case BLE_GAP_EVT_SEC_INFO_REQUEST:
+ {
+ NRF_LOG_DEBUG("Received BLE_GAP_EVT_SEC_INFO_REQUEST");
+
+ ble_gap_enc_info_t * p_enc_info = NULL;
+ ble_gap_irk_t * p_id_info = NULL;
+
+ #if (NRF_DFU_BLE_REQUIRES_BONDS)
+ /* If there is a match in diversifier, then set the correct keys. */
+ if (p_gap->params.sec_info_request.master_id.ediv ==
+ m_peer_data.enc_key.master_id.ediv)
+ {
+ p_enc_info = &m_peer_data.enc_key.enc_info;
+ }
+ p_id_info = &m_peer_data.ble_id.id_info;
+ #endif
+
+ err_code = sd_ble_gap_sec_info_reply(p_gap->conn_handle, p_enc_info, p_id_info, NULL);
+ APP_ERROR_CHECK(err_code);
+ } break;
+
+ case BLE_GAP_EVT_CONN_SEC_UPDATE:
+ case BLE_GATTS_EVT_SYS_ATTR_MISSING:
+ {
+ #if (NRF_DFU_BLE_REQUIRES_BONDS)
+ err_code = service_changed_send();
+ #else
+ err_code = sd_ble_gatts_sys_attr_set(p_gap->conn_handle, NULL, 0, 0);
+ #endif
+ APP_ERROR_CHECK(err_code);
+ NRF_LOG_DEBUG("Finished handling conn sec update");
+ } break;
+
+ default:
+ /* No implementation needed. */
+ break;
+ }
+}
+
+
+#if (!NRF_DFU_BLE_REQUIRES_BONDS)
+static uint32_t gap_address_change(void)
+{
+ uint32_t err_code;
+ ble_gap_addr_t addr;
+
+ err_code = sd_ble_gap_addr_get(&addr);
+ VERIFY_SUCCESS(err_code);
+
+ /* Increase the BLE address by one when advertising openly. */
+ addr.addr[0] += 1;
+
+ err_code = sd_ble_gap_addr_set(&addr);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+#endif
+
+
+/**@brief Function for initializing GAP.
+ *
+ * @details This function sets up all necessary GAP (Generic Access Profile) parameters of
+ * the device. It also sets the permissions and appearance.
+ */
+static uint32_t gap_params_init(void)
+{
+ uint32_t err_code;
+ ble_gap_conn_sec_mode_t sec_mode;
+ uint8_t const * device_name;
+ uint32_t name_len;
+
+ BLE_GAP_CONN_SEC_MODE_SET_OPEN(&sec_mode);
+
+#if (!NRF_DFU_BLE_REQUIRES_BONDS)
+
+ err_code = gap_address_change();
+ VERIFY_SUCCESS(err_code);
+
+ if ((m_flags & DFU_BLE_FLAG_USE_ADV_NAME) != 0)
+ {
+ NRF_LOG_DEBUG("Setting adv name: %s, length: %d", m_adv_name.name, m_adv_name.len);
+ device_name = m_adv_name.name;
+ name_len = m_adv_name.len;
+ }
+ else
+#endif
+ {
+ NRF_LOG_DEBUG("Using default advertising name");
+ device_name = (uint8_t const *)(NRF_DFU_BLE_ADV_NAME);
+ name_len = strlen(NRF_DFU_BLE_ADV_NAME);
+ }
+
+ err_code = sd_ble_gap_device_name_set(&sec_mode, device_name, name_len);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = sd_ble_gap_ppcp_set(&m_gap_conn_params);
+ return err_code;
+}
+
+
+static uint32_t ble_stack_init()
+{
+ ret_code_t err_code;
+ uint32_t ram_start = 0;
+
+ /* Register as a BLE event observer to receive BLE events. */
+ NRF_SDH_BLE_OBSERVER(m_ble_evt_observer, BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
+
+ err_code = nrf_dfu_mbr_init_sd();
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Setting up vector table: 0x%08x", BOOTLOADER_START_ADDR);
+ err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_START_ADDR);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Enabling SoftDevice.");
+ err_code = nrf_sdh_enable_request();
+ VERIFY_SUCCESS(err_code);
+
+ /* Fetch the start address of the application RAM. */
+ err_code = nrf_sdh_ble_app_ram_start_get(&ram_start);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Configuring BLE stack.");
+ err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
+ VERIFY_SUCCESS(err_code);
+
+ /* Enable the BLE stack. */
+ NRF_LOG_DEBUG("Enabling the BLE stack.");
+ return nrf_sdh_ble_enable(&ram_start);
+}
+
+
+/**@brief Function for adding DFU Packet characteristic to the BLE Stack.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_pkt_char_add(ble_dfu_t * const p_dfu)
+{
+ ble_gatts_char_md_t char_md =
+ {
+ .char_props.write_wo_resp = 1,
+ };
+
+ ble_uuid_t char_uuid =
+ {
+ .type = p_dfu->uuid_type,
+ .uuid = BLE_DFU_PKT_CHAR_UUID,
+ };
+
+ ble_gatts_attr_md_t attr_md =
+ {
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .vlen = 1,
+ .write_perm =
+ {
+ .sm = 1,
+ #if NRF_DFU_BLE_REQUIRES_BONDS
+ .lv = 2,
+ #else
+ .lv = 1,
+ #endif
+ }
+ };
+
+ ble_gatts_attr_t attr_char_value =
+ {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &attr_md,
+ .max_len = MAX_DFU_PKT_LEN,
+ };
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->dfu_pkt_handles);
+}
+
+
+/**@brief Function for adding DFU Control Point characteristic to the BLE Stack.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return NRF_SUCCESS on success. Otherwise an error code.
+ */
+static uint32_t dfu_ctrl_pt_add(ble_dfu_t * const p_dfu)
+{
+ ble_gatts_char_md_t char_md =
+ {
+ .char_props.write = 1,
+ .char_props.notify = 1,
+ };
+
+ ble_uuid_t char_uuid =
+ {
+ .type = p_dfu->uuid_type,
+ .uuid = BLE_DFU_CTRL_PT_UUID,
+ };
+
+ ble_gatts_attr_md_t attr_md =
+ {
+ .vloc = BLE_GATTS_VLOC_STACK,
+ .wr_auth = 1,
+ .vlen = 1,
+ .write_perm =
+ {
+ .sm = 1,
+ #if NRF_DFU_BLE_REQUIRES_BONDS
+ .lv = 2,
+ #else
+ .lv = 1,
+ #endif
+ },
+ };
+
+ ble_gatts_attr_t attr_char_value =
+ {
+ .p_uuid = &char_uuid,
+ .p_attr_md = &attr_md,
+ .max_len = BLE_GATT_ATT_MTU_DEFAULT,
+ };
+
+ return sd_ble_gatts_characteristic_add(p_dfu->service_handle,
+ &char_md,
+ &attr_char_value,
+ &p_dfu->dfu_ctrl_pt_handles);
+}
+
+
+/**@brief Function for checking if the CCCD of DFU Control point is configured for Notification.
+ *
+ * @details This function checks if the CCCD of DFU Control Point characteristic is configured
+ * for Notification by the DFU Controller.
+ *
+ * @param[in] p_dfu DFU Service structure.
+ *
+ * @return True if the CCCD of DFU Control Point characteristic is configured for Notification.
+ * False otherwise.
+ */
+uint32_t ble_dfu_init(ble_dfu_t * p_dfu)
+{
+ ASSERT(p_dfu != NULL);
+
+ ble_uuid_t service_uuid;
+ uint32_t err_code;
+
+ m_conn_handle = BLE_CONN_HANDLE_INVALID;
+
+ BLE_UUID_BLE_ASSIGN(service_uuid, BLE_DFU_SERVICE_UUID);
+
+ err_code = sd_ble_gatts_service_add(BLE_GATTS_SRVC_TYPE_PRIMARY,
+ &service_uuid,
+ &(p_dfu->service_handle));
+ VERIFY_SUCCESS(err_code);
+
+ ble_uuid128_t const base_uuid128 =
+ {
+ {
+ 0x50, 0xEA, 0xDA, 0x30, 0x88, 0x83, 0xB8, 0x9F,
+ 0x60, 0x4F, 0x15, 0xF3, 0x00, 0x00, 0xC9, 0x8E
+ }
+ };
+
+ err_code = sd_ble_uuid_vs_add(&base_uuid128, &p_dfu->uuid_type);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = dfu_pkt_char_add(p_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = dfu_ctrl_pt_add(p_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t ble_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_flags & DFU_BLE_FLAG_INITIALIZED)
+ {
+ return err_code;
+ }
+
+ NRF_LOG_DEBUG("Initializing BLE DFU transport");
+
+ m_observer = observer;
+
+ err_code = nrf_balloc_init(&m_buffer_pool);
+ UNUSED_RETURN_VALUE(err_code);
+
+ err_code = ble_stack_init();
+ VERIFY_SUCCESS(err_code);
+
+#if (NRF_DFU_BLE_REQUIRES_BONDS)
+ /* Copy out the peer data if bonds are required */
+ if (nrf_dfu_settings_peer_data_is_valid())
+ {
+ NRF_LOG_DEBUG("Copying peer data");
+
+ err_code = nrf_dfu_settings_peer_data_copy(&m_peer_data);
+ UNUSED_RETURN_VALUE(err_code);
+ }
+ else
+ {
+ APP_ERROR_HANDLER(NRF_ERROR_INTERNAL);
+ }
+#else
+ /* Copy out the new advertisement name when bonds are not required and the name is set. */
+ if (nrf_dfu_settings_adv_name_is_valid())
+ {
+ err_code = nrf_dfu_settings_adv_name_copy(&m_adv_name);
+ UNUSED_RETURN_VALUE(err_code);
+
+ /* Set flags for advertisement name that is to be used */
+ m_flags |= DFU_BLE_FLAG_USE_ADV_NAME;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No advertising name found");
+ }
+#endif
+
+ err_code = gap_params_init();
+ VERIFY_SUCCESS(err_code);
+
+ /* Initialize the Device Firmware Update Service. */
+ err_code = ble_dfu_init(&m_dfu);
+ VERIFY_SUCCESS(err_code);
+
+ err_code = advertising_start();
+ VERIFY_SUCCESS(err_code);
+
+ m_flags |= DFU_BLE_FLAG_INITIALIZED;
+
+ NRF_LOG_DEBUG("BLE DFU transport initialized.");
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t ble_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if ((m_flags & DFU_BLE_FLAG_INITIALIZED) && (p_exception != &ble_dfu_transport))
+ {
+ NRF_LOG_DEBUG("Shutting down BLE transport.");
+
+ if (m_conn_handle != BLE_CONN_HANDLE_INVALID)
+ {
+ NRF_LOG_DEBUG("Disconnecting.");
+
+ /* Set flag to prevent advertisement from starting */
+ m_flags |= DFU_BLE_RESETTING_SOON;
+
+ /* Disconnect from the peer. */
+ err_code = sd_ble_gap_disconnect(m_conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION);
+ VERIFY_SUCCESS(err_code);
+
+ /* Wait a bit for the disconnect event to be sent on air. */
+ nrf_delay_ms(200);
+ }
+ else
+ {
+ err_code = sd_ble_gap_adv_stop(m_adv_handle);
+ UNUSED_RETURN_VALUE(err_code);
+ }
+
+ err_code = nrf_sdh_disable_request();
+ if (err_code == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("BLE transport shut down.");
+ }
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h
new file mode 100644
index 0000000..04d2d55
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble.h
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu_ble DFU BLE Service
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer for <em>Bluetooth</em> low energy.
+ *
+ * @details The Device Firmware Update (DFU) Service is a GATT-based service that can be used for
+ * performing firmware updates over BLE. Note that this implementation uses
+ * vendor-specific UUIDs for the service and characteristics, and is intended to demonstrate
+ * firmware updates over BLE. See @ref lib_dfu_transport_ble "DFU Transport: BLE" for more information on the service and the profile.
+ */
+
+#ifndef NRF_DFU_BLE_H__
+#define NRF_DFU_BLE_H__
+
+#include <stdint.h>
+#include "ble_gatts.h"
+#include "ble.h"
+#include "nrf_dfu_transport.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// This is a 16-bit UUID.
+#define BLE_DFU_SERVICE_UUID 0xFE59 //!< UUID of the DFU Service.
+
+// These UUIDs are used with the Nordic base address to create a 128-bit UUID (0x8EC9XXXXF3154F609FB8838830DAEA50).
+#define BLE_DFU_CTRL_PT_UUID 0x0001 //!< UUID of the DFU Control Point.
+#define BLE_DFU_PKT_CHAR_UUID 0x0002 //!< UUID of the DFU Packet Characteristic.
+
+
+/**@brief DFU Service.
+ *
+ * @details This structure contains status information related to the service.
+ */
+typedef struct
+{
+ uint16_t service_handle; /**< Handle of the DFU Service (as provided by the SoftDevice). */
+ uint8_t uuid_type; /**< UUID type assigned to the DFU Service by the SoftDevice. */
+ ble_gatts_char_handles_t dfu_pkt_handles; /**< Handles related to the DFU Packet Characteristic. */
+ ble_gatts_char_handles_t dfu_ctrl_pt_handles; /**< Handles related to the DFU Control Point Characteristic. */
+} ble_dfu_t;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_BLE_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h
new file mode 100644
index 0000000..0377a4c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/ble_dfu/nrf_dfu_ble_svci_bond_sharing.h
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu_svci_bond_sharing Supervisor call interface for bond sharing
+ * @{
+ * @ingroup nrf_dfu
+ * @brief The Supervisor call interface is a thread-safe method to call into the current application or into an external application using a Supervisor instruction.
+ *
+ */
+
+
+#ifndef NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+#define NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+
+#include <stdbool.h>
+#include "nrf_svci.h"
+#include "nrf_svci_async_function.h"
+#include "sdk_config.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_DFU_SVCI_SET_PEER_DATA 2
+#define NRF_DFU_SVCI_SET_ADV_NAME 3
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+
+/**@brief Sets up the async SVCI interface for exchanging peer data like bonding and the system attribute table.
+ *
+ * @details The peer data will be stored in flash by the bootloader. This requires memory management and
+ * handling forwarding of system events and state from the main application to the bootloader.
+ *
+ * @note This is only available in the buttonless DFU that supports bond sharing.
+ */
+NRF_SVCI_ASYNC_FUNC_DECLARE(NRF_DFU_SVCI_SET_PEER_DATA, nrf_dfu_set_peer_data, nrf_dfu_peer_data_t, nrf_dfu_peer_data_state_t);
+
+/**@brief Sets up the async SVCI interface for exchanging advertisement name to use when entering DFU mode.
+ *
+ * @details The advertisement name will be stored in flash by the bootloader. This requires memory management
+ * and handling forwarding of system events and state from the main application to the bootloader.
+ *
+ * @note This is only available in the buttonless DFU that does not support bond sharing.
+ */
+NRF_SVCI_ASYNC_FUNC_DECLARE(NRF_DFU_SVCI_SET_ADV_NAME, nrf_dfu_set_adv_name, nrf_dfu_adv_name_t, nrf_dfu_set_adv_name_state_t);
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_BLE_SVCI_BOND_SHARING_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options
new file mode 100644
index 0000000..a9ed61e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.options
@@ -0,0 +1,3 @@
+dfu.Hash.hash max_size:32
+dfu.SignedCommand.signature max_size:64
+dfu.InitCommand.sd_req max_count:16 \ No newline at end of file
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c
new file mode 100644
index 0000000..2396dc6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.c
@@ -0,0 +1,116 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb constant definitions */
+/* Generated by nanopb-0.3.6-dev at Wed Dec 13 13:37:53 2017. */
+
+#include "dfu-cc.pb.h"
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+const bool dfu_init_command_is_debug_default = false;
+
+
+const pb_field_t dfu_hash_fields[3] = {
+ PB_FIELD( 1, UENUM , REQUIRED, STATIC , FIRST, dfu_hash_t, hash_type, hash_type, 0),
+ PB_FIELD( 2, BYTES , REQUIRED, STATIC , OTHER, dfu_hash_t, hash, hash_type, 0),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_init_command_fields[10] = {
+ PB_FIELD( 1, UINT32 , OPTIONAL, STATIC , FIRST, dfu_init_command_t, fw_version, fw_version, 0),
+ PB_FIELD( 2, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, hw_version, fw_version, 0),
+ PB_FIELD( 3, UINT32 , REPEATED, STATIC , OTHER, dfu_init_command_t, sd_req, hw_version, 0),
+ PB_FIELD( 4, UENUM , OPTIONAL, STATIC , OTHER, dfu_init_command_t, type, sd_req, 0),
+ PB_FIELD( 5, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, sd_size, type, 0),
+ PB_FIELD( 6, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, bl_size, sd_size, 0),
+ PB_FIELD( 7, UINT32 , OPTIONAL, STATIC , OTHER, dfu_init_command_t, app_size, bl_size, 0),
+ PB_FIELD( 8, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_init_command_t, hash, app_size, &dfu_hash_fields),
+ PB_FIELD( 9, BOOL , OPTIONAL, STATIC , OTHER, dfu_init_command_t, is_debug, hash, &dfu_init_command_is_debug_default),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_command_fields[3] = {
+ PB_FIELD( 1, UENUM , OPTIONAL, STATIC , FIRST, dfu_command_t, op_code, op_code, 0),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_command_t, init, op_code, &dfu_init_command_fields),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_signed_command_fields[4] = {
+ PB_FIELD( 1, MESSAGE , REQUIRED, STATIC , FIRST, dfu_signed_command_t, command, command, &dfu_command_fields),
+ PB_FIELD( 2, UENUM , REQUIRED, STATIC , OTHER, dfu_signed_command_t, signature_type, command, 0),
+ PB_FIELD( 3, BYTES , REQUIRED, STATIC , OTHER, dfu_signed_command_t, signature, signature_type, 0),
+ PB_LAST_FIELD
+};
+
+const pb_field_t dfu_packet_fields[3] = {
+ PB_FIELD( 1, MESSAGE , OPTIONAL, STATIC , FIRST, dfu_packet_t, command, command, &dfu_command_fields),
+ PB_FIELD( 2, MESSAGE , OPTIONAL, STATIC , OTHER, dfu_packet_t, signed_command, command, &dfu_signed_command_fields),
+ PB_LAST_FIELD
+};
+
+
+/* Check that field information fits in pb_field_t */
+#if !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_32BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in 8 or 16 bit
+ * field descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 65536 && pb_membersize(dfu_command_t, init) < 65536 && pb_membersize(dfu_signed_command_t, command) < 65536 && pb_membersize(dfu_packet_t, command) < 65536 && pb_membersize(dfu_packet_t, signed_command) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_command_dfu_signed_command_dfu_packet)
+#endif
+
+#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT)
+/* If you get an error here, it means that you need to define PB_FIELD_16BIT
+ * compile-time option. You can do that in pb.h or on compiler command line.
+ *
+ * The reason you need to do this is that some of your messages contain tag
+ * numbers or field sizes that are larger than what can fit in the default
+ * 8 bit descriptors.
+ */
+PB_STATIC_ASSERT((pb_membersize(dfu_init_command_t, hash) < 256 && pb_membersize(dfu_command_t, init) < 256 && pb_membersize(dfu_signed_command_t, command) < 256 && pb_membersize(dfu_packet_t, command) < 256 && pb_membersize(dfu_packet_t, signed_command) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_dfu_hash_dfu_init_command_dfu_command_dfu_signed_command_dfu_packet)
+#endif
+
+
+/* @@protoc_insertion_point(eof) */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h
new file mode 100644
index 0000000..fae43c5
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.pb.h
@@ -0,0 +1,213 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/* Automatically generated nanopb header */
+/* Generated by nanopb-0.3.6-dev at Wed Dec 13 13:37:53 2017. */
+
+#ifndef PB_DFU_CC_PB_H_INCLUDED
+#define PB_DFU_CC_PB_H_INCLUDED
+#include <pb.h>
+
+/* @@protoc_insertion_point(includes) */
+#if PB_PROTO_HEADER_VERSION != 30
+#error Regenerate this file with the current version of nanopb generator.
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Enum definitions */
+typedef enum
+{
+ DFU_FW_TYPE_APPLICATION = 0,
+ DFU_FW_TYPE_SOFTDEVICE = 1,
+ DFU_FW_TYPE_BOOTLOADER = 2,
+ DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER = 3
+} dfu_fw_type_t;
+#define DFU_FW_TYPE_MIN DFU_FW_TYPE_APPLICATION
+#define DFU_FW_TYPE_MAX DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER
+#define DFU_FW_TYPE_ARRAYSIZE ((dfu_fw_type_t)(DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER+1))
+
+typedef enum
+{
+ DFU_HASH_TYPE_NO_HASH = 0,
+ DFU_HASH_TYPE_CRC = 1,
+ DFU_HASH_TYPE_SHA128 = 2,
+ DFU_HASH_TYPE_SHA256 = 3,
+ DFU_HASH_TYPE_SHA512 = 4
+} dfu_hash_type_t;
+#define DFU_HASH_TYPE_MIN DFU_HASH_TYPE_NO_HASH
+#define DFU_HASH_TYPE_MAX DFU_HASH_TYPE_SHA512
+#define DFU_HASH_TYPE_ARRAYSIZE ((dfu_hash_type_t)(DFU_HASH_TYPE_SHA512+1))
+
+typedef enum
+{
+ DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256 = 0,
+ DFU_SIGNATURE_TYPE_ED25519 = 1
+} dfu_signature_type_t;
+#define DFU_SIGNATURE_TYPE_MIN DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256
+#define DFU_SIGNATURE_TYPE_MAX DFU_SIGNATURE_TYPE_ED25519
+#define DFU_SIGNATURE_TYPE_ARRAYSIZE ((dfu_signature_type_t)(DFU_SIGNATURE_TYPE_ED25519+1))
+
+typedef enum
+{
+ DFU_COMMAND_OP_CODE_INIT = 1
+} dfu_command_op_code_t;
+#define DFU_COMMAND_OP_CODE_MIN DFU_COMMAND_OP_CODE_INIT
+#define DFU_COMMAND_OP_CODE_MAX DFU_COMMAND_OP_CODE_INIT
+#define DFU_COMMAND_OP_CODE_ARRAYSIZE ((dfu_command_op_code_t)(DFU_COMMAND_OP_CODE_INIT+1))
+
+/* Struct definitions */
+typedef PB_BYTES_ARRAY_T(32) dfu_hash_hash_t;
+typedef struct {
+ dfu_hash_type_t hash_type;
+ dfu_hash_hash_t hash;
+/* @@protoc_insertion_point(struct:dfu_hash_t) */
+} dfu_hash_t;
+
+typedef struct {
+ bool has_fw_version;
+ uint32_t fw_version;
+ bool has_hw_version;
+ uint32_t hw_version;
+ pb_size_t sd_req_count;
+ uint32_t sd_req[16];
+ bool has_type;
+ dfu_fw_type_t type;
+ bool has_sd_size;
+ uint32_t sd_size;
+ bool has_bl_size;
+ uint32_t bl_size;
+ bool has_app_size;
+ uint32_t app_size;
+ bool has_hash;
+ dfu_hash_t hash;
+ bool has_is_debug;
+ bool is_debug;
+/* @@protoc_insertion_point(struct:dfu_init_command_t) */
+} dfu_init_command_t;
+
+typedef struct {
+ bool has_op_code;
+ dfu_command_op_code_t op_code;
+ bool has_init;
+ dfu_init_command_t init;
+/* @@protoc_insertion_point(struct:dfu_command_t) */
+} dfu_command_t;
+
+typedef PB_BYTES_ARRAY_T(64) dfu_signed_command_signature_t;
+typedef struct {
+ dfu_command_t command;
+ dfu_signature_type_t signature_type;
+ dfu_signed_command_signature_t signature;
+/* @@protoc_insertion_point(struct:dfu_signed_command_t) */
+} dfu_signed_command_t;
+
+typedef struct {
+ bool has_command;
+ dfu_command_t command;
+ bool has_signed_command;
+ dfu_signed_command_t signed_command;
+/* @@protoc_insertion_point(struct:dfu_packet_t) */
+} dfu_packet_t;
+
+/* Default values for struct fields */
+extern const bool dfu_init_command_is_debug_default;
+
+/* Initializer values for message structs */
+#define DFU_HASH_INIT_DEFAULT {(dfu_hash_type_t)0, {0, {0}}}
+#define DFU_INIT_COMMAND_INIT_DEFAULT {false, 0, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_DEFAULT, false, false}
+#define DFU_COMMAND_INIT_DEFAULT {false, (dfu_command_op_code_t)0, false, DFU_INIT_COMMAND_INIT_DEFAULT}
+#define DFU_SIGNED_COMMAND_INIT_DEFAULT {DFU_COMMAND_INIT_DEFAULT, (dfu_signature_type_t)0, {0, {0}}}
+#define DFU_PACKET_INIT_DEFAULT {false, DFU_COMMAND_INIT_DEFAULT, false, DFU_SIGNED_COMMAND_INIT_DEFAULT}
+#define DFU_HASH_INIT_ZERO {(dfu_hash_type_t)0, {0, {0}}}
+#define DFU_INIT_COMMAND_INIT_ZERO {false, 0, false, 0, 0, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, false, (dfu_fw_type_t)0, false, 0, false, 0, false, 0, false, DFU_HASH_INIT_ZERO, false, 0}
+#define DFU_COMMAND_INIT_ZERO {false, (dfu_command_op_code_t)0, false, DFU_INIT_COMMAND_INIT_ZERO}
+#define DFU_SIGNED_COMMAND_INIT_ZERO {DFU_COMMAND_INIT_ZERO, (dfu_signature_type_t)0, {0, {0}}}
+#define DFU_PACKET_INIT_ZERO {false, DFU_COMMAND_INIT_ZERO, false, DFU_SIGNED_COMMAND_INIT_ZERO}
+
+/* Field tags (for use in manual encoding/decoding) */
+#define DFU_HASH_HASH_TYPE_TAG 1
+#define DFU_HASH_HASH_TAG 2
+#define DFU_INIT_COMMAND_FW_VERSION_TAG 1
+#define DFU_INIT_COMMAND_HW_VERSION_TAG 2
+#define DFU_INIT_COMMAND_SD_REQ_TAG 3
+#define DFU_INIT_COMMAND_TYPE_TAG 4
+#define DFU_INIT_COMMAND_SD_SIZE_TAG 5
+#define DFU_INIT_COMMAND_BL_SIZE_TAG 6
+#define DFU_INIT_COMMAND_APP_SIZE_TAG 7
+#define DFU_INIT_COMMAND_HASH_TAG 8
+#define DFU_INIT_COMMAND_IS_DEBUG_TAG 9
+#define DFU_COMMAND_OP_CODE_TAG 1
+#define DFU_COMMAND_INIT_TAG 2
+#define DFU_SIGNED_COMMAND_COMMAND_TAG 1
+#define DFU_SIGNED_COMMAND_SIGNATURE_TYPE_TAG 2
+#define DFU_SIGNED_COMMAND_SIGNATURE_TAG 3
+#define DFU_PACKET_COMMAND_TAG 1
+#define DFU_PACKET_SIGNED_COMMAND_TAG 2
+
+/* Struct field encoding specification for nanopb */
+extern const pb_field_t dfu_hash_fields[3];
+extern const pb_field_t dfu_init_command_fields[10];
+extern const pb_field_t dfu_command_fields[3];
+extern const pb_field_t dfu_signed_command_fields[4];
+extern const pb_field_t dfu_packet_fields[3];
+
+/* Maximum encoded size of messages (where known) */
+#define DFU_HASH_SIZE 36
+#define DFU_INIT_COMMAND_SIZE 168
+#define DFU_COMMAND_SIZE 173
+#define DFU_SIGNED_COMMAND_SIZE 244
+#define DFU_PACKET_SIZE 423
+
+/* Message IDs (where set with "msgid" option) */
+#ifdef PB_MSGID
+
+#define DFU_CC_MESSAGES \
+
+
+#endif
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+/* @@protoc_insertion_point(eof) */
+
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto
new file mode 100644
index 0000000..69f9680
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/dfu-cc.proto
@@ -0,0 +1,66 @@
+package dfu;
+
+// Version 0.1
+
+enum FwType {
+ APPLICATION = 0; // default, compatible with proto3
+ SOFTDEVICE = 1;
+ BOOTLOADER = 2;
+ SOFTDEVICE_BOOTLOADER = 3;
+}
+
+enum HashType {
+ NO_HASH = 0;
+ CRC = 1;
+ SHA128 = 2;
+ SHA256 = 3;
+ SHA512 = 4;
+}
+
+message Hash {
+ required HashType hash_type = 1;
+ required bytes hash = 2;
+}
+
+// Commands data
+message InitCommand {
+ optional uint32 fw_version = 1;
+ optional uint32 hw_version = 2;
+ repeated uint32 sd_req = 3 [packed = true]; // packed option is default in proto3
+ optional FwType type = 4;
+
+ optional uint32 sd_size = 5;
+ optional uint32 bl_size = 6;
+ optional uint32 app_size = 7;
+
+ optional Hash hash = 8;
+
+ optional bool is_debug = 9 [default = false];
+}
+
+// Command type
+message Command {
+ enum OpCode {
+ INIT = 1;
+ }
+ optional OpCode op_code = 1;
+ optional InitCommand init = 2;
+}
+
+// Signed command types
+enum SignatureType {
+ ECDSA_P256_SHA256 = 0;
+ ED25519 = 1;
+}
+
+message SignedCommand {
+ required Command command = 1;
+ required SignatureType signature_type = 2;
+ required bytes signature = 3;
+}
+
+// Parent packet type
+message Packet {
+ optional Command command = 1;
+ optional SignedCommand signed_command = 2;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c
new file mode 100644
index 0000000..f2c9796
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.c
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu.h"
+
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_req_handler.h"
+#include "app_timer.h"
+#include "nrf_log.h"
+
+static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
+
+
+
+/**
+ * @brief This function calls the user's observer (@ref m_observer) after it is done handling the event.
+ */
+static void dfu_observer(nrf_dfu_evt_type_t event)
+{
+ switch (event)
+ {
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ {
+#ifndef NRF_DFU_NO_TRANSPORT
+ UNUSED_RETURN_VALUE(nrf_dfu_transports_close(NULL));
+#endif
+ break;
+ }
+ default:
+ break;
+ }
+
+ /* Call user's observer if present. */
+ if (m_user_observer)
+ {
+ m_user_observer(event);
+ }
+}
+
+
+
+uint32_t nrf_dfu_init(nrf_dfu_observer_t observer)
+{
+ uint32_t ret_val;
+
+ m_user_observer = observer;
+
+ NRF_LOG_INFO("Entering DFU mode.");
+
+ dfu_observer(NRF_DFU_EVT_DFU_INITIALIZED);
+
+ // Initializing transports
+ ret_val = nrf_dfu_transports_init(dfu_observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not initalize DFU transport: 0x%08x", ret_val);
+ return ret_val;
+ }
+
+ ret_val = nrf_dfu_req_handler_init(dfu_observer);
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h
new file mode 100644
index 0000000..34d7aee
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu.h
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu DFU modules
+ * @{
+ * @ingroup nrf_bootloader
+ * @brief Modules providing Device Firmware Update (DFU) functionality.
+ *
+ * The DFU module, in combination with the @ref nrf_bootloader module,
+ * can be used to implement a bootloader that supports Device Firmware Updates.
+ */
+
+#ifndef NRF_DFU_H__
+#define NRF_DFU_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define NRF_DFU_SCHED_EVENT_DATA_SIZE (sizeof(nrf_dfu_request_t))
+
+
+/** @brief Function for initializing a DFU operation.
+ *
+ * This function initializes a DFU operation and any transports that are registered
+ * in the system.
+ *
+ * @param[in] observer Function for receiving DFU notifications.
+ *
+ * @retval NRF_SUCCESS If the DFU operation was successfully initialized.
+ */
+uint32_t nrf_dfu_init(nrf_dfu_observer_t observer);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c
new file mode 100644
index 0000000..c4e047a
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.c
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_flash.h"
+#include "nrf_dfu_types.h"
+
+#include "nrf_fstorage.h"
+#include "nrf_fstorage_sd.h"
+#include "nrf_fstorage_nvmc.h"
+
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_flash
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+void dfu_fstorage_evt_handler(nrf_fstorage_evt_t * p_evt);
+
+
+NRF_FSTORAGE_DEF(nrf_fstorage_t m_fs) =
+{
+ .evt_handler = dfu_fstorage_evt_handler,
+ .start_addr = MBR_SIZE,
+ .end_addr = BOOTLOADER_SETTINGS_ADDRESS + BOOTLOADER_SETTINGS_PAGE_SIZE
+};
+
+static uint32_t m_flash_operations_pending;
+
+void dfu_fstorage_evt_handler(nrf_fstorage_evt_t * p_evt)
+{
+ if (NRF_LOG_ENABLED && (m_flash_operations_pending > 0))
+ {
+ m_flash_operations_pending--;
+ }
+
+ if (p_evt->result == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Flash %s success: addr=%p, pending %d",
+ (p_evt->id == NRF_FSTORAGE_EVT_WRITE_RESULT) ? "write" : "erase",
+ p_evt->addr, m_flash_operations_pending);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Flash %s failed (0x%x): addr=%p, len=0x%x bytes, pending %d",
+ (p_evt->id == NRF_FSTORAGE_EVT_WRITE_RESULT) ? "write" : "erase",
+ p_evt->result, p_evt->addr, p_evt->len, m_flash_operations_pending);
+ }
+
+ if (p_evt->p_param)
+ {
+ //lint -save -e611 (Suspicious cast)
+ ((nrf_dfu_flash_callback_t)(p_evt->p_param))((void*)p_evt->p_src);
+ //lint -restore
+ }
+}
+
+
+ret_code_t nrf_dfu_flash_init(bool sd_irq_initialized)
+{
+ nrf_fstorage_api_t * p_api_impl;
+
+ /* Setup the desired API implementation. */
+#ifdef BLE_STACK_SUPPORT_REQD
+ if (sd_irq_initialized)
+ {
+ NRF_LOG_DEBUG("Initializing nrf_fstorage_sd backend.");
+ p_api_impl = &nrf_fstorage_sd;
+ }
+ else
+#endif
+ {
+ NRF_LOG_DEBUG("Initializing nrf_fstorage_nvmc backend.");
+ p_api_impl = &nrf_fstorage_nvmc;
+ }
+
+ return nrf_fstorage_init(&m_fs, p_api_impl, NULL);
+}
+
+
+ret_code_t nrf_dfu_flash_store(uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t rc;
+
+ NRF_LOG_DEBUG("nrf_fstorage_write(addr=%p, src=%p, len=%d bytes), queue usage: %d",
+ dest, p_src, len, m_flash_operations_pending);
+
+ //lint -save -e611 (Suspicious cast)
+ rc = nrf_fstorage_write(&m_fs, dest, p_src, len, (void *)callback);
+ //lint -restore
+
+ if ((NRF_LOG_ENABLED) && (rc == NRF_SUCCESS))
+ {
+ m_flash_operations_pending++;
+ }
+ else
+ {
+ NRF_LOG_WARNING("nrf_fstorage_write() failed with error 0x%x.", rc);
+ }
+
+ return rc;
+}
+
+
+ret_code_t nrf_dfu_flash_erase(uint32_t page_addr,
+ uint32_t num_pages,
+ nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t rc;
+
+ NRF_LOG_DEBUG("nrf_fstorage_erase(addr=0x%p, len=%d pages), queue usage: %d",
+ page_addr, num_pages, m_flash_operations_pending);
+
+ //lint -save -e611 (Suspicious cast)
+ rc = nrf_fstorage_erase(&m_fs, page_addr, num_pages, (void *)callback);
+ //lint -restore
+
+ if ((NRF_LOG_ENABLED) && (rc == NRF_SUCCESS))
+ {
+ m_flash_operations_pending++;
+ }
+ else
+ {
+ NRF_LOG_WARNING("nrf_fstorage_erase() failed with error 0x%x.", rc);
+ }
+
+ return rc;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h
new file mode 100644
index 0000000..fb14610
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_flash.h
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_flash Flash operations
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_FLASH_H__
+#define NRF_DFU_FLASH_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief nrf_fstorage event handler function for DFU fstorage operations.
+ *
+ * This function will be called after a flash operation has completed.
+ */
+typedef void (*nrf_dfu_flash_callback_t)(void * p_buf);
+
+
+/**@brief Function for initializing the flash module.
+ *
+ * Depending on whether or not the SoftDevice is present and its IRQ have been initialized,
+ * this function initializes the correct @ref nrf_fstorage backend.
+ *
+ * @param[in] sd_irq_initialized Whether or not the SoftDevice IRQ have been initialized.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ */
+ret_code_t nrf_dfu_flash_init(bool sd_irq_initialized);
+
+
+/**@brief Function for storing data to flash.
+ *
+ * This functions is asynchronous when the SoftDevice is enabled and synchronous when
+ * the SoftDevice is not present or disabled. In both cases, if a callback function is provided,
+ * it will be called when the operation has completed.
+ *
+ * @note The content of @p p_src should be kept in memory until the operation has completed.
+ *
+ * @param[in] dest The address where the data should be stored.
+ * @param[in] p_src Pointer to the address where the data should be copied from.
+ * This address can be in flash or RAM.
+ * @param[in] len The number of bytes to be copied from @p p_src to @p dest.
+ * @param[in] callback Callback function.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_STATE If nrf_dfu_flash is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR If @p p_src or @p dest is not word-aligned.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p len is zero.
+ * @retval NRF_ERROR_NULL If @p p_src is NULL.
+ * @retval NRF_ERROR_NO_MEM If nrf_fstorage is out of memory.
+ */
+ret_code_t nrf_dfu_flash_store(uint32_t dest,
+ void const * p_src,
+ uint32_t len,
+ nrf_dfu_flash_callback_t callback);
+
+
+/**@brief Function for erasing data from flash.
+ *
+ * This functions is asynchronous when the SoftDevice is enabled and synchronous when
+ * the SoftDevice is not present or disabled. In both cases, if a callback function is provided,
+ * it will be called when the operation has completed.
+ *
+ * @param[in] page_addr The address of the first flash page to be deleted.
+ * @param[in] num_pages The number of flash pages to be deleted.
+ * @param[in] callback Callback function.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INVALID_STATE If nrf_dfu_flash is not initialized.
+ * @retval NRF_ERROR_INVALID_ADDR If @p page_addr is not aligned to a page boundary or the
+ * operation would go beyond the flash memory boundaries.
+ * @retval NRF_ERROR_INVALID_LENGTH If @p num_pages is zero.
+ * @retval NRF_ERROR_NULL If @p page_addr is NULL.
+ * @retval NRF_ERROR_NO_MEM If the queue of nrf_fstorage is full.
+ */
+ret_code_t nrf_dfu_flash_erase(uint32_t page_addr, uint32_t num_pages, nrf_dfu_flash_callback_t callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif // NRF_DFU_FLASH_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c
new file mode 100644
index 0000000..ba42123
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.c
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_handling_error.h"
+
+#include "nrf_log.h"
+#include "nrf_dfu_req_handler.h"
+
+static nrf_dfu_ext_error_code_t m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR;
+
+nrf_dfu_result_t ext_error_set(nrf_dfu_ext_error_code_t error_code)
+{
+ m_last_error = error_code;
+
+ return NRF_DFU_RES_CODE_EXT_ERROR;
+}
+
+nrf_dfu_ext_error_code_t ext_error_get()
+{
+ nrf_dfu_ext_error_code_t last_error = m_last_error;
+ m_last_error = NRF_DFU_EXT_ERROR_NO_ERROR;
+
+ return last_error;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h
new file mode 100644
index 0000000..5a459e9
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_handling_error.h
@@ -0,0 +1,124 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+ /**@file
+ *
+ * @defgroup nrf_dfu_rescodes DFU result codes
+ * @{
+ * @ingroup sdk_nrf_dfu_transport
+ * @brief When the DFU controller sends requests to the DFU bootloader on
+ * the DFU target, the DFU bootloader answers with any of these result codes.
+ */
+
+
+#ifndef DFU_HANDLING_ERROR_H__
+#define DFU_HANDLING_ERROR_H__
+
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+
+/**@brief DFU request extended result codes.
+ *
+ * @details When an event returns @ref NRF_DFU_RES_CODE_EXT_ERROR, it also stores an extended error code.
+ * The transport layer can then send the extended error code together with the error code to give
+ * the controller additional information about the cause of the error.
+ */
+typedef enum
+{
+ NRF_DFU_EXT_ERROR_NO_ERROR = 0x00, /**< No extended error code has been set. This error indicates an implementation problem. */
+ NRF_DFU_EXT_ERROR_INVALID_ERROR_CODE = 0x01, /**< Invalid error code. This error code should never be used outside of development. */
+ NRF_DFU_EXT_ERROR_WRONG_COMMAND_FORMAT = 0x02, /**< The format of the command was incorrect. This error code is not used in the
+ current implementation, because @ref NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED
+ and @ref NRF_DFU_RES_CODE_INVALID_PARAMETER cover all
+ possible format errors. */
+ NRF_DFU_EXT_ERROR_UNKNOWN_COMMAND = 0x03, /**< The command was successfully parsed, but it is not supported or unknown. */
+ NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID = 0x04, /**< The init command is invalid. The init packet either has
+ an invalid update type or it is missing required fields for the update type
+ (for example, the init packet for a SoftDevice update is missing the SoftDevice size field). */
+ NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE = 0x05, /**< The firmware version is too low. For an application, the version must be greater than
+ the current application. For a bootloader, it must be greater than or equal
+ to the current version. This requirement prevents downgrade attacks.*/
+ NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE = 0x06, /**< The hardware version of the device does not match the required
+ hardware version for the update. */
+ NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE = 0x07, /**< The array of supported SoftDevices for the update does not contain
+ the FWID of the current SoftDevice. */
+ NRF_DFU_EXT_ERROR_SIGNATURE_MISSING = 0x08, /**< The init packet does not contain a signature. This error code is not used in the
+ current implementation, because init packets without a signature
+ are regarded as invalid. */
+ NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE = 0x09, /**< The hash type that is specified by the init packet is not supported by the DFU bootloader. */
+ NRF_DFU_EXT_ERROR_HASH_FAILED = 0x0A, /**< The hash of the firmware image cannot be calculated. */
+ NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE = 0x0B, /**< The type of the signature is unknown or not supported by the DFU bootloader. */
+ NRF_DFU_EXT_ERROR_VERIFICATION_FAILED = 0x0C, /**< The hash of the received firmware image does not match the hash in the init packet. */
+ NRF_DFU_EXT_ERROR_INSUFFICIENT_SPACE = 0x0D, /**< The available space on the device is insufficient to hold the firmware. */
+} nrf_dfu_ext_error_code_t;
+
+
+/**@brief Function for setting an extended error code that can be retrieved later.
+ *
+ * @details When an extended error occurs in the DFU process, this function can be used to store the error.
+ *
+ * @param error_code The error code to store.
+ *
+ * @retval NRF_DFU_RES_CODE_EXT_ERROR
+ */
+nrf_dfu_result_t ext_error_set(nrf_dfu_ext_error_code_t error_code);
+
+/**@brief Function for getting the most recent extended error code.
+ *
+ * @details This function is used by the transport layer to fetch the most recent extended error code.
+ *
+ * @return The most recent error code. If the function is called again before a new error occurs, @ref NRF_DFU_EXT_ERROR_NO_ERROR is returned.
+ */
+nrf_dfu_ext_error_code_t ext_error_get( void );
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // DFU_HANDLING_ERROR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c
new file mode 100644
index 0000000..974a466
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.c
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_mbr.h"
+#include "nrf_mbr.h"
+#include "nrf_dfu_types.h"
+#include "nrf_log.h"
+#include "nrf_bootloader_info.h"
+
+#define MBR_IRQ_FORWARD_ADDRESS_ADDRESS (0x20000000) //!< The address of the variable that decides where the MBR forwards interrupts
+
+uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len)
+{
+ uint32_t ret_val;
+ uint32_t const len_words = len / sizeof(uint32_t);
+
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_COPY_BL,
+ .params.copy_bl.bl_src = p_src,
+ .params.copy_bl.bl_len = len_words
+ };
+
+ ret_val = sd_mbr_command(&command);
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_mbr_init_sd(void)
+{
+ uint32_t ret_val;
+
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_INIT_SD
+ };
+
+ ret_val = sd_mbr_command(&command);
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_mbr_irq_forward_address_set(void)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_PARAM;
+ uint32_t address = MBR_SIZE;
+
+ NRF_LOG_DEBUG("running irq table set");
+
+#ifndef BLE_STACK_SUPPORT_REQD
+ sd_mbr_command_t command =
+ {
+ .command = SD_MBR_COMMAND_IRQ_FORWARD_ADDRESS_SET,
+ .params.irq_forward_address_set.address = address,
+ };
+
+ ret_val = sd_mbr_command(&command);
+#endif
+
+ if (ret_val == NRF_ERROR_INVALID_PARAM)
+ {
+ // Manually set the forward address if this MBR doesn't have the command.
+ *(uint32_t *)(MBR_IRQ_FORWARD_ADDRESS_ADDRESS) = address;
+
+ ret_val = NRF_SUCCESS;
+ }
+
+ NRF_LOG_DEBUG("After running irq table set");
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h
new file mode 100644
index 0000000..2fcd1b3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_mbr.h
@@ -0,0 +1,90 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_mbr MBR functions
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_MBR_H__
+#define NRF_DFU_MBR_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for copying the bootloader using an MBR command.
+ *
+ * @param[in] p_src Source address of the bootloader data to copy.
+ * @param[in] len Length of the data to copy in bytes.
+ *
+ * @return This function will return only if the command request could not be run.
+ * See @ref sd_mbr_command_copy_bl_t for possible return values.
+ */
+uint32_t nrf_dfu_mbr_copy_bl(uint32_t * p_src, uint32_t len);
+
+
+/** @brief Function for initializing the SoftDevice using an MBR command.
+ *
+ * @retval NRF_SUCCESS If the SoftDevice was initialized successfully.
+ * Any other return value indicates that the SoftDevice
+ * could not be initialized.
+ */
+uint32_t nrf_dfu_mbr_init_sd(void);
+
+
+/** @brief Function for setting the address of the IRQ table to the app's using an MBR command.
+ *
+ * @retval NRF_SUCCESS If the address of the new irq table was set. Any other
+ * return value indicates that the address could not be set.
+ */
+uint32_t nrf_dfu_mbr_irq_forward_address_set(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_MBR_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c
new file mode 100644
index 0000000..6dfb1cc
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.c
@@ -0,0 +1,855 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_config.h"
+#include "nrf_dfu.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_fstorage.h"
+#include "nrf_bootloader_info.h"
+#include "app_util.h"
+#include "pb.h"
+#include "pb_common.h"
+#include "pb_decode.h"
+#include "dfu-cc.pb.h"
+#include "crc32.h"
+#include "app_scheduler.h"
+#include "sdk_macros.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "nrf_dfu_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_req_handler
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_DFU_PROTOCOL_VERSION (0x01)
+
+
+STATIC_ASSERT(DFU_SIGNED_COMMAND_SIZE <= INIT_COMMAND_MAX_SIZE);
+
+static uint32_t m_firmware_start_addr; /**< Start address of the current firmware image. */
+static uint32_t m_firmware_size_req; /**< The size of the entire firmware image. Defined by the init command. */
+
+static nrf_dfu_observer_t m_observer;
+
+
+static void on_dfu_complete(nrf_fstorage_evt_t * p_evt)
+{
+ UNUSED_PARAMETER(p_evt);
+
+ NRF_LOG_DEBUG("All flash operations have completed. DFU completed.");
+
+ m_observer(NRF_DFU_EVT_DFU_COMPLETED);
+}
+
+
+static nrf_dfu_result_t ext_err_code_handle(nrf_dfu_result_t ret_val)
+{
+ if (ret_val < NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ return ret_val;
+ }
+ else
+ {
+ nrf_dfu_ext_error_code_t ext_err =
+ (nrf_dfu_ext_error_code_t)((uint8_t)ret_val - (uint8_t)NRF_DFU_RES_CODE_EXT_ERROR);
+ return ext_error_set(ext_err);
+ }
+}
+
+
+static void on_protocol_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_PROTOCOL_VERSION");
+
+ if (NRF_DFU_PROTOCOL_VERSION_MSG)
+ {
+ p_res->protocol.version = NRF_DFU_PROTOCOL_VERSION;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("NRF_DFU_OP_PROTOCOL_VERSION disabled.");
+ p_res->result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ }
+}
+
+
+static void on_hw_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_HARDWARE_VERSION");
+
+ p_res->hardware.part = NRF_FICR->INFO.PART;
+ p_res->hardware.variant = NRF_FICR->INFO.VARIANT;
+
+ /* FICR values are in Kilobytes, we report them in bytes. */
+ p_res->hardware.memory.ram_size = NRF_FICR->INFO.RAM * 1024;
+ p_res->hardware.memory.rom_size = NRF_FICR->INFO.FLASH * 1024;
+ p_res->hardware.memory.rom_page_size = NRF_FICR->CODEPAGESIZE;
+}
+
+
+static void on_fw_version_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_FIRMWARE_VERSION");
+ NRF_LOG_DEBUG("Firmware image requested: %d", p_req->firmware.image_number);
+
+ if (NRF_DFU_PROTOCOL_FW_VERSION_MSG)
+ {
+ uint8_t fw_count = 1;
+
+ if (SD_PRESENT)
+ {
+ fw_count++;
+ }
+
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
+ {
+ fw_count++;
+ }
+
+ p_res->result = NRF_DFU_RES_CODE_SUCCESS;
+
+ if (p_req->firmware.image_number == 0)
+ {
+ /* Bootloader is always present and it is always image zero. */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_BOOTLOADER;
+ p_res->firmware.version = s_dfu_settings.bootloader_version;
+ p_res->firmware.addr = BOOTLOADER_START_ADDR;
+ p_res->firmware.len = BOOTLOADER_SIZE;
+ }
+ else if ((p_req->firmware.image_number == 1) && SD_PRESENT)
+ {
+ /* If a SoftDevice is present, it will be firmware image one. */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_SOFTDEVICE;
+ p_res->firmware.version = SD_VERSION_GET(MBR_SIZE);
+ p_res->firmware.addr = MBR_SIZE;
+ p_res->firmware.len = SD_SIZE_GET(MBR_SIZE);
+ }
+ else if ((p_req->firmware.image_number < fw_count))
+ {
+ /* Either there is no SoftDevice and the firmware image requested is one,
+ * or there is a SoftDevice and the firmware image requested is two.
+ */
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_APPLICATION;
+ p_res->firmware.version = s_dfu_settings.app_version;
+ p_res->firmware.addr = nrf_dfu_app_start_address();
+ p_res->firmware.len = s_dfu_settings.bank_0.image_size;
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No such firmware image");
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_UNKNOWN;
+ p_res->firmware.version = 0x00;
+ p_res->firmware.addr = 0x00;
+ p_res->firmware.len = 0x00;
+ }
+ }
+ else
+ {
+ NRF_LOG_DEBUG("NRF_DFU_OP_FIRMWARE_VERSION disabled.");
+ p_res->result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ p_res->firmware.type = NRF_DFU_FIRMWARE_TYPE_UNKNOWN;
+ }
+}
+
+
+static void on_ping_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_PING");
+ p_res->ping.id = p_req->ping.id;
+}
+
+
+static void on_mtu_get_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_MTU_GET");
+ p_res->mtu.size = p_req->mtu.size;
+}
+
+
+static void on_prn_set_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ UNUSED_PARAMETER(p_res);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_RECEIPT_NOTIF_SET");
+}
+
+
+static void on_abort_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ UNUSED_PARAMETER(p_res);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_ABORT");
+
+ m_observer(NRF_DFU_EVT_DFU_ABORTED);
+}
+
+
+/* Set offset and CRC fields in the response for a 'command' message. */
+static void cmd_response_offset_and_crc_set(nrf_dfu_response_t * const p_res)
+{
+ ASSERT(p_res);
+
+ /* Copy the CRC and offset of the init packet. */
+ p_res->crc.offset = s_dfu_settings.progress.command_offset;
+ p_res->crc.crc = s_dfu_settings.progress.command_crc;
+}
+
+
+static void on_cmd_obj_select_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (command)");
+
+ p_res->select.max_size = INIT_COMMAND_MAX_SIZE;
+ cmd_response_offset_and_crc_set(p_res);
+}
+
+
+static void on_cmd_obj_create_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_CREATE (command)");
+
+ m_observer(NRF_DFU_EVT_DFU_STARTED);
+
+ nrf_dfu_result_t ret_val = nrf_dfu_validation_init_cmd_create(p_req->create.object_size);
+ p_res->result = ext_err_code_handle(ret_val);
+}
+
+
+static void on_cmd_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_req->write.p_data);
+ ASSERT(p_req->write.len);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (command)");
+
+ nrf_dfu_result_t ret_val;
+
+ ret_val = nrf_dfu_validation_init_cmd_append(p_req->write.p_data, p_req->write.len);
+ p_res->result = ext_err_code_handle(ret_val);
+
+ /* Update response. This is only used when the PRN is triggered and the 'write' message
+ * is answered with a CRC message and these field are copied into the response. */
+ cmd_response_offset_and_crc_set(p_res);
+
+ /* If a callback to free the request payload buffer was provided, invoke it now. */
+ if (p_req->callback.write)
+ {
+ p_req->callback.write((void*)p_req->write.p_data);
+ }
+}
+
+
+static void on_cmd_obj_execute_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (command)");
+
+ nrf_dfu_result_t ret_val;
+ ret_val = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
+ p_res->result = ext_err_code_handle(ret_val);
+
+ if (p_res->result == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ if (nrf_dfu_settings_write(NULL) == NRF_SUCCESS)
+ {
+ /* Setting DFU to initialized */
+ NRF_LOG_DEBUG("Writing valid init command to flash.");
+ }
+ else
+ {
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+ }
+}
+
+
+static void on_cmd_obj_crc_request(nrf_dfu_request_t const * p_req, nrf_dfu_response_t * p_res)
+{
+ UNUSED_PARAMETER(p_req);
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (command)");
+
+ cmd_response_offset_and_crc_set(p_res);
+}
+
+
+/** @brief Function handling command requests from the transport layer.
+ *
+ * @param p_req[in] Pointer to the structure holding the DFU request.
+ * @param p_res[out] Pointer to the structure holding the DFU response.
+ *
+ * @retval NRF_SUCCESS If the command request was executed successfully.
+ * Any other error code indicates that the data request
+ * could not be handled.
+ */
+static void nrf_dfu_command_req(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ on_cmd_obj_create_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ on_cmd_obj_crc_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ on_cmd_obj_write_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ {
+ on_cmd_obj_execute_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ on_cmd_obj_select_request(p_req, p_res);
+ } break;
+
+ default:
+ {
+ ASSERT(false);
+ } break;
+ }
+}
+
+
+static void on_data_obj_select_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_SELECT (data)");
+
+ p_res->select.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->select.offset = s_dfu_settings.progress.firmware_image_offset;
+
+ p_res->select.max_size = DATA_OBJECT_MAX_SIZE;
+
+ NRF_LOG_DEBUG("crc = 0x%x, offset = 0x%x, max_size = 0x%x",
+ p_res->select.crc,
+ p_res->select.offset,
+ p_res->select.max_size);
+}
+
+
+static void on_data_obj_create_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_CREATE (data)");
+
+ if (!nrf_dfu_validation_init_cmd_present())
+ {
+ /* Can't accept data because DFU isn't initialized by init command. */
+ NRF_LOG_ERROR("Cannot create data object without valid init command");
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ if (p_req->create.object_size == 0)
+ {
+ NRF_LOG_ERROR("Object size cannot be 0.")
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ if ( ((p_req->create.object_size & (CODE_PAGE_SIZE - 1)) != 0)
+ && (s_dfu_settings.progress.firmware_image_offset_last + p_req->create.object_size != m_firmware_size_req))
+ {
+ NRF_LOG_ERROR("Object size must be page aligned");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ if (p_req->create.object_size > DATA_OBJECT_MAX_SIZE)
+ {
+ /* It is impossible to handle the command because the size is too large */
+ NRF_LOG_ERROR("Invalid size for object (too large)");
+ p_res->result = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ return;
+ }
+
+ if ((s_dfu_settings.progress.firmware_image_offset_last + p_req->create.object_size) >
+ m_firmware_size_req)
+ {
+ NRF_LOG_ERROR("Creating the object with size 0x%08x would overflow firmware size. "
+ "Offset is 0x%08x and firmware size is 0x%08x.",
+ p_req->create.object_size,
+ s_dfu_settings.progress.firmware_image_offset_last,
+ m_firmware_size_req);
+
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ s_dfu_settings.progress.data_object_size = p_req->create.object_size;
+ s_dfu_settings.progress.firmware_image_crc = s_dfu_settings.progress.firmware_image_crc_last;
+ s_dfu_settings.progress.firmware_image_offset = s_dfu_settings.progress.firmware_image_offset_last;
+ s_dfu_settings.write_offset = s_dfu_settings.progress.firmware_image_offset_last;
+
+ /* Erase the page we're at. */
+ if (nrf_dfu_flash_erase((m_firmware_start_addr + s_dfu_settings.progress.firmware_image_offset),
+ CEIL_DIV(p_req->create.object_size, CODE_PAGE_SIZE), NULL) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Erase operation failed");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ return;
+ }
+
+ NRF_LOG_DEBUG("Creating object with size: %d. Offset: 0x%08x, CRC: 0x%08x",
+ s_dfu_settings.progress.data_object_size,
+ s_dfu_settings.progress.firmware_image_offset,
+ s_dfu_settings.progress.firmware_image_crc);
+}
+
+
+static void on_data_obj_write_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_WRITE (data)");
+
+ if (!nrf_dfu_validation_init_cmd_present())
+ {
+ /* Can't accept data because DFU isn't initialized by init command. */
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return;
+ }
+
+ uint32_t const data_object_offset = s_dfu_settings.progress.firmware_image_offset -
+ s_dfu_settings.progress.firmware_image_offset_last;
+
+ if ((p_req->write.len + data_object_offset) > s_dfu_settings.progress.data_object_size)
+ {
+ /* Can't accept data because too much data has been received. */
+ NRF_LOG_ERROR("Write request too long");
+ p_res->result = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ return;
+ }
+
+ uint32_t const write_addr = m_firmware_start_addr + s_dfu_settings.write_offset;
+
+ ASSERT(p_req->callback.write);
+
+ ret_code_t ret =
+ nrf_dfu_flash_store(write_addr, p_req->write.p_data, p_req->write.len, p_req->callback.write);
+
+ if (ret != NRF_SUCCESS)
+ {
+ /* When nrf_dfu_flash_store() fails because there is no space in the queue,
+ * stop processing the request so that the peer can detect a CRC error
+ * and retransmit this object. Remember to manually free the buffer !
+ */
+ p_req->callback.write((void*)p_req->write.p_data);
+ return;
+ }
+
+ /* Update the CRC of the firmware image. */
+ s_dfu_settings.write_offset += p_req->write.len;
+ s_dfu_settings.progress.firmware_image_offset += p_req->write.len;
+ s_dfu_settings.progress.firmware_image_crc =
+ crc32_compute(p_req->write.p_data, p_req->write.len, &s_dfu_settings.progress.firmware_image_crc);
+
+ /* This is only used when the PRN is triggered and the 'write' message
+ * is answered with a CRC message and these field are copied into the response.
+ */
+ p_res->write.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->write.offset = s_dfu_settings.progress.firmware_image_offset;
+}
+
+
+static void on_data_obj_crc_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_CRC_GET (data)");
+ NRF_LOG_DEBUG("Offset:%d, CRC:0x%08x",
+ s_dfu_settings.progress.firmware_image_offset,
+ s_dfu_settings.progress.firmware_image_crc);
+
+ p_res->crc.crc = s_dfu_settings.progress.firmware_image_crc;
+ p_res->crc.offset = s_dfu_settings.progress.firmware_image_offset;
+}
+
+
+static void on_data_obj_execute_request_sched(void * p_evt, uint16_t event_length)
+{
+ UNUSED_PARAMETER(event_length);
+
+ nrf_dfu_request_t * p_req = (nrf_dfu_request_t *)(p_evt);
+
+ /* Wait for all buffers to be written in flash. */
+ if (nrf_fstorage_is_busy(NULL))
+ {
+ ret_code_t ret = app_sched_event_put(p_req,
+ sizeof(nrf_dfu_request_t),
+ on_data_obj_execute_request_sched);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to schedule object execute: 0x%x.", ret);
+ }
+ return;
+ }
+
+ nrf_dfu_response_t res =
+ {
+ .request = NRF_DFU_OP_OBJECT_EXECUTE,
+ };
+
+ nrf_dfu_flash_callback_t dfu_settings_callback;
+
+ /* Whole firmware image was received, validate it. */
+ if (s_dfu_settings.progress.firmware_image_offset == m_firmware_size_req)
+ {
+ NRF_LOG_DEBUG("Postvalidation of firmware image.");
+
+ res.result = nrf_dfu_validation_post_data_execute(m_firmware_start_addr, m_firmware_size_req);
+ res.result = ext_err_code_handle(res.result);
+
+ /* Callback to on_dfu_complete() after updating the settings. */
+ dfu_settings_callback = (nrf_dfu_flash_callback_t)(on_dfu_complete);
+ }
+ else
+ {
+ res.result = NRF_DFU_RES_CODE_SUCCESS;
+ /* No callback required. */
+ dfu_settings_callback = NULL;
+ }
+
+ /* Provide response to transport */
+ p_req->callback.response(&res, p_req->p_context);
+
+ /* Store settings to flash if the whole image was received or if configured
+ * to save progress information in flash.
+ */
+ if ((dfu_settings_callback != NULL) || NRF_DFU_SAVE_PROGRESS_IN_FLASH)
+ {
+ ret_code_t ret = nrf_dfu_settings_write(dfu_settings_callback);
+ UNUSED_RETURN_VALUE(ret);
+ }
+
+ NRF_LOG_DEBUG("Request handling complete. Result: 0x%x", res.result);
+}
+
+
+static bool on_data_obj_execute_request(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ NRF_LOG_DEBUG("Handle NRF_DFU_OP_OBJECT_EXECUTE (data)");
+
+ uint32_t const data_object_size = s_dfu_settings.progress.firmware_image_offset -
+ s_dfu_settings.progress.firmware_image_offset_last;
+
+ if (s_dfu_settings.progress.data_object_size != data_object_size)
+ {
+ /* The size of the written object was not as expected. */
+ NRF_LOG_ERROR("Invalid data. expected: %d, got: %d",
+ s_dfu_settings.progress.data_object_size,
+ data_object_size);
+
+ p_res->result = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ return true;
+ }
+
+ /* Update the offset and crc values for the last object written. */
+ s_dfu_settings.progress.data_object_size = 0;
+ s_dfu_settings.progress.firmware_image_crc_last = s_dfu_settings.progress.firmware_image_crc;
+ s_dfu_settings.progress.firmware_image_offset_last = s_dfu_settings.progress.firmware_image_offset;
+
+ on_data_obj_execute_request_sched(p_req, 0);
+
+ m_observer(NRF_DFU_EVT_OBJECT_RECEIVED);
+
+ return false;
+}
+
+
+static bool nrf_dfu_data_req(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ ASSERT(p_req);
+ ASSERT(p_res);
+
+ bool response_ready = true;
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ on_data_obj_create_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ on_data_obj_write_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ {
+ on_data_obj_crc_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ {
+ response_ready = on_data_obj_execute_request(p_req, p_res);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ on_data_obj_select_request(p_req, p_res);
+ } break;
+
+ default:
+ {
+ ASSERT(false);
+ } break;
+ }
+
+ return response_ready;
+}
+
+
+/**@brief Function for handling requests to manipulate data or command objects.
+ *
+ * @param[in] p_req Request.
+ * @param[out] p_res Response.
+ *
+ * @return Whether response is ready to be sent.
+ */
+static bool nrf_dfu_obj_op(nrf_dfu_request_t * p_req, nrf_dfu_response_t * p_res)
+{
+ /* Keep track of the current object type since write and execute requests don't contain it. */
+ static nrf_dfu_obj_type_t current_object = NRF_DFU_OBJ_TYPE_COMMAND;
+
+ if ( (p_req->request == NRF_DFU_OP_OBJECT_SELECT)
+ || (p_req->request == NRF_DFU_OP_OBJECT_CREATE))
+ {
+ STATIC_ASSERT(offsetof(nrf_dfu_request_select_t, object_type) ==
+ offsetof(nrf_dfu_request_create_t, object_type),
+ "Wrong object_type offset!");
+
+ current_object = (nrf_dfu_obj_type_t)(p_req->select.object_type);
+ }
+
+ bool response_ready = true;
+
+ switch (current_object)
+ {
+ case NRF_DFU_OBJ_TYPE_COMMAND:
+ nrf_dfu_command_req(p_req, p_res);
+ break;
+
+ case NRF_DFU_OBJ_TYPE_DATA:
+ response_ready = nrf_dfu_data_req(p_req, p_res);
+ break;
+
+ default:
+ /* The select request had an invalid object type. */
+ NRF_LOG_ERROR("Invalid object type in request.");
+ current_object = NRF_DFU_OBJ_TYPE_INVALID;
+ p_res->result = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ break;
+ }
+
+ return response_ready;
+}
+
+
+static void nrf_dfu_req_handler_req_process(nrf_dfu_request_t * p_req)
+{
+ ASSERT(p_req->callback.response);
+
+ bool response_ready = true;
+
+ /* The request handlers assume these values to be set. */
+ nrf_dfu_response_t response =
+ {
+ .request = p_req->request,
+ .result = NRF_DFU_RES_CODE_SUCCESS,
+ };
+
+
+ switch (p_req->request)
+ {
+ case NRF_DFU_OP_PROTOCOL_VERSION:
+ {
+ on_protocol_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_HARDWARE_VERSION:
+ {
+ on_hw_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ on_fw_version_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_PING:
+ {
+ on_ping_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ on_prn_set_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_MTU_GET:
+ {
+ on_mtu_get_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_ABORT:
+ {
+ on_abort_request(p_req, &response);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ /* Restart the inactivity timer on CREATE messages. */
+ /* Fallthrough. */
+ case NRF_DFU_OP_OBJECT_SELECT:
+ case NRF_DFU_OP_OBJECT_WRITE:
+ case NRF_DFU_OP_OBJECT_EXECUTE:
+ case NRF_DFU_OP_CRC_GET:
+ {
+ response_ready = nrf_dfu_obj_op(p_req, &response);
+ } break;
+
+ default:
+ NRF_LOG_INFO("Invalid opcode received: 0x%x.", p_req->request);
+ response.result = NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED;
+ break;
+ }
+
+ if (response_ready)
+ {
+ NRF_LOG_DEBUG("Request handling complete. Result: 0x%x", response.result);
+
+ p_req->callback.response(&response, p_req->p_context);
+
+ if (response.result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ m_observer(NRF_DFU_EVT_DFU_FAILED);
+ }
+ }
+}
+
+
+static void nrf_dfu_req_handler_req(void * p_evt, uint16_t event_length)
+{
+ nrf_dfu_request_t * p_req = (nrf_dfu_request_t *)(p_evt);
+ nrf_dfu_req_handler_req_process(p_req);
+}
+
+
+ret_code_t nrf_dfu_req_handler_on_req(nrf_dfu_request_t * p_req)
+{
+ ret_code_t ret;
+
+ if (p_req->callback.response == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+ ret = app_sched_event_put(p_req, sizeof(nrf_dfu_request_t), nrf_dfu_req_handler_req);
+ if (ret != NRF_SUCCESS)
+ {
+ NRF_LOG_WARNING("Scheduler ran out of space!");
+ }
+
+ return ret;
+}
+
+
+ret_code_t nrf_dfu_req_handler_init(nrf_dfu_observer_t observer)
+{
+ ret_code_t ret_val;
+ nrf_dfu_result_t result;
+
+ if (observer == NULL)
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#ifdef BLE_STACK_SUPPORT_REQD
+ ret_val = nrf_dfu_flash_init(true);
+#else
+ ret_val = nrf_dfu_flash_init(false);
+#endif
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ nrf_dfu_validation_init();
+ if (nrf_dfu_validation_init_cmd_present())
+ {
+ /* Execute a previously received init packed. Subsequent executes will have no effect. */
+ result = nrf_dfu_validation_init_cmd_execute(&m_firmware_start_addr, &m_firmware_size_req);
+ if (result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ /* Init packet in flash is not valid! */
+ return NRF_ERROR_INTERNAL;
+ }
+ }
+
+ m_observer = observer;
+
+ /* Initialize extended error handling with "No error" as the most recent error. */
+ result = ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+ UNUSED_RETURN_VALUE(result);
+
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h
new file mode 100644
index 0000000..c9d10d2
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_req_handler.h
@@ -0,0 +1,345 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_req_handler Request handling
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_REQ_HANDLER_H__
+#define NRF_DFU_REQ_HANDLER_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "app_util_platform.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ANON_UNIONS_ENABLE;
+
+/**
+ * @brief DFU object types.
+ */
+typedef enum
+{
+ NRF_DFU_OBJ_TYPE_INVALID, //!< Invalid object type.
+ NRF_DFU_OBJ_TYPE_COMMAND, //!< Command object.
+ NRF_DFU_OBJ_TYPE_DATA, //!< Data object.
+} nrf_dfu_obj_type_t;
+
+/**
+ * @brief DFU protocol operation.
+ */
+typedef enum
+{
+ NRF_DFU_OP_PROTOCOL_VERSION = 0x00, //!< Retrieve protocol version.
+ NRF_DFU_OP_OBJECT_CREATE = 0x01, //!< Create selected object.
+ NRF_DFU_OP_RECEIPT_NOTIF_SET = 0x02, //!< Set receipt notification.
+ NRF_DFU_OP_CRC_GET = 0x03, //!< Request CRC of selected object.
+ NRF_DFU_OP_OBJECT_EXECUTE = 0x04, //!< Execute selected object.
+ NRF_DFU_OP_OBJECT_SELECT = 0x06, //!< Select object.
+ NRF_DFU_OP_MTU_GET = 0x07, //!< Retrieve MTU size.
+ NRF_DFU_OP_OBJECT_WRITE = 0x08, //!< Write selected object.
+ NRF_DFU_OP_PING = 0x09, //!< Ping.
+ NRF_DFU_OP_HARDWARE_VERSION = 0x0A, //!< Retrieve hardware version.
+ NRF_DFU_OP_FIRMWARE_VERSION = 0x0B, //!< Retrieve firmware version.
+ NRF_DFU_OP_ABORT = 0x0C, //!< Abort the DFU procedure.
+ NRF_DFU_OP_RESPONSE = 0x60, //!< Response.
+ NRF_DFU_OP_INVALID = 0xFF,
+} nrf_dfu_op_t;
+
+/**
+ * @brief DFU operation result code.
+ */
+typedef enum
+{
+ NRF_DFU_RES_CODE_INVALID = 0x00, //!< Invalid opcode.
+ NRF_DFU_RES_CODE_SUCCESS = 0x01, //!< Operation successful.
+ NRF_DFU_RES_CODE_OP_CODE_NOT_SUPPORTED = 0x02, //!< Opcode not supported.
+ NRF_DFU_RES_CODE_INVALID_PARAMETER = 0x03, //!< Missing or invalid parameter value.
+ NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES = 0x04, //!< Not enough memory for the data object.
+ NRF_DFU_RES_CODE_INVALID_OBJECT = 0x05, //!< Data object does not match the firmware and hardware requirements, the signature is wrong, or parsing the command failed.
+ NRF_DFU_RES_CODE_UNSUPPORTED_TYPE = 0x07, //!< Not a valid object type for a Create request.
+ NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED = 0x08, //!< The state of the DFU process does not allow this operation.
+ NRF_DFU_RES_CODE_OPERATION_FAILED = 0x0A, //!< Operation failed.
+ NRF_DFU_RES_CODE_EXT_ERROR = 0x0B, //!< Extended error. The next byte of the response contains the error code of the extended error (see @ref nrf_dfu_ext_error_code_t.
+} nrf_dfu_result_t;
+
+typedef enum
+{
+ NRF_DFU_FIRMWARE_TYPE_SOFTDEVICE = 0x00,
+ NRF_DFU_FIRMWARE_TYPE_APPLICATION = 0x01,
+ NRF_DFU_FIRMWARE_TYPE_BOOTLOADER = 0x02,
+ NRF_DFU_FIRMWARE_TYPE_UNKNOWN = 0xFF,
+} nrf_dfu_firmware_type_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PROTOCOL_VERSION response details.
+ */
+typedef struct
+{
+ uint8_t version; //!< Protocol version.
+} nrf_dfu_response_protocol_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_HARDWARE_VERSION response details.
+ */
+typedef struct
+{
+ uint32_t part; //!< Hardware part, from FICR register.
+ uint32_t variant; //!< Hardware variant, from FICR register.
+ struct
+ {
+ uint32_t rom_size; //!< ROM size, in bytes.
+ uint32_t ram_size; //!< RAM size, in bytes.
+ uint32_t rom_page_size; //!< ROM flash page size, in bytes.
+ } memory;
+} nrf_dfu_response_hardware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_FIRMWARE_VERSION response details.
+ */
+typedef struct
+{
+ nrf_dfu_firmware_type_t type; //!< Firmware type.
+ uint32_t version; //!< Firmware version.
+ uint32_t addr; //!< Firmware address in flash.
+ uint32_t len; //!< Firmware length in bytes.
+} nrf_dfu_response_firmware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_SELECT response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset.
+ uint32_t crc; //!< Current CRC.
+ uint32_t max_size; //!< Maximum size of selected object.
+} nrf_dfu_response_select_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_CREATE response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset
+ uint32_t crc; //!< Current CRC.
+} nrf_dfu_response_create_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_WRITE response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Used only when packet receipt notification is used.
+ uint32_t crc; //!< Used only when packet receipt notification is used.
+} nrf_dfu_response_write_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_CRC_GET response details.
+ */
+typedef struct
+{
+ uint32_t offset; //!< Current offset.
+ uint32_t crc; //!< Current CRC.
+} nrf_dfu_response_crc_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PING response details.
+ */
+typedef struct
+{
+ uint8_t id; //!< The received ID which is echoed back.
+} nrf_dfu_response_ping_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_MTU_GET response details.
+ */
+typedef struct
+{
+ uint16_t size; //!< The MTU size as specified by the local transport.
+} nrf_dfu_response_mtu_t;
+
+/**
+ * @brief DFU response message.
+ */
+typedef struct
+{
+ nrf_dfu_op_t request; //!< Requested operation.
+ nrf_dfu_result_t result; //!< Result of the operation.
+ union
+ {
+ nrf_dfu_response_protocol_t protocol; //!< Protocol version response.
+ nrf_dfu_response_hardware_t hardware; //!< Hardware version response.
+ nrf_dfu_response_firmware_t firmware; //!< Firmware version response.
+ nrf_dfu_response_select_t select; //!< Select object response..
+ nrf_dfu_response_create_t create; //!< Create object response..
+ nrf_dfu_response_write_t write; //!< Write object response.
+ nrf_dfu_response_crc_t crc; //!< CRC response.
+ nrf_dfu_response_ping_t ping; //!< Ping response.
+ nrf_dfu_response_mtu_t mtu; //!< MTU response.
+ };
+} nrf_dfu_response_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_FIRMWARE_VERSION request details.
+ */
+typedef struct
+{
+ uint8_t image_number; //!< Index of the firmware.
+} nrf_dfu_request_firmware_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_SELECT request details.
+ */
+typedef struct
+{
+ uint32_t object_type; //!< Object type. See @ref nrf_dfu_obj_type_t.
+} nrf_dfu_request_select_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_CREATE request details.
+ */
+typedef struct
+{
+ uint32_t object_type; //!< Object type. See @ref nrf_dfu_obj_type_t.
+ uint32_t object_size; //!< Object size in bytes.
+} nrf_dfu_request_create_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_OBJECT_WRITE request details.
+ */
+typedef struct
+{
+ uint8_t const * p_data; //!< Data.
+ uint16_t len; //!< Length of data in @ref nrf_dfu_request_write_t::p_data.
+} nrf_dfu_request_write_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_PING request details.
+ */
+typedef struct
+{
+ uint8_t id; //!< Ping ID that will be returned in response.
+} nrf_dfu_request_ping_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_MTU_GET request details.
+ */
+typedef struct
+{
+ uint16_t size; //!< Transport MTU size in bytes.
+} nrf_dfu_request_mtu_t;
+
+/**
+ * @brief @ref NRF_DFU_OP_RECEIPT_NOTIF_SET request details.
+ */
+typedef struct
+{
+ uint32_t target; //!< Target PRN.
+} nrf_dfu_request_prn_t;
+
+
+typedef void (*nrf_dfu_response_callback_t)(nrf_dfu_response_t * p_res, void * p_context);
+
+/**
+ *@brief DFU request.
+ */
+typedef struct
+{
+ nrf_dfu_op_t request; //!< Requested operation.
+ void * p_context;
+ struct
+ {
+ nrf_dfu_response_callback_t response; //!< Callback to call to send the response.
+ nrf_dfu_flash_callback_t write;
+ } callback;
+ union
+ {
+ nrf_dfu_request_firmware_t firmware; //!< Firmware version request.
+ nrf_dfu_request_select_t select; //!< Select object request.
+ nrf_dfu_request_create_t create; //!< Create object request.
+ nrf_dfu_request_write_t write; //!< Write object request.
+ nrf_dfu_request_ping_t ping; //!< Ping.
+ nrf_dfu_request_mtu_t mtu; //!< MTU size request.
+ nrf_dfu_request_prn_t prn; //!< Set receipt notification request.
+ };
+} nrf_dfu_request_t;
+
+
+/**@brief Function for initializing the request handling module.
+ *
+ * @param observer Function for receiving notifications.
+ *
+ * @retval NRF_SUCCESS If the operation was successful.
+ * @retval NRF_ERROR_INTERNAL If the init packet in flash is not valid.
+ * @retval NRF_ERROR_INVALID_PARAM If observer is not provided.
+ */
+ret_code_t nrf_dfu_req_handler_init(nrf_dfu_observer_t observer);
+
+
+/**@brief Function for scheduling processing of a DFU request.
+ *
+ * Requests are processed asynchronously by the scheduler.
+ *
+ * @param[in] p_req Request to be handled. The response callback must be non-null.
+ *
+ * @retval NRF_SUCCESS If the command request was executed successfully.
+ * @retval NRF_ERROR_NO_MEM If the scheduler ran out of memory.
+ * @retval NRF_ERROR_INVALID_PARAM If the response callback is NULL.
+ */
+ret_code_t nrf_dfu_req_handler_on_req(nrf_dfu_request_t * p_req);
+
+
+ANON_UNIONS_DISABLE;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_REQ_HANDLER_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c
new file mode 100644
index 0000000..13e89b4
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_settings.h"
+#include <stddef.h>
+#include <string.h>
+#include "app_error.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_soc.h"
+#include "crc32.h"
+#include "nrf_nvmc.h"
+
+#define DFU_SETTINGS_INIT_COMMAND_OFFSET offsetof(nrf_dfu_settings_t, init_command) //<! Offset in the settings struct where the InitCommand is located.
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_settings
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+/**@brief This variable reserves a page in flash for bootloader settings
+ * to ensure the linker doesn't place any code or variables at this location.
+ */
+#if defined (__CC_ARM )
+
+ uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ __attribute__((at(BOOTLOADER_SETTINGS_ADDRESS)))
+ __attribute__((used));
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ __attribute__((section(".bootloader_settings_page")))
+ __attribute__((used));
+
+#elif defined ( __ICCARM__ )
+
+ __no_init __root uint8_t m_dfu_settings_buffer[BOOTLOADER_SETTINGS_PAGE_SIZE]
+ @ BOOTLOADER_SETTINGS_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_dfu_settings placement.
+
+#endif // Compiler specific
+
+#ifndef BL_SETTINGS_ACCESS_ONLY
+#if defined(NRF52_SERIES)
+
+/**@brief This variable reserves a page in flash for MBR parameters
+ * to ensure the linker doesn't place any code or variables at this location.
+ */
+#if defined ( __CC_ARM )
+
+ uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ __attribute__((at(NRF_MBR_PARAMS_PAGE_ADDRESS)))
+ __attribute__((used));
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ __attribute__ ((section(".mbr_params_page")));
+
+#elif defined ( __ICCARM__ )
+
+ __no_init uint8_t m_mbr_params_page[NRF_MBR_PARAMS_PAGE_SIZE]
+ @ NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_mbr_params_page placement.
+
+#endif // Compiler specific
+
+
+/**@brief This variable has the linker write the MBR parameters page address to the
+ * UICR register. This value will be written in the HEX file and thus to the
+ * UICR when the bootloader is flashed into the chip.
+ */
+#if defined ( __CC_ARM )
+
+ uint32_t const m_uicr_mbr_params_page_address
+ __attribute__((at(NRF_UICR_MBR_PARAMS_PAGE_ADDRESS))) = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+
+ uint32_t const m_uicr_mbr_params_page_address
+ __attribute__ ((section(".uicr_mbr_params_page")))
+ __attribute__ ((used)) = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#elif defined ( __ICCARM__ )
+
+ __root uint32_t const m_uicr_mbr_params_page_address
+ @ NRF_UICR_MBR_PARAMS_PAGE_ADDRESS = NRF_MBR_PARAMS_PAGE_ADDRESS;
+
+#else
+
+ #error Not a valid compiler/linker for m_mbr_params_page placement.
+
+#endif // Compiler specific
+#endif // #if defined( NRF52_SERIES )
+#endif // #ifndef BL_SETTINGS_ACCESS_ONLY
+
+
+nrf_dfu_settings_t s_dfu_settings;
+
+
+static uint32_t nrf_dfu_settings_crc_get(void)
+{
+ // The crc is calculated from the s_dfu_settings struct, except the crc itself and the init command
+ return crc32_compute((uint8_t*)&s_dfu_settings + 4, DFU_SETTINGS_INIT_COMMAND_OFFSET - 4, NULL);
+}
+
+
+ret_code_t nrf_dfu_settings_init(bool sd_irq_initialized)
+{
+ NRF_LOG_DEBUG("Calling nrf_dfu_settings_init()...");
+
+ ret_code_t rc = nrf_dfu_flash_init(sd_irq_initialized);
+ if (rc != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("nrf_dfu_flash_init() failed with error: %x", rc);
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Copy the DFU settings out of flash and into a buffer in RAM.
+ memcpy((void*)&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t));
+
+ if (s_dfu_settings.crc != 0xFFFFFFFF)
+ {
+ // CRC is set. Content must be valid
+ uint32_t crc = nrf_dfu_settings_crc_get();
+ if (crc == s_dfu_settings.crc)
+ {
+ return NRF_SUCCESS;
+ }
+ }
+
+ // Reached if the page is erased or CRC is wrong.
+ NRF_LOG_DEBUG("Resetting bootloader settings.");
+
+ memset(&s_dfu_settings, 0x00, sizeof(nrf_dfu_settings_t));
+ s_dfu_settings.settings_version = NRF_DFU_SETTINGS_VERSION;
+
+ rc = nrf_dfu_settings_write(NULL);
+ if (rc != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("nrf_dfu_flash_write() failed with error: %x", rc);
+ return NRF_ERROR_INTERNAL;
+ }
+ return NRF_SUCCESS;
+}
+
+
+ret_code_t nrf_dfu_settings_write(nrf_dfu_flash_callback_t callback)
+{
+ ret_code_t err_code;
+
+ if (memcmp(&s_dfu_settings, m_dfu_settings_buffer, sizeof(nrf_dfu_settings_t)) == 0)
+ {
+ NRF_LOG_DEBUG("New settings are identical to old, write not needed. Skipping.");
+ if (callback != NULL)
+ {
+ callback(NULL);
+ }
+ return NRF_SUCCESS;
+ }
+
+ NRF_LOG_DEBUG("Writing settings...");
+ NRF_LOG_DEBUG("Erasing old settings at: 0x%08x", (uint32_t)m_dfu_settings_buffer);
+
+ // Not setting the callback function because ERASE is required before STORE
+ // Only report completion on successful STORE.
+ err_code = nrf_dfu_flash_erase((uint32_t)m_dfu_settings_buffer, 1, NULL);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not erase the settings page!");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ s_dfu_settings.crc = nrf_dfu_settings_crc_get();
+
+ static nrf_dfu_settings_t temp_dfu_settings;
+ memcpy(&temp_dfu_settings, &s_dfu_settings, sizeof(nrf_dfu_settings_t));
+
+ err_code = nrf_dfu_flash_store((uint32_t)m_dfu_settings_buffer,
+ &temp_dfu_settings,
+ sizeof(nrf_dfu_settings_t),
+ callback);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not write the DFU settings page!");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ return NRF_SUCCESS;
+}
+
+__WEAK ret_code_t nrf_dfu_settings_additional_erase(void)
+{
+ NRF_LOG_WARNING("No additional data erased");
+ return NRF_SUCCESS;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h
new file mode 100644
index 0000000..9e9dedb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings.h
@@ -0,0 +1,173 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_dfu_settings DFU settings
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_SETTINGS_H__
+#define NRF_DFU_SETTINGS_H__
+
+#include <stdint.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_flash.h"
+#include "sdk_config.h"
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/**@brief Global settings.
+ *
+ * @note Using this variable is not thread-safe.
+ *
+ */
+extern nrf_dfu_settings_t s_dfu_settings;
+
+
+/**@brief Function for writing DFU settings to flash.
+ *
+ * @param[in] callback Pointer to a function that is called after completing the write operation.
+ *
+ * @retval NRF_SUCCESS If the write process was successfully initiated.
+ * @retval NRF_ERROR_INTERNAL If a flash error occurred.
+ */
+ret_code_t nrf_dfu_settings_write(nrf_dfu_flash_callback_t callback);
+
+
+/**@brief Function for initializing the DFU settings module.
+ *
+ * @retval NRF_SUCCESS If the initialization was successful.
+ * @retval NRF_ERROR_INTERNAL If a flash error occurred.
+ */
+ret_code_t nrf_dfu_settings_init(bool sd_irq_initialized);
+
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+/** @brief Function for storing peer data received through an SVCI call in DFU settings.
+ *
+ * @note The content of the type can be verified by a CRC value stored inside the struct
+ * If the CRC value is 0xFFFFFFFF, it means that no data is set.
+ *
+ * @note The storage operation is an asynchronous progress. Success will be notified
+ * through system events raised by the SoftDevice.
+ *
+ * @param[in] p_data Peer data to be stored in flash.
+ *
+ * @retval NRF_SUCCESS Asynchronous operation was successfully started.
+ * @retval NRF_ERROR_NULL p_data was NULL.
+ * @retval Any other error code reported by SoftDevice API calls.
+ */
+ret_code_t nrf_dfu_settings_peer_data_write(nrf_dfu_peer_data_t * p_data);
+
+
+/** @brief Function for copying peer data from DFU settings to RAM.
+ *
+ * @param[in,out] p_data Structure to copy peer data to.
+ *
+ * @retval NRF_SUCCESS Peer data was successfully copied.
+ * @retval NRF_ERROR_NULL p_data was NULL.
+ */
+ret_code_t nrf_dfu_settings_peer_data_copy(nrf_dfu_peer_data_t * p_data);
+
+
+/** @brief Function for validating peer data in DFU settings.
+ *
+ * @retval True if peer data is validated by CRC, false if not.
+ */
+bool nrf_dfu_settings_peer_data_is_valid(void);
+
+
+/** @brief Function for storing an advertisement name received through an SVCI call in DFU settings.
+ *
+ * @note The content of the type is verifyable by a CRC-value stored inside the struct.
+ *
+ * @note The storage operation is an asynchronous progress. Success will be notified
+ * through system events raised by the SoftDevice.
+ *
+ * @param[in] p_adv_name Structure holding information about the new advertisement name.
+ *
+ * @retval NRF_SUCCESS Asynchronous operation was successfully started.
+ * @retval NRF_ERROR_NULL p_adv_name was NULL.
+ * @retval Any other error code reported by SoftDevice API calls.
+ */
+ret_code_t nrf_dfu_settings_adv_name_write(nrf_dfu_adv_name_t * p_adv_name);
+
+
+/** @brief Function for copying the advertisement name from DFU settings to RAM.
+ *
+ * @param[in,out] p_adv_name Structure to copy the new advertisement name to.
+ *
+ * @retval NRF_SUCCESS Advertisement name was successfully copied.
+ * @retval NRF_ERROR_NULL p_adv_name was NULL.
+ */
+ret_code_t nrf_dfu_settings_adv_name_copy(nrf_dfu_adv_name_t * p_adv_name);
+
+
+/** @brief Function for validating advertisement data in DFU settings.
+ *
+ * @retval True if advertisement name is validated by CRC, false if not.
+ */
+bool nrf_dfu_settings_adv_name_is_valid(void);
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+/** @brief Function for erasing additional data in DFU settings.
+ *
+ * @note Erasing additional data in DFU settings is only possible
+ * if nrf_dfu_flash is initialized to not use SoftDevice calls.
+ *
+ * @retval NRF_SUCCESS Additional data was successfully erased.
+ * @retval Any other error code reported by nrf_dfu_flash
+ */
+ret_code_t nrf_dfu_settings_additional_erase(void);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_SETTINGS_H__
+
+/**@} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c
new file mode 100644
index 0000000..41deb9e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_settings_svci.c
@@ -0,0 +1,185 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stddef.h>
+#include <string.h>
+#include "app_error.h"
+#include "sdk_macros.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_nvmc.h"
+#include "crc32.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_settings_svci
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define DFU_SETTINGS_PEER_DATA_OFFSET offsetof(nrf_dfu_settings_t, peer_data) //<! Offset in the settings struct where the additional peer data is located.
+#define DFU_SETTINGS_ADV_NAME_OFFSET offsetof(nrf_dfu_settings_t, adv_name) //<! Offset in the settings struct where the additional advertisement name is located.
+
+extern nrf_dfu_settings_t s_dfu_settings;
+extern uint8_t m_dfu_settings_buffer[CODE_PAGE_SIZE];
+
+#if defined(NRF_DFU_BLE_REQUIRES_BONDS) && (NRF_DFU_BLE_REQUIRES_BONDS == 1)
+
+ret_code_t nrf_dfu_settings_peer_data_write(nrf_dfu_peer_data_t * p_data)
+{
+ uint32_t ret_val;
+
+ uint32_t * p_peer_data_settings =
+ (uint32_t*) &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET];
+
+ uint32_t crc = (uint32_t)*p_peer_data_settings;
+
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ if (crc != 0xFFFFFFFF)
+ {
+ // Already written to, must be cleared out
+ // Reset required.
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ p_data->crc = crc32_compute((uint8_t*)p_data + 4, sizeof(nrf_dfu_peer_data_t) - 4, NULL);
+
+ // Using SoftDevice call since this function cannot use static memory.
+ ret_val = sd_flash_write(p_peer_data_settings,
+ (uint32_t*)p_data,
+ sizeof(nrf_dfu_peer_data_t)/4);
+
+ return ret_val;
+}
+
+
+ret_code_t nrf_dfu_settings_peer_data_copy(nrf_dfu_peer_data_t * p_data)
+{
+ VERIFY_PARAM_NOT_NULL(p_data);
+
+ memcpy(p_data, &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET], sizeof(nrf_dfu_peer_data_t));
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_dfu_settings_peer_data_is_valid(void)
+{
+ nrf_dfu_peer_data_t * p_peer_data =
+ (nrf_dfu_peer_data_t*) &m_dfu_settings_buffer[DFU_SETTINGS_PEER_DATA_OFFSET];
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ uint32_t crc = crc32_compute((uint8_t*)p_peer_data + 4, sizeof(nrf_dfu_peer_data_t) - 4, NULL);
+
+ return (p_peer_data->crc == crc);
+}
+
+#else // not NRF_DFU_BLE_REQUIRES_BONDS
+
+ret_code_t nrf_dfu_settings_adv_name_write(nrf_dfu_adv_name_t * p_adv_name)
+{
+ uint32_t ret_val;
+
+ uint32_t * p_adv_name_settings =
+ (uint32_t*) &m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET];
+
+ uint32_t crc = (uint32_t)*p_adv_name_settings;
+
+ VERIFY_PARAM_NOT_NULL(p_adv_name);
+
+ if (crc != 0xFFFFFFFF)
+ {
+ // Already written to, must be cleared out.
+ // Reset required
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ p_adv_name->crc = crc32_compute((uint8_t *)p_adv_name + 4, sizeof(nrf_dfu_adv_name_t) - 4, NULL);
+
+ // Using SoftDevice call since this function cannot use static memory.
+ ret_val = sd_flash_write(p_adv_name_settings,
+ (uint32_t*) p_adv_name,
+ sizeof(nrf_dfu_adv_name_t)/4);
+ return ret_val;
+}
+
+
+ret_code_t nrf_dfu_settings_adv_name_copy(nrf_dfu_adv_name_t * p_adv_name)
+{
+ VERIFY_PARAM_NOT_NULL(p_adv_name);
+ memcpy(p_adv_name, &m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET], sizeof(nrf_dfu_adv_name_t));
+
+ return NRF_SUCCESS;
+}
+
+
+bool nrf_dfu_settings_adv_name_is_valid(void)
+{
+ nrf_dfu_adv_name_t * p_adv_name =
+ (nrf_dfu_adv_name_t*)&m_dfu_settings_buffer[DFU_SETTINGS_ADV_NAME_OFFSET];
+
+ // Calculate the CRC for the structure excluding the CRC value itself.
+ uint32_t crc = crc32_compute((uint8_t*)p_adv_name + 4, sizeof(nrf_dfu_adv_name_t) - 4, NULL);
+
+ return (p_adv_name->crc == crc);
+}
+
+#endif
+
+
+//lint -save -e(14)
+ret_code_t nrf_dfu_settings_additional_erase(void)
+{
+ ret_code_t ret_code = NRF_SUCCESS;
+
+ // Check CRC for both types.
+ if ( (s_dfu_settings.peer_data.crc != 0xFFFFFFFF)
+ || (s_dfu_settings.adv_name.crc != 0xFFFFFFFF))
+ {
+ NRF_LOG_DEBUG("Erasing settings page additional data.");
+
+ // Erasing and resetting the settings page without the peer data/adv data
+ nrf_nvmc_page_erase(BOOTLOADER_SETTINGS_ADDRESS);
+ nrf_nvmc_write_words(BOOTLOADER_SETTINGS_ADDRESS, (uint32_t const *)&s_dfu_settings, DFU_SETTINGS_PEER_DATA_OFFSET / 4);
+ }
+
+ return ret_code;
+}
+//lint -restore
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c
new file mode 100644
index 0000000..ceff394
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci.c
@@ -0,0 +1,86 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_log.h"
+#include "nrf_sdm.h"
+#include "app_util.h"
+
+#define APP_START_ADDR CODE_START
+
+
+uint32_t nrf_dfu_svci_vector_table_set(void)
+{
+ uint32_t err_code;
+
+ if (NRF_UICR->NRFFW[0] != 0xFFFFFFFF)
+ {
+ NRF_LOG_INFO("Setting vector table to bootloader: 0x%08x", NRF_UICR->NRFFW[0]);
+ err_code = sd_softdevice_vector_table_base_set(NRF_UICR->NRFFW[0]);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+ }
+
+ NRF_LOG_ERROR("No bootloader was found");
+ return NRF_ERROR_NO_MEM;
+}
+
+
+uint32_t nrf_dfu_svci_vector_table_unset(void)
+{
+ uint32_t err_code;
+
+ NRF_LOG_INFO("Setting vector table to main app: 0x%08x", APP_START_ADDR);
+ err_code = sd_softdevice_vector_table_base_set(APP_START_ADDR);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running sd_softdevice_vector_table_base_set");
+ return err_code;
+ }
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c
new file mode 100644
index 0000000..ce75be7
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_svci_handler.c
@@ -0,0 +1,222 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include "nrf_svci_async_handler.h"
+#include "app_error.h"
+#include "nrf_nvmc.h"
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_ble_svci_bond_sharing.h"
+#include "nrf_log.h"
+#include "nrf_dfu_settings.h"
+#include "sdk_config.h"
+
+
+#if (NRF_DFU_TRANSPORT_BLE && NRF_DFU_BLE_REQUIRES_BONDS)
+
+
+NRF_SVCI_ASYNC_HANDLER_CREATE(NRF_DFU_SVCI_SET_PEER_DATA,
+ nrf_dfu_set_peer_data, nrf_dfu_peer_data_t, nrf_dfu_peer_data_state_t);
+
+
+static uint32_t nrf_dfu_set_peer_data_handler(nrf_dfu_set_peer_data_svci_async_t * p_async)
+{
+ VERIFY_PARAM_NOT_NULL(p_async);
+
+ p_async->async_func = nrf_dfu_set_peer_data_on_call;
+ p_async->sys_evt_handler = nrf_dfu_set_peer_data_on_sys_evt;
+ p_async->state = DFU_PEER_DATA_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t nrf_dfu_set_peer_data_on_call(nrf_dfu_peer_data_t * p_data,
+ nrf_dfu_peer_data_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_BUSY;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ switch (*p_state)
+ {
+ case DFU_PEER_DATA_STATE_INVALID:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_PEER_DATA_STATE_INITIALIZED:
+ ret_val = nrf_dfu_settings_peer_data_write(p_data);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_state = DFU_PEER_DATA_STATE_WRITE_REQUESTED;
+ }
+ break;
+
+ case DFU_PEER_DATA_STATE_WRITE_REQUESTED:
+ return NRF_ERROR_BUSY;
+
+ case DFU_PEER_DATA_STATE_WRITE_FINISHED:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_PEER_DATA_STATE_WRITE_FAILED:
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_dfu_set_peer_data_on_sys_evt(uint32_t sys_event, nrf_dfu_peer_data_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_STATE;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (*p_state == DFU_PEER_DATA_STATE_WRITE_REQUESTED)
+ {
+ switch (sys_event)
+ {
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ return NRF_ERROR_BUSY;
+
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ (*p_state) = DFU_PEER_DATA_STATE_WRITE_FINISHED;
+ break;
+
+ default:
+ // Event not intended for us
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+#elif (NRF_DFU_TRANSPORT_BLE && !NRF_DFU_BLE_REQUIRES_BONDS)
+
+
+NRF_SVCI_ASYNC_HANDLER_CREATE(NRF_DFU_SVCI_SET_ADV_NAME,
+ nrf_dfu_set_adv_name, nrf_dfu_adv_name_t, nrf_dfu_set_adv_name_state_t);
+
+
+static uint32_t nrf_dfu_set_adv_name_handler(nrf_dfu_set_adv_name_svci_async_t * p_async)
+{
+ VERIFY_PARAM_NOT_NULL(p_async);
+
+ p_async->async_func = nrf_dfu_set_adv_name_on_call;
+ p_async->sys_evt_handler = nrf_dfu_set_adv_name_on_sys_evt;
+ p_async->state = DFU_ADV_NAME_STATE_INITIALIZED;
+
+ return NRF_SUCCESS;
+}
+
+
+static uint32_t nrf_dfu_set_adv_name_on_call(nrf_dfu_adv_name_t * p_adv_name,
+ nrf_dfu_set_adv_name_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_BUSY;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ return NRF_ERROR_FORBIDDEN;
+ }
+
+ switch (*p_state)
+ {
+ case DFU_ADV_NAME_STATE_INVALID:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_ADV_NAME_STATE_INITIALIZED:
+ ret_val = nrf_dfu_settings_adv_name_write(p_adv_name);
+ if (ret_val == NRF_SUCCESS)
+ {
+ *p_state = DFU_ADV_NAME_STATE_WRITE_REQUESTED;
+ }
+ break;
+
+ case DFU_ADV_NAME_STATE_WRITE_REQUESTED:
+ return NRF_ERROR_BUSY;
+
+ case DFU_ADV_NAME_STATE_WRITE_FINISHED:
+ return NRF_ERROR_INVALID_STATE;
+
+ case DFU_ADV_NAME_STATE_WRITE_FAILED:
+ return NRF_ERROR_INVALID_STATE;
+ }
+
+ return ret_val;
+}
+
+
+static uint32_t nrf_dfu_set_adv_name_on_sys_evt(uint32_t sys_event, nrf_dfu_set_adv_name_state_t * p_state)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_STATE;
+
+ VERIFY_PARAM_NOT_NULL(p_state);
+
+ if (*p_state == DFU_ADV_NAME_STATE_WRITE_REQUESTED)
+ {
+ switch (sys_event)
+ {
+ case NRF_EVT_FLASH_OPERATION_ERROR:
+ return NRF_ERROR_BUSY;
+
+ case NRF_EVT_FLASH_OPERATION_SUCCESS:
+ ret_val = NRF_SUCCESS;
+ (*p_state) = DFU_ADV_NAME_STATE_WRITE_FINISHED;
+ break;
+
+ default:
+ // Event not intended for us
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+#endif // NRF_DFU_TRANSPORT_BLE && !NRF_DFU_BLE_REQUIRES_BONDS
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c
new file mode 100644
index 0000000..6075538
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.c
@@ -0,0 +1,91 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_transport.h"
+#include "nrf_log.h"
+
+
+#define DFU_TRANS_SECTION_ITEM_GET(i) NRF_SECTION_ITEM_GET(dfu_trans, nrf_dfu_transport_t, (i))
+#define DFU_TRANS_SECTION_ITEM_COUNT NRF_SECTION_ITEM_COUNT(dfu_trans, nrf_dfu_transport_t)
+
+NRF_SECTION_DEF(dfu_trans, const nrf_dfu_transport_t);
+
+
+uint32_t nrf_dfu_transports_init(nrf_dfu_observer_t observer)
+{
+ uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT;
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Initializing transports (found: %d)", num_transports);
+
+ for (uint32_t i = 0; i < num_transports; i++)
+ {
+ nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i);
+ ret_val = trans->init_func(observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Failed to initialize transport %d, error %d", i, ret_val);
+ break;
+ }
+ }
+
+ return ret_val;
+}
+
+
+uint32_t nrf_dfu_transports_close(nrf_dfu_transport_t const * p_exception)
+{
+ uint32_t const num_transports = DFU_TRANS_SECTION_ITEM_COUNT;
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Shutting down transports (found: %d)", num_transports);
+
+ for (uint32_t i = 0; i < num_transports; i++)
+ {
+ nrf_dfu_transport_t * const trans = DFU_TRANS_SECTION_ITEM_GET(i);
+ ret_val = trans->close_func(p_exception);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("Failed to shutdown transport %d, error %d", i, ret_val);
+ break;
+ }
+ }
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h
new file mode 100644
index 0000000..b8368f0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_transport.h
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_transport DFU transport
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Generic Device Firmware Update (DFU) transport interface.
+ *
+ * @details The DFU transport module defines a generic interface that must
+ * be implemented for each transport layer.
+ */
+
+#ifndef NRF_DFU_TRANSPORT_H__
+#define NRF_DFU_TRANSPORT_H__
+
+#include <stdint.h>
+#include "nrf_section.h"
+#include "nrf_dfu_types.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Forward declaration of nrf_dfu_transport_t */
+typedef struct nrf_dfu_transport_s nrf_dfu_transport_t;
+
+/** @brief Function type for initializing a DFU transport.
+ *
+ * @details This function initializes a DFU transport. The implementation
+ * of the function must initialize DFU mode and stay in service
+ * until either the device is reset or the DFU operation is finalized.
+ * When the DFU transport receives requests, it should call @ref nrf_dfu_req_handler_on_req for handling the requests.
+ *
+ * @param observer Function for receiving DFU transport notifications.
+ *
+ * @retval NRF_SUCCESS If initialization was successful for the transport. Any other return code indicates that the DFU transport could not be initialized.
+ */
+typedef uint32_t (*nrf_dfu_init_fn_t)(nrf_dfu_observer_t observer);
+
+
+/** @brief Function type for closing down a DFU transport.
+ *
+ * @details This function closes down a DFU transport in a gentle way.
+ *
+ * @param[in] p_exception If exception matches current transport closing should be omitted.
+ *
+ * @retval NRF_SUCCESS If closing was successful for the transport. Any other return code indicates that the DFU transport could not be closed closed down.
+ */
+typedef uint32_t (*nrf_dfu_close_fn_t)(nrf_dfu_transport_t const * p_exception);
+
+
+
+/** @brief DFU transport registration.
+ *
+ * @details Every DFU transport must provide a registration of the initialization function.
+ */
+struct nrf_dfu_transport_s
+{
+ nrf_dfu_init_fn_t init_func; /**< Registration of the init function to run to initialize a DFU transport. */
+ nrf_dfu_close_fn_t close_func; /**< Registration of the close function to close down a DFU transport. */
+};
+
+
+/** @brief Function for initializing all the registered DFU transports.
+ *
+ * @retval NRF_SUCCESS If all DFU transport were initialized successfully.
+ * Any other error code indicates that at least one DFU
+ * transport could not be initialized.
+ */
+uint32_t nrf_dfu_transports_init(nrf_dfu_observer_t observer);
+
+/** @brief Function for closing down all (with optional exception) the registered DFU transports.
+ *
+ * @param[in] p_exception Transport which should not be closed. NULL if all transports should be closed.
+ * @retval NRF_SUCCESS If all DFU transport were closed down successfully.
+ * Any other error code indicates that at least one DFU
+ * transport could not be closed down.
+ */
+uint32_t nrf_dfu_transports_close(nrf_dfu_transport_t const * p_exception);
+
+
+/** @brief Macro for registering a DFU transport by using section variables.
+ *
+ * @details This macro places a variable in a section named "dfu_trans", which
+ * is initialized by @ref nrf_dfu_transports_init.
+ */
+#define DFU_TRANSPORT_REGISTER(trans_var) NRF_SECTION_ITEM_REGISTER(dfu_trans, trans_var)
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_TRANSPORT_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c
new file mode 100644
index 0000000..582d60c
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.c
@@ -0,0 +1,237 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_trigger_usb.h"
+#include "app_usbd_string_config.h"
+#include "app_usbd.h"
+#include "app_usbd_nrf_dfu_trigger.h"
+#include "nrf_drv_clock.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_gpio.h"
+#include "boards.h"
+#include "app_util.h"
+#include "app_usbd_serial_num.h"
+#define NRF_LOG_MODULE_NAME nrf_dfu_trigger_usb
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#ifndef BSP_SELF_PINRESET_PIN
+#error "This module is intended to be used with boards that have the GP pin shortened with the RESET pin."
+#endif
+
+/**
+ * @brief Enable power USB detection.
+ *
+ * Configure if the example supports USB port connection.
+ */
+#ifndef USBD_POWER_DETECTION
+#define USBD_POWER_DETECTION true
+#endif
+
+#define DFU_FLASH_PAGE_SIZE (NRF_FICR->CODEPAGESIZE)
+#define DFU_FLASH_PAGE_COUNT (NRF_FICR->CODESIZE)
+
+// Semantic versioning string.
+#define VERSION_STRING STRINGIFY(APP_VERSION_MAJOR) "." STRINGIFY(APP_VERSION_MINOR) "." STRINGIFY(APP_VERSION_PATCH) APP_VERSION_PRERELEASE APP_VERSION_METADATA
+
+static uint8_t m_version_string[] = APP_NAME " " VERSION_STRING; ///< Human-readable version string.
+static app_usbd_nrf_dfu_trigger_nordic_info_t m_dfu_info; ///< Struct with various information about the current firmware.
+
+static void dfu_trigger_evt_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_nrf_dfu_trigger_user_event_t event)
+{
+ UNUSED_PARAMETER(p_inst);
+
+ switch (event)
+ {
+ case APP_USBD_NRF_DFU_TRIGGER_USER_EVT_DETACH:
+ NRF_LOG_INFO("DFU Detach request received. Triggering a pin reset.");
+ NRF_LOG_FINAL_FLUSH();
+ nrf_gpio_cfg_output(BSP_SELF_PINRESET_PIN);
+ nrf_gpio_pin_clear(BSP_SELF_PINRESET_PIN);
+ break;
+ default:
+ break;
+ }
+}
+
+
+APP_USBD_NRF_DFU_TRIGGER_GLOBAL_DEF(m_app_dfu,
+ NRF_DFU_TRIGGER_USB_INTERFACE_NUM,
+ &m_dfu_info,
+ m_version_string,
+ dfu_trigger_evt_handler);
+
+
+static void usbd_user_evt_handler(app_usbd_event_type_t event)
+{
+ switch (event)
+ {
+ case APP_USBD_EVT_DRV_SUSPEND:
+ break;
+ case APP_USBD_EVT_DRV_RESUME:
+ break;
+ case APP_USBD_EVT_STARTED:
+ break;
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_disable();
+ break;
+ case APP_USBD_EVT_POWER_DETECTED:
+ NRF_LOG_INFO("USB power detected");
+
+ if (!nrf_drv_usbd_is_enabled())
+ {
+ app_usbd_enable();
+ }
+ break;
+ case APP_USBD_EVT_POWER_REMOVED:
+ NRF_LOG_INFO("USB power removed");
+ app_usbd_stop();
+ break;
+ case APP_USBD_EVT_POWER_READY:
+ NRF_LOG_INFO("USB ready");
+ app_usbd_start();
+ break;
+ default:
+ break;
+ }
+}
+
+
+static void serial_number_strings_create(void)
+{
+ // Remove characters that are not supported in semantic versioning strings.
+ for (size_t i = strlen(APP_NAME) + 1; i < strlen((char*)m_version_string); i++)
+ {
+ if (((m_version_string[i] >= 'a') && (m_version_string[i] <= 'z'))
+ || ((m_version_string[i] >= 'A') && (m_version_string[i] <= 'Z'))
+ || ((m_version_string[i] >= '0') && (m_version_string[i] <= '9'))
+ || (m_version_string[i] == '+')
+ || (m_version_string[i] == '.')
+ || (m_version_string[i] == '-'))
+ {
+ // Valid semantic versioning character.
+ }
+ else
+ {
+ m_version_string[i] = '-';
+ }
+ }
+
+#if !NRF_DFU_TRIGGER_USB_USB_SHARED
+ app_usbd_serial_num_generate();
+#endif
+}
+
+#if !(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+static void usbd_evt_handler(app_usbd_internal_evt_t const * const p_event)
+{
+ app_usbd_event_execute(p_event);
+}
+#endif
+
+ret_code_t nrf_dfu_trigger_usb_init(void)
+{
+ ret_code_t ret;
+ static bool initialized = false;
+
+ if (initialized)
+ {
+ return NRF_SUCCESS;
+ }
+
+ m_dfu_info.wAddress = CODE_START;
+ m_dfu_info.wFirmwareSize = CODE_SIZE;
+ m_dfu_info.wVersionMajor = APP_VERSION_MAJOR;
+ m_dfu_info.wVersionMinor = APP_VERSION_MINOR;
+ m_dfu_info.wFirmwareID = APP_ID;
+ m_dfu_info.wFlashPageSize = DFU_FLASH_PAGE_SIZE;
+ m_dfu_info.wFlashSize = m_dfu_info.wFlashPageSize * DFU_FLASH_PAGE_COUNT;
+
+ serial_number_strings_create();
+
+ if (!NRF_DFU_TRIGGER_USB_USB_SHARED)
+ {
+ static const app_usbd_config_t usbd_config = {
+
+#if !(APP_USBD_CONFIG_EVENT_QUEUE_ENABLE)
+ .ev_handler = usbd_evt_handler,
+#endif
+ .ev_state_proc = usbd_user_evt_handler
+ };
+
+ ret = nrf_drv_clock_init();
+ if ((ret != NRF_SUCCESS) && (ret != NRF_ERROR_MODULE_ALREADY_INITIALIZED))
+ {
+ return ret;
+ }
+
+ ret = app_usbd_init(&usbd_config);
+ if (ret != NRF_SUCCESS)
+ {
+ return ret;
+ }
+ }
+
+ app_usbd_class_inst_t const * class_dfu = app_usbd_nrf_dfu_trigger_class_inst_get(&m_app_dfu);
+ ret = app_usbd_class_append(class_dfu);
+
+ if (!NRF_DFU_TRIGGER_USB_USB_SHARED)
+ {
+ if (USBD_POWER_DETECTION)
+ {
+ ret = app_usbd_power_events_enable();
+ APP_ERROR_CHECK(ret);
+ }
+ else
+ {
+ NRF_LOG_INFO("No USB power detection enabled\r\nStarting USB now");
+
+ app_usbd_enable();
+ app_usbd_start();
+ }
+ }
+
+ if (ret == NRF_SUCCESS)
+ {
+ initialized = true;
+ }
+
+ return ret;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h
new file mode 100644
index 0000000..c7ce4d3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_trigger_usb.h
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_DFU_TRIGGER_USB_H
+#define NRF_DFU_TRIGGER_USB_H
+
+#include "sdk_errors.h"
+
+/**
+ * @defgroup nrf_dfu_trigger_usb USB DFU trigger library
+ * @ingroup app_common
+ *
+ * @brief @tagAPI52840 USB DFU trigger library is used to enter the bootloader and read the firmware version.
+ *
+ * @details See @ref lib_dfu_trigger_usb for additional documentation.
+ * @{
+ */
+
+/**
+ * @brief Function for initializing the USB DFU trigger library.
+ *
+ * @note If the USB is also used for other purposes, then this function must be called after USB is
+ * initialized but before it is enabled. In this case, the configuration flag @ref
+ * NRF_DFU_TRIGGER_USB_USB_SHARED must be set to 1.
+ *
+ * @note Calling this again after the first success has no effect and returns @ref NRF_SUCCESS.
+ *
+ * @note If @ref APP_USBD_CONFIG_EVENT_QUEUE_ENABLE is on (1), USB events must be handled manually.
+ * See @ref app_usbd_event_queue_process.
+ *
+ * @retval NRF_SUCCESS On successful initialization.
+ * @return An error code on failure, for example if called at a wrong time.
+ */
+ret_code_t nrf_dfu_trigger_usb_init(void);
+
+/** @} */
+
+#endif //NRF_DFU_TRIGGER_USB_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h
new file mode 100644
index 0000000..5ccd290
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_types.h
@@ -0,0 +1,302 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_types DFU types
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_TYPES_H__
+#define NRF_DFU_TYPES_H__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "nrf.h"
+#include "nrf_mbr.h"
+#include "app_util_platform.h"
+#include "sdk_config.h"
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+#include "ble_gap.h"
+#define SYSTEM_SERVICE_ATT_SIZE 8 /**< Size of the system service attribute length including CRC-16 at the end. */
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+#define INIT_COMMAND_MAX_SIZE 256 /**< Maximum size of the init command stored in dfu_settings. */
+
+/** @brief Size of a flash page. This value is used for calculating the size of the reserved
+ * flash space in the bootloader region.
+ */
+#if defined(NRF51)
+ #define CODE_PAGE_SIZE (PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
+#elif defined(NRF52) || defined(NRF52840_XXAA)
+ #define CODE_PAGE_SIZE (MBR_PAGE_SIZE_IN_WORDS * sizeof(uint32_t))
+#else
+ #error "Architecture not set."
+#endif
+
+/** @brief Maximum size of a data object.*/
+#if defined(NRF51)
+ #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE * 4)
+#elif defined(NRF52_SERIES) || defined (__SDK_DOXYGEN__)
+ #define DATA_OBJECT_MAX_SIZE (CODE_PAGE_SIZE)
+#else
+ #error "Architecture not set."
+#endif
+
+/** @brief Page location of the bootloader settings address.
+ */
+#if defined (NRF51)
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0003FC00UL)
+#elif defined( NRF52810_XXAA )
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0002F000UL)
+#elif defined( NRF52832_XXAA )
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x0007F000UL)
+#elif defined(NRF52840_XXAA)
+ #define BOOTLOADER_SETTINGS_ADDRESS (0x000FF000UL)
+#else
+ #error No valid target set for BOOTLOADER_SETTINGS_ADDRESS.
+#endif
+
+#define BOOTLOADER_SETTINGS_PAGE_SIZE (CODE_PAGE_SIZE)
+
+/**
+ * @brief MBR parameters page in UICR.
+ *
+ * Register location in UICR where the page address of the MBR parameters page is stored (only used by the nRF52 MBR).
+ *
+ * @note If the value at the given location is 0xFFFFFFFF, no MBR parameters page is set.
+ */
+#define NRF_UICR_MBR_PARAMS_PAGE_ADDRESS (NRF_UICR_BASE + 0x18)
+#define NRF_MBR_PARAMS_PAGE_SIZE (CODE_PAGE_SIZE)
+
+/** @brief Page location of the MBR parameters page address.
+ */
+#if defined(NRF52840_XXAA) || defined(NRF52840_XXAA_ENGA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x000FE000UL)
+#elif defined(NRF52832_XXAA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0007E000UL)
+#elif defined(NRF52810_XXAA)
+ #define NRF_MBR_PARAMS_PAGE_ADDRESS (0x0002E000UL)
+#endif
+
+/** @brief Size (in bytes) of the flash area reserved for application data.
+ *
+ * The area is found at the end of the application area, next to the start of
+ * the bootloader. This area will not be erased by the bootloader during a
+ * firmware upgrade. The default value is 3 pages which matches the size used
+ * in most SDK examples.
+ */
+#ifndef DFU_APP_DATA_RESERVED
+#define DFU_APP_DATA_RESERVED (CODE_PAGE_SIZE * 3)
+#endif
+
+/** @brief Total size of the region between the SoftDevice and the bootloader.
+ */
+#define DFU_REGION_END(bootloader_start_addr) ((bootloader_start_addr) - (DFU_APP_DATA_RESERVED))
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#define DFU_REGION_START (nrf_dfu_bank0_start_addr())
+#else
+#define DFU_REGION_START (MBR_SIZE)
+#endif
+
+#define DFU_REGION_TOTAL_SIZE ((DFU_REGION_END) - (DFU_REGION_START))
+
+#define NRF_DFU_CURRENT_BANK_0 0x00
+#define NRF_DFU_CURRENT_BANK_1 0x01
+
+#define NRF_DFU_BANK_LAYOUT_DUAL 0x00
+#define NRF_DFU_BANK_LAYOUT_SINGLE 0x01
+
+/** @brief DFU bank state codes.
+ *
+ * @details The DFU bank state indicates the content of a bank:
+ * A valid image of a certain type or an invalid image.
+ */
+
+#define NRF_DFU_BANK_INVALID 0x00 /**< Invalid image. */
+#define NRF_DFU_BANK_VALID_APP 0x01 /**< Valid application. */
+#define NRF_DFU_BANK_VALID_SD 0xA5 /**< Valid SoftDevice. */
+#define NRF_DFU_BANK_VALID_BL 0xAA /**< Valid bootloader. */
+#define NRF_DFU_BANK_VALID_SD_BL 0xAC /**< Valid SoftDevice and bootloader. */
+
+/** @brief Description of a single bank. */
+#pragma pack(4)
+typedef struct
+{
+ uint32_t image_size; /**< Size of the image in the bank. */
+ uint32_t image_crc; /**< CRC of the image. If set to 0, the CRC is ignored. */
+ uint32_t bank_code; /**< Identifier code for the bank. */
+} nrf_dfu_bank_t;
+
+/**@brief DFU progress.
+ *
+ * Be aware of the difference between objects and firmware images. A firmware image consists of multiple objects, each of a maximum size @ref DATA_OBJECT_MAX_SIZE.
+ *
+ * @note The union inside this struct is cleared when CREATE_OBJECT of command type is executed, and when there is a valid post-validation.
+ * In DFU activation (after reset) the @ref dfu_progress_t::update_start_address will be used in case of a SD/SD+BL update.
+ */
+ANON_UNIONS_ENABLE;
+typedef struct
+{
+ uint32_t command_size; /**< The size of the current init command stored in the DFU settings. */
+ uint32_t command_offset; /**< The offset of the currently received init command data. The offset will increase as the init command is received. */
+ uint32_t command_crc; /**< The calculated CRC of the init command (calculated after the transfer is completed). */
+ uint32_t data_object_size; /**< The size of the last object created. Note that this size is not the size of the whole firmware image.*/
+ union
+ {
+ struct
+ {
+ uint32_t firmware_image_crc; /**< CRC value of the current firmware (continuously calculated as data is received). */
+ uint32_t firmware_image_crc_last; /**< The CRC of the last executed object. */
+ uint32_t firmware_image_offset; /**< The offset of the current firmware image being transferred. Note that this offset is the offset in the entire firmware image and not only the current object. */
+ uint32_t firmware_image_offset_last;/**< The offset of the last executed object from the start of the firmware image. */
+ };
+ struct
+ {
+ uint32_t update_start_address; /**< Value indicating the start address of the new firmware (before copy). It's always used, but it's most important for an SD/SD+BL update where the SD changes size or if the DFU process had a power loss when updating a SD with changed size. */
+ };
+ };
+} dfu_progress_t;
+ANON_UNIONS_DISABLE;
+
+/** @brief Event types in the bootloader and DFU process. */
+typedef enum
+{
+ NRF_DFU_EVT_DFU_INITIALIZED, /**< Starting DFU. */
+ NRF_DFU_EVT_TRANSPORT_ACTIVATED, /**< Transport activated (e.g. BLE connected, USB plugged in). */
+ NRF_DFU_EVT_TRANSPORT_DEACTIVATED, /**< Transport deactivated (e.g. BLE disconnected, USB plugged out). */
+ NRF_DFU_EVT_DFU_STARTED, /**< DFU process started. */
+ NRF_DFU_EVT_OBJECT_RECEIVED, /**< A DFU data object has been received. */
+ NRF_DFU_EVT_DFU_FAILED, /**< DFU process has failed, been interrupted, or hung. */
+ NRF_DFU_EVT_DFU_COMPLETED, /**< DFU process completed. */
+ NRF_DFU_EVT_DFU_ABORTED, /**< DFU process aborted. */
+} nrf_dfu_evt_type_t;
+
+/**
+ * @brief Function for notifying DFU state.
+ */
+typedef void (*nrf_dfu_observer_t)(nrf_dfu_evt_type_t notification);
+
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+
+typedef struct
+{
+ uint32_t crc; /**< CRC of the rest of the parameters in this struct. */
+ ble_gap_id_key_t ble_id; /**< BLE GAP identity key of the device that initiated the DFU process. */
+ ble_gap_enc_key_t enc_key; /**< Encryption key structure containing encrypted diversifier and LTK for reestablishing the bond. */
+ uint8_t sys_serv_attr[SYSTEM_SERVICE_ATT_SIZE]; /**< System service attributes for restoring of Service Changed Indication setting in DFU mode. */
+} nrf_dfu_peer_data_t;
+
+typedef enum
+{
+ DFU_PEER_DATA_STATE_INVALID = 0,
+ DFU_PEER_DATA_STATE_INITIALIZED = 1,
+ DFU_PEER_DATA_STATE_WRITE_REQUESTED = 2,
+ DFU_PEER_DATA_STATE_WRITE_FINISHED = 3,
+ DFU_PEER_DATA_STATE_WRITE_FAILED = 4,
+} nrf_dfu_peer_data_state_t;
+
+typedef struct
+{
+ uint32_t crc; /**< CRC of the rest of the parameters in this struct. Calculated by the bootloader. */
+ uint8_t name[20]; /**< New advertisement name to set. */
+ uint32_t len; /**< Length of the advertisement name. */
+} nrf_dfu_adv_name_t;
+
+typedef enum
+{
+ DFU_ADV_NAME_STATE_INVALID = 0,
+ DFU_ADV_NAME_STATE_INITIALIZED = 1,
+ DFU_ADV_NAME_STATE_WRITE_REQUESTED = 2,
+ DFU_ADV_NAME_STATE_WRITE_FINISHED = 3,
+ DFU_ADV_NAME_STATE_WRITE_FAILED = 4,
+} nrf_dfu_set_adv_name_state_t;
+
+#endif // NRF_DFU_TRANSPORT_BLE
+
+
+/**@brief DFU settings for application and bank data.
+ */
+typedef struct
+{
+ uint32_t crc; /**< CRC for the stored DFU settings, not including the CRC itself. If 0xFFFFFFF, the CRC has never been calculated. */
+ uint32_t settings_version; /**< Version of the current DFU settings struct layout. */
+ uint32_t app_version; /**< Version of the last stored application. */
+ uint32_t bootloader_version; /**< Version of the last stored bootloader. */
+
+ uint32_t bank_layout; /**< Bank layout: single bank or dual bank. This value can change. */
+ uint32_t bank_current; /**< The bank that is currently used. */
+
+ nrf_dfu_bank_t bank_0; /**< Bank 0. */
+ nrf_dfu_bank_t bank_1; /**< Bank 1. */
+
+ uint32_t write_offset; /**< Write offset for the current operation. */
+ uint32_t sd_size; /**< Size of the SoftDevice. */
+
+ dfu_progress_t progress; /**< Current DFU progress. */
+
+ uint32_t enter_buttonless_dfu;
+ uint8_t init_command[INIT_COMMAND_MAX_SIZE]; /**< Buffer for storing the init command. */
+
+#if defined(NRF_DFU_TRANSPORT_BLE) && NRF_DFU_TRANSPORT_BLE
+ nrf_dfu_peer_data_t peer_data; /**< Not included in calculated CRC. */
+ nrf_dfu_adv_name_t adv_name; /**< Not included in calculated CRC. */
+#endif // NRF_DFU_TRANSPORT_BLE
+
+} nrf_dfu_settings_t;
+
+#pragma pack() // revert pack settings
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_TYPES_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c
new file mode 100644
index 0000000..286eea6
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.c
@@ -0,0 +1,259 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_dfu_utils.h"
+
+#include "nrf_dfu_settings.h"
+#include "nrf_bootloader_info.h"
+#include "crc32.h"
+#include "nrf_log.h"
+
+void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank)
+{
+ // Set the bank-code to invalid, and reset size/CRC
+ memset(p_bank, 0, sizeof(nrf_dfu_bank_t));
+
+ // Reset write pointer after completed operation
+ s_dfu_settings.write_offset = 0;
+}
+
+
+#ifndef BLE_STACK_SUPPORT_REQD
+void nrf_dfu_softdevice_invalidate(void)
+{
+ static const uint32_t all_zero = 0UL;
+
+ if (SD_PRESENT)
+ {
+ ret_code_t err_code = nrf_dfu_flash_store(SD_MAGIC_NUMBER_ABS_OFFSET_GET(MBR_SIZE), &all_zero, 4, NULL);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not invalidate SoftDevice.")
+ }
+ else
+ {
+ // If there is an app it must be invalidated since its start address can no longer be resolved.
+ if (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP)
+ {
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
+ }
+ // Since the start of bank 0 has now implicitly been moved to the start
+ // of the invalidated SoftDevice, its image size must be increased by the
+ // same amount so the start of bank 1 will be correctly calculated.
+ s_dfu_settings.bank_0.image_size += SD_SIZE_GET(MBR_SIZE) - MBR_SIZE;
+ }
+ }
+}
+#endif
+
+
+uint32_t nrf_dfu_bank0_start_addr(void)
+{
+ if (SD_PRESENT)
+ {
+ return ALIGN_TO_PAGE(SD_SIZE_GET(MBR_SIZE));
+ }
+ else
+ {
+ return MBR_SIZE;
+ }
+}
+
+
+uint32_t nrf_dfu_bank1_start_addr(void)
+{
+ uint32_t bank0_addr = nrf_dfu_bank0_start_addr();
+ return ALIGN_TO_PAGE(bank0_addr + s_dfu_settings.bank_0.image_size);
+}
+
+
+uint32_t nrf_dfu_app_start_address(void)
+{
+ return nrf_dfu_bank0_start_addr();
+}
+
+
+uint32_t nrf_dfu_softdevice_start_address(void)
+{
+ return MBR_SIZE;
+}
+
+
+bool nrf_dfu_app_is_valid(bool do_crc)
+{
+ NRF_LOG_DEBUG("Enter nrf_dfu_app_is_valid");
+ if (s_dfu_settings.bank_0.bank_code != NRF_DFU_BANK_VALID_APP)
+ {
+ // Bank 0 has no valid app. Nothing to boot
+ NRF_LOG_DEBUG("Return false in valid app check");
+ return false;
+ }
+
+ // If CRC == 0, the CRC check is skipped.
+ if (do_crc && (s_dfu_settings.bank_0.image_crc != 0))
+ {
+ uint32_t crc = crc32_compute((uint8_t*) nrf_dfu_app_start_address(),
+ s_dfu_settings.bank_0.image_size,
+ NULL);
+
+ if (crc != s_dfu_settings.bank_0.image_crc)
+ {
+ // CRC does not match with what is stored.
+ NRF_LOG_DEBUG("Return false in CRC");
+ return false;
+ }
+ }
+
+ NRF_LOG_DEBUG("Return true. App was valid");
+ return true;
+}
+
+
+
+uint32_t nrf_dfu_cache_prepare(const uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice)
+{
+ ret_code_t err_code;
+ bool cache_too_small;
+ enum
+ {
+ INITIAL_DELETE_APP = 0,
+ APP_DELETED_DELETE_SOFTDEVICE = 1,
+ SOFTDEVICE_DELETED = 2
+ } pass;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_cache_prepare()");
+ NRF_LOG_DEBUG("required_size: 0x%x.", required_size);
+ NRF_LOG_DEBUG("single_bank: %s.", single_bank ? "true" : "false");
+ NRF_LOG_DEBUG("keep_app: %s.", keep_app ? "true" : "false");
+ NRF_LOG_DEBUG("keep_softdevice: %s.", keep_softdevice ? "true" : "false");
+ NRF_LOG_DEBUG("SD_PRESENT: %s.", SD_PRESENT ? "true" : "false");
+ NRF_LOG_DEBUG("Bank contents:");
+ NRF_LOG_DEBUG("Bank 0 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_0.bank_code, s_dfu_settings.bank_0.image_size);
+ NRF_LOG_DEBUG("Bank 1 code: 0x%02x: Size: 0x%x", s_dfu_settings.bank_1.bank_code, s_dfu_settings.bank_1.image_size);
+
+ // Pass 0 deletes the app if necessary or requested, and if so, proceeds to pass 1.
+ // Pass 1 deletes the SoftDevice if necessary or requested, and if so, proceeds to pass 2.
+ // Pass 2 does a last size check.
+ for (pass = INITIAL_DELETE_APP; pass <= SOFTDEVICE_DELETED; pass++)
+ {
+ uint32_t cache_address;
+ const uint32_t bootloader_start_addr = BOOTLOADER_START_ADDR; // Assign to a variable to prevent warning in Keil 4.
+ bool keep_firmware = true;
+ bool delete_more;
+
+ switch (pass)
+ {
+ case INITIAL_DELETE_APP:
+ cache_address = nrf_dfu_bank1_start_addr();
+
+ // If there is no app, keep_app should be assumed false, so we can free up more space.
+ keep_firmware = keep_app && (s_dfu_settings.bank_0.bank_code == NRF_DFU_BANK_VALID_APP);
+ break;
+
+ case APP_DELETED_DELETE_SOFTDEVICE:
+ cache_address = nrf_dfu_bank0_start_addr();
+
+ // If there is no SoftDevice, keep_SoftDevice should be assumed true, because there is
+ // no point to continuing since the SoftDevice is the last firmware that can be deleted.
+ keep_firmware = keep_softdevice || !SD_PRESENT;
+ break;
+
+ case SOFTDEVICE_DELETED:
+ cache_address = nrf_dfu_softdevice_start_address();
+ break;
+
+ default:
+ ASSERT(false);
+ cache_address = 0;
+ break;
+ }
+
+ ASSERT(cache_address <= DFU_REGION_END(bootloader_start_addr));
+ cache_too_small = required_size > (DFU_REGION_END(bootloader_start_addr) - cache_address);
+ delete_more = cache_too_small || single_bank; // Delete app or SoftDevice only if we need more room, or if single bank is requested.
+
+ NRF_LOG_DEBUG("pass: %d.", pass);
+ NRF_LOG_DEBUG("cache_address: 0x%x.", cache_address);
+ NRF_LOG_DEBUG("cache_too_small: %s.", cache_too_small ? "true" : "false");
+ NRF_LOG_DEBUG("keep_firmware: %s.", keep_firmware ? "true" : "false");
+ NRF_LOG_DEBUG("delete_more: %s.", delete_more ? "true" : "false");
+
+ if (!delete_more || keep_firmware || (pass >= SOFTDEVICE_DELETED))
+ {
+ // Stop, done.
+ break;
+ }
+ }
+
+ if (cache_too_small)
+ {
+ NRF_LOG_WARNING("Aborting. Cannot fit new firmware on device");
+ err_code = NRF_ERROR_NO_MEM;
+ }
+ else
+ {
+ // Room was found. Make the necessary preparations for receiving update.
+
+#ifndef BLE_STACK_SUPPORT_REQD
+ if (pass >= SOFTDEVICE_DELETED)
+ {
+ NRF_LOG_DEBUG("Invalidating SoftDevice.");
+ nrf_dfu_softdevice_invalidate();
+ }
+#endif
+ if (pass >= APP_DELETED_DELETE_SOFTDEVICE)
+ {
+ NRF_LOG_DEBUG("Invalidating app.");
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
+ }
+
+ s_dfu_settings.bank_layout = NRF_DFU_BANK_LAYOUT_DUAL;
+ s_dfu_settings.bank_current = NRF_DFU_CURRENT_BANK_1;
+
+ // Prepare bank for new image.
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
+
+ // Store the Firmware size in the bank for continuations
+ s_dfu_settings.bank_1.image_size = required_size;
+
+ err_code = NRF_SUCCESS;
+ }
+
+ return err_code;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h
new file mode 100644
index 0000000..6369f92
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_utils.h
@@ -0,0 +1,167 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_utils DFU utilities
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef NRF_DFU_UTILS_H__
+#define NRF_DFU_UTILS_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "app_util.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * Round up val to the next page boundary
+ */
+#define ALIGN_TO_PAGE(val) ALIGN_NUM((CODE_PAGE_SIZE), (val))
+
+
+/** @brief Function for getting the start address of bank 0.
+ *
+ * @note Bank 0 starts after the SoftDevice if a SoftDevice is present.
+ *
+ * @return The start address of bank 0.
+ */
+uint32_t nrf_dfu_bank0_start_addr(void);
+
+
+/** @brief Function for getting the start address of bank 1.
+ *
+ * @return The start address of bank 1.
+ */
+uint32_t nrf_dfu_bank1_start_addr(void);
+
+
+/** @brief Function for getting the start address of the app.
+ *
+ * @return The start address of the bootable app.
+ */
+uint32_t nrf_dfu_app_start_address(void);
+
+
+/** @brief Function for getting the start address of the SoftDevice.
+ *
+ * @return The start address of the SoftDevivce.
+ */
+uint32_t nrf_dfu_softdevice_start_address(void);
+
+
+/** @brief Function for checking if the main application is valid.
+ *
+ * @details This function checks if there is a valid application
+ * located at Bank 0.
+ *
+ * @param[in] do_crc Perform CRC check on application.
+ *
+ * @retval true If a valid application has been detected.
+ * @retval false If there is no valid application.
+ */
+bool nrf_dfu_app_is_valid(bool do_crc);
+
+
+/** @brief Function for finding and preparing a place in flash in which to store a DFU update.
+ *
+ * @details This function checks the size requirements and selects a location for
+ * placing the cache of the DFU images.
+ * The function tries to find enough space after the existing firmwares. If there is not
+ * enough space, the present application is deleted. If there is still not enough space,
+ * the SoftDevice is deleted.
+ * If @p single_bank is true, the default behavior is to immediately delete the app and
+ * SoftDevice as necessary to place the new firmware at its intended location. If the
+ * intended location cannot be made available, or if the update is a bootloader update,
+ * the update will be a dual bank update, and nothing will be deleted by this function
+ * except when needed for size.
+ * If @p keep_app is true, the app is never deleted by this function. Likewise if @p
+ * keep_softdevice is true, the SoftDevice is never deleted by this function.
+ * If the new firmware cannot fit within the constraints, nothing is deleted and the
+ * function fails.
+ *
+ * @param[in] required_size Requirements for the size of the new image.
+ * @param[in] single_bank Whether to put the firmware directly where it's meant to go.
+ * @p keep_app and @p keep_softdevice take precedence over this.
+ * @param[in] keep_app True to ensure the app is not deleted by this function. This
+ * effectively enforces dual bank update.
+ * @param[out] keep_softdevice True to ensure the SoftDevice is not deleted by this function.
+ *
+ * @retval NRF_SUCCESS If a cache location was found for the DFU process.
+ * @retval NRF_ERROR_NO_MEM If there is not enough space available to receive the update.
+ * Nothing has been deleted.
+ */
+uint32_t nrf_dfu_cache_prepare(uint32_t required_size, bool single_bank, bool keep_app, bool keep_softdevice);
+
+
+/**@brief Function for making sure a SoftDevice is not recognized as such anymore.
+ *
+ * @details It works by overwriting the magic number of the SoftDevice with 0s. The
+ * magic number is used throughout the bootloader to detect whether a SoftDevice
+ * is present.
+ *
+ * @warning This function should only be called when both banks are already invalid.
+ * because the (implicit) position of the banks will shift when the SoftDevice
+ * is invalidated.
+ */
+void nrf_dfu_softdevice_invalidate(void);
+
+
+/**@brief Function for making sure a bank is not copied or booted.
+ *
+ * @details This also sets the size of the bank to 0.
+ *
+ * @param[in] p_bank Pointer to the bank to be invalidated.
+ */
+void nrf_dfu_bank_invalidate(nrf_dfu_bank_t * const p_bank);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_UTILS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c
new file mode 100644
index 0000000..566702d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.c
@@ -0,0 +1,745 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_dfu_flash.h"
+#include "nrf_bootloader_info.h"
+#include "pb.h"
+#include "pb_common.h"
+#include "pb_decode.h"
+#include "dfu-cc.pb.h"
+#include "crc32.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "nrf_dfu_validation.h"
+#include "nrf_dfu_ver_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_validation
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#ifndef NRF_DFU_DEBUG
+#ifdef NRF_DFU_DEBUG_VERSION
+#define NRF_DFU_DEBUG 1
+#else
+#define NRF_DFU_DEBUG 0
+#endif
+#endif
+
+#ifndef DFU_REQUIRES_SOFTDEVICE
+#ifndef BLE_STACK_SUPPORT_REQD
+#define DFU_REQUIRES_SOFTDEVICE 0
+#else
+#define DFU_REQUIRES_SOFTDEVICE 1
+#endif
+#endif
+
+#define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
+
+/* Whether a complete init command has been received and prevalidated, but the firmware
+ * is not yet fully transferred. This value will also be correct after reset.
+ */
+static bool m_valid_init_cmd_present = false;
+static dfu_packet_t m_packet = DFU_PACKET_INIT_DEFAULT;
+static uint8_t* m_init_packet_data_ptr = 0;
+static uint32_t m_init_packet_data_len = 0;
+static pb_istream_t m_pb_stream;
+
+static nrf_crypto_ecdsa_verify_context_t m_verify_context = {0};
+
+static nrf_crypto_hash_context_t m_hash_context = {0};
+
+
+__ALIGN(4) extern const uint8_t pk[64];
+
+/** @brief Value length structure holding the public key.
+ *
+ * @details The pk value pointed to is the public key present in dfu_public_key.c
+ */
+static nrf_crypto_ecc_public_key_t m_public_key;
+
+/** @brief Structure to hold a signature
+ */
+static nrf_crypto_ecdsa_secp256r1_signature_t m_signature;
+
+/** @brief Structure to hold the hash for the init packet
+ */
+static nrf_crypto_hash_sha256_digest_t m_init_packet_hash;
+
+/** @brief Structure to hold the hash for the firmware image
+ */
+static nrf_crypto_hash_sha256_digest_t m_fw_hash;
+
+
+static void pb_decoding_callback(pb_istream_t *str, uint32_t tag, pb_wire_type_t wire_type, void *iter)
+{
+ pb_field_iter_t* p_iter = (pb_field_iter_t *) iter;
+
+ // match the beginning of the init command
+ if (p_iter->pos->ptr == &dfu_init_command_fields[0])
+ {
+ uint8_t * ptr = (uint8_t *)str->state;
+ uint32_t size = str->bytes_left;
+
+ // remove tag byte
+ ptr++;
+ size--;
+
+ // store the info in init_packet_data
+ m_init_packet_data_ptr = ptr;
+ m_init_packet_data_len = size;
+
+ NRF_LOG_DEBUG("PB: Init packet data len: %d", size);
+ }
+}
+
+/** @brief Function for decoding byte stream into variable.
+ *
+ * @retval true If the stored init command was successfully decoded.
+ * @retval false If there was no stored init command, or the decoding failed.
+ */
+static bool stored_init_cmd_decode(void)
+{
+ m_pb_stream = pb_istream_from_buffer(s_dfu_settings.init_command,
+ s_dfu_settings.progress.command_size);
+
+ // Attach our callback to follow the field decoding
+ m_pb_stream.decoding_callback = pb_decoding_callback;
+
+ m_init_packet_data_ptr = NULL;
+ m_init_packet_data_len = 0;
+
+ if (!pb_decode(&m_pb_stream, dfu_packet_fields, &m_packet))
+ {
+ NRF_LOG_ERROR("Handler: Invalid protocol buffer m_pb_stream");
+ return false;
+ }
+
+ return true;
+}
+
+
+void nrf_dfu_validation_init(void)
+{
+ ret_code_t err_code;
+
+ // If the command is stored to flash, init command was valid.
+ if ( (s_dfu_settings.progress.command_size != 0)
+ && stored_init_cmd_decode()
+ && (s_dfu_settings.bank_1.image_size != 0))
+ {
+ m_valid_init_cmd_present = true;
+ }
+ else
+ {
+ m_valid_init_cmd_present = false;
+ }
+
+ err_code = nrf_crypto_init();
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_PARAMETER(err_code);
+
+
+ err_code = nrf_crypto_ecc_public_key_from_raw(&g_nrf_crypto_ecc_secp256r1_curve_info,
+ &m_public_key,
+ pk,
+ sizeof(pk));
+ ASSERT(err_code == NRF_SUCCESS);
+ UNUSED_PARAMETER(err_code);
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if (size == 0)
+ {
+ ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ }
+ else if (size > INIT_COMMAND_MAX_SIZE)
+ {
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ // Set DFU to uninitialized.
+ m_valid_init_cmd_present = false;
+
+ // Reset all progress.
+ s_dfu_settings.write_offset = 0;
+ memset(&s_dfu_settings.progress, 0x00, sizeof(dfu_progress_t));
+
+ // Set the init command size.
+ s_dfu_settings.progress.command_size = size;
+ }
+ return ret_val;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if ((length + s_dfu_settings.progress.command_offset) > s_dfu_settings.progress.command_size)
+ {
+ NRF_LOG_ERROR("Init command larger than expected.");
+ ret_val = NRF_DFU_RES_CODE_INVALID_PARAMETER;
+ }
+ else
+ {
+ // Copy the received data to RAM, update offset and calculate CRC.
+ memcpy(&s_dfu_settings.init_command[s_dfu_settings.progress.command_offset],
+ p_data,
+ length);
+
+ s_dfu_settings.progress.command_offset += length;
+ s_dfu_settings.progress.command_crc = crc32_compute(p_data,
+ length,
+ &s_dfu_settings.progress.command_crc);
+ }
+ return ret_val;
+}
+
+
+void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
+ uint32_t * p_crc,
+ uint32_t * p_max_size)
+{
+ *p_offset = s_dfu_settings.progress.command_offset;
+ *p_crc = s_dfu_settings.progress.command_crc;
+ *p_max_size = INIT_COMMAND_MAX_SIZE;
+}
+
+
+bool nrf_dfu_validation_init_cmd_present(void)
+{
+ return m_valid_init_cmd_present;
+}
+
+
+// Function determines if init command signature is obligatory
+static bool signature_required(dfu_fw_type_t fw_type_to_be_updated)
+{
+ bool result = true;
+
+ if ((!DFU_REQUIRES_SOFTDEVICE && (fw_type_to_be_updated == DFU_FW_TYPE_SOFTDEVICE)) ||
+ (fw_type_to_be_updated == DFU_FW_TYPE_APPLICATION))
+ {
+ result = NRF_DFU_REQUIRE_SIGNED_APP_UPDATE;
+ }
+ return result;
+}
+
+
+// Function to perform signature check if required.
+static nrf_dfu_result_t signature_check(dfu_fw_type_t fw_type,
+ dfu_signature_type_t signature_type,
+ dfu_signed_command_signature_t const * p_signature)
+{
+ ret_code_t err_code;
+ size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ if (!signature_required(fw_type))
+ {
+ return NRF_DFU_RES_CODE_SUCCESS;
+ }
+
+ NRF_LOG_INFO("Signature required. Checking signature.")
+ if (p_signature == NULL)
+ {
+ NRF_LOG_WARNING("No signature found.");
+ return EXT_ERR(NRF_DFU_EXT_ERROR_SIGNATURE_MISSING);
+ }
+
+ if (signature_type != DFU_SIGNATURE_TYPE_ECDSA_P256_SHA256)
+ {
+ NRF_LOG_INFO("Invalid signature type");
+ return EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_SIGNATURE_TYPE);
+ }
+
+ NRF_LOG_INFO("Calculating init packet hash (init packet len: %d)", m_init_packet_data_len);
+ err_code = nrf_crypto_hash_calculate(&m_hash_context,
+ &g_nrf_crypto_hash_sha256_info,
+ m_init_packet_data_ptr,
+ m_init_packet_data_len,
+ m_init_packet_hash,
+ &hash_len);
+ if (err_code != NRF_SUCCESS)
+ {
+ return NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+
+ if (sizeof(m_signature) != p_signature->size)
+ {
+ return NRF_DFU_RES_CODE_OPERATION_FAILED;
+ }
+
+ // Prepare the signature received over the air.
+ memcpy(m_signature, p_signature->bytes, p_signature->size);
+
+ // calculate the signature
+ NRF_LOG_INFO("Verify signature");
+ err_code = nrf_crypto_ecdsa_verify(&m_verify_context,
+ &m_public_key,
+ m_init_packet_hash,
+ hash_len,
+ m_signature,
+ sizeof(m_signature));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Signature failed (err_code: 0x%x)", err_code);
+ NRF_LOG_DEBUG("Signature:");
+ NRF_LOG_HEXDUMP_DEBUG(m_signature, sizeof(m_signature));
+ NRF_LOG_DEBUG("Hash:");
+ NRF_LOG_HEXDUMP_DEBUG(m_init_packet_hash, hash_len);
+ NRF_LOG_DEBUG("Public Key:");
+ NRF_LOG_HEXDUMP_DEBUG(pk, sizeof(pk));
+ NRF_LOG_FLUSH();
+
+ return NRF_DFU_RES_CODE_INVALID_OBJECT;
+ }
+
+ NRF_LOG_INFO("Image verified");
+ return NRF_DFU_RES_CODE_SUCCESS;
+}
+
+
+// Function to calculate the total size of the firmware(s) in the update.
+static nrf_dfu_result_t update_data_size_get(dfu_init_command_t const * p_init, uint32_t * p_size)
+{
+ nrf_dfu_result_t ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ uint32_t fw_sz = 0;
+
+ if ((p_init->type == DFU_FW_TYPE_APPLICATION) && (p_init->has_app_size == true))
+ {
+ fw_sz = p_init->app_size;
+ }
+ else
+ {
+ if ((p_init->type & DFU_FW_TYPE_SOFTDEVICE) && (p_init->has_sd_size == true))
+ {
+ fw_sz = p_init->sd_size;
+ }
+
+ if ((p_init->type & DFU_FW_TYPE_BOOTLOADER) && (p_init->has_bl_size == true))
+ {
+ if (p_init->bl_size <= BOOTLOADER_SIZE)
+ {
+ fw_sz += p_init->bl_size;
+ }
+ else
+ {
+ NRF_LOG_ERROR("BL size (%d) over limit (%d)", p_init->bl_size, BOOTLOADER_SIZE);
+ fw_sz = 0;
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ }
+ }
+
+ if (fw_sz)
+ {
+ *p_size = fw_sz;
+ ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ }
+ else
+ {
+ NRF_LOG_ERROR("Init packet does not contain valid firmware size");
+ }
+
+ return ret_val;
+}
+
+
+/**
+ * @brief Function to check if single bank update should be used.
+ *
+ * @param new_fw_type Firmware type.
+ */
+static bool use_single_bank(dfu_fw_type_t new_fw_type)
+{
+ bool result = false;
+
+ if (((new_fw_type == DFU_FW_TYPE_APPLICATION) || (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)) &&
+ NRF_DFU_SINGLE_BANK_APP_UPDATES)
+ {
+ result = true;
+ }
+
+ return result;
+}
+
+
+// Function to determine if the new firmware needs a SoftDevice to be present.
+static bool update_requires_softdevice(dfu_init_command_t const * p_init)
+{
+ return ((p_init->sd_req_count > 0) && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD));
+}
+
+
+// Function to determine if the SoftDevice can be removed during the update or not.
+static bool keep_softdevice(dfu_init_command_t const * p_init)
+{
+ UNUSED_PARAMETER(p_init); // It's unused when DFU_REQUIRES_SOFTDEVICE is true.
+ return DFU_REQUIRES_SOFTDEVICE || update_requires_softdevice(p_init);
+}
+
+
+/**@brief Function to determine where to temporarily store the incoming firmware.
+ * This also checks whether the update will fit, and deletes existing
+ * firmware to make room for the new firmware.
+ *
+ * @param[in] p_init Init command.
+ * @param[in] fw_size The size of the incoming firmware.
+ * @param[out] p_addr The address at which to initially store the firmware.
+ *
+ * @retval NRF_DFU_RES_CODE_SUCCESS If the size check passed and
+ * an address was found.
+ * @retval NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES If the size check failed.
+ */
+static nrf_dfu_result_t update_data_addr_get(dfu_init_command_t const * p_init,
+ uint32_t fw_size,
+ uint32_t * p_addr)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ ret_code_t err_code = nrf_dfu_cache_prepare(fw_size,
+ use_single_bank(p_init->type),
+ NRF_DFU_FORCE_DUAL_BANK_APP_UPDATES,
+ keep_softdevice(p_init));
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Can't find room for update");
+ ret_val = NRF_DFU_RES_CODE_INSUFFICIENT_RESOURCES;
+ }
+ else
+ {
+ *p_addr = nrf_dfu_bank1_start_addr();
+ NRF_LOG_DEBUG("Write address set to 0x%08x", *p_addr);
+ }
+ return ret_val;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
+ uint32_t * p_data_len)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+
+ if (s_dfu_settings.progress.command_offset != s_dfu_settings.progress.command_size)
+ {
+ // The object wasn't the right (requested) size
+ NRF_LOG_ERROR("Execute with faulty offset");
+ ret_val = NRF_DFU_RES_CODE_OPERATION_NOT_PERMITTED;
+ }
+ else if (m_valid_init_cmd_present)
+ {
+ *p_dst_data_addr = nrf_dfu_bank1_start_addr();
+ *p_data_len = s_dfu_settings.bank_1.image_size;
+ ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ }
+ else if (stored_init_cmd_decode() &&
+ (m_packet.has_signed_command || m_packet.has_command))
+ {
+ dfu_command_t const * p_command = &m_packet.command;
+ dfu_signature_type_t signature_type = (dfu_signature_type_t) 0; // Placeholder.
+ dfu_signed_command_signature_t * p_signature = NULL;
+
+ *p_dst_data_addr = 0;
+ *p_data_len = 0;
+
+ if (m_packet.has_signed_command)
+ {
+ p_command = &m_packet.signed_command.command;
+ signature_type = m_packet.signed_command.signature_type;
+ p_signature = &m_packet.signed_command.signature;
+ }
+
+ // Validate signature.
+ ret_val = signature_check(p_command->init.type, signature_type, p_signature);
+
+ // Validate versions
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = nrf_dfu_ver_validation_check(&p_command->init);
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ m_valid_init_cmd_present = true;
+ }
+ }
+
+ // Get size of binary
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = update_data_size_get(&p_command->init, p_data_len);
+ }
+
+ //Get address where to flash the binary
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ ret_val = update_data_addr_get(&p_command->init, *p_data_len, p_dst_data_addr);
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Failed to decode init packet");
+ ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ }
+
+ return ret_val;
+}
+
+
+// Function to check the hash received in the init command against the received firmware.
+static bool fw_hash_ok(dfu_init_command_t const * p_init, uint32_t fw_start_addr, uint32_t fw_size)
+{
+ ret_code_t err_code;
+ bool result = true;
+ size_t hash_len = NRF_CRYPTO_HASH_SIZE_SHA256;
+
+ ASSERT(p_init != NULL);
+
+ NRF_LOG_DEBUG("Hash verification. Firmware start address: 0x%x, size: 0x%x", fw_start_addr, fw_size);
+ err_code = nrf_crypto_hash_calculate(&m_hash_context,
+ &g_nrf_crypto_hash_sha256_info,
+ (uint8_t*)fw_start_addr,
+ fw_size,
+ m_fw_hash,
+ &hash_len);
+
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not run hash verification (err_code 0x%x).", err_code);
+ result = false;
+ }
+ else if (memcmp(m_fw_hash, p_init->hash.hash.bytes, NRF_CRYPTO_HASH_SIZE_SHA256) != 0)
+ {
+ NRF_LOG_WARNING("Hash verification failed.");
+ NRF_LOG_DEBUG("Expected FW hash:")
+ NRF_LOG_HEXDUMP_DEBUG(p_init->hash.hash.bytes, NRF_CRYPTO_HASH_SIZE_SHA256);
+ NRF_LOG_DEBUG("Actual FW hash:")
+ NRF_LOG_HEXDUMP_DEBUG(m_fw_hash, NRF_CRYPTO_HASH_SIZE_SHA256);
+ NRF_LOG_FLUSH();
+
+ result = false;
+ }
+
+ return result;
+}
+
+
+// Function to check if the update contains a SoftDevice and, if so, if it is of a different
+// major version than the existing SoftDevice.
+static bool is_major_softdevice_update(uint32_t new_sd_addr)
+{
+ // True if there is no SD right now, but there is a new one coming. This counts as a major update.
+ bool result = !SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER);
+
+ if (SD_PRESENT && (SD_MAGIC_NUMBER_GET(new_sd_addr) == SD_MAGIC_NUMBER))
+ {
+ // Both SoftDevices are present.
+ uint32_t current_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(MBR_SIZE));
+ uint32_t new_SD_major = SD_MAJOR_VERSION_EXTRACT(SD_VERSION_GET(new_sd_addr));
+
+ result = (current_SD_major != new_SD_major);
+
+ NRF_LOG_INFO("SoftDevice update is a %s version update. Current: %d. New: %d.",
+ result ? "major" : "minor",
+ current_SD_major,
+ new_SD_major);
+ }
+
+ return result;
+}
+
+
+/**@brief Validate the SoftDevice size and magic number in structure found at 0x2000 in received SoftDevice.
+ *
+ * @param[in] sd_start_addr Start address of received SoftDevice.
+ * @param[in] sd_size Size of received SoftDevice in bytes.
+ */
+static bool softdevice_info_ok(uint32_t sd_start_addr, uint32_t sd_size)
+{
+ bool result = true;
+
+ if (SD_MAGIC_NUMBER_GET(sd_start_addr) != SD_MAGIC_NUMBER)
+ {
+ NRF_LOG_ERROR("The SoftDevice does not contain the magic number identifying it as a SoftDevice.");
+ result = false;
+ }
+ else if (SD_SIZE_GET(sd_start_addr) < ALIGN_TO_PAGE(sd_size + MBR_SIZE))
+ {
+ // The size in the info struct should be rounded up to a page boundary
+ // and be larger than the actual size + the size of the MBR.
+ NRF_LOG_ERROR("The SoftDevice size in the info struct is too small compared with the size reported in the init command.");
+ result = false;
+ }
+
+ return result;
+}
+
+
+static void postvalidate_app(dfu_init_command_t * p_init)
+{
+ s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_APP;
+
+ NRF_LOG_DEBUG("Invalidating old application in bank 0.");
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_INVALID;
+
+ if (!DFU_REQUIRES_SOFTDEVICE && !update_requires_softdevice(p_init))
+ {
+ // App does not need SD, so it should be placed where SD is.
+ nrf_dfu_softdevice_invalidate();
+ }
+
+ if (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false)))
+ {
+ s_dfu_settings.app_version = p_init->fw_version;
+ }
+}
+
+
+// Function to check a received SoftDevice and/or Bootloader firmware
+// before it is copied into place.
+static bool postvalidate_sd_bl(dfu_init_command_t * p_init,
+ bool with_sd,
+ bool with_bl,
+ uint32_t start_addr)
+{
+ if (with_sd)
+ {
+ if (!softdevice_info_ok(start_addr, p_init->sd_size))
+ {
+ return false;
+ }
+
+ if (is_major_softdevice_update(start_addr))
+ {
+ NRF_LOG_WARNING("Invalidating app because it is incompatible with the SoftDevice.");
+ if (DFU_REQUIRES_SOFTDEVICE && !with_bl)
+ {
+ NRF_LOG_ERROR("Major SD update but no BL. Abort to avoid incapacitating the BL.");
+ return false;
+ }
+
+ // Invalidate app since it may not be compatible with new SD.
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_0);
+ }
+
+ // Mark the update as valid.
+ s_dfu_settings.bank_1.bank_code = with_bl ? NRF_DFU_BANK_VALID_SD_BL
+ : NRF_DFU_BANK_VALID_SD;
+
+ s_dfu_settings.sd_size = p_init->sd_size;
+ }
+ else
+ {
+ s_dfu_settings.bank_1.bank_code = NRF_DFU_BANK_VALID_BL;
+ }
+
+
+ if (with_bl &&
+ (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && (p_init->has_is_debug == false || p_init->is_debug == false))))
+ {
+ // If the update contains a bootloader, update the version.
+ // Unless the update is a debug packet.
+ s_dfu_settings.bootloader_version = p_init->fw_version;
+ }
+
+ return true;
+}
+
+
+nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t src_addr, uint32_t data_len)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ dfu_init_command_t * p_init = m_packet.has_signed_command ? &m_packet.signed_command.command.init
+ : &m_packet.command.init;
+
+ if (!fw_hash_ok(p_init, src_addr, data_len))
+ {
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_VERIFICATION_FAILED);
+ }
+ else
+ {
+ if (p_init->type == DFU_FW_TYPE_APPLICATION)
+ {
+ postvalidate_app(p_init);
+ }
+ else
+ {
+ bool with_sd = p_init->type & DFU_FW_TYPE_SOFTDEVICE;
+ bool with_bl = p_init->type & DFU_FW_TYPE_BOOTLOADER;
+
+ if (!postvalidate_sd_bl(p_init, with_sd, with_bl, src_addr))
+ {
+ ret_val = NRF_DFU_RES_CODE_INVALID_OBJECT;
+ if (with_sd && !DFU_REQUIRES_SOFTDEVICE &&
+ (src_addr == nrf_dfu_softdevice_start_address()))
+ {
+ nrf_dfu_softdevice_invalidate();
+ }
+ }
+ }
+ }
+
+ if (ret_val == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ // Store CRC32 for image
+ s_dfu_settings.bank_1.image_crc = s_dfu_settings.progress.firmware_image_crc;
+ s_dfu_settings.bank_1.image_size = data_len;
+ }
+ else
+ {
+ nrf_dfu_bank_invalidate(&s_dfu_settings.bank_1);
+ }
+
+ // Set the progress to zero and remove the last command
+ memset(&s_dfu_settings.progress, 0, sizeof(dfu_progress_t));
+ memset(s_dfu_settings.init_command, 0xFF, DFU_SIGNED_COMMAND_SIZE);
+
+ s_dfu_settings.write_offset = 0;
+ s_dfu_settings.progress.update_start_address = src_addr;
+
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h
new file mode 100644
index 0000000..d0de004
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_validation.h
@@ -0,0 +1,127 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup sdk_nrf_dfu_validation Validation
+ * @{
+ * @ingroup nrf_dfu
+ */
+
+#ifndef __NRF_DFU_VALIDATION_H
+#define __NRF_DFU_VALIDATION_H
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "nrf_dfu_handling_error.h"
+
+/**
+ * @brief Function for module initialization.
+ *
+ * Function checks if there is a valid init packet in DFU settings written in flash.
+ */
+void nrf_dfu_validation_init(void);
+
+/**
+ * @brief Function called on reception of init command creation request.
+ *
+ * @param[in] size Size of incoming init packet.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_create(uint32_t size);
+
+/**
+ * @brief Function called on reception of fragment of init command.
+ *
+ * @param[in] p_data Init command fragment.
+ * @param[in] length Init command fragment size.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_append(uint8_t const * p_data, uint32_t length);
+
+/**
+ * @brief Function for getting init command status.
+ *
+ * @param[out] p_offset Current offset.
+ * @param[out] p_crc Current CRC.
+ * @param[out] p_max_size Maximum size of init command.
+ */
+void nrf_dfu_validation_init_cmd_status_get(uint32_t * p_offset,
+ uint32_t * p_crc,
+ uint32_t * p_max_size);
+
+/**
+ * @brief Function for inquiring whether a valid init command has been received.
+ *
+ * @return true if there is a valid init command. This can be true at boot time
+ * if the device was reset during a DFU operation.
+ */
+bool nrf_dfu_validation_init_cmd_present(void);
+
+/**
+ * @brief Function for validating init command.
+ *
+ * If init command is successfully validated Bank 1 details are written to out parameters.
+ *
+ * Until @ref nrf_dfu_validation_init_cmd_create is called, this function can be called
+ * again after the first time without side effects to retrieve address and length.
+ *
+ * @param[out] p_dst_data_addr Bank 1 start address if validation is successful.
+ * @param[out] p_data_len Bank 1 length if validation is successful.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_init_cmd_execute(uint32_t * p_dst_data_addr,
+ uint32_t * p_data_len);
+
+/**
+ * @brief Function for postvalidating the update. Function is called once all data is received.
+ *
+ * @param[in] dst_data_addr Bank 1 start address.
+ * @param[in] data_len Bank 1 length.
+ *
+ * @return Operation result. See @ref nrf_dfu_result_t
+ */
+nrf_dfu_result_t nrf_dfu_validation_post_data_execute(uint32_t dst_data_addr, uint32_t data_len);
+
+#endif //__NRF_DFU_VALIDATION_H
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c
new file mode 100644
index 0000000..4958dd3
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.c
@@ -0,0 +1,241 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdbool.h>
+#include "nrf_dfu_types.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_crypto.h"
+#include "nrf_assert.h"
+#include "dfu-cc.pb.h"
+#include "nrf_dfu_ver_validation.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_ver_validation
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+
+#ifndef NRF_DFU_DEBUG
+#ifdef NRF_DFU_DEBUG_VERSION
+#define NRF_DFU_DEBUG 1
+#else
+#define NRF_DFU_DEBUG 0
+#endif
+#endif
+
+/** @brief Macro for reading the Firmware ID of a SoftDevice at a given base address.
+ */
+#ifndef _SD_FWID_GET
+#define _SD_FWID_GET(baseaddr) SD_OFFSET_GET_UINT16(baseaddr, 0x0C)
+#endif
+
+#define EXT_ERR(err) (nrf_dfu_result_t)((uint32_t)NRF_DFU_RES_CODE_EXT_ERROR + (uint32_t)err)
+
+static bool sd_req_check(uint32_t const * p_sd_req, uint8_t sd_req_cnt)
+{
+ bool result = false;
+ for (uint8_t i = 0; i < sd_req_cnt; i++)
+ {
+ if (p_sd_req[i] == _SD_FWID_GET(MBR_SIZE))
+ {
+ // Found a matching sd_req field. sd_req is ok.
+ result = true;
+ break;
+ }
+ }
+ return result;
+}
+
+static bool sd_req_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+ bool result;
+#ifdef BLE_STACK_SUPPORT_REQD
+ // The bootloader needs the SoftDevice, so disabling NRF_DFU_APP_DOWNGRADE_PREVENTION
+ // should not be applied to SoftDevice updates.
+ const bool prevent_downgrade = NRF_DFU_APP_DOWNGRADE_PREVENTION || (p_init->type == DFU_FW_TYPE_SOFTDEVICE);
+#else
+ const bool prevent_downgrade = NRF_DFU_APP_DOWNGRADE_PREVENTION;
+#endif
+
+ if (SD_PRESENT)
+ {
+ if (p_init->sd_req_count && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD))
+ {
+ result = sd_req_check(p_init->sd_req, p_init->sd_req_count);
+ }
+ else if (p_init->type == DFU_FW_TYPE_APPLICATION)
+ {
+ // The application wants to overwrite the SoftDevice.
+ if (prevent_downgrade && (p_init->sd_req_count > 1) && (p_init->sd_req[0] == SD_REQ_APP_OVERWRITES_SD))
+ {
+ // The application can overwrite the SD if sd_req[0] == 0 and table has the fwid of the current SD.
+ result = sd_req_check(p_init->sd_req, p_init->sd_req_count);
+ }
+ else
+ {
+ result = true;
+ }
+ }
+ else
+ {
+ // Don't allow SoftDevice updates which assume no SD is present already.
+ result = !prevent_downgrade || (p_init->type != DFU_FW_TYPE_SOFTDEVICE);
+ }
+ }
+ else
+ {
+ if (p_init->sd_req_count && (p_init->sd_req[0] != SD_REQ_APP_OVERWRITES_SD))
+ {
+ // Fail if there is no SD and the update requires SD.
+ result = false;
+ }
+ else
+ {
+ // If there is no SD and update has SD it is accepted only if it has a fw_version.
+ result = !prevent_downgrade || p_init->has_fw_version;
+ }
+ }
+ return result;
+}
+
+static bool fw_hash_type_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+
+ return (p_init->hash.hash_type == DFU_HASH_TYPE_SHA256);
+}
+
+static bool fw_version_required(dfu_fw_type_t new_fw_type)
+{
+ bool result = true;
+
+ if (new_fw_type == DFU_FW_TYPE_SOFTDEVICE)
+ {
+ result = false; // fw_version is optional in SoftDevice updates. If present, it will be checked against the app version.
+ }
+ else if (new_fw_type == DFU_FW_TYPE_APPLICATION)
+ {
+ result = NRF_DFU_APP_DOWNGRADE_PREVENTION; // fw_version is configurable in app updates.
+ }
+
+ return result;
+}
+
+
+static bool fw_type_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+
+ return ((p_init->has_type)
+ && ( (p_init->type == DFU_FW_TYPE_APPLICATION)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE)
+ || (p_init->type == DFU_FW_TYPE_BOOTLOADER)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE_BOOTLOADER)));
+}
+
+
+// This function assumes p_init->has_fw_version.
+static bool fw_version_ok(dfu_init_command_t const * p_init)
+{
+ ASSERT(p_init != NULL);
+ ASSERT(p_init->has_fw_version);
+
+ if ( (p_init->type == DFU_FW_TYPE_APPLICATION)
+ || (p_init->type == DFU_FW_TYPE_SOFTDEVICE))
+ {
+ return ((p_init->fw_version >= s_dfu_settings.app_version) || !NRF_DFU_APP_DOWNGRADE_PREVENTION);
+ }
+ else
+ {
+ return (p_init->fw_version > s_dfu_settings.bootloader_version);
+ }
+}
+
+nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init)
+{
+ nrf_dfu_result_t ret_val = NRF_DFU_RES_CODE_SUCCESS;
+ if (!fw_type_ok(p_init))
+ {
+ NRF_LOG_ERROR("Invalid firmware type.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ else if (!fw_hash_type_ok(p_init))
+ {
+ NRF_LOG_ERROR("Invalid hash type.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_WRONG_HASH_TYPE);
+ }
+ else if (!NRF_DFU_DEBUG ||
+ (NRF_DFU_DEBUG && ((p_init->has_is_debug == false) || (p_init->is_debug == false))))
+ {
+ if (p_init->has_hw_version == false)
+ {
+ NRF_LOG_ERROR("No HW version.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ else if (p_init->hw_version != NRF_DFU_HW_VERSION)
+ {
+ NRF_LOG_WARNING("Faulty HW version.");
+ ret_val = EXT_ERR( NRF_DFU_EXT_ERROR_HW_VERSION_FAILURE);
+ }
+ else if (!sd_req_ok(p_init))
+ {
+ NRF_LOG_WARNING("SD req not met.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_SD_VERSION_FAILURE);
+ }
+ else if (p_init->has_fw_version)
+ {
+ if (!fw_version_ok(p_init))
+ {
+ NRF_LOG_WARNING("FW version too low.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_FW_VERSION_FAILURE);
+ }
+ }
+ else
+ {
+ if (fw_version_required(p_init->type))
+ {
+ NRF_LOG_ERROR("FW version missing.");
+ ret_val = EXT_ERR(NRF_DFU_EXT_ERROR_INIT_COMMAND_INVALID);
+ }
+ }
+ }
+ return ret_val;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h
new file mode 100644
index 0000000..5014b15
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/dfu/nrf_dfu_ver_validation.h
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef __NRF_DFU_VER_VALIDATION_H
+#define __NRF_DFU_VER_VALIDATION_H
+
+#include "stdint.h"
+#include "sdk_errors.h"
+#include "nrf_dfu_handling_error.h"
+#include "dfu-cc.pb.h"
+
+/** @brief SD_REQ field value which indicates that Softdevice can be overwritten by the application. */
+#define SD_REQ_APP_OVERWRITES_SD 0
+
+/**
+ * @brief Function for validating version of new firmware.
+ *
+ * @return NRF_DFU_RES_CODE_SUCCESS if successful or error code otherwise
+ */
+nrf_dfu_result_t nrf_dfu_ver_validation_check(dfu_init_command_t const * p_init);
+
+#endif //__NRF_DFU_VER_VALIDATION_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c
new file mode 100644
index 0000000..3e62e47
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.c
@@ -0,0 +1,394 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader.h"
+
+#include "compiler_abstraction.h"
+#include "nrf.h"
+#include "boards.h"
+#include "sdk_config.h"
+#include "nrf_power.h"
+#include "nrf_delay.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_dfu.h"
+#include "nrf_error.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_wdt.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_bootloader_app_start.h"
+#include "nrf_bootloader_fw_activation.h"
+#include "nrf_bootloader_dfu_timers.h"
+#include "app_scheduler.h"
+#include "app_timer.h"
+
+static nrf_dfu_observer_t m_user_observer; //<! Observer callback set by the user.
+
+#define SCHED_QUEUE_SIZE 32 /**< Maximum number of events in the scheduler queue. */
+#define SCHED_EVENT_DATA_SIZE MAX(NRF_DFU_SCHED_EVENT_DATA_SIZE, APP_TIMER_SCHED_EVENT_DATA_SIZE) /**< Maximum app_scheduler event size. */
+
+#if !(defined(NRF_BL_DFU_ENTER_METHOD_BUTTON) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_PINRESET) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_GPREGRET) && \
+ defined(NRF_BL_DFU_ENTER_METHOD_BUTTONLESS))
+ #error Configuration file is missing flags. Update sdk_config.h.
+#endif
+
+STATIC_ASSERT((NRF_BL_DFU_INACTIVITY_TIMEOUT_MS >= 100) || (NRF_BL_DFU_INACTIVITY_TIMEOUT_MS == 0),
+ "NRF_BL_DFU_INACTIVITY_TIMEOUT_MS must be 100 ms or more, or 0 to indicate that it is disabled.");
+
+#if defined(NRF_LOG_BACKEND_FLASH_START_PAGE)
+STATIC_ASSERT(NRF_LOG_BACKEND_FLASH_START_PAGE != 0,
+ "If nrf_log flash backend is used it cannot use space after code because it would collide with settings page.");
+#endif
+
+/**@brief Weak implemenation of nrf_dfu_init
+ *
+ * @note This function will be overridden if nrf_dfu.c is
+ * compiled and linked with the project
+ */
+ #if (__LINT__ != 1)
+__WEAK uint32_t nrf_dfu_init(nrf_dfu_observer_t observer)
+{
+ NRF_LOG_DEBUG("in weak nrf_dfu_init");
+ return NRF_SUCCESS;
+}
+#endif
+
+
+/**@brief Weak implementation of nrf_dfu_init
+ *
+ * @note This function must be overridden in application if
+ * user-specific initialization is needed.
+ */
+__WEAK uint32_t nrf_dfu_init_user(void)
+{
+ NRF_LOG_DEBUG("in weak nrf_dfu_init_user");
+ return NRF_SUCCESS;
+}
+
+
+static void bootloader_reset(void)
+{
+ NRF_LOG_DEBUG("Resetting bootloader.");
+
+ NRF_LOG_FINAL_FLUSH();
+
+#if NRF_MODULE_ENABLED(NRF_LOG_BACKEND_RTT)
+ // To allow the buffer to be flushed by the host.
+ nrf_delay_ms(100);
+#endif
+
+ NVIC_SystemReset();
+}
+
+
+static void inactivity_timeout(void)
+{
+ NRF_LOG_INFO("Inactivity timeout.");
+ bootloader_reset();
+}
+
+
+/**@brief Function for handling DFU events.
+ */
+static void dfu_observer(nrf_dfu_evt_type_t evt_type)
+{
+ switch (evt_type)
+ {
+ case NRF_DFU_EVT_DFU_STARTED:
+ case NRF_DFU_EVT_OBJECT_RECEIVED:
+ nrf_bootloader_dfu_inactivity_timer_restart(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS, inactivity_timeout);
+ break;
+ case NRF_DFU_EVT_DFU_COMPLETED:
+ case NRF_DFU_EVT_DFU_ABORTED:
+ bootloader_reset();
+ break;
+ default:
+ break;
+ }
+
+ if (m_user_observer)
+ {
+ m_user_observer(evt_type);
+ }
+}
+
+
+/**@brief Function for initializing the event scheduler.
+ */
+static void scheduler_init(void)
+{
+ APP_SCHED_INIT(SCHED_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
+}
+
+
+/**@brief Suspend the CPU until an interrupt occurs.
+ */
+static void wait_for_event(void)
+{
+#ifdef BLE_STACK_SUPPORT_REQD
+ (void)sd_app_evt_wait();
+#else
+ // Wait for an event.
+ __WFE();
+ // Clear the internal event register.
+ __SEV();
+ __WFE();
+#endif
+}
+
+
+/**@brief Continually sleep and process tasks whenever woken.
+ */
+static void loop_forever(void)
+{
+ while (true)
+ {
+ //feed the watchdog if enabled.
+ nrf_bootloader_wdt_feed();
+
+ app_sched_execute();
+
+ if (!NRF_LOG_PROCESS())
+ {
+ wait_for_event();
+ }
+ }
+}
+
+/**@brief Function for initializing button used to enter DFU mode.
+ */
+static void dfu_enter_button_init(void)
+{
+ nrf_gpio_cfg_sense_input(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN,
+ BUTTON_PULL,
+ NRF_GPIO_PIN_SENSE_LOW);
+}
+
+
+static bool crc_on_valid_app_required(void)
+{
+ bool ret = true;
+ if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_SYSTEMOFF_RESET &&
+ (nrf_power_resetreas_get() & NRF_POWER_RESETREAS_OFF_MASK))
+ {
+ nrf_power_resetreas_clear(NRF_POWER_RESETREAS_OFF_MASK);
+ ret = false;
+ }
+ else if (NRF_BL_APP_CRC_CHECK_SKIPPED_ON_GPREGRET2 &&
+ (nrf_power_gpregret2_get() & BOOTLOADER_DFU_SKIP_CRC))
+ {
+ nrf_power_gpregret2_set(nrf_power_gpregret2_get() & ~BOOTLOADER_DFU_SKIP_CRC);
+ ret = false;
+ }
+ else
+ {
+ }
+
+ return ret;
+}
+
+
+/**@brief Function for clearing all DFU enter flags that
+ * preserve state during reset.
+ *
+ * @details This is used to make sure that each of these flags
+ * is checked only once after reset.
+ */
+static void dfu_enter_flags_clear(void)
+{
+ if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
+ (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
+ {
+ // Clear RESETPIN flag.
+ NRF_POWER->RESETREAS |= POWER_RESETREAS_RESETPIN_Msk;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
+ (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
+ {
+ // Clear DFU mark in GPREGRET register.
+ nrf_power_gpregret_set(nrf_power_gpregret_get() & ~BOOTLOADER_DFU_START);
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
+ (s_dfu_settings.enter_buttonless_dfu == 1))
+ {
+ // Clear DFU flag in flash settings.
+ s_dfu_settings.enter_buttonless_dfu = 0;
+ APP_ERROR_CHECK(nrf_dfu_settings_write(NULL));
+ }
+}
+
+
+/**@brief Function for checking whether to enter DFU mode or not.
+ */
+static bool dfu_enter_check(void)
+{
+ if (!nrf_dfu_app_is_valid(crc_on_valid_app_required()))
+ {
+ NRF_LOG_DEBUG("DFU mode because app is not valid.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTON &&
+ (nrf_gpio_pin_read(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN) == 0))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via button.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_PINRESET &&
+ (NRF_POWER->RESETREAS & POWER_RESETREAS_RESETPIN_Msk))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via pin-reset.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
+ (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
+ return true;
+ }
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTONLESS &&
+ (s_dfu_settings.enter_buttonless_dfu == 1))
+ {
+ NRF_LOG_DEBUG("DFU mode requested via bootloader settings.");
+ return true;
+ }
+
+ return false;
+}
+
+
+ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
+{
+ NRF_LOG_DEBUG("In nrf_bootloader_init");
+
+ uint32_t ret_val;
+ nrf_bootloader_fw_activation_result_t activation_result;
+ uint32_t initial_timeout;
+ bool dfu_enter = false;
+
+ m_user_observer = observer;
+
+ if (NRF_BL_DFU_ENTER_METHOD_BUTTON)
+ {
+ dfu_enter_button_init();
+ }
+
+ ret_val = nrf_dfu_settings_init(false);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // Check if an update needs to be activated and activate it.
+ activation_result = nrf_bootloader_fw_activate();
+
+ switch (activation_result)
+ {
+ case ACTIVATION_NONE:
+ initial_timeout = NRF_BL_DFU_INACTIVITY_TIMEOUT_MS;
+ dfu_enter = dfu_enter_check();
+ break;
+
+ case ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE:
+ initial_timeout = NRF_BL_DFU_CONTINUATION_TIMEOUT_MS;
+ dfu_enter = true;
+ break;
+
+ case ACTIVATION_SUCCESS:
+ bootloader_reset();
+ NRF_LOG_ERROR("Should never come here: After bootloader_reset()");
+ return NRF_ERROR_INTERNAL; // Should not reach this.
+
+ case ACTIVATION_ERROR:
+ default:
+ return NRF_ERROR_INTERNAL;
+ }
+
+ if (dfu_enter)
+ {
+ nrf_bootloader_wdt_init();
+
+ scheduler_init();
+
+ // Clear all DFU stop flags.
+ dfu_enter_flags_clear();
+
+ // Call user-defined init function if implemented
+ ret_val = nrf_dfu_init_user();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_bootloader_dfu_inactivity_timer_restart(initial_timeout, inactivity_timeout);
+
+ ret_val = nrf_dfu_init(dfu_observer);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ NRF_LOG_DEBUG("Enter main loop");
+ loop_forever(); // This function will never return.
+ NRF_LOG_ERROR("Should never come here: After looping forever.");
+ }
+ else
+ {
+ // Erase additional data like peer data or advertisement name
+ ret_val = nrf_dfu_settings_additional_erase();
+ if (ret_val != NRF_SUCCESS)
+ {
+ return NRF_ERROR_INTERNAL;
+ }
+
+ nrf_bootloader_app_start();
+ NRF_LOG_ERROR("Should never come here: After nrf_bootloader_app_start()");
+ }
+
+ // Should not be reached.
+ return NRF_ERROR_INTERNAL;
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h
new file mode 100644
index 0000000..d588b02
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ *
+ * @defgroup nrf_bootloader Bootloader modules
+ * @{
+ * @ingroup app_common
+ * @brief Bootloader and DFU modules
+ *
+ * The bootloader module can be used to implement a basic bootloader that
+ * can be extended with, for example, Device Firmware Update (DFU) support
+ * or custom functionality.
+ */
+
+#ifndef NRF_BOOTLOADER_H__
+#define NRF_BOOTLOADER_H__
+
+#include <stdint.h>
+#include "nrf_dfu.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** @brief Function for initializing the bootloader.
+ *
+ * @details This function is the entry point of all bootloader operations.
+ * If DFU functionality is compiled in, the DFU process is initialized
+ * when running this function.
+ *
+ * @note This function does not return unless an error occurred.
+ *
+ * @retval NRF_ERROR_INTERNAL Something went wrong.
+ */
+ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c
new file mode 100644
index 0000000..b12cda0
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.c
@@ -0,0 +1,77 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_bootloader_app_start.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_log.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_bootloader_info.h"
+
+// Do the final stages of app_start. Protect flash and run app. See nrf_bootloader_app_start_final.c
+void nrf_bootloader_app_start_final(uint32_t start_addr);
+
+void nrf_bootloader_app_start(void)
+{
+ uint32_t start_addr = MBR_SIZE; // Always boot from end of MBR. If a SoftDevice is present, it will boot the app.
+ NRF_LOG_DEBUG("Running nrf_bootloader_app_start with address: 0x%08x", start_addr);
+ uint32_t err_code;
+
+ // Disable and clear interrupts
+ // Notice that this disables only 'external' interrupts (positive IRQn).
+ NRF_LOG_DEBUG("Disabling interrupts. NVIC->ICER[0]: 0x%x", NVIC->ICER[0]);
+
+ NVIC->ICER[0]=0xFFFFFFFF;
+ NVIC->ICPR[0]=0xFFFFFFFF;
+#if defined(__NRF_NVIC_ISER_COUNT) && __NRF_NVIC_ISER_COUNT == 2
+ NVIC->ICER[1]=0xFFFFFFFF;
+ NVIC->ICPR[1]=0xFFFFFFFF;
+#endif
+
+ err_code = nrf_dfu_mbr_irq_forward_address_set();
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed running nrf_dfu_mbr_irq_forward_address_set()");
+ }
+
+ NRF_LOG_FLUSH();
+ nrf_bootloader_app_start_final(start_addr);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h
new file mode 100644
index 0000000..0bce18d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start.h
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_app Application start
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_APP_START_H__
+#define NRF_BOOTLOADER_APP_START_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "sdk_errors.h"
+
+
+/**@brief Function for using hardware to protect flash from writing and reading.
+ *
+ * @details This function will apply write/erase protection to a specific area. Read
+ * protection is optional, decided by \p read_protect. This function uses
+ * the BPROT or ACL peripheral, depending on which is available.
+ *
+ * @param[in] address The start address of the area to protect. Must be a flash page
+ * boundary.
+ * @param[in] size The size of the area to protect, in bytes. Must be a multiple
+ * of flash page size.
+ * @param[in] read_protect Whether to protect the area from reading/executing as well.
+ * This is not available on chips with the BPROT peripheral
+ * (e.g. nrf52832, nrf52810).
+ *
+ * @retval NRF_SUCCESS Flash protection applied successfully.
+ * @retval NRF_ERROR_NO_MEM No more ACL instances to use for flash protection.
+ * @retval NRF_ERROR_INVALID_PARAM Address was out of range or size was not a multiple
+ * of flash page size.
+ */
+ret_code_t nrf_bootloader_flash_protect(uint32_t address, uint32_t size, bool read_protect);
+
+/**@brief Function for starting another application (and aborting the current one).
+ *
+ * @details This function uses the provided address to swap the stack pointer and then load
+ * the address of the reset handler to be executed. It checks the current system mode
+ * (thread/handler). If in thread mode, it resets into the other application.
+ * If in handler mode, isr_abort is executed to ensure that handler mode is left correctly.
+ * It then jumps into the reset handler of the other application.
+ *
+ * @note This function assumes the SoftDevice has not previously been initialized.
+ *
+ * @note This function will never return, but issues a reset into the provided application.
+ */
+void nrf_bootloader_app_start(void);
+
+#endif // NRF_BOOTLOADER_APP_START_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c
new file mode 100644
index 0000000..a818322
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_app_start_final.c
@@ -0,0 +1,256 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "sdk_config.h"
+#include "nrf_bootloader_app_start.h"
+#include <stdint.h>
+#include "nrf.h"
+#include "nrf_peripherals.h"
+#include "nrf_bootloader_info.h"
+#include "nrf_dfu_types.h"
+#include "nrf_assert.h"
+#include "nrf_log.h"
+#include "sdk_config.h"
+
+
+// Enabling the NRF_BOOTLOADER_READ_PROTECT define is untested.
+// Read-protecting the bootloader requires certain functions to run from RAM.
+// In GCC and SES this is done automatically when the define is enabled. You will
+// get warnings which can be ignored.
+// In Keil you must change project settings to run the entire file from RAM.
+#ifndef NRF_BOOTLOADER_READ_PROTECT
+#define NRF_BOOTLOADER_READ_PROTECT 0
+#endif
+
+
+#define HANDLER_MODE_EXIT 0xFFFFFFF9 // When this is jumped to, the CPU will exit interrupt context
+ // (handler mode), and pop values from the stack into registers.
+ // See ARM's documentation for "Exception entry and return".
+#define EXCEPTION_STACK_WORD_COUNT 8 // The number of words popped from the stack when
+ // HANDLER_MODE_EXIT is branched to.
+
+
+/**@brief Function that sets the stack pointer and link register, and starts executing a particular address.
+ *
+ * @param[in] new_msp The new value to set in the main stack pointer.
+ * @param[in] new_lr The new value to set in the link register.
+ * @param[in] addr The address to execute.
+ */
+#if defined ( __CC_ARM )
+__ASM __STATIC_INLINE void jump_to_addr(uint32_t new_msp, uint32_t new_lr, uint32_t addr)
+{
+ MSR MSP, R0;
+ MOV LR, R1;
+ BX R2;
+}
+#else
+__STATIC_INLINE void jump_to_addr(uint32_t new_msp, uint32_t new_lr, uint32_t addr)
+{
+ __ASM volatile ("MSR MSP, %[arg]" : : [arg] "r" (new_msp));
+ __ASM volatile ("MOV LR, %[arg]" : : [arg] "r" (new_lr) : "lr");
+ __ASM volatile ("BX %[arg]" : : [arg] "r" (addr));
+}
+#endif
+
+
+/**@brief Function for booting an app as if the chip was reset.
+ *
+ * @param[in] vector_table_addr The address of the app's vector table.
+ */
+__STATIC_INLINE void app_start(uint32_t vector_table_addr)
+{
+ const uint32_t current_isr_num = (__get_IPSR() & IPSR_ISR_Msk);
+ const uint32_t new_msp = *((uint32_t *)(vector_table_addr)); // The app's Stack Pointer is found as the first word of the vector table.
+ const uint32_t reset_handler = *((uint32_t *)(vector_table_addr + sizeof(uint32_t))); // The app's Reset Handler is found as the second word of the vector table.
+ const uint32_t new_lr = 0xFFFFFFFF;
+
+ __set_CONTROL(0x00000000); // Set CONTROL to its reset value 0.
+ __set_PRIMASK(0x00000000); // Set PRIMASK to its reset value 0.
+ __set_BASEPRI(0x00000000); // Set BASEPRI to its reset value 0.
+ __set_FAULTMASK(0x00000000); // Set FAULTMASK to its reset value 0.
+
+ if (current_isr_num == 0)
+ {
+ // The CPU is in Thread mode (main context).
+ jump_to_addr(new_msp, new_lr, reset_handler); // Jump directly to the App's Reset Handler.
+ }
+ else
+ {
+ // The CPU is in Handler mode (interrupt context).
+
+ const uint32_t exception_stack[EXCEPTION_STACK_WORD_COUNT] = // To be copied onto the stack.
+ {
+ 0x00000000, // New value of R0. Cleared by setting to 0.
+ 0x00000000, // New value of R1. Cleared by setting to 0.
+ 0x00000000, // New value of R2. Cleared by setting to 0.
+ 0x00000000, // New value of R3. Cleared by setting to 0.
+ 0x00000000, // New value of R12. Cleared by setting to 0.
+ 0xFFFFFFFF, // New value of LR. Cleared by setting to all 1s.
+ reset_handler, // New value of PC. The CPU will continue by executing the App's Reset Handler.
+ xPSR_T_Msk, // New value of xPSR (Thumb mode set).
+ };
+ const uint32_t exception_sp = new_msp - sizeof(exception_stack);
+
+ memcpy((uint32_t *)exception_sp, exception_stack, sizeof(exception_stack)); // 'Push' exception_stack onto the App's stack.
+
+ jump_to_addr(exception_sp, new_lr, HANDLER_MODE_EXIT); // 'Jump' to the special value to exit handler mode. new_lr is superfluous here.
+ // exception_stack will be popped from the stack, so the resulting SP will be the new_msp.
+ // Execution will continue from the App's Reset Handler.
+ }
+}
+
+#if NRF_BOOTLOADER_READ_PROTECT
+#ifdef __ICCARM__
+__ramfunc
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+__attribute__((noinline, long_call, section(".data")))
+#elif defined ( __CC_ARM )
+#warning "Keil requires changes to project settings to run this file from RAM. Ignore this warning if configuration has been made."
+#endif
+#endif
+ret_code_t nrf_bootloader_flash_protect(uint32_t address, uint32_t size, bool read_protect)
+{
+ if ((size & (CODE_PAGE_SIZE - 1)) || (address > BOOTLOADER_SETTINGS_ADDRESS))
+ {
+ return NRF_ERROR_INVALID_PARAM;
+ }
+
+#if defined(ACL_PRESENT)
+
+ // Protect using ACL.
+ static uint32_t acl_instance = 0;
+
+ uint32_t const wmask = (ACL_ACL_PERM_WRITE_Disable << ACL_ACL_PERM_WRITE_Pos);
+ uint32_t const rwmask = wmask | (ACL_ACL_PERM_READ_Disable << ACL_ACL_PERM_READ_Pos);
+ uint32_t const mask = read_protect ? rwmask: wmask;
+
+ do
+ {
+ if (acl_instance >= ACL_REGIONS_COUNT)
+ {
+ return NRF_ERROR_NO_MEM;
+ }
+
+ NRF_ACL->ACL[acl_instance].ADDR = address;
+ NRF_ACL->ACL[acl_instance].SIZE = size;
+ NRF_ACL->ACL[acl_instance].PERM = mask;
+
+ acl_instance++;
+
+ } while (NRF_ACL->ACL[acl_instance - 1].ADDR != address
+ || NRF_ACL->ACL[acl_instance - 1].SIZE != size
+ || NRF_ACL->ACL[acl_instance - 1].PERM != mask); // Check whether the acl_instance has been used before.
+
+#elif defined (BPROT_PRESENT)
+
+ // Protect using BPROT. BPROT does not support read protection.
+ uint32_t pagenum_start = address / CODE_PAGE_SIZE;
+ uint32_t pagenum_end = pagenum_start + ((size - 1) / CODE_PAGE_SIZE);
+
+ for (uint32_t i = pagenum_start; i <= pagenum_end; i++)
+ {
+ uint32_t config_index = i / 32;
+ uint32_t mask = (1 << (i - config_index * 32));
+
+ switch (config_index)
+ {
+ case 0:
+ NRF_BPROT->CONFIG0 = mask;
+ break;
+ case 1:
+ NRF_BPROT->CONFIG1 = mask;
+ break;
+ case 2:
+ NRF_BPROT->CONFIG2 = mask;
+ break;
+ case 3:
+ NRF_BPROT->CONFIG3 = mask;
+ break;
+ }
+ }
+
+#endif
+
+ return NRF_SUCCESS;
+}
+
+
+#if NRF_BOOTLOADER_READ_PROTECT
+#ifdef __ICCARM__
+__ramfunc
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+__attribute__((noinline, long_call, section(".data")))
+#elif defined ( __CC_ARM )
+#warning "Keil requires changes to project settings to run this file from RAM. Ignore this warning if configuration has been made."
+#endif
+#endif
+void nrf_bootloader_app_start_final(uint32_t vector_table_addr)
+{
+ ret_code_t ret_val;
+
+ // Protect MBR & bootloader code and params pages.
+ if (NRF_BOOTLOADER_READ_PROTECT)
+ {
+ ret_val = nrf_bootloader_flash_protect(0, MBR_SIZE, NRF_BOOTLOADER_READ_PROTECT);
+ }
+
+ // Size of the flash area to protect.
+ uint32_t area_size;
+
+ if (!NRF_BL_SETTINGS_PAGE_PROTECT)
+ {
+ area_size = BOOTLOADER_SIZE + NRF_MBR_PARAMS_PAGE_SIZE;
+ }
+ else
+ {
+ area_size = BOOTLOADER_SIZE + NRF_MBR_PARAMS_PAGE_SIZE + BOOTLOADER_SETTINGS_PAGE_SIZE;
+ }
+
+ ret_val = nrf_bootloader_flash_protect(BOOTLOADER_START_ADDR,
+ area_size,
+ NRF_BOOTLOADER_READ_PROTECT);
+
+ if (!NRF_BOOTLOADER_READ_PROTECT && (ret_val != NRF_SUCCESS))
+ {
+ NRF_LOG_ERROR("Could not protect bootloader and settings pages, 0x%x.", ret_val);
+ }
+
+ // Run application
+ app_start(vector_table_addr);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c
new file mode 100644
index 0000000..a6b056e
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.c
@@ -0,0 +1,126 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader_dfu_timers.h"
+
+#include "app_timer.h"
+#include "nrf_clock.h"
+
+APP_TIMER_DEF(m_dfu_inactivity_timer); //!< Timer for aborting DFU if no update happens.
+APP_TIMER_DEF(m_wdt_feed_timer); //!< Timer for feeding the application's watchdog (WDT) while the bootloader is running.
+
+static bool m_app_timer_initialized;
+
+/** @brief Function for handling the timeouts by calling the callback in the context.
+ */
+static void timeout_handler(void * p_context)
+{
+ if (p_context)
+ {
+ //lint -save -e611 "Suspicious cast"
+ ((nrf_bootloader_dfu_timeout_callback_t)p_context)();
+ //lint -restore
+ }
+}
+
+
+/**@brief Initialization of app_timer. Function ensures that initialization happens only once.
+ */
+static void timer_init(void)
+{
+ if (!m_app_timer_initialized)
+ {
+ if (!nrf_clock_lf_is_running())
+ {
+ nrf_clock_task_trigger(NRF_CLOCK_TASK_LFCLKSTART);
+
+ // Wait for the clock to be ready.
+ while (!nrf_clock_lf_is_running()) {;}
+ }
+
+ uint32_t err_code = app_timer_init();
+ APP_ERROR_CHECK(err_code);
+
+ // Start a single shot timer that will reset the DFU on timeout.
+ err_code = app_timer_create(&m_dfu_inactivity_timer,
+ APP_TIMER_MODE_SINGLE_SHOT,
+ timeout_handler);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ err_code = app_timer_create(&m_wdt_feed_timer,
+ APP_TIMER_MODE_REPEATED,
+ timeout_handler);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ m_app_timer_initialized = true;
+ }
+}
+
+
+/**@brief Function for initializing app_timer if necessary, and (re)starting a timer.
+ */
+static void timer_start(app_timer_t * p_timer, uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ ret_code_t err_code;
+
+ timer_init();
+
+ err_code = app_timer_stop(p_timer);
+ ASSERT(err_code == NRF_SUCCESS);
+
+ if (timeout_ms != 0)
+ {
+ //lint -save -e611 "Suspicious cast"
+ err_code = app_timer_start(p_timer, APP_TIMER_TICKS(timeout_ms), (void *)callback);
+ //lint -restore
+ ASSERT(err_code == NRF_SUCCESS);
+ }
+}
+
+
+void nrf_bootloader_dfu_inactivity_timer_restart(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ timer_start(m_dfu_inactivity_timer, timeout_ms, callback);
+}
+
+
+void nrf_bootloader_wdt_feed_timer_start(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback)
+{
+ timer_start(m_wdt_feed_timer, timeout_ms, callback);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h
new file mode 100644
index 0000000..5104dfd
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_dfu_timers.h
@@ -0,0 +1,87 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_dfu_timers Timers for DFU in the bootloader
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_DFU_TIMERS_H__
+#define NRF_BOOTLOADER_DFU_TIMERS_H__
+
+#include <stdint.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**@brief Handler called on timeout of a timer requested by the watchdog.
+ */
+typedef void (*nrf_bootloader_dfu_timeout_callback_t)(void);
+
+
+/**@brief Function for restarting the inactivity timer.
+ *
+ * @note Calling this function cancels any previous calls to this function.
+ *
+ * @param[in] timeout_ms The number of milliseconds until reset if not restarted.
+ * If 0 is passed, the timer will be stopped and not restarted.
+ * @param[in] callback Function to be called on timeout.
+ */
+void nrf_bootloader_dfu_inactivity_timer_restart(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback);
+
+
+/**@brief Function for initializing and starting a repeated timer for feeding the watchdog.
+ *
+ * @param[in] timeout_ms Timer period.
+ * @param[in] callback Function called on every timeout.
+ */
+void nrf_bootloader_wdt_feed_timer_start(uint32_t timeout_ms, nrf_bootloader_dfu_timeout_callback_t callback);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_DFU_TIMERS_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c
new file mode 100644
index 0000000..40e4870
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.c
@@ -0,0 +1,436 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_bootloader_fw_activation.h"
+#include "nrf_dfu_settings.h"
+#include "nrf_dfu_mbr.h"
+#include "nrf_bootloader_info.h"
+#include "crc32.h"
+#include "nrf_log.h"
+#include "nrf_log_ctrl.h"
+#include "nrf_dfu_utils.h"
+#include "nrf_bootloader_wdt.h"
+
+
+static volatile bool m_flash_write_done;
+
+
+/**
+ * @brief Function for copying image. Image is copied in chunks. Frequency of storing progress
+ * in flash is configured by input parameter.
+ *
+ * @param[in] dst_addr Destination address. Must be page aligned.
+ * @param[in] src_addr Source address. Must be higher value than dst_addr.
+ * @param[in] size Image size.
+ * @param[in] progress_update_step Number of copied pages that triggers saving progress to non-volatile memory.
+ * Note that step can be decreased if there is a risk of corruption caused by source
+ * and destination overlapping.
+ *
+ * @return NRF_SUCCESS or error code in case of failure.
+ */
+static uint32_t image_copy(uint32_t dst_addr,
+ uint32_t src_addr,
+ uint32_t size,
+ uint32_t progress_update_step)
+{
+ if (src_addr == dst_addr)
+ {
+ NRF_LOG_DEBUG("No copy needed src_addr: 0x%x, dst_addr: 0x%x", src_addr, dst_addr);
+ return NRF_SUCCESS;
+ }
+
+ ASSERT(src_addr >= dst_addr);
+ ASSERT(progress_update_step > 0);
+ ASSERT((dst_addr % CODE_PAGE_SIZE) == 0);
+
+ uint32_t max_safe_progress_upd_step = (src_addr - dst_addr)/CODE_PAGE_SIZE;
+ ASSERT(max_safe_progress_upd_step > 0);
+
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t pages_left = CEIL_DIV(size, CODE_PAGE_SIZE);
+
+ //Firmware copying is time consuming operation thus watchdog handling is started
+ nrf_bootloader_wdt_init();
+
+ progress_update_step = MIN(progress_update_step, max_safe_progress_upd_step);
+
+ while (size > 0)
+ {
+ uint32_t pages;
+ uint32_t bytes;
+ if (pages_left <= progress_update_step)
+ {
+ pages = pages_left;
+ bytes = size;
+ }
+ else
+ {
+ pages = progress_update_step;
+ bytes = progress_update_step * CODE_PAGE_SIZE;
+ }
+ // Erase the target pages
+ ret_val = nrf_dfu_flash_erase(dst_addr, pages, NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ // Flash one page
+ NRF_LOG_DEBUG("Copying 0x%x to 0x%x, size: 0x%x", src_addr, dst_addr, bytes);
+ ret_val = nrf_dfu_flash_store(dst_addr,
+ (uint32_t *)src_addr,
+ ALIGN_NUM(sizeof(uint32_t), bytes),
+ NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ return ret_val;
+ }
+
+ pages_left -= pages;
+ size -= bytes;
+ dst_addr += bytes;
+ src_addr += bytes;
+ s_dfu_settings.write_offset += bytes;
+
+ //store progress in flash on every successful chunk write
+ ret_val = nrf_dfu_settings_write(NULL);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to write image copying progress to settings page.");
+ return ret_val;
+ }
+ }
+
+ return ret_val;
+}
+
+/** @brief Function to continue application update.
+ *
+ * @details This function will be called after reset if there is a valid application in Bank1
+ * required to be copied down to Bank 0.
+ *
+ * @return NRF_SUCCESS if continuation was successful, NRF_ERROR_INTERNAL if new firmware does not
+ * contain softdevice or other error coming from modules used by this function.
+ */
+static uint32_t app_activate(void)
+{
+ // This function is only in use when new app is present in Bank 1
+ uint32_t const image_size = s_dfu_settings.bank_1.image_size;
+
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t target_addr = nrf_dfu_bank0_start_addr() + s_dfu_settings.write_offset;
+ uint32_t length_left = (image_size - s_dfu_settings.write_offset);
+ uint32_t crc;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_app_continue");
+
+ src_addr += s_dfu_settings.write_offset;
+
+ if (src_addr == target_addr)
+ {
+ length_left = 0;
+ }
+
+ ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to copy firmware.");
+ return ret_val;
+ }
+
+ // Check the CRC of the copied data. Enable if so.
+ crc = crc32_compute((uint8_t*)nrf_dfu_bank0_start_addr(), image_size, NULL);
+
+ if (crc == s_dfu_settings.bank_1.image_crc)
+ {
+ NRF_LOG_DEBUG("Setting app as valid");
+ s_dfu_settings.bank_0.bank_code = NRF_DFU_BANK_VALID_APP;
+ s_dfu_settings.bank_0.image_crc = crc;
+ s_dfu_settings.bank_0.image_size = image_size;
+ }
+ else
+ {
+ NRF_LOG_ERROR("CRC computation failed for copied app: "
+ "src crc: 0x%08x, res crc: 0x%08x",
+ s_dfu_settings.bank_1.image_crc,
+ crc);
+ }
+
+ return ret_val;
+}
+
+
+/** @brief Function to execute the continuation of a SoftDevice update.
+ *
+ * @return NRF_SUCCESS if continuation was successful, NRF_ERROR_INTERNAL if new firmware does not
+ * contain softdevice or other error coming from modules used by this function.
+ */
+static uint32_t sd_activate(void)
+{
+ uint32_t ret_val = NRF_SUCCESS;
+ uint32_t target_addr = nrf_dfu_softdevice_start_address() + s_dfu_settings.write_offset;
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+ uint32_t sd_size = s_dfu_settings.sd_size;
+ uint32_t length_left = ALIGN_TO_PAGE(sd_size - s_dfu_settings.write_offset);
+
+ NRF_LOG_DEBUG("Enter nrf_bootloader_dfu_sd_continue");
+
+ if (SD_MAGIC_NUMBER_GET(src_addr) != SD_MAGIC_NUMBER)
+ {
+ NRF_LOG_ERROR("Source address does not contain a valid SoftDevice.")
+ return NRF_ERROR_INTERNAL;
+ }
+
+ // This can be a continuation due to a power failure
+ src_addr += s_dfu_settings.write_offset;
+
+ if (s_dfu_settings.write_offset == sd_size)
+ {
+ NRF_LOG_DEBUG("SD already copied");
+ return NRF_SUCCESS;
+ }
+
+ if (s_dfu_settings.write_offset == 0)
+ {
+ NRF_LOG_DEBUG("Updating SD. Old SD ver: %d, New ver: %d",
+ SD_VERSION_GET(MBR_SIZE) / 1000000, SD_VERSION_GET(src_addr) / 1000000);
+ }
+
+ ret_val = image_copy(target_addr, src_addr, length_left, NRF_BL_FW_COPY_PROGRESS_STORE_STEP);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to copy firmware.");
+ return ret_val;
+ }
+
+ ret_val = nrf_dfu_settings_write(NULL);
+
+ return ret_val;
+}
+
+
+/** @brief Function to continue bootloader update.
+ *
+ * @details This function will be called after reset if there is a valid bootloader in Bank 0 or Bank 1
+ * required to be relocated and activated through MBR commands.
+ *
+ * @return This function will not return if the bootloader is copied successfully.
+ * After the copy is verified, the device will reset and start the new bootloader.
+ *
+ * @retval NRF_SUCCESS Continuation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH Invalid length of flash operation.
+ * @retval NRF_ERROR_NO_MEM If no parameter page is provided (see sds for more info).
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid command is given.
+ * @retval NRF_ERROR_INTERNAL Internal error that should not happen.
+ * @retval NRF_ERROR_FORBIDDEN If NRF_UICR->BOOTADDR is not set.
+ */
+static uint32_t bl_activate(void)
+{
+ uint32_t ret_val = NRF_ERROR_INVALID_DATA;
+ nrf_dfu_bank_t * p_bank = &s_dfu_settings.bank_1;
+ uint32_t len = p_bank->image_size;
+ uint32_t src_addr = s_dfu_settings.progress.update_start_address;
+
+ if (p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL)
+ {
+ src_addr += s_dfu_settings.sd_size;
+ len -= s_dfu_settings.sd_size;
+ }
+
+ NRF_LOG_DEBUG("Verifying BL: Addr: 0x%08x, Src: 0x%08x, Len: 0x%08x", BOOTLOADER_START_ADDR, src_addr, len);
+
+ // This code is a configurable workaround for updating SD+BL from SDK 12.x.y - 14.1.0
+ // SoftDevice size increase would lead to unaligned source address when comparing new BL in SD+BL updates.
+ // This workaround is not required once BL is successfully installed with a version that is compiled SDK 14.1.0
+#if defined(NRF52832_XXAA) && defined(BLE_STACK_SUPPORT_REQD)
+ if ((p_bank->bank_code == NRF_DFU_BANK_VALID_SD_BL) &&
+ (memcmp((void *)BOOTLOADER_START_ADDR, (void *)(src_addr - 0x4000), len) == 0))
+ {
+ ret_val = NRF_SUCCESS;
+ }
+#endif // defined(NRF52832_XXAA)
+
+ // Check if the BL has already been copied.
+ if ((ret_val != NRF_SUCCESS) &&
+ (memcmp((void *)BOOTLOADER_START_ADDR, (void *)src_addr, len) == 0))
+ {
+ ret_val = NRF_SUCCESS;
+ }
+
+ // If the bootloader is the same as the banked version, the copy is finished
+ if (ret_val == NRF_SUCCESS)
+ {
+ NRF_LOG_DEBUG("No bootloader copy needed, bootloader update complete.");
+ }
+ else
+ {
+ NRF_LOG_DEBUG("Copying bootloader: Src: 0x%08x, Len: 0x%08x", src_addr, len);
+ NRF_LOG_FLUSH();
+
+ nrf_bootloader_wdt_feed();
+
+ // Bootloader is different than the banked version. Continue copy
+ // Note that if the SD and BL was combined, then the split point between them is in s_dfu_settings.sd_size
+ // On success this function won't return.
+ ret_val = nrf_dfu_mbr_copy_bl((uint32_t*)src_addr, len);
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Request to copy BL failed");
+ }
+ }
+
+ return ret_val;
+}
+
+
+/** @brief Function to continue combined bootloader and SoftDevice update.
+ *
+ * @details This function will be called after reset if there is a valid bootloader and SoftDevice in Bank 0 or Bank 1
+ * required to be relocated and activated through MBR commands.
+ *
+ * @retval NRF_SUCCESS Continuation was successful.
+ * @retval NRF_ERROR_INVALID_LENGTH Invalid length.
+ * @retval NRF_ERROR_NO_MEM If UICR.NRFFW[1] is not set (i.e. is 0xFFFFFFFF).
+ * @retval NRF_ERROR_INVALID_PARAM If an invalid command is given.
+ * @retval NRF_ERROR_INTERNAL Indicates that the contents of the memory blocks where not verified correctly after copying.
+ * @retval NRF_ERROR_NULL If the content of the memory blocks differs after copying.
+ * @retval NRF_ERROR_FORBIDDEN If NRF_UICR->BOOTADDR is not set.
+ */
+static uint32_t sd_bl_activate()
+{
+ uint32_t ret_val = NRF_SUCCESS;
+
+ NRF_LOG_DEBUG("Enter nrf_dfu_sd_bl_continue");
+
+ ret_val = sd_activate();
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("SD+BL: SD copy failed");
+ return ret_val;
+ }
+
+ ret_val = bl_activate();
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("SD+BL: BL copy failed");
+ return ret_val;
+ }
+
+ return ret_val;
+}
+
+
+static void flash_write_callback(void * p_context)
+{
+ UNUSED_PARAMETER(p_context);
+ m_flash_write_done = true;
+}
+
+
+nrf_bootloader_fw_activation_result_t nrf_bootloader_fw_activate(void)
+{
+ nrf_bootloader_fw_activation_result_t result;
+ uint32_t ret_val = NRF_SUCCESS;
+ nrf_dfu_bank_t * p_bank = &s_dfu_settings.bank_1;
+ bool sd_update = false;
+
+
+ NRF_LOG_DEBUG("Enter nrf_bootloader_fw_activate");
+
+ switch (p_bank->bank_code)
+ {
+ case NRF_DFU_BANK_VALID_APP:
+ NRF_LOG_DEBUG("Valid App");
+ ret_val = app_activate();
+ break;
+ case NRF_DFU_BANK_VALID_SD:
+ NRF_LOG_DEBUG("Valid SD");
+ ret_val = sd_activate();
+ sd_update = true;
+ break;
+ case NRF_DFU_BANK_VALID_BL:
+ NRF_LOG_DEBUG("Valid BL");
+ ret_val = bl_activate();
+ break;
+ case NRF_DFU_BANK_VALID_SD_BL:
+ NRF_LOG_DEBUG("Valid SD + BL");
+ ret_val = sd_bl_activate();
+ sd_update = true;
+ break;
+ case NRF_DFU_BANK_INVALID:
+ default:
+ NRF_LOG_INFO("No firmware to activate.");
+ return ACTIVATION_NONE;
+ }
+
+ if (ret_val != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Activation failed with error %d (bank code: 0x%x)", ret_val, p_bank->bank_code);
+ result = ACTIVATION_ERROR;
+ }
+
+ // Invalidate bank, marking completion.
+ nrf_dfu_bank_invalidate(p_bank);
+
+ m_flash_write_done = false;
+ ret_val = nrf_dfu_settings_write(flash_write_callback);
+ ASSERT(m_flash_write_done);
+
+ /* At this point flash module is performing blocking operation. It is expected that operation is already performed. */
+ if (ret_val == NRF_SUCCESS)
+ {
+ result = ACTIVATION_SUCCESS;
+ if (sd_update && nrf_dfu_app_is_valid(true))
+ {
+ //If SD was updated and application is valid we want to stay in DFU to receive application.
+ NRF_LOG_DEBUG("A SoftDevice has just been activated. It's likely that an application will come immediately");
+ result = ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE;
+ }
+ }
+ else
+ {
+ NRF_LOG_ERROR("Could not write settings.");
+ result = ACTIVATION_ERROR;
+ }
+
+ return result;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h
new file mode 100644
index 0000000..312491d
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_fw_activation.h
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2018 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_fw_activation Firmware activation
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_FW_ACTIVATION_H__
+#define NRF_BOOTLOADER_FW_ACTIVATION_H__
+
+#include <stdint.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+typedef enum
+{
+ ACTIVATION_NONE, //!< No new update was found.
+ ACTIVATION_SUCCESS, //!< Update was successfully activated.
+ ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE, //!< Update was successfully activated, but there might be additional update(s) to be transferred.
+ ACTIVATION_ERROR, //!< Activation of an update failed.
+} nrf_bootloader_fw_activation_result_t;
+
+/** @brief Function for activating a firmware received during DFU.
+ *
+ * @details This function initiates or continues the DFU copy-back
+ * routines. These routines are fail-safe operations to activate
+ * either a new SoftDevice, bootloader, combination of SoftDevice and
+ * bootloader, or a new application.
+ *
+ * @details This function relies on accessing MBR commands through supervisor calls.
+ * It does not rely on the SoftDevice for flash operations.
+ *
+ * @note When updating the bootloader or both bootloader and SoftDevice in combination,
+ * this function does not return, but rather initiates a reboot to activate
+ * the new bootloader.
+ *
+ * @retval ACTIVATION_NONE If no update was found.
+ * @retval ACTIVATION_SUCCESS If the firmware update was successfully activated.
+ * @retval ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE If the firmware update was successfully activated,
+ * but there are likely more updates to be transferred.
+ * @retval ACTIVATION_ERROR If the firmware update could not be activated.
+ */
+nrf_bootloader_fw_activation_result_t nrf_bootloader_fw_activate(void);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_BOOTLOADER_FW_ACTIVATION_H__
+
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c
new file mode 100644
index 0000000..77a8ad1
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.c
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader_info.h"
+
+
+/** @brief This variable ensures that the linker script will write the bootloader start address
+ * to the UICR register. This value will be written in the HEX file and thus written to
+ * UICR when the bootloader is flashed into the chip.
+ */
+#if defined (__CC_ARM )
+ #pragma push
+ #pragma diag_suppress 1296
+ uint32_t m_uicr_bootloader_start_address __attribute__((at(NRF_UICR_BOOTLOADER_START_ADDRESS)))
+ = BOOTLOADER_START_ADDR;
+ #pragma pop
+#elif defined ( __GNUC__ ) || defined ( __SES_ARM )
+ volatile uint32_t m_uicr_bootloader_start_address __attribute__ ((section(".uicr_bootloader_start_address")))
+ = BOOTLOADER_START_ADDR;
+#elif defined ( __ICCARM__ )
+ __root const uint32_t m_uicr_bootloader_start_address @ NRF_UICR_BOOTLOADER_START_ADDRESS
+ = BOOTLOADER_START_ADDR;
+#endif
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h
new file mode 100644
index 0000000..812cddb
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_info.h
@@ -0,0 +1,188 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+/**@file
+ *
+ * @defgroup nrf_bootloader_info Bootloader Information
+ * @{
+ * @ingroup nrf_bootloader
+ */
+
+#ifndef NRF_BOOTLOADER_INFO_H__
+#define NRF_BOOTLOADER_INFO_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "app_util.h"
+#include "nrf.h"
+#include "nrf_mbr.h"
+
+/** @brief Macro for getting the start address of the bootloader image.
+ *
+ * The macro is not a compile time symbol. It cannot be used as a
+ * constant expression, for example, inside a static assert or linker script
+ * at-placement.
+ */
+#ifndef BOOTLOADER_START_ADDR
+#if (__LINT__ == 1)
+ #define BOOTLOADER_START_ADDR (0x3AC00)
+#elif defined(CODE_START)
+ #define BOOTLOADER_START_ADDR (CODE_START)
+#else
+ #error Not a valid compiler/linker for BOOTLOADER_START_ADDR.
+#endif
+#endif
+
+
+/** @brief Macro for getting the size of the bootloader image.
+ */
+#ifndef BOOTLOADER_SIZE
+#if defined ( NRF51 )
+ #define BOOTLOADER_SIZE (BOOTLOADER_SETTINGS_ADDRESS - BOOTLOADER_START_ADDR)
+#elif defined( NRF52_SERIES )
+ #define BOOTLOADER_SIZE (NRF_MBR_PARAMS_PAGE_ADDRESS - BOOTLOADER_START_ADDR)
+#elif (__LINT__ == 1)
+ #define BOOTLOADER_SIZE (0x6000)
+#endif
+#endif
+
+
+/**
+ * @brief Bootloader start address in UICR.
+ *
+ * Register location in UICR where the bootloader start address is stored.
+ *
+ * @note If the value at the given location is 0xFFFFFFFF, the bootloader address is not set.
+ */
+#define NRF_UICR_BOOTLOADER_START_ADDRESS (NRF_UICR_BASE + 0x14)
+
+
+// The following macros are for accessing the SoftDevice information structure,
+// which is found inside the SoftDevice binary.
+
+/** @brief Macro for converting an offset inside the SoftDevice information struct to an absolute address.
+ */
+#define SD_INFO_ABS_OFFSET_GET(baseaddr, offset) ((baseaddr) + (SOFTDEVICE_INFO_STRUCT_OFFSET) + (offset))
+
+/** @brief Macros for reading a byte or a word at a particular offset inside a SoftDevice information struct.
+ * Use MBR_SIZE as baseaddr when the SoftDevice is installed just above the MBR (the usual case).
+ */
+#define SD_OFFSET_GET_UINT32(baseaddr, offset) (*((uint32_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+#define SD_OFFSET_GET_UINT16(baseaddr, offset) (*((uint16_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+#define SD_OFFSET_GET_UINT8(baseaddr, offset) (*((uint8_t *) SD_INFO_ABS_OFFSET_GET(baseaddr, offset)))
+
+
+#ifdef BLE_STACK_SUPPORT_REQD
+#include "nrf_sdm.h"
+#else
+/** @brief The offset inside the SoftDevice at which the information struct is placed.
+ * To see the layout of the information struct, see the SoftDevice specification.
+ */
+#define SOFTDEVICE_INFO_STRUCT_OFFSET (0x2000)
+
+#define SD_INFO_STRUCT_SIZE(baseaddr) SD_OFFSET_GET_UINT8(baseaddr, 0x00)
+
+/** @brief Macro for reading the size of a SoftDevice at a given base address.
+ */
+#ifndef SD_SIZE_GET
+#define SD_SIZE_GET(baseaddr) SD_OFFSET_GET_UINT32(baseaddr, 0x08)
+#endif
+
+/** @brief Macro for reading the version of a SoftDevice at a given base address.
+ * This expression checks the length of the information struct to see if the version is present.
+ * The version number is constructed like this:
+ * major_version * 1000000 + minor_version * 1000 + bugfix_version
+ */
+#ifndef SD_VERSION_GET
+#define SD_VERSION_GET(baseaddr) ((SD_INFO_STRUCT_SIZE(baseaddr) > (0x14)) \
+ ? SD_OFFSET_GET_UINT32(baseaddr, 0x14) \
+ : 0)
+#endif
+#endif
+
+
+/** @brief Macro for reading the magic number of a SoftDevice at a given base address.
+ */
+#ifndef SD_MAGIC_NUMBER_GET
+#define SD_MAGIC_NUMBER_GET(baseaddr) SD_OFFSET_GET_UINT32(baseaddr, 0x04)
+#endif
+
+/** @brief Macro for getting the absolute address of the magic number.
+ */
+#define SD_MAGIC_NUMBER_ABS_OFFSET_GET(baseaddr) SD_INFO_ABS_OFFSET_GET(baseaddr, 0x04)
+
+/** @brief The number present at a specific location in all SoftDevices.
+ */
+#define SD_MAGIC_NUMBER ((uint32_t)0x51B1E5DB)
+
+/** @brief Whether a SoftDevice is at its regular location.
+ */
+#ifndef SD_PRESENT
+#define SD_PRESENT ((SD_MAGIC_NUMBER_GET(MBR_SIZE)) == (SD_MAGIC_NUMBER))
+#endif
+
+/** @brief The multiplier for the major version of the SoftDevice. See \ref SD_VERSION_GET
+ */
+#define SD_MAJOR_VERSION_MULTIPLIER (1000000)
+
+/** @brief Read the major version of the SoftDevice from the raw version number. See \ref SD_VERSION_GET.
+ */
+#define SD_MAJOR_VERSION_EXTRACT(raw_version) ((raw_version)/SD_MAJOR_VERSION_MULTIPLIER)
+
+
+#define BOOTLOADER_DFU_GPREGRET_MASK (0xB0) /**< Magic pattern written to GPREGRET register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
+#define BOOTLOADER_DFU_START_BIT_MASK (0x01) /**< Bit mask to signal from main application to enter DFU mode using a buttonless service. */
+
+#define BOOTLOADER_DFU_GPREGRET2_MASK (0xA8) /**< Magic pattern written to GPREGRET2 register to signal between main app and DFU. The 3 lower bits are assumed to be used for signalling purposes.*/
+#define BOOTLOADER_DFU_SKIP_CRC_BIT_MASK (0x01) /**< Bit mask to signal from main application that CRC-check is not needed for image verification. */
+
+
+#define BOOTLOADER_DFU_START (BOOTLOADER_DFU_GPREGRET_MASK | BOOTLOADER_DFU_START_BIT_MASK) /**< Magic number to signal that bootloader should enter DFU mode because of signal from Buttonless DFU in main app.*/
+#define BOOTLOADER_DFU_SKIP_CRC (BOOTLOADER_DFU_GPREGRET2_MASK | BOOTLOADER_DFU_SKIP_CRC_BIT_MASK) /**< Magic number to signal that CRC can be skipped due to low power modes.*/
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // #ifndef NRF_BOOTLOADER_INFO_H__
+/** @} */
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c
new file mode 100644
index 0000000..b75d6ef
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.c
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include "nrf_bootloader_wdt.h"
+#include "nrf_wdt.h"
+#include "nrf_bootloader_dfu_timers.h"
+#include "nrf_log_ctrl.h"
+
+#define NRF_LOG_MODULE_NAME nrf_bootloader_wdt
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+//Flag used to determine if internal feeding should stay active.
+static bool m_wdt_keep_internal_feed;
+
+static void wdt_feed(void)
+{
+ if (nrf_wdt_started())
+ {
+ for (nrf_wdt_rr_register_t i = NRF_WDT_RR0; i < NRF_WDT_RR7; i++)
+ {
+ if (nrf_wdt_reload_request_is_enabled(i))
+ {
+ nrf_wdt_reload_request_set(i);
+ }
+ }
+ }
+}
+
+
+static void wdt_feed_timer_handler(void)
+{
+ if (m_wdt_keep_internal_feed)
+ {
+ NRF_LOG_INFO("Internal feed");
+ wdt_feed();
+ }
+}
+
+
+void WDT_IRQHandler(void)
+{
+ nrf_wdt_event_clear(NRF_WDT_EVENT_TIMEOUT);
+ NRF_LOG_FINAL_FLUSH();
+}
+
+void nrf_bootloader_wdt_init(void)
+{
+ static bool initialized = false;
+
+ if (initialized)
+ {
+ return;
+ }
+
+ if (nrf_wdt_started())
+ {
+ uint32_t approx_wdt_ms = nrf_wdt_reload_value_get() / 32;
+
+ NRF_LOG_INFO("WDT enabled CRV:%d ms", approx_wdt_ms);
+
+ //wdt_ticks must be reduced (0.75) to feed the watchdog before the timeout.
+ uint32_t reduced_timeout_ms = (approx_wdt_ms * 3)/4;
+
+ /* Ideally, watchdog should be fed by the bootloader from the main context but if bootloader latency
+ * (mainly driven by signature check) is big enough there is a risk that watchdog will not be fed
+ * on time. In that case watchdog will be fed from timer context. */
+ m_wdt_keep_internal_feed =
+ (reduced_timeout_ms < NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS);
+
+ /* initial watchdog feed */
+ wdt_feed();
+
+ /* If internal feed is needed or WDT is active in sleep module must provide regular wakeup interrupt.*/
+ bool wdt_start_timer = m_wdt_keep_internal_feed || (NRF_WDT->CONFIG & WDT_CONFIG_SLEEP_Msk);
+ if (wdt_start_timer)
+ {
+ NRF_LOG_INFO("Starting a timer (%d ms) for feeding watchdog.", reduced_timeout_ms);
+ nrf_bootloader_wdt_feed_timer_start(reduced_timeout_ms, wdt_feed_timer_handler);
+ }
+
+ NVIC_EnableIRQ(WDT_IRQn);
+ }
+ else
+ {
+ NRF_LOG_INFO("WDT is not enabled");
+ }
+
+ initialized = true;
+}
+
+void nrf_bootloader_wdt_feed(void)
+{
+ if (nrf_wdt_started())
+ {
+ wdt_feed();
+ }
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h
new file mode 100644
index 0000000..0a6cb9b
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/nrf_bootloader_wdt.h
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#ifndef NRF_BOOTLOADER_WDT_H
+#define NRF_BOOTLOADER_WDT_H
+
+/**@file
+ *
+ * @defgroup nrf_bootloader_wdt Automated feeding of the watchdog
+ * @{
+ * @ingroup nrf_bootloader
+ * @brief Module that keeps the WDT from timing out if the WDT has been started in the application.
+ */
+
+#include "sdk_errors.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**
+ * @brief Function for checking whether the WDT peripheral is started and for getting its configuration.
+ *
+ * The module uses app_timer to start regular feeding of the watchdog. Timer interval
+ * is chosen based on watchdog settings. When @ref nrf_bootloader_wdt_feed is called, internal
+ * feeding is stopped assuming that the application takes responsibity of watchdog feeding.
+ * However, if @ref NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS or the watchdog is configured to
+ * run during sleep, then internal feeding (from app_timer handler context) is kept active.
+ */
+void nrf_bootloader_wdt_init(void);
+
+
+/**
+ * @brief Function for feeding the watchdog (if active).
+ */
+void nrf_bootloader_wdt_feed(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif //NRF_BOOTLOADER_WDT_H
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
new file mode 100644
index 0000000..8e14b05
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.c
@@ -0,0 +1,265 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_serial.h"
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_handling_error.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+
+
+
+static uint32_t response_ext_err_payload_add(uint8_t * p_buffer, uint32_t buf_offset)
+{
+ p_buffer[buf_offset] = ext_error_get();
+ (void) ext_error_set(NRF_DFU_EXT_ERROR_NO_ERROR);
+
+ return 1;
+}
+
+
+static void response_send(nrf_dfu_serial_t * p_transport,
+ nrf_dfu_response_t const * p_response)
+{
+ uint8_t index = 0;
+ uint8_t * p_serialized_rsp = p_transport->p_rsp_buf;
+
+ NRF_LOG_DEBUG("Sending Response: [0x%01x, 0x%01x]", p_response->request, p_response->result);
+
+ p_serialized_rsp[index++] = NRF_DFU_OP_RESPONSE;
+ p_serialized_rsp[index++] = p_response->request;
+ p_serialized_rsp[index++] = (uint8_t)(p_response->result);
+
+ if (p_response->result == NRF_DFU_RES_CODE_SUCCESS)
+ {
+ switch (p_response->request)
+ {
+ case NRF_DFU_OP_PROTOCOL_VERSION:
+ {
+ p_serialized_rsp[index] = p_response->protocol.version;
+ index += sizeof(uint8_t);
+ } break;
+
+ case NRF_DFU_OP_HARDWARE_VERSION:
+ {
+ index += uint32_encode(p_response->hardware.part, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.variant, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.rom_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.ram_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->hardware.memory.rom_page_size, &p_serialized_rsp[index]);
+ } break;
+
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ p_serialized_rsp[index++] = p_response->firmware.type;
+ index += uint32_encode(p_response->firmware.version, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->firmware.addr, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->firmware.len, &p_serialized_rsp[index]);
+ } break;
+
+ case NRF_DFU_OP_CRC_GET:
+ index += uint32_encode(p_response->crc.offset, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->crc.crc, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ index += uint32_encode(p_response->select.max_size, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->select.offset, &p_serialized_rsp[index]);
+ index += uint32_encode(p_response->select.crc, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_MTU_GET:
+ index += uint16_encode(p_response->mtu.size, &p_serialized_rsp[index]);
+ break;
+
+ case NRF_DFU_OP_PING:
+ p_serialized_rsp[index] = p_response->ping.id;
+ index += sizeof(uint8_t);
+ break;
+
+ default:
+ // no implementation
+ break;
+ }
+ }
+ else if (p_response->result == NRF_DFU_RES_CODE_EXT_ERROR)
+ {
+ index += response_ext_err_payload_add(p_serialized_rsp, index);
+ }
+
+ if (index > NRF_SERIAL_MAX_RESPONSE_SIZE)
+ {
+ NRF_LOG_ERROR("Message is larger than expected.");
+ }
+
+ // Send response.
+ if (p_transport->rsp_func((uint8_t const *)(p_serialized_rsp), index) != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed to send data over serial interface!");
+ }
+}
+
+
+void dfu_req_handler_rsp_clbk(nrf_dfu_response_t * p_res, void * p_context)
+{
+ nrf_dfu_serial_t * p_transport = (nrf_dfu_serial_t *)(p_context);
+
+ if (p_res->result != NRF_DFU_RES_CODE_SUCCESS)
+ {
+ NRF_LOG_WARNING("DFU request completed with result: 0x%x", p_res->result);
+ }
+
+ switch (p_res->request)
+ {
+ default:
+ /* Reply normally.
+ * Make sure to reply to NRF_DFU_OP_OBJECT_CREATE when running DFU over serial,
+ * otherwise the transfer might run very slow, without an apparent reason.
+ */
+ break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ p_transport->pkt_notif_target_count--;
+
+ if ( (p_transport->pkt_notif_target == 0)
+ || (p_transport->pkt_notif_target_count != 0))
+ {
+ /* Do not reply to _OBJECT_WRITE messages. */
+ return;
+ }
+
+ /* Reply with a CRC message and reset the packet counter. */
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+
+ p_res->request = NRF_DFU_OP_CRC_GET;
+ p_res->crc.offset = p_res->write.offset;
+ p_res->crc.crc = p_res->write.crc;
+ } break;
+ }
+
+ response_send(p_transport, p_res);
+}
+
+
+void nrf_dfu_serial_on_packet_received(nrf_dfu_serial_t * p_transport,
+ uint8_t const * p_data,
+ uint32_t length)
+{
+ uint8_t const * p_payload = &p_data[NRF_SERIAL_OPCODE_SIZE];
+ uint16_t const payload_len = (length - NRF_SERIAL_OPCODE_SIZE);
+
+ nrf_dfu_request_t request =
+ {
+ .request = (nrf_dfu_op_t)(p_data[0]),
+ .callback.response = dfu_req_handler_rsp_clbk,
+ .p_context = p_transport
+ };
+
+ bool buf_free = true;
+
+ switch (request.request)
+ {
+ case NRF_DFU_OP_FIRMWARE_VERSION:
+ {
+ request.firmware.image_number = p_payload[0];
+ } break;
+
+ case NRF_DFU_OP_RECEIPT_NOTIF_SET:
+ {
+ NRF_LOG_DEBUG("Set receipt notif target: %d", p_transport->pkt_notif_target);
+
+ p_transport->pkt_notif_target = uint16_decode(&p_payload[0]);
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+ } break;
+
+ case NRF_DFU_OP_OBJECT_SELECT:
+ {
+ request.select.object_type = p_payload[0];
+ } break;
+
+ case NRF_DFU_OP_OBJECT_CREATE:
+ {
+ // Reset the packet receipt notification on create object
+ p_transport->pkt_notif_target_count = p_transport->pkt_notif_target;
+
+ request.create.object_type = p_payload[0];
+ request.create.object_size = uint32_decode(&p_payload[1]);
+ } break;
+
+ case NRF_DFU_OP_OBJECT_WRITE:
+ {
+ // Buffer will be freed asynchronously
+ buf_free = false;
+
+ request.write.p_data = p_payload;
+ request.write.len = payload_len;
+ request.callback.write = p_transport->payload_free_func;
+ } break;
+
+ case NRF_DFU_OP_MTU_GET:
+ {
+ NRF_LOG_DEBUG("Received serial mtu");
+ request.mtu.size = p_transport->mtu;
+ } break;
+
+ case NRF_DFU_OP_PING:
+ {
+ NRF_LOG_DEBUG("Received ping %d", p_payload[0]);
+ request.ping.id = p_payload[0];
+ } break;
+
+ default:
+ /* Do nothing. */
+ break;
+ }
+
+ if (buf_free)
+ {
+ p_transport->payload_free_func((void *)(p_payload));
+ }
+
+ ret_code_t ret_code = nrf_dfu_req_handler_on_req(&request);
+ ASSERT(ret_code == NRF_SUCCESS);
+}
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h
new file mode 100644
index 0000000..c14ee40
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial.h
@@ -0,0 +1,109 @@
+/**
+ * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#ifndef NRF_DFU_SERIAL_H__
+#define NRF_DFU_SERIAL_H__
+
+#include <stdint.h>
+#include "sdk_errors.h"
+#include "nrf_dfu_req_handler.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial DFU Serial transports shared part
+ * @{
+ * @ingroup nrf_dfu
+ * @brief Shared part of Device Firmware Update (DFU) transport layers using serial interface (UART, USB CDC ACM).
+ *
+ * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
+ * @ingroup nrf_dfu_serial
+ * @brief Configuration for Device Firmware Update (DFU) transport layer using UART.
+ *
+ * @defgroup nrf_dfu_serial_usb DFU Serial USB CDC ACM transport
+ * @ingroup nrf_dfu_serial
+ * @brief Configuration for Device Firmware Update (DFU) transport layer using USB CDC ACM.
+ *
+ */
+
+#define NRF_SERIAL_MAX_RESPONSE_SIZE (sizeof(nrf_dfu_response_t))
+
+/**
+ * Prototype for function for sending response over serial DFU transport.
+ */
+typedef ret_code_t (*nrf_serial_rsp_func_t)(uint8_t const * p_data, uint32_t length);
+
+/**
+ * Prototype for function for freeing RX buffer.
+ *
+ * Function is called when input data is processed.
+ */
+typedef void (*nrf_serial_rx_buf_free_func_t)(void * p_buf);
+
+
+/**@brief DFU serial transport layer state.
+ *
+ * @details This structure contains status information related to the serial transport layer type.
+ */
+typedef struct
+{
+ uint16_t pkt_notif_target;
+ uint16_t pkt_notif_target_count;
+ nrf_serial_rsp_func_t rsp_func;
+ nrf_serial_rx_buf_free_func_t payload_free_func;
+ uint32_t mtu;
+ uint8_t * p_rsp_buf;
+} nrf_dfu_serial_t;
+
+void nrf_dfu_serial_on_packet_received(nrf_dfu_serial_t * p_transport,
+ uint8_t const * p_data,
+ uint32_t length);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // NRF_DFU_SERIAL_H__
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c
new file mode 100644
index 0000000..3d0b783
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_uart.c
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "nrf_dfu_serial.h"
+
+#include <string.h>
+#include "boards.h"
+#include "app_util_platform.h"
+#include "nrf_dfu_transport.h"
+#include "nrf_dfu_req_handler.h"
+#include "slip.h"
+#include "nrf_balloc.h"
+#include "nrf_drv_uart.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial_uart
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial_uart DFU Serial UART transport
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer using UART.
+ */
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+#define NRF_UART_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
+#define RX_BUF_SIZE (64) //to get 64bytes payload
+#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
+#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
+#define UART_SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1)
+#define BALLOC_BUF_SIZE ((CEIL_DIV((RX_BUF_SIZE+OPCODE_SIZE),sizeof(uint32_t))*sizeof(uint32_t)))
+
+NRF_BALLOC_DEF(m_payload_pool, (UART_SLIP_MTU + 1), NRF_DFU_SERIAL_UART_RX_BUFFERS);
+
+static nrf_drv_uart_t m_uart = NRF_DRV_UART_INSTANCE(0);
+static uint8_t m_rx_byte;
+
+static nrf_dfu_serial_t m_serial;
+static slip_t m_slip;
+static uint8_t m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP];
+static bool m_active;
+
+static nrf_dfu_observer_t m_observer;
+
+static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const uart_dfu_transport) =
+{
+ .init_func = uart_dfu_transport_init,
+ .close_func = uart_dfu_transport_close,
+};
+
+static void payload_free(void * p_buf)
+{
+ uint8_t * p_buf_root = (uint8_t *)p_buf - DATA_OFFSET; //pointer is shifted to point to data
+ nrf_balloc_free(&m_payload_pool, p_buf_root);
+}
+
+static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
+{
+ uint32_t slip_len;
+ (void) slip_encode(m_rsp_buf, (uint8_t *)p_data, length, &slip_len);
+
+ return nrf_drv_uart_tx(&m_uart, m_rsp_buf, slip_len);
+}
+
+static __INLINE void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
+{
+ ret_code_t ret_code;
+
+ ret_code = slip_decode_add_byte(&m_slip, p_data[0]);
+ (void) nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
+
+ if (ret_code == NRF_SUCCESS)
+ {
+ // Activity detected on current transport, close all except active one.
+ UNUSED_RETURN_VALUE(nrf_dfu_transports_close(&uart_dfu_transport));
+
+ nrf_dfu_serial_on_packet_received(p_transport,
+ (uint8_t const *)m_slip.p_buffer,
+ m_slip.current_index);
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Failed to allocate buffer");
+ return;
+ }
+ NRF_LOG_INFO("Allocated buffer %x", p_rx_buf);
+ // reset the slip decoding
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.state = SLIP_STATE_DECODING;
+ }
+
+}
+
+static void uart_event_handler(nrf_drv_uart_event_t * p_event, void * p_context)
+{
+ switch (p_event->type)
+ {
+ case NRF_DRV_UART_EVT_RX_DONE:
+ on_rx_complete((nrf_dfu_serial_t*)p_context,
+ p_event->data.rxtx.p_data,
+ p_event->data.rxtx.bytes);
+ break;
+
+ case NRF_DRV_UART_EVT_ERROR:
+ APP_ERROR_HANDLER(p_event->data.error.error_mask);
+ break;
+
+ default:
+ // No action.
+ break;
+ }
+}
+
+static uint32_t uart_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code = NRF_SUCCESS;
+
+ if (m_active)
+ {
+ return err_code;
+ }
+
+ NRF_LOG_DEBUG("serial_dfu_transport_init()");
+
+ m_observer = observer;
+
+ err_code = nrf_balloc_init(&m_payload_pool);
+ if (err_code != NRF_SUCCESS)
+ {
+ return err_code;
+ }
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.buffer_len = UART_SLIP_MTU;
+ m_slip.state = SLIP_STATE_DECODING;
+
+ m_serial.rsp_func = rsp_send;
+ m_serial.payload_free_func = payload_free;
+ m_serial.mtu = UART_SLIP_MTU;
+ m_serial.p_rsp_buf = &m_rsp_buf[NRF_UART_MAX_RESPONSE_SIZE_SLIP -
+ NRF_SERIAL_MAX_RESPONSE_SIZE];
+
+ nrf_drv_uart_config_t uart_config = NRF_DRV_UART_DEFAULT_CONFIG;
+
+ uart_config.pseltxd = TX_PIN_NUMBER;
+ uart_config.pselrxd = RX_PIN_NUMBER;
+ uart_config.pselcts = CTS_PIN_NUMBER;
+ uart_config.pselrts = RTS_PIN_NUMBER;
+ uart_config.hwfc = NRF_DFU_SERIAL_UART_USES_HWFC ?
+ NRF_UART_HWFC_ENABLED : NRF_UART_HWFC_DISABLED;
+ uart_config.p_context = &m_serial;
+
+ err_code = nrf_drv_uart_init(&m_uart, &uart_config, uart_event_handler);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed initializing uart");
+ return err_code;
+ }
+
+ err_code = nrf_drv_uart_rx(&m_uart, &m_rx_byte, 1);
+ if (err_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Failed initializing rx");
+ }
+
+ NRF_LOG_DEBUG("serial_dfu_transport_init() completed");
+
+ m_active = true;
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+
+ return err_code;
+}
+
+
+static uint32_t uart_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ if ((m_active == true) && (p_exception != &uart_dfu_transport))
+ {
+ nrf_drv_uart_uninit(&m_uart);
+ m_active = false;
+ }
+
+ return NRF_SUCCESS;
+}
+
diff --git a/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c
new file mode 100644
index 0000000..2b45643
--- /dev/null
+++ b/thirdparty/nRF5_SDK_15.0.0_a53641a/components/libraries/bootloader/serial_dfu/nrf_dfu_serial_usb.c
@@ -0,0 +1,370 @@
+/**
+ * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form, except as embedded into a Nordic
+ * Semiconductor ASA integrated circuit in a product or a software update for
+ * such product, must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution.
+ *
+ * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * 4. This software, with or without modification, must only be used with a
+ * Nordic Semiconductor ASA integrated circuit.
+ *
+ * 5. Any software provided in binary form under this license must not be reverse
+ * engineered, decompiled, modified and/or disassembled.
+ *
+ * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
+ * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include <string.h>
+#include "nrf_dfu_req_handler.h"
+#include "nrf_dfu_transport.h"
+#include "slip.h"
+#include "nrf_balloc.h"
+#include "nrf_drv_power.h"
+#include "nrf_drv_clock.h"
+#include "nrf_drv_usbd.h"
+#include "nrf_dfu_serial.h"
+#include "app_scheduler.h"
+#include "app_usbd.h"
+#include "app_usbd_cdc_acm.h"
+#include "app_usbd_core.h"
+#include "app_usbd_string_desc.h"
+#include "app_util_platform.h"
+#include "app_usbd_serial_num.h"
+
+#define NRF_LOG_MODULE_NAME nrf_dfu_serial_usb
+#include "nrf_log.h"
+NRF_LOG_MODULE_REGISTER();
+
+/**@file
+ *
+ * @defgroup nrf_dfu_serial_usb DFU Serial USB CDC ACM transport
+ * @ingroup nrf_dfu
+ * @brief Device Firmware Update (DFU) transport layer using USB CDC ACM.
+ */
+
+#define NRF_SERIAL_OPCODE_SIZE (sizeof(uint8_t))
+
+#define NRF_USB_MAX_RESPONSE_SIZE_SLIP (2 * NRF_SERIAL_MAX_RESPONSE_SIZE + 1)
+
+#define RX_BUF_SIZE (1024)
+#define SLIP_MTU (2 * (RX_BUF_SIZE + 1) + 1)
+#define OPCODE_OFFSET (sizeof(uint32_t) - NRF_SERIAL_OPCODE_SIZE)
+#define DATA_OFFSET (OPCODE_OFFSET + NRF_SERIAL_OPCODE_SIZE)
+
+#define CDC_ACM_COMM_INTERFACE 0
+#define CDC_ACM_COMM_EPIN NRF_DRV_USBD_EPIN2
+#define CDC_ACM_DATA_INTERFACE 1
+#define CDC_ACM_DATA_EPIN NRF_DRV_USBD_EPIN1
+#define CDC_ACM_DATA_EPOUT NRF_DRV_USBD_EPOUT1
+
+/**
+ * @brief Enable power USB detection
+ *
+ * Configure if example supports USB port connection
+ */
+#ifndef USBD_POWER_DETECTION
+#define USBD_POWER_DETECTION true
+#endif
+
+/**
+ * @brief Interfaces list passed to @ref APP_USBD_CDC_ACM_GLOBAL_DEF
+ * */
+#define CDC_ACM_INTERFACES_CONFIG() \
+ APP_USBD_CDC_ACM_CONFIG(CDC_ACM_COMM_INTERFACE, \
+ CDC_ACM_COMM_EPIN, \
+ CDC_ACM_DATA_INTERFACE, \
+ CDC_ACM_DATA_EPIN, \
+ CDC_ACM_DATA_EPOUT)
+
+/*lint -save -e26 -e64 -e505 -e651 */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event);
+
+/**@brief CDC_ACM class instance. */
+APP_USBD_CDC_ACM_GLOBAL_DEF(m_app_cdc_acm,
+ cdc_acm_user_ev_handler,
+ CDC_ACM_COMM_INTERFACE,
+ CDC_ACM_DATA_INTERFACE,
+ CDC_ACM_COMM_EPIN,
+ CDC_ACM_DATA_EPIN,
+ CDC_ACM_DATA_EPOUT,
+ APP_USBD_CDC_COMM_PROTOCOL_NONE);
+/*lint -restore */
+
+NRF_BALLOC_DEF(m_payload_pool, (SLIP_MTU+1), NRF_DFU_SERIAL_USB_RX_BUFFERS);
+
+static nrf_dfu_serial_t m_serial;
+static slip_t m_slip;
+static uint8_t m_rsp_buf[NRF_USB_MAX_RESPONSE_SIZE_SLIP];
+static uint8_t m_rx_buf[NRF_DRV_USBD_EPSIZE];
+
+static nrf_dfu_observer_t m_observer;
+
+static uint32_t usb_dfu_transport_init(nrf_dfu_observer_t observer);
+static uint32_t usb_dfu_transport_close(nrf_dfu_transport_t const * p_exception);
+
+
+DFU_TRANSPORT_REGISTER(nrf_dfu_transport_t const usb_dfu_transport) =
+{
+ .init_func = usb_dfu_transport_init,
+ .close_func = usb_dfu_transport_close,
+};
+
+
+static void payload_free(void * p_buf)
+{
+ uint8_t * p_buf_root = ((uint8_t *)(p_buf)) - DATA_OFFSET; //pointer is shifted to point to data
+ nrf_balloc_free(&m_payload_pool, p_buf_root);
+}
+
+
+static ret_code_t rsp_send(uint8_t const * p_data, uint32_t length)
+{
+ ASSERT(p_data);
+ ASSERT(length != 0);
+
+ uint32_t slip_len;
+
+ // Cannot fail if inputs are non-NULL.
+ (void) slip_encode(m_rsp_buf, (uint8_t *)(p_data), length, &slip_len);
+
+ return app_usbd_cdc_acm_write(&m_app_cdc_acm, m_rsp_buf, slip_len);
+}
+
+
+static void on_rx_complete(nrf_dfu_serial_t * p_transport, uint8_t * p_data, uint8_t len)
+{
+ ret_code_t ret_code;
+
+ for (uint32_t i = 0; i < len; i++)
+ {
+ ret_code = slip_decode_add_byte(&m_slip, p_data[i]);
+ if (ret_code != NRF_SUCCESS)
+ {
+ continue;
+ }
+
+ // Activity detected on current transport, close all except active one.
+ (void) nrf_dfu_transports_close(&usb_dfu_transport);
+
+ nrf_dfu_serial_on_packet_received(p_transport,
+ (uint8_t const *)(m_slip.p_buffer),
+ m_slip.current_index);
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Failed to allocate buffer!");
+ return;
+ }
+
+ NRF_LOG_DEBUG("Allocated buffer %x", p_rx_buf);
+ // reset the slip decoding
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.state = SLIP_STATE_DECODING;
+ }
+}
+
+/**
+ * @brief User event handler @ref app_usbd_cdc_acm_user_ev_handler_t (headphones)
+ * */
+static void cdc_acm_user_ev_handler(app_usbd_class_inst_t const * p_inst,
+ app_usbd_cdc_acm_user_event_t event)
+{
+ ret_code_t ret_code;
+
+ switch (event)
+ {
+ case APP_USBD_CDC_ACM_USER_EVT_PORT_OPEN:
+ {
+ ret_code = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buf, 1);
+ NRF_LOG_WARNING("Could not read from CDC. Error: 0x%x.", ret_code);
+ } break;
+
+ case APP_USBD_CDC_ACM_USER_EVT_RX_DONE:
+ {
+ do
+ {
+ on_rx_complete(&m_serial, m_rx_buf, 1);
+ ret_code = app_usbd_cdc_acm_read(&m_app_cdc_acm, m_rx_buf, 1);
+ } while (ret_code == NRF_SUCCESS);
+ } break;
+
+ default:
+ break;
+ }
+}
+
+
+static void usbd_dfu_transport_ev_handler(app_usbd_event_type_t event)
+{
+ switch (event)
+ {
+ case APP_USBD_EVT_STOPPED:
+ app_usbd_disable();
+ break;
+
+ case APP_USBD_EVT_POWER_DETECTED:
+ NRF_LOG_INFO("USB power detected");
+ if (!nrf_drv_usbd_is_enabled())
+ {
+ app_usbd_enable();
+ }
+
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_ACTIVATED);
+ }
+ break;
+
+ case APP_USBD_EVT_POWER_REMOVED:
+ NRF_LOG_INFO("USB power removed");
+ app_usbd_stop();
+ if (m_observer)
+ {
+ m_observer(NRF_DFU_EVT_TRANSPORT_DEACTIVATED);
+ }
+ break;
+
+ case APP_USBD_EVT_POWER_READY:
+ NRF_LOG_INFO("USB ready");
+ app_usbd_start();
+ break;
+
+ default:
+ break;
+ }
+}
+
+
+static void usbd_sched_event_handler(void * p_event_data, uint16_t event_size)
+{
+ app_usbd_event_execute(p_event_data);
+}
+
+
+static void usbd_event_handler(app_usbd_internal_evt_t const * const p_event)
+{
+ ret_code_t ret_code;
+ if (p_event->type == APP_USBD_EVT_DRV_SOF)
+ {
+ app_usbd_event_execute(p_event);
+ }
+ else
+ {
+ ret_code = app_sched_event_put(p_event,
+ sizeof(app_usbd_internal_evt_t),
+ usbd_sched_event_handler);
+
+ if (ret_code != NRF_SUCCESS)
+ {
+ NRF_LOG_ERROR("Could not schedule USB event!");
+ }
+ }
+}
+
+
+static uint32_t usb_dfu_transport_init(nrf_dfu_observer_t observer)
+{
+ uint32_t err_code;
+
+ /* Execute event directly in interrupt handler */
+ static const app_usbd_config_t usbd_config =
+ {
+ .ev_handler = usbd_event_handler,
+ .ev_state_proc = usbd_dfu_transport_ev_handler
+ };
+
+ (void) nrf_balloc_init(&m_payload_pool); //Result is checked by checking result of _alloc().
+
+ m_observer = observer;
+
+ uint8_t * p_rx_buf = nrf_balloc_alloc(&m_payload_pool);
+ if (p_rx_buf == NULL)
+ {
+ NRF_LOG_ERROR("Could not allocate payload pool.");
+ return NRF_ERROR_INTERNAL;
+ }
+
+ m_slip.p_buffer = &p_rx_buf[OPCODE_OFFSET];
+ m_slip.current_index = 0;
+ m_slip.buffer_len = SLIP_MTU;
+ m_slip.state = SLIP_STATE_DECODING;
+
+ m_serial.rsp_func = rsp_send;
+ m_serial.payload_free_func = payload_free;
+ m_serial.mtu = SLIP_MTU;
+ m_serial.p_rsp_buf = &m_rsp_buf[NRF_USB_MAX_RESPONSE_SIZE_SLIP -
+ NRF_SERIAL_MAX_RESPONSE_SIZE];
+
+
+ NRF_LOG_DEBUG("Initializing drivers.");
+
+ err_code = nrf_drv_clock_init();
+ if (err_code != NRF_ERROR_MODULE_ALREADY_INITIALIZED)
+ {
+ VERIFY_SUCCESS(err_code);
+ }
+
+ err_code = nrf_drv_power_init(NULL);
+ VERIFY_SUCCESS(err_code);
+
+ app_usbd_serial_num_generate();
+
+ err_code = app_usbd_init(&usbd_config);
+ VERIFY_SUCCESS(err_code);
+
+ app_usbd_class_inst_t const * class_cdc_acm = app_usbd_cdc_acm_class_inst_get(&m_app_cdc_acm);
+ err_code = app_usbd_class_append(class_cdc_acm);
+ VERIFY_SUCCESS(err_code);
+
+ NRF_LOG_DEBUG("Starting USB");
+
+ if (USBD_POWER_DETECTION)
+ {
+ err_code = app_usbd_power_events_enable();
+ VERIFY_SUCCESS(err_code);
+ }
+ else
+ {
+ NRF_LOG_DEBUG("No USB power detection enabled, starting USB now");
+
+ app_usbd_enable();
+ app_usbd_start();
+ }
+
+ NRF_LOG_DEBUG("USB Transport initialized");
+
+ return err_code;
+}
+
+
+static uint32_t usb_dfu_transport_close(nrf_dfu_transport_t const * p_exception)
+{
+ return NRF_SUCCESS;
+}