Qi Yao / LinkNode---test123

Dependencies:   mbed

Fork of LinkNode-Test by Qi Yao

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers btle_security.cpp Source File

btle_security.cpp

00001 /* mbed Microcontroller Library
00002  * Copyright (c) 2006-2013 ARM Limited
00003  *
00004  * Licensed under the Apache License, Version 2.0 (the "License");
00005  * you may not use this file except in compliance with the License.
00006  * You may obtain a copy of the License at
00007  *
00008  *     http://www.apache.org/licenses/LICENSE-2.0
00009  *
00010  * Unless required by applicable law or agreed to in writing, software
00011  * distributed under the License is distributed on an "AS IS" BASIS,
00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  * See the License for the specific language governing permissions and
00014  * limitations under the License.
00015  */
00016 
00017 #include "btle.h"
00018 
00019 #include "nRF5xGap.h"
00020 #include "nRF5xSecurityManager.h"
00021 
00022 extern "C" {
00023 #include "pstorage.h "
00024 #include "device_manager.h "
00025 }
00026 
00027 #include "btle_security.h"
00028 
00029 static dm_application_instance_t applicationInstance;
00030 static ret_code_t dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result);
00031 
00032 ble_error_t
00033 btle_initializeSecurity(bool                                      enableBonding,
00034                         bool                                      requireMITM,
00035                         SecurityManager::SecurityIOCapabilities_t iocaps,
00036                         const SecurityManager::Passkey_t          passkey)
00037 {
00038     /* guard against multiple initializations */
00039     static bool initialized = false;
00040     if (initialized) {
00041         return BLE_ERROR_NONE;
00042     }
00043 
00044     if (pstorage_init() != NRF_SUCCESS) {
00045         return BLE_ERROR_UNSPECIFIED;
00046     }
00047 
00048     ret_code_t rc;
00049     if (passkey) {
00050         ble_opt_t opts;
00051         opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey);
00052         if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) {
00053             switch (rc) {
00054                 case BLE_ERROR_INVALID_CONN_HANDLE:
00055                 case NRF_ERROR_INVALID_ADDR:
00056                 case NRF_ERROR_INVALID_PARAM:
00057                 default:
00058                     return BLE_ERROR_INVALID_PARAM;
00059                 case NRF_ERROR_INVALID_STATE:
00060                     return BLE_ERROR_INVALID_STATE;
00061                 case NRF_ERROR_BUSY:
00062                     return BLE_STACK_BUSY;
00063             }
00064         }
00065     }
00066 
00067     dm_init_param_t dm_init_param = {
00068         .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */
00069     };
00070     if (dm_init(&dm_init_param) != NRF_SUCCESS) {
00071         return BLE_ERROR_UNSPECIFIED;
00072     }
00073 
00074     const dm_application_param_t dm_param = {
00075         .evt_handler  = dm_handler,
00076         .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID,
00077         .sec_param    = {
00078             .bond          = enableBonding,/**< Perform bonding. */
00079             .mitm          = requireMITM,  /**< Man In The Middle protection required. */
00080             .io_caps       = iocaps,       /**< IO capabilities, see @ref BLE_GAP_IO_CAPS. */
00081             .oob           = 0,            /**< Out Of Band data available. */
00082             .min_key_size  = 16,           /**< Minimum encryption key size in octets between 7 and 16. If 0 then not applicable in this instance. */
00083             .max_key_size  = 16,           /**< Maximum encryption key size in octets between min_key_size and 16. */
00084             .kdist_periph  = {
00085               .enc  = 1,                     /**< Long Term Key and Master Identification. */
00086               .id   = 1,                     /**< Identity Resolving Key and Identity Address Information. */
00087               .sign = 1,                     /**< Connection Signature Resolving Key. */
00088             },                             /**< Key distribution bitmap: keys that the peripheral device will distribute. */
00089         }
00090     };
00091 
00092     if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) {
00093         switch (rc) {
00094             case NRF_ERROR_INVALID_STATE:
00095                 return BLE_ERROR_INVALID_STATE;
00096             case NRF_ERROR_NO_MEM:
00097                 return BLE_ERROR_NO_MEM;
00098             default:
00099                 return BLE_ERROR_UNSPECIFIED;
00100         }
00101     }
00102 
00103     initialized = true;
00104     return BLE_ERROR_NONE;
00105 }
00106 
00107 ble_error_t
00108 btle_purgeAllBondingState(void)
00109 {
00110     ret_code_t rc;
00111     if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) {
00112         return BLE_ERROR_NONE;
00113     }
00114 
00115     switch (rc) {
00116         case NRF_ERROR_INVALID_STATE:
00117             return BLE_ERROR_INVALID_STATE;
00118         case NRF_ERROR_NO_MEM:
00119             return BLE_ERROR_NO_MEM;
00120         default:
00121             return BLE_ERROR_UNSPECIFIED;
00122     }
00123 }
00124 
00125 ble_error_t
00126 btle_getLinkSecurity(Gap::Handle_t connectionHandle, SecurityManager::LinkSecurityStatus_t *securityStatusP)
00127 {
00128     ret_code_t rc;
00129     dm_handle_t dmHandle = {
00130         .appl_id = applicationInstance,
00131     };
00132     if ((rc = dm_handle_get(connectionHandle, &dmHandle)) != NRF_SUCCESS) {
00133         if (rc == NRF_ERROR_NOT_FOUND) {
00134             return BLE_ERROR_INVALID_PARAM;
00135         } else {
00136             return BLE_ERROR_UNSPECIFIED;
00137         }
00138     }
00139 
00140     if ((rc = dm_security_status_req(&dmHandle, reinterpret_cast<dm_security_status_t *>(securityStatusP))) != NRF_SUCCESS) {
00141         switch (rc) {
00142             case NRF_ERROR_INVALID_STATE:
00143                 return BLE_ERROR_INVALID_STATE;
00144             case NRF_ERROR_NO_MEM:
00145                 return BLE_ERROR_NO_MEM;
00146             default:
00147                 return BLE_ERROR_UNSPECIFIED;
00148         }
00149     }
00150 
00151     return BLE_ERROR_NONE;
00152 }
00153 
00154 ret_code_t
00155 dm_handler(dm_handle_t const *p_handle, dm_event_t const *p_event, ret_code_t event_result)
00156 {
00157     switch (p_event->event_id) {
00158         case DM_EVT_SECURITY_SETUP: /* started */ {
00159             const ble_gap_sec_params_t *peerParams = &p_event->event_param.p_gap_param->params.sec_params_request.peer_params;
00160             nRF5xSecurityManager::getInstance().processSecuritySetupInitiatedEvent(p_event->event_param.p_gap_param->conn_handle,
00161                                                                                    peerParams->bond,
00162                                                                                    peerParams->mitm,
00163                                                                                    (SecurityManager::SecurityIOCapabilities_t)peerParams->io_caps);
00164             break;
00165         }
00166         case DM_EVT_SECURITY_SETUP_COMPLETE:
00167             nRF5xSecurityManager::getInstance().
00168                 processSecuritySetupCompletedEvent(p_event->event_param.p_gap_param->conn_handle,
00169                                                    (SecurityManager::SecurityCompletionStatus_t)(p_event->event_param.p_gap_param->params.auth_status.auth_status));
00170             break;
00171         case DM_EVT_LINK_SECURED: {
00172             unsigned securityMode                    = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.sm;
00173             unsigned level                           = p_event->event_param.p_gap_param->params.conn_sec_update.conn_sec.sec_mode.lv;
00174             SecurityManager::SecurityMode_t resolvedSecurityMode = SecurityManager::SECURITY_MODE_NO_ACCESS;
00175             switch (securityMode) {
00176                 case 1:
00177                     switch (level) {
00178                         case 1:
00179                             resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_OPEN_LINK;
00180                             break;
00181                         case 2:
00182                             resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_NO_MITM;
00183                             break;
00184                         case 3:
00185                             resolvedSecurityMode = SecurityManager::SECURITY_MODE_ENCRYPTION_WITH_MITM;
00186                             break;
00187                     }
00188                     break;
00189                 case 2:
00190                     switch (level) {
00191                         case 1:
00192                             resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_NO_MITM;
00193                             break;
00194                         case 2:
00195                             resolvedSecurityMode = SecurityManager::SECURITY_MODE_SIGNED_WITH_MITM;
00196                             break;
00197                     }
00198                     break;
00199             }
00200 
00201             nRF5xSecurityManager::getInstance().processLinkSecuredEvent(p_event->event_param.p_gap_param->conn_handle, resolvedSecurityMode);
00202             break;
00203         }
00204         case DM_EVT_DEVICE_CONTEXT_STORED:
00205             nRF5xSecurityManager::getInstance().processSecurityContextStoredEvent(p_event->event_param.p_gap_param->conn_handle);
00206             break;
00207         default:
00208             break;
00209     }
00210 
00211     return NRF_SUCCESS;
00212 }