Nordic stack and drivers for the mbed BLE API. Version to work around build bug.

Dependents:   microbit_rubber_ducky microbit_mouse_BLE microbit_mouse_BLE_daybreak_version microbit_presenter

Fork of nRF51822 by Nordic Semiconductor

Committer:
vcoubard
Date:
Mon Jan 11 10:19:06 2016 +0000
Revision:
549:3f782c64d014
Parent:
541:884f95bf5351
Child:
558:c4b56f9d6f3b
Synchronized with git rev a5a46f2f
Author: Rohit Grover
Release 2.0.7
=============

* Fix a bug in the assembly sequence that starts the Nordic bootloader. With
GCC, a MOV instruction was getting converted into an ADDS, which came with
an unwanted side-effect of updating the XPSR. We relocated the offending MOV
instruction such that it would not affect a conditional branch statement.
This would show only with GCC, and when jumping to the bootloader while in
handler mode.

* Fix hardfaults generated from the handling of Radio Notification events.
Radio notification events are interrupts generated at very high priority.
They have the potential to pre-empt other interrupt handling, causing race
conditions when interrupted handlers were involved in calling into BLE_API.
Radio-notification events should defer their callback handling to low-
priority handlers through the use of Tickers or Timeouts.

* Introduce watchdog header file from Nordic SDK 8.1.

* Update license headers to reflect the latest licenses from Nordic.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vcoubard 541:884f95bf5351 1 /* mbed Microcontroller Library
vcoubard 541:884f95bf5351 2 * Copyright (c) 2006-2013 ARM Limited
vcoubard 541:884f95bf5351 3 *
vcoubard 541:884f95bf5351 4 * Licensed under the Apache License, Version 2.0 (the "License");
vcoubard 541:884f95bf5351 5 * you may not use this file except in compliance with the License.
vcoubard 541:884f95bf5351 6 * You may obtain a copy of the License at
vcoubard 541:884f95bf5351 7 *
vcoubard 541:884f95bf5351 8 * http://www.apache.org/licenses/LICENSE-2.0
vcoubard 541:884f95bf5351 9 *
vcoubard 541:884f95bf5351 10 * Unless required by applicable law or agreed to in writing, software
vcoubard 541:884f95bf5351 11 * distributed under the License is distributed on an "AS IS" BASIS,
vcoubard 541:884f95bf5351 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
vcoubard 541:884f95bf5351 13 * See the License for the specific language governing permissions and
vcoubard 541:884f95bf5351 14 * limitations under the License.
vcoubard 541:884f95bf5351 15 */
vcoubard 541:884f95bf5351 16
vcoubard 541:884f95bf5351 17 #include "btle.h"
vcoubard 541:884f95bf5351 18
vcoubard 541:884f95bf5351 19 #include "nRF5xGap.h"
vcoubard 541:884f95bf5351 20 #include "nRF5xSecurityManager.h"
vcoubard 541:884f95bf5351 21
vcoubard 549:3f782c64d014 22 extern "C" {
vcoubard 549:3f782c64d014 23 #include "pstorage.h"
vcoubard 541:884f95bf5351 24 #include "device_manager.h"
vcoubard 549:3f782c64d014 25 }
vcoubard 549:3f782c64d014 26
vcoubard 541:884f95bf5351 27 #include "btle_security.h"
vcoubard 541:884f95bf5351 28
vcoubard 541:884f95bf5351 29 static dm_application_instance_t applicationInstance;
vcoubard 541:884f95bf5351 30 static ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result);
vcoubard 541:884f95bf5351 31
vcoubard 541:884f95bf5351 32 ble_error_t
vcoubard 541:884f95bf5351 33 btle_initializeSecurity(bool enableBonding,
vcoubard 541:884f95bf5351 34 bool requireMITM,
vcoubard 541:884f95bf5351 35 SecurityManager::SecurityIOCapabilities_t iocaps,
vcoubard 541:884f95bf5351 36 const SecurityManager::Passkey_t passkey)
vcoubard 541:884f95bf5351 37 {
vcoubard 541:884f95bf5351 38 /* guard against multiple initializations */
vcoubard 541:884f95bf5351 39 static bool initialized = false;
vcoubard 541:884f95bf5351 40 if (initialized) {
vcoubard 541:884f95bf5351 41 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 42 }
vcoubard 541:884f95bf5351 43
vcoubard 541:884f95bf5351 44 if (pstorage_init() != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 45 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 46 }
vcoubard 541:884f95bf5351 47
vcoubard 541:884f95bf5351 48 ret_code_t rc;
vcoubard 541:884f95bf5351 49 if (passkey) {
vcoubard 541:884f95bf5351 50 ble_opt_t opts;
vcoubard 541:884f95bf5351 51 opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
vcoubard 541:884f95bf5351 52 if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 53 switch (rc) {
vcoubard 541:884f95bf5351 54 case BLE_ERROR_INVALID_CONN_HANDLE:
vcoubard 541:884f95bf5351 55 case NRF_ERROR_INVALID_ADDR:
vcoubard 541:884f95bf5351 56 case NRF_ERROR_INVALID_PARAM:
vcoubard 541:884f95bf5351 57 default:
vcoubard 541:884f95bf5351 58 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 59 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 60 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 61 case NRF_ERROR_BUSY:
vcoubard 541:884f95bf5351 62 return BLE_STACK_BUSY;
vcoubard 541:884f95bf5351 63 }
vcoubard 541:884f95bf5351 64 }
vcoubard 541:884f95bf5351 65 }
vcoubard 541:884f95bf5351 66
vcoubard 541:884f95bf5351 67 dm_init_param_t dm_init_param = {
vcoubard 541:884f95bf5351 68 .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
vcoubard 541:884f95bf5351 69 };
vcoubard 541:884f95bf5351 70 if (dm_init(&dm_init_param) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 71 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 72 }
vcoubard 541:884f95bf5351 73
vcoubard 541:884f95bf5351 74 const dm_application_param_t dm_param = {
vcoubard 541:884f95bf5351 75 .evt_handler = dm_handler,
vcoubard 541:884f95bf5351 76 .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
vcoubard 541:884f95bf5351 77 .sec_param = {
vcoubard 541:884f95bf5351 78 .bond = enableBonding,/**< Perform bonding. */
vcoubard 541:884f95bf5351 79 .mitm = requireMITM, /**< Man In The Middle protection required. */
vcoubard 541:884f95bf5351 80 .io_caps = iocaps, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
vcoubard 541:884f95bf5351 81 .oob = 0, /**< Out Of Band data available. */
vcoubard 541:884f95bf5351 82 .min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
vcoubard 541:884f95bf5351 83 .max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
vcoubard 541:884f95bf5351 84 .kdist_periph = {
vcoubard 541:884f95bf5351 85 .enc = 1, /**< Long Term Key and Master Identification. */
vcoubard 541:884f95bf5351 86 .id = 1, /**< Identity Resolving Key and Identity Address Information. */
vcoubard 541:884f95bf5351 87 .sign = 1, /**< Connection Signature Resolving Key. */
vcoubard 541:884f95bf5351 88 }, /**< Key distribution bitmap: keys that the peripheral device will distribute. */
vcoubard 541:884f95bf5351 89 }
vcoubard 541:884f95bf5351 90 };
vcoubard 541:884f95bf5351 91
vcoubard 541:884f95bf5351 92 if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 93 switch (rc) {
vcoubard 541:884f95bf5351 94 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 95 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 96 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 97 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 98 default:
vcoubard 541:884f95bf5351 99 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 100 }
vcoubard 541:884f95bf5351 101 }
vcoubard 541:884f95bf5351 102
vcoubard 541:884f95bf5351 103 initialized = true;
vcoubard 541:884f95bf5351 104 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 105 }
vcoubard 541:884f95bf5351 106
vcoubard 541:884f95bf5351 107 ble_error_t
vcoubard 541:884f95bf5351 108 btle_purgeAllBondingState(void)
vcoubard 541:884f95bf5351 109 {
vcoubard 541:884f95bf5351 110 ret_code_t rc;
vcoubard 541:884f95bf5351 111 if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 112 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 113 }
vcoubard 541:884f95bf5351 114
vcoubard 541:884f95bf5351 115 switch (rc) {
vcoubard 541:884f95bf5351 116 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 117 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 118 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 119 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 120 default:
vcoubard 541:884f95bf5351 121 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 122 }
vcoubard 541:884f95bf5351 123 }
vcoubard 541:884f95bf5351 124
vcoubard 541:884f95bf5351 125 ble_error_t
vcoubard 541:884f95bf5351 126 btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
vcoubard 541:884f95bf5351 127 {
vcoubard 541:884f95bf5351 128 ret_code_t rc;
vcoubard 541:884f95bf5351 129 dm_handle_t dmHandle = {
vcoubard 541:884f95bf5351 130 .appl_id = applicationInstance,
vcoubard 541:884f95bf5351 131 };
vcoubard 541:884f95bf5351 132 if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 133 if (rc == NRF_ERROR_NOT_FOUND) {
vcoubard 541:884f95bf5351 134 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 135 } else {
vcoubard 541:884f95bf5351 136 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 137 }
vcoubard 541:884f95bf5351 138 }
vcoubard 541:884f95bf5351 139
vcoubard 541:884f95bf5351 140 if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 141 switch (rc) {
vcoubard 541:884f95bf5351 142 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 143 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 144 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 145 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 146 default:
vcoubard 541:884f95bf5351 147 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 148 }
vcoubard 541:884f95bf5351 149 }
vcoubard 541:884f95bf5351 150
vcoubard 541:884f95bf5351 151 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 152 }
vcoubard 541:884f95bf5351 153
vcoubard 541:884f95bf5351 154 ret_code_t
vcoubard 541:884f95bf5351 155 dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
vcoubard 541:884f95bf5351 156 {
vcoubard 541:884f95bf5351 157 switch (p_event->event_id) {
vcoubard 541:884f95bf5351 158 case DM_EVT_SECURITY_SETUP: /* started */ {
vcoubard 541:884f95bf5351 159 const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
vcoubard 541:884f95bf5351 160 nRF5xSecurityManager::getInstance().processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 541:884f95bf5351 161 peerParams->bond,
vcoubard 541:884f95bf5351 162 peerParams->mitm,
vcoubard 541:884f95bf5351 163 (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
vcoubard 541:884f95bf5351 164 break;
vcoubard 541:884f95bf5351 165 }
vcoubard 541:884f95bf5351 166 case DM_EVT_SECURITY_SETUP_COMPLETE:
vcoubard 541:884f95bf5351 167 nRF5xSecurityManager::getInstance().
vcoubard 541:884f95bf5351 168 processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 541:884f95bf5351 169 (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
vcoubard 541:884f95bf5351 170 break;
vcoubard 541:884f95bf5351 171 case DM_EVT_LINK_SECURED: {
vcoubard 541:884f95bf5351 172 unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
vcoubard 541:884f95bf5351 173 unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
vcoubard 541:884f95bf5351 174 SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
vcoubard 541:884f95bf5351 175 switch (securityMode) {
vcoubard 541:884f95bf5351 176 case 1:
vcoubard 541:884f95bf5351 177 switch (level) {
vcoubard 541:884f95bf5351 178 case 1:
vcoubard 541:884f95bf5351 179 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
vcoubard 541:884f95bf5351 180 break;
vcoubard 541:884f95bf5351 181 case 2:
vcoubard 541:884f95bf5351 182 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
vcoubard 541:884f95bf5351 183 break;
vcoubard 541:884f95bf5351 184 case 3:
vcoubard 541:884f95bf5351 185 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
vcoubard 541:884f95bf5351 186 break;
vcoubard 541:884f95bf5351 187 }
vcoubard 541:884f95bf5351 188 break;
vcoubard 541:884f95bf5351 189 case 2:
vcoubard 541:884f95bf5351 190 switch (level) {
vcoubard 541:884f95bf5351 191 case 1:
vcoubard 541:884f95bf5351 192 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
vcoubard 541:884f95bf5351 193 break;
vcoubard 541:884f95bf5351 194 case 2:
vcoubard 541:884f95bf5351 195 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
vcoubard 541:884f95bf5351 196 break;
vcoubard 541:884f95bf5351 197 }
vcoubard 541:884f95bf5351 198 break;
vcoubard 541:884f95bf5351 199 }
vcoubard 541:884f95bf5351 200
vcoubard 541:884f95bf5351 201 nRF5xSecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
vcoubard 541:884f95bf5351 202 break;
vcoubard 541:884f95bf5351 203 }
vcoubard 541:884f95bf5351 204 case DM_EVT_DEVICE_CONTEXT_STORED:
vcoubard 541:884f95bf5351 205 nRF5xSecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
vcoubard 541:884f95bf5351 206 break;
vcoubard 541:884f95bf5351 207 default:
vcoubard 541:884f95bf5351 208 break;
vcoubard 541:884f95bf5351 209 }
vcoubard 541:884f95bf5351 210
vcoubard 541:884f95bf5351 211 return NRF_SUCCESS;
rgrover1 133:74079098b3c9 212 }