test

Dependencies:   nrf51-sdk

Dependents:   microbit-dal

Fork of nRF51822 by Lancaster University

Committer:
vcoubard
Date:
Mon Jan 11 10:19:18 2016 +0000
Revision:
565:cf03471a4ec4
Parent:
558:c4b56f9d6f3b
Child:
566:e425ad9e5d6e
Synchronized with git rev 0bcc2e96
Author: Andres Amaya Garcia
Modify shutdown due to BLE API change

The module is updated to comply with the changes to BLE API regarding correct
shutdown functionality. The following changes are introduced to ble-nrf51822:

* Calls to the old static function shutdown in Gap, GattClient, GattServer and
SecurityManager are removed.
* The cleanup function in Gap, GattClient, GattServer and SecurityManager is
renamed to `reset()` and made public.
* The static references inside nRF5xGap, nRF5xGattClient, nRF5xGattServer and
nRF5xSecurityManager to objects of their own class are moved to nRF5xn.
* The static getInstance accessors in nRF5xGap, nRF5xGattClient,
nRF5xGattServer and nRF5xSecurityManager are removed and their functionality is
moved to the implemented virtual accessors in nRF5xn i.e. getGap(),
getGattClient, etc.
* A static function Instance is added to nRF5xn class to make the transport
object accessible across the module.

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 565:cf03471a4ec4 19 #include "nRF5xn.h"
vcoubard 541:884f95bf5351 20
vcoubard 549:3f782c64d014 21 extern "C" {
vcoubard 549:3f782c64d014 22 #include "pstorage.h"
vcoubard 541:884f95bf5351 23 #include "device_manager.h"
vcoubard 549:3f782c64d014 24 }
vcoubard 549:3f782c64d014 25
vcoubard 541:884f95bf5351 26 #include "btle_security.h"
vcoubard 541:884f95bf5351 27
vcoubard 541:884f95bf5351 28 static dm_application_instance_t applicationInstance;
vcoubard 541:884f95bf5351 29 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 30
vcoubard 558:c4b56f9d6f3b 31 // default security parameters
vcoubard 558:c4b56f9d6f3b 32 static ble_gap_sec_params_t securityParameters = {
vcoubard 558:c4b56f9d6f3b 33 .bond = true, /**< Perform bonding. */
vcoubard 558:c4b56f9d6f3b 34 .mitm = true, /**< Man In The Middle protection required. */
vcoubard 558:c4b56f9d6f3b 35 .io_caps = SecurityManager::IO_CAPS_NONE, /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
vcoubard 558:c4b56f9d6f3b 36 .oob = 0, /**< Out Of Band data available. */
vcoubard 558:c4b56f9d6f3b 37 .min_key_size = 16, /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
vcoubard 558:c4b56f9d6f3b 38 .max_key_size = 16, /**< Maximum encryption key size in octets between min_key_size and 16. */
vcoubard 558:c4b56f9d6f3b 39 .kdist_periph = {
vcoubard 558:c4b56f9d6f3b 40 .enc = 1, /**< Long Term Key and Master Identification. */
vcoubard 558:c4b56f9d6f3b 41 .id = 1, /**< Identity Resolving Key and Identity Address Information. */
vcoubard 558:c4b56f9d6f3b 42 .sign = 1, /**< Connection Signature Resolving Key. */
vcoubard 558:c4b56f9d6f3b 43 }, /**< Key distribution bitmap: keys that the peripheral device will distribute. */
vcoubard 558:c4b56f9d6f3b 44 };
vcoubard 558:c4b56f9d6f3b 45
vcoubard 541:884f95bf5351 46 ble_error_t
vcoubard 541:884f95bf5351 47 btle_initializeSecurity(bool enableBonding,
vcoubard 541:884f95bf5351 48 bool requireMITM,
vcoubard 541:884f95bf5351 49 SecurityManager::SecurityIOCapabilities_t iocaps,
vcoubard 541:884f95bf5351 50 const SecurityManager::Passkey_t passkey)
vcoubard 541:884f95bf5351 51 {
vcoubard 541:884f95bf5351 52 /* guard against multiple initializations */
vcoubard 541:884f95bf5351 53 static bool initialized = false;
vcoubard 541:884f95bf5351 54 if (initialized) {
vcoubard 541:884f95bf5351 55 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 56 }
vcoubard 541:884f95bf5351 57
vcoubard 541:884f95bf5351 58 if (pstorage_init() != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 59 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 60 }
vcoubard 541:884f95bf5351 61
vcoubard 541:884f95bf5351 62 ret_code_t rc;
vcoubard 541:884f95bf5351 63 if (passkey) {
vcoubard 541:884f95bf5351 64 ble_opt_t opts;
vcoubard 541:884f95bf5351 65 opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
vcoubard 541:884f95bf5351 66 if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 67 switch (rc) {
vcoubard 541:884f95bf5351 68 case BLE_ERROR_INVALID_CONN_HANDLE:
vcoubard 541:884f95bf5351 69 case NRF_ERROR_INVALID_ADDR:
vcoubard 541:884f95bf5351 70 case NRF_ERROR_INVALID_PARAM:
vcoubard 541:884f95bf5351 71 default:
vcoubard 541:884f95bf5351 72 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 73 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 74 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 75 case NRF_ERROR_BUSY:
vcoubard 541:884f95bf5351 76 return BLE_STACK_BUSY;
vcoubard 541:884f95bf5351 77 }
vcoubard 541:884f95bf5351 78 }
vcoubard 541:884f95bf5351 79 }
vcoubard 541:884f95bf5351 80
vcoubard 541:884f95bf5351 81 dm_init_param_t dm_init_param = {
vcoubard 541:884f95bf5351 82 .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
vcoubard 541:884f95bf5351 83 };
vcoubard 541:884f95bf5351 84 if (dm_init(&dm_init_param) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 85 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 86 }
vcoubard 541:884f95bf5351 87
vcoubard 558:c4b56f9d6f3b 88 // update default security parameters with function call parameters
vcoubard 558:c4b56f9d6f3b 89 securityParameters.bond = enableBonding;
vcoubard 558:c4b56f9d6f3b 90 securityParameters.mitm = requireMITM;
vcoubard 558:c4b56f9d6f3b 91 securityParameters.io_caps = iocaps;
vcoubard 558:c4b56f9d6f3b 92
vcoubard 541:884f95bf5351 93 const dm_application_param_t dm_param = {
vcoubard 541:884f95bf5351 94 .evt_handler = dm_handler,
vcoubard 541:884f95bf5351 95 .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
vcoubard 558:c4b56f9d6f3b 96 .sec_param = securityParameters
vcoubard 541:884f95bf5351 97 };
vcoubard 541:884f95bf5351 98
vcoubard 541:884f95bf5351 99 if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 100 switch (rc) {
vcoubard 541:884f95bf5351 101 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 102 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 103 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 104 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 105 default:
vcoubard 541:884f95bf5351 106 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 107 }
vcoubard 541:884f95bf5351 108 }
vcoubard 541:884f95bf5351 109
vcoubard 541:884f95bf5351 110 initialized = true;
vcoubard 541:884f95bf5351 111 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 112 }
vcoubard 541:884f95bf5351 113
vcoubard 541:884f95bf5351 114 ble_error_t
vcoubard 541:884f95bf5351 115 btle_purgeAllBondingState(void)
vcoubard 541:884f95bf5351 116 {
vcoubard 541:884f95bf5351 117 ret_code_t rc;
vcoubard 541:884f95bf5351 118 if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
vcoubard 541:884f95bf5351 119 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 120 }
vcoubard 541:884f95bf5351 121
vcoubard 541:884f95bf5351 122 switch (rc) {
vcoubard 541:884f95bf5351 123 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 124 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 125 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 126 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 127 default:
vcoubard 541:884f95bf5351 128 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 129 }
vcoubard 541:884f95bf5351 130 }
vcoubard 541:884f95bf5351 131
vcoubard 541:884f95bf5351 132 ble_error_t
vcoubard 541:884f95bf5351 133 btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
vcoubard 541:884f95bf5351 134 {
vcoubard 541:884f95bf5351 135 ret_code_t rc;
vcoubard 541:884f95bf5351 136 dm_handle_t dmHandle = {
vcoubard 541:884f95bf5351 137 .appl_id = applicationInstance,
vcoubard 541:884f95bf5351 138 };
vcoubard 541:884f95bf5351 139 if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 140 if (rc == NRF_ERROR_NOT_FOUND) {
vcoubard 541:884f95bf5351 141 return BLE_ERROR_INVALID_PARAM;
vcoubard 541:884f95bf5351 142 } else {
vcoubard 541:884f95bf5351 143 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 144 }
vcoubard 541:884f95bf5351 145 }
vcoubard 541:884f95bf5351 146
vcoubard 541:884f95bf5351 147 if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
vcoubard 541:884f95bf5351 148 switch (rc) {
vcoubard 541:884f95bf5351 149 case NRF_ERROR_INVALID_STATE:
vcoubard 541:884f95bf5351 150 return BLE_ERROR_INVALID_STATE;
vcoubard 541:884f95bf5351 151 case NRF_ERROR_NO_MEM:
vcoubard 541:884f95bf5351 152 return BLE_ERROR_NO_MEM;
vcoubard 541:884f95bf5351 153 default:
vcoubard 541:884f95bf5351 154 return BLE_ERROR_UNSPECIFIED;
vcoubard 541:884f95bf5351 155 }
vcoubard 541:884f95bf5351 156 }
vcoubard 541:884f95bf5351 157
vcoubard 541:884f95bf5351 158 return BLE_ERROR_NONE;
vcoubard 541:884f95bf5351 159 }
vcoubard 541:884f95bf5351 160
vcoubard 558:c4b56f9d6f3b 161 ble_error_t
vcoubard 558:c4b56f9d6f3b 162 btle_setLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::SecurityMode_t securityMode)
vcoubard 558:c4b56f9d6f3b 163 {
vcoubard 558:c4b56f9d6f3b 164 // use default and updated parameters as starting point
vcoubard 558:c4b56f9d6f3b 165 // and modify structure based on security mode.
vcoubard 558:c4b56f9d6f3b 166 ble_gap_sec_params_t params = securityParameters;
vcoubard 558:c4b56f9d6f3b 167
vcoubard 558:c4b56f9d6f3b 168 switch (securityMode) {
vcoubard 558:c4b56f9d6f3b 169 case SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK:
vcoubard 558:c4b56f9d6f3b 170 /**< Require no protection, open link. */
vcoubard 558:c4b56f9d6f3b 171 securityParameters.bond = false;
vcoubard 558:c4b56f9d6f3b 172 securityParameters.mitm = false;
vcoubard 558:c4b56f9d6f3b 173 break;
vcoubard 558:c4b56f9d6f3b 174
vcoubard 558:c4b56f9d6f3b 175 case SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM:
vcoubard 558:c4b56f9d6f3b 176 /**< Require encryption, but no MITM protection. */
vcoubard 558:c4b56f9d6f3b 177 securityParameters.bond = true;
vcoubard 558:c4b56f9d6f3b 178 securityParameters.mitm = false;
vcoubard 558:c4b56f9d6f3b 179 break;
vcoubard 558:c4b56f9d6f3b 180
vcoubard 558:c4b56f9d6f3b 181 // not yet implemented security modes
vcoubard 558:c4b56f9d6f3b 182 case SecurityManager::SECURITY_MODE_NO_ACCESS:
vcoubard 558:c4b56f9d6f3b 183 case SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM:
vcoubard 558:c4b56f9d6f3b 184 /**< Require encryption and MITM protection. */
vcoubard 558:c4b56f9d6f3b 185 case SecurityManager::SECURITY_MODE_SIGNED_NO_MITM:
vcoubard 558:c4b56f9d6f3b 186 /**< Require signing or encryption, but no MITM protection. */
vcoubard 558:c4b56f9d6f3b 187 case SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM:
vcoubard 558:c4b56f9d6f3b 188 /**< Require signing or encryption, and MITM protection. */
vcoubard 558:c4b56f9d6f3b 189 default:
vcoubard 558:c4b56f9d6f3b 190 return BLE_ERROR_NOT_IMPLEMENTED;
vcoubard 558:c4b56f9d6f3b 191 }
vcoubard 558:c4b56f9d6f3b 192
vcoubard 558:c4b56f9d6f3b 193 // update security settings for given connection
vcoubard 558:c4b56f9d6f3b 194 uint32_t result = sd_ble_gap_authenticate(connectionHandle, &params);
vcoubard 558:c4b56f9d6f3b 195
vcoubard 558:c4b56f9d6f3b 196 if (result == NRF_SUCCESS) {
vcoubard 558:c4b56f9d6f3b 197 return BLE_ERROR_NONE;
vcoubard 558:c4b56f9d6f3b 198 } else {
vcoubard 558:c4b56f9d6f3b 199 return BLE_ERROR_UNSPECIFIED;
vcoubard 558:c4b56f9d6f3b 200 }
vcoubard 558:c4b56f9d6f3b 201 }
vcoubard 558:c4b56f9d6f3b 202
vcoubard 541:884f95bf5351 203 ret_code_t
vcoubard 541:884f95bf5351 204 dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
vcoubard 541:884f95bf5351 205 {
vcoubard 565:cf03471a4ec4 206 nRF5xn &ble = nRF5xn::Instance(BLE::DEFAULT_INSTANCE);
vcoubard 565:cf03471a4ec4 207 nRF5xSecurityManager &securityManager = (nRF5xSecurityManager &) ble.getSecurityManager();
vcoubard 565:cf03471a4ec4 208
vcoubard 541:884f95bf5351 209 switch (p_event->event_id) {
vcoubard 541:884f95bf5351 210 case DM_EVT_SECURITY_SETUP: /* started */ {
vcoubard 541:884f95bf5351 211 const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
vcoubard 565:cf03471a4ec4 212 securityManager.processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 541:884f95bf5351 213 peerParams->bond,
vcoubard 541:884f95bf5351 214 peerParams->mitm,
vcoubard 541:884f95bf5351 215 (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
vcoubard 541:884f95bf5351 216 break;
vcoubard 541:884f95bf5351 217 }
vcoubard 541:884f95bf5351 218 case DM_EVT_SECURITY_SETUP_COMPLETE:
vcoubard 565:cf03471a4ec4 219 securityManager.
vcoubard 541:884f95bf5351 220 processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
vcoubard 541:884f95bf5351 221 (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
vcoubard 541:884f95bf5351 222 break;
vcoubard 541:884f95bf5351 223 case DM_EVT_LINK_SECURED: {
vcoubard 541:884f95bf5351 224 unsigned securityMode = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
vcoubard 541:884f95bf5351 225 unsigned level = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
vcoubard 541:884f95bf5351 226 SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
vcoubard 541:884f95bf5351 227 switch (securityMode) {
vcoubard 541:884f95bf5351 228 case 1:
vcoubard 541:884f95bf5351 229 switch (level) {
vcoubard 541:884f95bf5351 230 case 1:
vcoubard 541:884f95bf5351 231 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
vcoubard 541:884f95bf5351 232 break;
vcoubard 541:884f95bf5351 233 case 2:
vcoubard 541:884f95bf5351 234 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
vcoubard 541:884f95bf5351 235 break;
vcoubard 541:884f95bf5351 236 case 3:
vcoubard 541:884f95bf5351 237 resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
vcoubard 541:884f95bf5351 238 break;
vcoubard 541:884f95bf5351 239 }
vcoubard 541:884f95bf5351 240 break;
vcoubard 541:884f95bf5351 241 case 2:
vcoubard 541:884f95bf5351 242 switch (level) {
vcoubard 541:884f95bf5351 243 case 1:
vcoubard 541:884f95bf5351 244 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
vcoubard 541:884f95bf5351 245 break;
vcoubard 541:884f95bf5351 246 case 2:
vcoubard 541:884f95bf5351 247 resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
vcoubard 541:884f95bf5351 248 break;
vcoubard 541:884f95bf5351 249 }
vcoubard 541:884f95bf5351 250 break;
vcoubard 541:884f95bf5351 251 }
vcoubard 541:884f95bf5351 252
vcoubard 565:cf03471a4ec4 253 securityManager.processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
vcoubard 541:884f95bf5351 254 break;
vcoubard 541:884f95bf5351 255 }
vcoubard 541:884f95bf5351 256 case DM_EVT_DEVICE_CONTEXT_STORED:
vcoubard 565:cf03471a4ec4 257 securityManager.processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
vcoubard 541:884f95bf5351 258 break;
vcoubard 541:884f95bf5351 259 default:
vcoubard 541:884f95bf5351 260 break;
vcoubard 541:884f95bf5351 261 }
vcoubard 541:884f95bf5351 262
vcoubard 541:884f95bf5351 263 return NRF_SUCCESS;
rgrover1 133:74079098b3c9 264 }