/**@brief Function for handling the Device Manager events. * * @param[in] p_evt Data associated to the device manager event. */ static uint32_t device_manager_evt_handler(dm_handle_t const * p_handle, dm_event_t const * p_event, ret_code_t event_result) { uint32_t err_code; static bool device_delete_all_started; // Recovery in the event of DM_DEVICE_CONTEXT_FULL if(event_result == DM_DEVICE_CONTEXT_FULL) { /* Clear all devices from the bond table*/ err_code = dm_device_delete_all(&m_app_handle); APP_ERROR_CHECK(err_code); device_delete_all_started = true; } else { APP_ERROR_CHECK(event_result); } if (p_event->event_id == DM_EVT_DEVICE_CONTEXT_STORED) { table_index_t table_index; //Find first and last bond created from m_bond_index_table app_bond_find(&m_app_bond_table,&table_index); //Increment counter if a new bond was created if(!(table_index.mr_cnt_val >= m_app_bond_table.app_bond_cnt[p_handle->device_id])) { table_index.mr_cnt_val++; m_app_bond_table.app_bond_cnt[p_handle->device_id] = table_index.mr_cnt_val; } //Delete first created bond if bond table is full if(((table_index.mr_cnt_val-table_index.lr_cnt_val)== DEVICE_MANAGER_MAX_BONDS-1) && (table_index.lr_cnt_val != NO_APP_CONTEXT)) { uint32_t err_code; dm_handle_t device; device.appl_id = 0; m_app_bond_table.app_bond_cnt[table_index.lr_index]=NO_APP_CONTEXT; device.device_id = m_app_bond_table.device_id[table_index.lr_index]; err_code = dm_device_delete(&device); APP_ERROR_CHECK(err_code); } //Update the app context for new device app_bond_update_context(&m_app_bond_table,p_handle); } else if (p_event->event_id ==DM_EVT_DEVICE_CONTEXT_DELETED) { /* Wait for all devices to be cleared before perfoming a sys reset */ if(device_delete_all_started && (p_handle->device_id == DEVICE_MANAGER_MAX_BONDS -1)) { err_code = sd_nvic_SystemReset(); APP_ERROR_CHECK(err_code); } } return NRF_SUCCESS; }
ble_error_t btle_initializeSecurity(bool enableBonding, bool requireMITM, SecurityManager::SecurityIOCapabilities_t iocaps, const SecurityManager::Passkey_t passkey) { /* guard against multiple initializations */ if (initialized) { return BLE_ERROR_NONE; } if (pstorage_init() != NRF_SUCCESS) { return BLE_ERROR_UNSPECIFIED; } ret_code_t rc; if (passkey) { ble_opt_t opts; opts.gap_opt.passkey.p_passkey = const_cast<uint8_t *>(passkey); if ((rc = sd_ble_opt_set(BLE_GAP_OPT_PASSKEY, &opts)) != NRF_SUCCESS) { switch (rc) { case BLE_ERROR_INVALID_CONN_HANDLE: case NRF_ERROR_INVALID_ADDR: case NRF_ERROR_INVALID_PARAM: default: return BLE_ERROR_INVALID_PARAM; case NRF_ERROR_INVALID_STATE: return BLE_ERROR_INVALID_STATE; case NRF_ERROR_BUSY: return BLE_STACK_BUSY; } } } dm_init_param_t dm_init_param = { .clear_persistent_data = false /* Set to true in case the module should clear all persistent data. */ }; if (dm_init(&dm_init_param) != NRF_SUCCESS) { return BLE_ERROR_UNSPECIFIED; } // update default security parameters with function call parameters securityParameters.bond = enableBonding; securityParameters.mitm = requireMITM; securityParameters.io_caps = iocaps; const dm_application_param_t dm_param = { .evt_handler = dm_handler, .service_type = DM_PROTOCOL_CNTXT_GATT_CLI_ID, .sec_param = securityParameters }; if ((rc = dm_register(&applicationInstance, &dm_param)) != NRF_SUCCESS) { switch (rc) { case NRF_ERROR_INVALID_STATE: return BLE_ERROR_INVALID_STATE; case NRF_ERROR_NO_MEM: return BLE_ERROR_NO_MEM; default: return BLE_ERROR_UNSPECIFIED; } } initialized = true; return BLE_ERROR_NONE; } ble_error_t btle_purgeAllBondingState(void) { ret_code_t rc; if ((rc = dm_device_delete_all(&applicationInstance)) == NRF_SUCCESS) { return BLE_ERROR_NONE; } switch (rc) { case NRF_ERROR_INVALID_STATE: return BLE_ERROR_INVALID_STATE; case NRF_ERROR_NO_MEM: return BLE_ERROR_NO_MEM; default: return BLE_ERROR_UNSPECIFIED; } }