Glimworm Beacons / nRF51822

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Tue Jul 21 13:23:43 2015 +0100
Revision:
386:3253b512fb24
Parent:
source/nordic-sdk/components/libraries/bootloader_dfu/experimental/dfu_app_handler.c@381:c997e9717fb7
Synchronized with git rev 928a5e63
Author: Rohit Grover
Release 0.4.1
=============

This is a minor release.

Enhancements
~~~~~~~~~~~~

* Hide duplicate symbol definitions in ble_types.h. These have already been
brought into ble/blecommon.h.

* Replace DiscoveredCharacteristic::setupOnDataRead() with
GattClient::onDataRead().

* Implement new API GattServer::areUpdatesEnabled() to determine notification
status for a characteristic.

Bugfixes
~~~~~~~~

* fix for #20: GattServer::addService() incorrectly initialized value
attribute-handles. These were getting confused with characteristicIndex.
Event handlers also return attribute handles correctly now; they were also
previously returning characteristic indices.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
rgrover1 371:8f7d2137727a 1 /*
rgrover1 371:8f7d2137727a 2 * Copyright (c) Nordic Semiconductor ASA
rgrover1 371:8f7d2137727a 3 * All rights reserved.
rgrover1 371:8f7d2137727a 4 *
rgrover1 371:8f7d2137727a 5 * Redistribution and use in source and binary forms, with or without modification,
rgrover1 371:8f7d2137727a 6 * are permitted provided that the following conditions are met:
rgrover1 371:8f7d2137727a 7 *
rgrover1 371:8f7d2137727a 8 * 1. Redistributions of source code must retain the above copyright notice, this
rgrover1 371:8f7d2137727a 9 * list of conditions and the following disclaimer.
rgrover1 371:8f7d2137727a 10 *
rgrover1 371:8f7d2137727a 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this
rgrover1 371:8f7d2137727a 12 * list of conditions and the following disclaimer in the documentation and/or
rgrover1 371:8f7d2137727a 13 * other materials provided with the distribution.
rgrover1 185:28d8c818d84f 14 *
rgrover1 371:8f7d2137727a 15 * 3. Neither the name of Nordic Semiconductor ASA nor the names of other
rgrover1 371:8f7d2137727a 16 * contributors to this software may be used to endorse or promote products
rgrover1 371:8f7d2137727a 17 * derived from this software without specific prior written permission.
rgrover1 371:8f7d2137727a 18 *
rgrover1 185:28d8c818d84f 19 *
rgrover1 371:8f7d2137727a 20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
rgrover1 371:8f7d2137727a 21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
rgrover1 371:8f7d2137727a 22 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
rgrover1 371:8f7d2137727a 23 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
rgrover1 371:8f7d2137727a 24 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
rgrover1 371:8f7d2137727a 25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
rgrover1 371:8f7d2137727a 26 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
rgrover1 371:8f7d2137727a 27 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
rgrover1 371:8f7d2137727a 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
rgrover1 371:8f7d2137727a 29 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
rgrover1 185:28d8c818d84f 30 *
rgrover1 185:28d8c818d84f 31 */
rgrover1 185:28d8c818d84f 32
rgrover1 185:28d8c818d84f 33 #include <string.h>
rgrover1 185:28d8c818d84f 34 #include "dfu_app_handler.h"
rgrover1 185:28d8c818d84f 35 #include "bootloader_util.h"
rgrover1 185:28d8c818d84f 36 #include "nrf.h"
rgrover1 185:28d8c818d84f 37 #include "nrf_sdm.h"
rgrover1 185:28d8c818d84f 38 #include "ble_gatts.h"
rgrover1 185:28d8c818d84f 39 #include "app_error.h"
rgrover1 185:28d8c818d84f 40 #include "dfu_ble_svc.h"
rgrover1 185:28d8c818d84f 41 #include "device_manager.h"
rgrover1 185:28d8c818d84f 42
rgrover1 185:28d8c818d84f 43 #define IRQ_ENABLED 0x01 /**< Field identifying if an interrupt is enabled. */
rgrover1 185:28d8c818d84f 44 #define MAX_NUMBER_INTERRUPTS 32 /**< Maximum number of interrupts available. */
rgrover1 185:28d8c818d84f 45
rgrover1 185:28d8c818d84f 46 static void dfu_app_reset_prepare(void); /**< Forward declare of default reset handler. */
rgrover1 185:28d8c818d84f 47 static dfu_app_reset_prepare_t m_reset_prepare = dfu_app_reset_prepare; /**< Callback function to application to prepare for system reset. Allows application to cleanup of service and memory prior to reset. */
rgrover1 185:28d8c818d84f 48 #if NEEDED
rgrover1 185:28d8c818d84f 49 static dfu_ble_peer_data_t m_peer_data; /**< Peer data to be used for data exchange when reseting into DFU mode. */
rgrover1 185:28d8c818d84f 50 static dm_handle_t m_dm_handle; /**< Device Manager handle with instance id's of current BLE connection. */
rgrover1 185:28d8c818d84f 51 static bool m_dm_handle_valid = false; /**< Variable indicating if the Device Manager handle is valid. */
rgrover1 185:28d8c818d84f 52 #endif /* NEEDED */
rgrover1 185:28d8c818d84f 53
rgrover1 185:28d8c818d84f 54
rgrover1 185:28d8c818d84f 55 /**@brief Default reset prepare handler if application hasn't registered a handler.
rgrover1 185:28d8c818d84f 56 */
rgrover1 185:28d8c818d84f 57 static void dfu_app_reset_prepare(void)
rgrover1 185:28d8c818d84f 58 {
rgrover1 185:28d8c818d84f 59 // Reset prepare should be handled by application.
rgrover1 185:28d8c818d84f 60 // This function can be extended to include default handling if application does not implement
rgrover1 185:28d8c818d84f 61 // own handler.
rgrover1 185:28d8c818d84f 62 }
rgrover1 185:28d8c818d84f 63
rgrover1 185:28d8c818d84f 64
rgrover1 185:28d8c818d84f 65 /**@brief Function for disabling all interrupts before jumping from bootloader to application.
rgrover1 185:28d8c818d84f 66 */
rgrover1 185:28d8c818d84f 67 static void interrupts_disable(void)
rgrover1 185:28d8c818d84f 68 {
rgrover1 185:28d8c818d84f 69 uint32_t interrupt_setting_mask;
rgrover1 185:28d8c818d84f 70 uint32_t irq = 0; // We start from first interrupt, i.e. interrupt 0.
rgrover1 185:28d8c818d84f 71
rgrover1 185:28d8c818d84f 72 // Fetch the current interrupt settings.
rgrover1 185:28d8c818d84f 73 interrupt_setting_mask = NVIC->ISER[0];
rgrover1 185:28d8c818d84f 74
rgrover1 185:28d8c818d84f 75 for (; irq < MAX_NUMBER_INTERRUPTS; irq++)
rgrover1 185:28d8c818d84f 76 {
rgrover1 185:28d8c818d84f 77 if (interrupt_setting_mask & (IRQ_ENABLED << irq))
rgrover1 185:28d8c818d84f 78 {
rgrover1 185:28d8c818d84f 79 // The interrupt was enabled, and hence disable it.
rgrover1 185:28d8c818d84f 80 NVIC_DisableIRQ((IRQn_Type)irq);
rgrover1 185:28d8c818d84f 81 }
rgrover1 185:28d8c818d84f 82 }
rgrover1 185:28d8c818d84f 83 }
rgrover1 185:28d8c818d84f 84
rgrover1 185:28d8c818d84f 85 #if NEEDED
rgrover1 185:28d8c818d84f 86 /**@brief Function for providing peer information to DFU for re-establishing bonded connection in
rgrover1 185:28d8c818d84f 87 * DFU mode.
rgrover1 185:28d8c818d84f 88 */
rgrover1 185:28d8c818d84f 89 static void dfu_app_set_peer_data(void)
rgrover1 185:28d8c818d84f 90 {
rgrover1 185:28d8c818d84f 91 uint32_t err_code;
rgrover1 185:28d8c818d84f 92 dm_sec_keyset_t key_set;
rgrover1 185:28d8c818d84f 93
rgrover1 185:28d8c818d84f 94 /** [DFU bond sharing] */
rgrover1 185:28d8c818d84f 95 err_code = dm_distributed_keys_get(&m_dm_handle, &key_set);
rgrover1 185:28d8c818d84f 96 APP_ERROR_CHECK(err_code);
rgrover1 185:28d8c818d84f 97
rgrover1 185:28d8c818d84f 98 m_peer_data.addr = key_set.keys_central.p_id_key->id_addr_info;
rgrover1 185:28d8c818d84f 99 m_peer_data.enc_key = *((ble_gap_enc_key_t *)(key_set.keys_central.enc_key.p_enc_key));
rgrover1 185:28d8c818d84f 100 m_peer_data.irk = key_set.keys_central.p_id_key->id_info;
rgrover1 185:28d8c818d84f 101
rgrover1 185:28d8c818d84f 102 err_code = dfu_ble_svc_set_peer_data(&m_peer_data);
rgrover1 185:28d8c818d84f 103 APP_ERROR_CHECK(err_code);
rgrover1 185:28d8c818d84f 104 /** [DFU bond sharing] */
rgrover1 185:28d8c818d84f 105 }
rgrover1 185:28d8c818d84f 106 #endif /* NEEDED */
rgrover1 185:28d8c818d84f 107
rgrover1 185:28d8c818d84f 108
rgrover1 185:28d8c818d84f 109 /**@brief Function for preparing the reset, disabling SoftDevice and jump to the bootloader.
rgrover1 185:28d8c818d84f 110 */
rgrover1 185:28d8c818d84f 111 void bootloader_start(void)
rgrover1 185:28d8c818d84f 112 {
rgrover1 185:28d8c818d84f 113 m_reset_prepare();
rgrover1 185:28d8c818d84f 114
rgrover1 185:28d8c818d84f 115 uint32_t err_code = sd_power_gpregret_set(BOOTLOADER_DFU_START);
rgrover1 185:28d8c818d84f 116 APP_ERROR_CHECK(err_code);
rgrover1 185:28d8c818d84f 117
rgrover1 185:28d8c818d84f 118 err_code = sd_softdevice_disable();
rgrover1 185:28d8c818d84f 119 APP_ERROR_CHECK(err_code);
rgrover1 185:28d8c818d84f 120
rgrover1 185:28d8c818d84f 121 err_code = sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR);
rgrover1 185:28d8c818d84f 122 APP_ERROR_CHECK(err_code);
rgrover1 185:28d8c818d84f 123
rgrover1 185:28d8c818d84f 124 // Commenting out the following block because it brings in unwanted dependencies from bonding.
rgrover1 185:28d8c818d84f 125 // TODO: discuss this with Nordic.
rgrover1 185:28d8c818d84f 126 // if (m_dm_handle_valid)
rgrover1 185:28d8c818d84f 127 // {
rgrover1 185:28d8c818d84f 128 // dfu_app_set_peer_data();
rgrover1 185:28d8c818d84f 129 // }
rgrover1 185:28d8c818d84f 130
rgrover1 185:28d8c818d84f 131 NVIC_ClearPendingIRQ(SWI2_IRQn);
rgrover1 185:28d8c818d84f 132 interrupts_disable();
rgrover1 185:28d8c818d84f 133 bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);
rgrover1 185:28d8c818d84f 134 }
rgrover1 185:28d8c818d84f 135
rgrover1 185:28d8c818d84f 136
rgrover1 185:28d8c818d84f 137 void dfu_app_on_dfu_evt(ble_dfu_t * p_dfu, ble_dfu_evt_t * p_evt)
rgrover1 185:28d8c818d84f 138 {
rgrover1 185:28d8c818d84f 139 switch (p_evt->ble_dfu_evt_type)
rgrover1 185:28d8c818d84f 140 {
rgrover1 185:28d8c818d84f 141 case BLE_DFU_START:
rgrover1 185:28d8c818d84f 142 // Starting the bootloader - will cause reset.
rgrover1 185:28d8c818d84f 143 bootloader_start();
rgrover1 185:28d8c818d84f 144 break;
rgrover1 185:28d8c818d84f 145
rgrover1 185:28d8c818d84f 146 case BLE_DFU_VALIDATE:
rgrover1 185:28d8c818d84f 147 case BLE_DFU_ACTIVATE_N_RESET:
rgrover1 185:28d8c818d84f 148 case BLE_DFU_SYS_RESET:
rgrover1 185:28d8c818d84f 149 case BLE_DFU_RECEIVE_INIT_DATA:
rgrover1 185:28d8c818d84f 150 case BLE_DFU_RECEIVE_APP_DATA:
rgrover1 185:28d8c818d84f 151 case BLE_DFU_PACKET_WRITE:
rgrover1 185:28d8c818d84f 152 case BLE_DFU_PKT_RCPT_NOTIF_ENABLED:
rgrover1 185:28d8c818d84f 153 case BLE_DFU_PKT_RCPT_NOTIF_DISABLED:
rgrover1 185:28d8c818d84f 154 case BLE_DFU_BYTES_RECEIVED_SEND:
rgrover1 185:28d8c818d84f 155 default:
rgrover1 185:28d8c818d84f 156 {
rgrover1 185:28d8c818d84f 157 // Unsupported event received from DFU Service.
rgrover1 185:28d8c818d84f 158 // Send back BLE_DFU_RESP_VAL_NOT_SUPPORTED message to peer.
rgrover1 185:28d8c818d84f 159 uint32_t err_code = ble_dfu_response_send(p_dfu,
rgrover1 185:28d8c818d84f 160 BLE_DFU_START_PROCEDURE,
rgrover1 185:28d8c818d84f 161 BLE_DFU_RESP_VAL_NOT_SUPPORTED);
rgrover1 185:28d8c818d84f 162 APP_ERROR_CHECK(err_code);
rgrover1 185:28d8c818d84f 163 }
rgrover1 185:28d8c818d84f 164 break;
rgrover1 185:28d8c818d84f 165 }
rgrover1 185:28d8c818d84f 166 }
rgrover1 185:28d8c818d84f 167
rgrover1 185:28d8c818d84f 168
rgrover1 185:28d8c818d84f 169 void dfu_app_reset_prepare_set(dfu_app_reset_prepare_t reset_prepare_func)
rgrover1 185:28d8c818d84f 170 {
rgrover1 185:28d8c818d84f 171 m_reset_prepare = reset_prepare_func;
rgrover1 185:28d8c818d84f 172 }
rgrover1 185:28d8c818d84f 173
rgrover1 185:28d8c818d84f 174 #if NEEDED
rgrover1 185:28d8c818d84f 175 void dfu_app_set_dm_handle(dm_handle_t const * p_dm_handle)
rgrover1 185:28d8c818d84f 176 {
rgrover1 185:28d8c818d84f 177 m_dm_handle_valid = false;
rgrover1 185:28d8c818d84f 178
rgrover1 185:28d8c818d84f 179 if (p_dm_handle != NULL)
rgrover1 185:28d8c818d84f 180 {
rgrover1 185:28d8c818d84f 181 m_dm_handle = *p_dm_handle;
rgrover1 185:28d8c818d84f 182 m_dm_handle_valid = true;
rgrover1 185:28d8c818d84f 183 }
rgrover1 185:28d8c818d84f 184 }
rgrover1 185:28d8c818d84f 185 #endif /* NEEDED */