No changes

Fork of nRF51822 by Nordic Semiconductor

Committer:
rgrover1
Date:
Mon Jul 06 10:13:26 2015 +0100
Revision:
370:295f76db798e
Parent:
362:6fa0d4d555f6
Child:
371:8f7d2137727a
Synchronized with git rev 9f72c4ba
Author: Rohit Grover
Release 0.3.7
=============

This is a minor set of enhancements mostly around reduce our global static
memory footprint.

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

* Reduce the maximum number of CHARACTERISTICS and DESCRIPTORS that can be
handled. This has memory implications for static global memory. It should
be possible to re-architect our solution for add_characteristic() to not
require these limits; hopefully we'll get there soon.

* Move nRF51GattServer::getInstance() into a .cpp file; same for nRF51Gap::getInstance().

* Reduce max bonds to managed by device-manager to 4; this has memory implications for static global memory.

* Reduce pStorage command queue size to 2; this has memory implications for static global memory.

* Replace uses of deprecated Gap::addr_type_t with Gap::AddressType_t.

* Some UUID-related types have moved into UUID class. Minor changes were needed to work around build errors.

Bugfixes
~~~~~~~~

* None.

Who changed what in which revision?

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