Add traces to HCI, BLE instance, Security DB and WSF cordio traces (#14138)

* ble HCI tracing

* fix typo in SM trace

* add BLE instance tracing

* route wsf traces to mbed tr_debug

* Update connectivity/FEATURE_BLE/source/cordio/source/BLEInstanceBaseImpl.cpp

Co-authored-by: Vincent Coubard <vincent.coubard@arm.com>

* print hci on cordio side

* trace controller supported features

* log reset sequence

* include config for printing enums

* remove duplicate trace

* add tracing to security db

* workaround for macro error on use outside trace

Co-authored-by: Vincent Coubard <vincent.coubard@arm.com>
pull/14198/head
Paul Szczepanek 2021-01-15 10:07:49 +00:00 committed by Paul Szczepanek
parent 5aa76e566a
commit 7b08388be6
22 changed files with 729 additions and 31 deletions

View File

@ -26,6 +26,10 @@
#include <stdarg.h>
#if MBED_CONF_CORDIO_TRACE_HCI_PACKETS
#include "mbed_wsf_trace.h"
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -289,6 +293,7 @@ bool_t WsfTokenService(void);
/*! \brief 3 argument HCI error trace. */
#define HCI_TRACE_ERR3(msg, var1, var2, var3) WSF_TRACE3("HCI", "ERR", msg, var1, var2, var3)
#if !MBED_CONF_CORDIO_TRACE_HCI_PACKETS
/*! \brief HCI PDUMP on command. */
#define HCI_PDUMP_CMD(len, pBuf)
/*! \brief HCI PDUMP on event. */
@ -301,6 +306,7 @@ bool_t WsfTokenService(void);
#define HCI_PDUMP_TX_ISO(len, pBuf)
/*! \brief HCI PDUMP on Received ISO message. */
#define HCI_PDUMP_RX_ISO(len, pBuf)
#endif // !MBED_CONF_CORDIO_TRACE_HCI_PACKETS
/*! \brief 0 argument DM info trace. */
#define DM_TRACE_INFO0(msg) WSF_TRACE0("DM", "INFO", msg)

View File

@ -108,10 +108,15 @@
"value": 16,
"macro_name": "BLE_GAP_HOST_PRIVACY_RESOLVED_CACHE_SIZE"
},
"ble-passkey-display-reversed-digits-deprecation": {
"help": "This option is part of the deprecation process. Set this to false to remove the deprecation notice. When set to true, the digits in the SecurityManager passkeyDiplay event are reversed. When set to false the digits are in the correct order.",
"value": true,
"macro_name": "BLE_PASSKEY_DISPLAY_REVERSED_DIGITS_DEPRECATION"
},
"trace-human-readable-enums": {
"help": "More hexadecimal values in traces will be printed as human readable strings.",
"value": false
}
},
"target_overrides": {

View File

@ -0,0 +1,337 @@
/* mbed Microcontroller Library
* Copyright (c) 2021 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ble_trace_helpers.h"
#define TRACE_GROUP "BLE "
namespace ble {
#if MBED_CONF_MBED_TRACE_ENABLE
const char* dm_callback_event_to_string(uint8_t event) {
#if MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
const char* ret = "INVALID";
switch(event)
{
case DM_RESET_CMPL_IND: ret = "DM_RESET_CMPL_IND"; break;
case DM_ADV_START_IND: ret = "DM_ADV_START_IND"; break;
case DM_ADV_STOP_IND: ret = "DM_ADV_STOP_IND"; break;
case DM_ADV_NEW_ADDR_IND: ret = "DM_ADV_NEW_ADDR_IND"; break;
case DM_SCAN_START_IND: ret = "DM_SCAN_START_IND"; break;
case DM_SCAN_STOP_IND: ret = "DM_SCAN_STOP_IND"; break;
case DM_SCAN_REPORT_IND: ret = "DM_SCAN_REPORT_IND"; break;
case DM_CONN_OPEN_IND: ret = "DM_CONN_OPEN_IND"; break;
case DM_CONN_CLOSE_IND: ret = "DM_CONN_CLOSE_IND"; break;
case DM_CONN_UPDATE_IND: ret = "DM_CONN_UPDATE_IND"; break;
case DM_SEC_PAIR_CMPL_IND: ret = "DM_SEC_PAIR_CMPL_IND"; break;
case DM_SEC_PAIR_FAIL_IND: ret = "DM_SEC_PAIR_FAIL_IND"; break;
case DM_SEC_ENCRYPT_IND: ret = "DM_SEC_ENCRYPT_IND"; break;
case DM_SEC_ENCRYPT_FAIL_IND: ret = "DM_SEC_ENCRYPT_FAIL_IND"; break;
case DM_SEC_AUTH_REQ_IND: ret = "DM_SEC_AUTH_REQ_IND"; break;
case DM_SEC_KEY_IND: ret = "DM_SEC_KEY_IND"; break;
case DM_SEC_LTK_REQ_IND: ret = "DM_SEC_LTK_REQ_IND"; break;
case DM_SEC_PAIR_IND: ret = "DM_SEC_PAIR_IND"; break;
case DM_SEC_SLAVE_REQ_IND: ret = "DM_SEC_SLAVE_REQ_IND"; break;
case DM_SEC_CALC_OOB_IND: ret = "DM_SEC_CALC_OOB_IND"; break;
case DM_SEC_ECC_KEY_IND: ret = "DM_SEC_ECC_KEY_IND"; break;
case DM_SEC_COMPARE_IND: ret = "DM_SEC_COMPARE_IND"; break;
case DM_SEC_KEYPRESS_IND: ret = "DM_SEC_KEYPRESS_IND"; break;
case DM_PRIV_RESOLVED_ADDR_IND: ret = "DM_PRIV_RESOLVED_ADDR_IND"; break;
case DM_PRIV_GENERATE_ADDR_IND: ret = "DM_PRIV_GENERATE_ADDR_IND"; break;
case DM_CONN_READ_RSSI_IND: ret = "DM_CONN_READ_RSSI_IND"; break;
case DM_PRIV_ADD_DEV_TO_RES_LIST_IND: ret = "DM_PRIV_ADD_DEV_TO_RES_LIST_IND"; break;
case DM_PRIV_REM_DEV_FROM_RES_LIST_IND: ret = "DM_PRIV_REM_DEV_FROM_RES_LIST_IND"; break;
case DM_PRIV_CLEAR_RES_LIST_IND: ret = "DM_PRIV_CLEAR_RES_LIST_IND"; break;
case DM_PRIV_READ_PEER_RES_ADDR_IND: ret = "DM_PRIV_READ_PEER_RES_ADDR_IND"; break;
case DM_PRIV_READ_LOCAL_RES_ADDR_IND: ret = "DM_PRIV_READ_LOCAL_RES_ADDR_IND"; break;
case DM_PRIV_SET_ADDR_RES_ENABLE_IND: ret = "DM_PRIV_SET_ADDR_RES_ENABLE_IND"; break;
case DM_REM_CONN_PARAM_REQ_IND: ret = "DM_REM_CONN_PARAM_REQ_IND"; break;
case DM_CONN_DATA_LEN_CHANGE_IND: ret = "DM_CONN_DATA_LEN_CHANGE_IND"; break;
case DM_CONN_WRITE_AUTH_TO_IND: ret = "DM_CONN_WRITE_AUTH_TO_IND"; break;
case DM_CONN_AUTH_TO_EXPIRED_IND: ret = "DM_CONN_AUTH_TO_EXPIRED_IND"; break;
case DM_PHY_READ_IND: ret = "DM_PHY_READ_IND"; break;
case DM_PHY_SET_DEF_IND: ret = "DM_PHY_SET_DEF_IND"; break;
case DM_PHY_UPDATE_IND: ret = "DM_PHY_UPDATE_IND"; break;
case DM_ADV_SET_START_IND: ret = "DM_ADV_SET_START_IND"; break;
case DM_ADV_SET_STOP_IND: ret = "DM_ADV_SET_STOP_IND"; break;
case DM_SCAN_REQ_RCVD_IND: ret = "DM_SCAN_REQ_RCVD_IND"; break;
case DM_EXT_SCAN_START_IND: ret = "DM_EXT_SCAN_START_IND"; break;
case DM_EXT_SCAN_STOP_IND: ret = "DM_EXT_SCAN_STOP_IND"; break;
case DM_EXT_SCAN_REPORT_IND: ret = "DM_EXT_SCAN_REPORT_IND"; break;
case DM_PER_ADV_SET_START_IND: ret = "DM_PER_ADV_SET_START_IND"; break;
case DM_PER_ADV_SET_STOP_IND: ret = "DM_PER_ADV_SET_STOP_IND"; break;
case DM_PER_ADV_SYNC_EST_IND: ret = "DM_PER_ADV_SYNC_EST_IND"; break;
case DM_PER_ADV_SYNC_EST_FAIL_IND: ret = "DM_PER_ADV_SYNC_EST_FAIL_IND"; break;
case DM_PER_ADV_SYNC_LOST_IND: ret = "DM_PER_ADV_SYNC_LOST_IND"; break;
case DM_PER_ADV_SYNC_TRSF_EST_IND: ret = "DM_PER_ADV_SYNC_TRSF_EST_IND"; break;
case DM_PER_ADV_SYNC_TRSF_EST_FAIL_IND: ret = "DM_PER_ADV_SYNC_TRSF_EST_FAIL_IND"; break;
case DM_PER_ADV_SYNC_TRSF_IND: ret = "DM_PER_ADV_SYNC_TRSF_IND"; break;
case DM_PER_ADV_SET_INFO_TRSF_IND: ret = "DM_PER_ADV_SET_INFO_TRSF_IND"; break;
case DM_PER_ADV_REPORT_IND: ret = "DM_PER_ADV_REPORT_IND"; break;
case DM_REMOTE_FEATURES_IND: ret = "DM_REMOTE_FEATURES_IND"; break;
case DM_READ_REMOTE_VER_INFO_IND: ret = "DM_READ_REMOTE_VER_INFO_IND"; break;
case DM_CONN_IQ_REPORT_IND: ret = "DM_CONN_IQ_REPORT_IND"; break;
case DM_CTE_REQ_FAIL_IND: ret = "DM_CTE_REQ_FAIL_IND"; break;
case DM_CONN_CTE_RX_SAMPLE_START_IND: ret = "DM_CONN_CTE_RX_SAMPLE_START_IND"; break;
case DM_CONN_CTE_RX_SAMPLE_STOP_IND: ret = "DM_CONN_CTE_RX_SAMPLE_STOP_IND"; break;
case DM_CONN_CTE_TX_CFG_IND: ret = "DM_CONN_CTE_TX_CFG_IND"; break;
case DM_CONN_CTE_REQ_START_IND: ret = "DM_CONN_CTE_REQ_START_IND"; break;
case DM_CONN_CTE_REQ_STOP_IND: ret = "DM_CONN_CTE_REQ_STOP_IND"; break;
case DM_CONN_CTE_RSP_START_IND: ret = "DM_CONN_CTE_RSP_START_IND"; break;
case DM_CONN_CTE_RSP_STOP_IND: ret = "DM_CONN_CTE_RSP_STOP_IND"; break;
case DM_READ_ANTENNA_INFO_IND: ret = "DM_READ_ANTENNA_INFO_IND"; break;
case DM_CIS_CIG_CONFIG_IND: ret = "DM_CIS_CIG_CONFIG_IND"; break;
case DM_CIS_CIG_REMOVE_IND: ret = "DM_CIS_CIG_REMOVE_IND"; break;
case DM_CIS_REQ_IND: ret = "DM_CIS_REQ_IND"; break;
case DM_CIS_OPEN_IND: ret = "DM_CIS_OPEN_IND"; break;
case DM_CIS_CLOSE_IND: ret = "DM_CIS_CLOSE_IND"; break;
case DM_REQ_PEER_SCA_IND: ret = "DM_REQ_PEER_SCA_IND"; break;
case DM_ISO_DATA_PATH_SETUP_IND: ret = "DM_ISO_DATA_PATH_SETUP_IND"; break;
case DM_ISO_DATA_PATH_REMOVE_IND: ret = "DM_ISO_DATA_PATH_REMOVE_IND"; break;
case DM_DATA_PATH_CONFIG_IND: ret = "DM_DATA_PATH_CONFIG_IND"; break;
case DM_READ_LOCAL_SUP_CODECS_IND: ret = "DM_READ_LOCAL_SUP_CODECS_IND"; break;
case DM_READ_LOCAL_SUP_CODEC_CAP_IND: ret = "DM_READ_LOCAL_SUP_CODEC_CAP_IND"; break;
case DM_READ_LOCAL_SUP_CTR_DLY_IND: ret = "DM_READ_LOCAL_SUP_CTR_DLY_IND"; break;
case DM_BIG_START_IND: ret = "DM_BIG_START_IND"; break;
case DM_BIG_STOP_IND: ret = "DM_BIG_STOP_IND"; break;
case DM_BIG_SYNC_EST_IND: ret = "DM_BIG_SYNC_EST_IND"; break;
case DM_BIG_SYNC_EST_FAIL_IND: ret = "DM_BIG_SYNC_EST_FAIL_IND"; break;
case DM_BIG_SYNC_LOST_IND: ret = "DM_BIG_SYNC_LOST_IND"; break;
case DM_BIG_SYNC_STOP_IND: ret = "DM_BIG_SYNC_STOP_IND"; break;
case DM_BIG_INFO_ADV_REPORT_IND: ret = "DM_BIG_INFO_ADV_REPORT_IND"; break;
case DM_L2C_CMD_REJ_IND: ret = "DM_L2C_CMD_REJ_IND"; break;
case DM_ERROR_IND: ret = "DM_ERROR_IND"; break;
case DM_HW_ERROR_IND: ret = "DM_HW_ERROR_IND"; break;
case DM_VENDOR_SPEC_IND: ret = "DM_VENDOR_SPEC_IND"; break;
#if MBED_CONF_CORDIO_ROUTE_UNHANDLED_COMMAND_COMPLETE_EVENTS
case DM_UNHANDLED_CMD_CMPL_EVT_IND: ret = "DM_UNHANDLED_CMD_CMPL_EVT_IND"; break;
#endif
}
#else // MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
static char ret[3] = "00";
sprintf(ret, "%02x", (int)event);
#endif // MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
return ret;
}
void trace_le_supported_features(uint64_t feat)
{
#if MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
if (feat & HCI_LE_SUP_FEAT_ENCRYPTION) tr_info("ENCRYPTION");
if (feat & HCI_LE_SUP_FEAT_CONN_PARAM_REQ_PROC) tr_info("CONN_PARAM_REQ_PROC");
if (feat & HCI_LE_SUP_FEAT_EXT_REJECT_IND) tr_info("EXT_REJECT_IND");
if (feat & HCI_LE_SUP_FEAT_SLV_INIT_FEAT_EXCH) tr_info("SLV_INIT_FEAT_EXCH");
if (feat & HCI_LE_SUP_FEAT_LE_PING) tr_info("LE_PING");
if (feat & HCI_LE_SUP_FEAT_DATA_LEN_EXT) tr_info("DATA_LEN_EXT");
if (feat & HCI_LE_SUP_FEAT_PRIVACY) tr_info("PRIVACY");
if (feat & HCI_LE_SUP_FEAT_EXT_SCAN_FILT_POLICY) tr_info("EXT_SCAN_FILT_POLICY");
if (feat & HCI_LE_SUP_FEAT_LE_2M_PHY) tr_info("LE_2M_PHY");
if (feat & HCI_LE_SUP_FEAT_STABLE_MOD_IDX_TRANSMITTER) tr_info("STABLE_MOD_IDX_TRANSMITTER");
if (feat & HCI_LE_SUP_FEAT_STABLE_MOD_IDX_RECEIVER) tr_info("STABLE_MOD_IDX_RECEIVER");
if (feat & HCI_LE_SUP_FEAT_LE_CODED_PHY) tr_info("LE_CODED_PHY");
if (feat & HCI_LE_SUP_FEAT_LE_EXT_ADV) tr_info("LE_EXT_ADV");
if (feat & HCI_LE_SUP_FEAT_LE_PER_ADV) tr_info("LE_PER_ADV");
if (feat & HCI_LE_SUP_FEAT_CH_SEL_2) tr_info("CH_SEL_2");
if (feat & HCI_LE_SUP_FEAT_LE_POWER_CLASS_1) tr_info("LE_POWER_CLASS_1");
if (feat & HCI_LE_SUP_FEAT_MIN_NUN_USED_CHAN) tr_info("MIN_NUN_USED_CHAN");
if (feat & HCI_LE_SUP_FEAT_CONN_CTE_REQ) tr_info("CONN_CTE_REQ");
if (feat & HCI_LE_SUP_FEAT_CONN_CTE_RSP) tr_info("CONN_CTE_RSP");
if (feat & HCI_LE_SUP_FEAT_CONNLESS_CTE_TRANS) tr_info("CONNLESS_CTE_TRANS");
if (feat & HCI_LE_SUP_FEAT_CONNLESS_CTE_RECV) tr_info("CONNLESS_CTE_RECV");
if (feat & HCI_LE_SUP_FEAT_ANTENNA_SWITCH_AOD) tr_info("ANTENNA_SWITCH_AOD");
if (feat & HCI_LE_SUP_FEAT_ANTENNA_SWITCH_AOA) tr_info("ANTENNA_SWITCH_AOA");
if (feat & HCI_LE_SUP_FEAT_RECV_CTE) tr_info("RECV_CTE");
if (feat & HCI_LE_SUP_FEAT_PAST_SENDER) tr_info("PAST_SENDER");
if (feat & HCI_LE_SUP_FEAT_PAST_RECIPIENT) tr_info("PAST_RECIPIENT");
if (feat & HCI_LE_SUP_FEAT_SCA_UPDATE) tr_info("SCA_UPDATE");
if (feat & HCI_LE_SUP_FEAT_REMOTE_PUB_KEY_VALIDATION) tr_info("REMOTE_PUB_KEY_VALIDATION");
if (feat & HCI_LE_SUP_FEAT_CIS_MASTER) tr_info("CIS_MASTER");
if (feat & HCI_LE_SUP_FEAT_CIS_SLAVE) tr_info("CIS_SLAVE");
if (feat & HCI_LE_SUP_FEAT_ISO_BROADCASTER) tr_info("ISO_BROADCASTER");
if (feat & HCI_LE_SUP_FEAT_ISO_SYNC_RECEIVER) tr_info("ISO_SYNC_RECEIVER");
if (feat & HCI_LE_SUP_FEAT_ISO_HOST_SUPPORT) tr_info("ISO_HOST_SUPPORT");
if (feat & HCI_LE_SUP_FEAT_POWER_CONTROL_REQUEST) tr_info("POWER_CONTROL_REQUEST");
if (feat & HCI_LE_SUP_FEAT_POWER_CHANGE_IND) tr_info("POWER_CHANGE_IND");
if (feat & HCI_LE_SUP_FEAT_PATH_LOSS_MONITOR) tr_info("PATH_LOSS_MONITOR");
#else // MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
tr_info("%s", tr_array((uint8_t*)&feat, 4));
#endif // MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
}
const char* hci_opcode_to_string(uint16_t opcode)
{
#if MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
const char* ret = "UNKNOWN OPCODE";
switch (opcode) {
case HCI_OPCODE_NOP: ret = "HCI_OPCODE_NOP"; break;
case HCI_OPCODE_DISCONNECT: ret = "HCI_OPCODE_DISCONNECT"; break;
case HCI_OPCODE_READ_REMOTE_VER_INFO: ret = "HCI_OPCODE_READ_REMOTE_VER_INFO"; break;
case HCI_OPCODE_SET_EVENT_MASK: ret = "HCI_OPCODE_SET_EVENT_MASK"; break;
case HCI_OPCODE_RESET: ret = "HCI_OPCODE_RESET"; break;
case HCI_OPCODE_READ_TX_PWR_LVL: ret = "HCI_OPCODE_READ_TX_PWR_LVL"; break;
case HCI_OPCODE_SET_EVENT_MASK_PAGE2: ret = "HCI_OPCODE_SET_EVENT_MASK_PAGE2"; break;
case HCI_OPCODE_READ_AUTH_PAYLOAD_TO: ret = "HCI_OPCODE_READ_AUTH_PAYLOAD_TO"; break;
case HCI_OPCODE_WRITE_AUTH_PAYLOAD_TO: ret = "HCI_OPCODE_WRITE_AUTH_PAYLOAD_TO"; break;
case HCI_OPCODE_CONFIG_DATA_PATH: ret = "HCI_OPCODE_CONFIG_DATA_PATH"; break;
case HCI_OPCODE_READ_LOCAL_VER_INFO: ret = "HCI_OPCODE_READ_LOCAL_VER_INFO"; break;
case HCI_OPCODE_READ_LOCAL_SUP_CMDS: ret = "HCI_OPCODE_READ_LOCAL_SUP_CMDS"; break;
case HCI_OPCODE_READ_LOCAL_SUP_FEAT: ret = "HCI_OPCODE_READ_LOCAL_SUP_FEAT"; break;
case HCI_OPCODE_READ_BUF_SIZE: ret = "HCI_OPCODE_READ_BUF_SIZE"; break;
case HCI_OPCODE_READ_BD_ADDR: ret = "HCI_OPCODE_READ_BD_ADDR"; break;
case HCI_OPCODE_READ_LOCAL_SUP_CODECS: ret = "HCI_OPCODE_READ_LOCAL_SUP_CODECS"; break;
case HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP: ret = "HCI_OPCODE_READ_LOCAL_SUP_CODEC_CAP"; break;
case HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY: ret = "HCI_OPCODE_READ_LOCAL_SUP_CONTROLLER_DLY"; break;
case HCI_OPCODE_READ_RSSI: ret = "HCI_OPCODE_READ_RSSI"; break;
case HCI_OPCODE_LE_SET_EVENT_MASK: ret = "HCI_OPCODE_LE_SET_EVENT_MASK"; break;
case HCI_OPCODE_LE_READ_BUF_SIZE: ret = "HCI_OPCODE_LE_READ_BUF_SIZE"; break;
case HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT: ret = "HCI_OPCODE_LE_READ_LOCAL_SUP_FEAT"; break;
case HCI_OPCODE_LE_SET_RAND_ADDR: ret = "HCI_OPCODE_LE_SET_RAND_ADDR"; break;
case HCI_OPCODE_LE_SET_ADV_PARAM: ret = "HCI_OPCODE_LE_SET_ADV_PARAM"; break;
case HCI_OPCODE_LE_READ_ADV_TX_POWER: ret = "HCI_OPCODE_LE_READ_ADV_TX_POWER"; break;
case HCI_OPCODE_LE_SET_ADV_DATA: ret = "HCI_OPCODE_LE_SET_ADV_DATA"; break;
case HCI_OPCODE_LE_SET_SCAN_RESP_DATA: ret = "HCI_OPCODE_LE_SET_SCAN_RESP_DATA"; break;
case HCI_OPCODE_LE_SET_ADV_ENABLE: ret = "HCI_OPCODE_LE_SET_ADV_ENABLE"; break;
case HCI_OPCODE_LE_SET_SCAN_PARAM: ret = "HCI_OPCODE_LE_SET_SCAN_PARAM"; break;
case HCI_OPCODE_LE_SET_SCAN_ENABLE: ret = "HCI_OPCODE_LE_SET_SCAN_ENABLE"; break;
case HCI_OPCODE_LE_CREATE_CONN: ret = "HCI_OPCODE_LE_CREATE_CONN"; break;
case HCI_OPCODE_LE_CREATE_CONN_CANCEL: ret = "HCI_OPCODE_LE_CREATE_CONN_CANCEL"; break;
case HCI_OPCODE_LE_READ_WHITE_LIST_SIZE: ret = "HCI_OPCODE_LE_READ_WHITE_LIST_SIZE"; break;
case HCI_OPCODE_LE_CLEAR_WHITE_LIST: ret = "HCI_OPCODE_LE_CLEAR_WHITE_LIST"; break;
case HCI_OPCODE_LE_ADD_DEV_WHITE_LIST: ret = "HCI_OPCODE_LE_ADD_DEV_WHITE_LIST"; break;
case HCI_OPCODE_LE_REMOVE_DEV_WHITE_LIST: ret = "HCI_OPCODE_LE_REMOVE_DEV_WHITE_LIST"; break;
case HCI_OPCODE_LE_CONN_UPDATE: ret = "HCI_OPCODE_LE_CONN_UPDATE"; break;
case HCI_OPCODE_LE_SET_HOST_CHAN_CLASS: ret = "HCI_OPCODE_LE_SET_HOST_CHAN_CLASS"; break;
case HCI_OPCODE_LE_READ_CHAN_MAP: ret = "HCI_OPCODE_LE_READ_CHAN_MAP"; break;
case HCI_OPCODE_LE_READ_REMOTE_FEAT: ret = "HCI_OPCODE_LE_READ_REMOTE_FEAT"; break;
case HCI_OPCODE_LE_ENCRYPT: ret = "HCI_OPCODE_LE_ENCRYPT"; break;
case HCI_OPCODE_LE_RAND: ret = "HCI_OPCODE_LE_RAND"; break;
case HCI_OPCODE_LE_START_ENCRYPTION: ret = "HCI_OPCODE_LE_START_ENCRYPTION"; break;
case HCI_OPCODE_LE_LTK_REQ_REPL: ret = "HCI_OPCODE_LE_LTK_REQ_REPL"; break;
case HCI_OPCODE_LE_LTK_REQ_NEG_REPL: ret = "HCI_OPCODE_LE_LTK_REQ_NEG_REPL"; break;
case HCI_OPCODE_LE_READ_SUP_STATES: ret = "HCI_OPCODE_LE_READ_SUP_STATES"; break;
case HCI_OPCODE_LE_RECEIVER_TEST: ret = "HCI_OPCODE_LE_RECEIVER_TEST"; break;
case HCI_OPCODE_LE_TRANSMITTER_TEST: ret = "HCI_OPCODE_LE_TRANSMITTER_TEST"; break;
case HCI_OPCODE_LE_TEST_END: ret = "HCI_OPCODE_LE_TEST_END"; break;
/* Version 4.1 */
case HCI_OPCODE_LE_REM_CONN_PARAM_REP: ret = "HCI_OPCODE_LE_REM_CONN_PARAM_REP"; break;
case HCI_OPCODE_LE_REM_CONN_PARAM_NEG_REP: ret = "HCI_OPCODE_LE_REM_CONN_PARAM_NEG_REP"; break;
/* Version 4.2 */
case HCI_OPCODE_LE_SET_DATA_LEN: ret = "HCI_OPCODE_LE_SET_DATA_LEN"; break;
case HCI_OPCODE_LE_READ_DEF_DATA_LEN: ret = "HCI_OPCODE_LE_READ_DEF_DATA_LEN"; break;
case HCI_OPCODE_LE_WRITE_DEF_DATA_LEN: ret = "HCI_OPCODE_LE_WRITE_DEF_DATA_LEN"; break;
case HCI_OPCODE_LE_READ_LOCAL_P256_PUB_KEY: ret = "HCI_OPCODE_LE_READ_LOCAL_P256_PUB_KEY"; break;
case HCI_OPCODE_LE_GENERATE_DHKEY: ret = "HCI_OPCODE_LE_GENERATE_DHKEY"; break;
case HCI_OPCODE_LE_ADD_DEV_RES_LIST: ret = "HCI_OPCODE_LE_ADD_DEV_RES_LIST"; break;
case HCI_OPCODE_LE_REMOVE_DEV_RES_LIST: ret = "HCI_OPCODE_LE_REMOVE_DEV_RES_LIST"; break;
case HCI_OPCODE_LE_CLEAR_RES_LIST: ret = "HCI_OPCODE_LE_CLEAR_RES_LIST"; break;
case HCI_OPCODE_LE_READ_RES_LIST_SIZE: ret = "HCI_OPCODE_LE_READ_RES_LIST_SIZE"; break;
case HCI_OPCODE_LE_READ_PEER_RES_ADDR: ret = "HCI_OPCODE_LE_READ_PEER_RES_ADDR"; break;
case HCI_OPCODE_LE_READ_LOCAL_RES_ADDR: ret = "HCI_OPCODE_LE_READ_LOCAL_RES_ADDR"; break;
case HCI_OPCODE_LE_SET_ADDR_RES_ENABLE: ret = "HCI_OPCODE_LE_SET_ADDR_RES_ENABLE"; break;
case HCI_OPCODE_LE_SET_RES_PRIV_ADDR_TO: ret = "HCI_OPCODE_LE_SET_RES_PRIV_ADDR_TO"; break;
case HCI_OPCODE_LE_READ_MAX_DATA_LEN: ret = "HCI_OPCODE_LE_READ_MAX_DATA_LEN"; break;
/* Version 5.0 */
case HCI_OPCODE_LE_READ_PHY: ret = "HCI_OPCODE_LE_READ_PHY"; break;
case HCI_OPCODE_LE_SET_DEF_PHY: ret = "HCI_OPCODE_LE_SET_DEF_PHY"; break;
case HCI_OPCODE_LE_SET_PHY: ret = "HCI_OPCODE_LE_SET_PHY"; break;
case HCI_OPCODE_LE_ENHANCED_RECEIVER_TEST: ret = "HCI_OPCODE_LE_ENHANCED_RECEIVER_TEST"; break;
case HCI_OPCODE_LE_ENHANCED_TRANSMITTER_TEST: ret = "HCI_OPCODE_LE_ENHANCED_TRANSMITTER_TEST"; break;
case HCI_OPCODE_LE_SET_ADV_SET_RAND_ADDR: ret = "HCI_OPCODE_LE_SET_ADV_SET_RAND_ADDR"; break;
case HCI_OPCODE_LE_SET_EXT_ADV_PARAM: ret = "HCI_OPCODE_LE_SET_EXT_ADV_PARAM"; break;
case HCI_OPCODE_LE_SET_EXT_ADV_DATA: ret = "HCI_OPCODE_LE_SET_EXT_ADV_DATA"; break;
case HCI_OPCODE_LE_SET_EXT_SCAN_RESP_DATA: ret = "HCI_OPCODE_LE_SET_EXT_SCAN_RESP_DATA"; break;
case HCI_OPCODE_LE_SET_EXT_ADV_ENABLE: ret = "HCI_OPCODE_LE_SET_EXT_ADV_ENABLE"; break;
case HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN: ret = "HCI_OPCODE_LE_READ_MAX_ADV_DATA_LEN"; break;
case HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS: ret = "HCI_OPCODE_LE_READ_NUM_SUP_ADV_SETS"; break;
case HCI_OPCODE_LE_REMOVE_ADV_SET: ret = "HCI_OPCODE_LE_REMOVE_ADV_SET"; break;
case HCI_OPCODE_LE_CLEAR_ADV_SETS: ret = "HCI_OPCODE_LE_CLEAR_ADV_SETS"; break;
case HCI_OPCODE_LE_SET_PER_ADV_PARAM: ret = "HCI_OPCODE_LE_SET_PER_ADV_PARAM"; break;
case HCI_OPCODE_LE_SET_PER_ADV_DATA: ret = "HCI_OPCODE_LE_SET_PER_ADV_DATA"; break;
case HCI_OPCODE_LE_SET_PER_ADV_ENABLE: ret = "HCI_OPCODE_LE_SET_PER_ADV_ENABLE"; break;
case HCI_OPCODE_LE_SET_EXT_SCAN_PARAM: ret = "HCI_OPCODE_LE_SET_EXT_SCAN_PARAM"; break;
case HCI_OPCODE_LE_SET_EXT_SCAN_ENABLE: ret = "HCI_OPCODE_LE_SET_EXT_SCAN_ENABLE"; break;
case HCI_OPCODE_LE_EXT_CREATE_CONN: ret = "HCI_OPCODE_LE_EXT_CREATE_CONN"; break;
case HCI_OPCODE_LE_PER_ADV_CREATE_SYNC: ret = "HCI_OPCODE_LE_PER_ADV_CREATE_SYNC"; break;
case HCI_OPCODE_LE_PER_ADV_CREATE_SYNC_CANCEL: ret = "HCI_OPCODE_LE_PER_ADV_CREATE_SYNC_CANCEL"; break;
case HCI_OPCODE_LE_PER_ADV_TERMINATE_SYNC: ret = "HCI_OPCODE_LE_PER_ADV_TERMINATE_SYNC"; break;
case HCI_OPCODE_LE_ADD_DEV_PER_ADV_LIST: ret = "HCI_OPCODE_LE_ADD_DEV_PER_ADV_LIST"; break;
case HCI_OPCODE_LE_REMOVE_DEV_PER_ADV_LIST: ret = "HCI_OPCODE_LE_REMOVE_DEV_PER_ADV_LIST"; break;
case HCI_OPCODE_LE_CLEAR_PER_ADV_LIST: ret = "HCI_OPCODE_LE_CLEAR_PER_ADV_LIST"; break;
case HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE: ret = "HCI_OPCODE_LE_READ_PER_ADV_LIST_SIZE"; break;
case HCI_OPCODE_LE_READ_TX_POWER: ret = "HCI_OPCODE_LE_READ_TX_POWER"; break;
case HCI_OPCODE_LE_WRITE_RF_PATH_COMP: ret = "HCI_OPCODE_LE_WRITE_RF_PATH_COMP"; break;
case HCI_OPCODE_LE_READ_RF_PATH_COMP: ret = "HCI_OPCODE_LE_READ_RF_PATH_COMP"; break;
case HCI_OPCODE_LE_SET_PRIVACY_MODE: ret = "HCI_OPCODE_LE_SET_PRIVACY_MODE"; break;
/* Version 5.1 */
case HCI_OPCODE_LE_RECEIVER_TEST_V3: ret = "HCI_OPCODE_LE_RECEIVER_TEST_V3"; break;
case HCI_OPCODE_LE_TRANSMITTER_TEST_V3: ret = "HCI_OPCODE_LE_TRANSMITTER_TEST_V3"; break;
case HCI_OPCODE_LE_SET_CONNLESS_CTE_TX_PARAMS: ret = "HCI_OPCODE_LE_SET_CONNLESS_CTE_TX_PARAMS"; break;
case HCI_OPCODE_LE_SET_CONNLESS_CTE_TX_ENABLE: ret = "HCI_OPCODE_LE_SET_CONNLESS_CTE_TX_ENABLE"; break;
case HCI_OPCODE_LE_SET_CONNLESS_IQ_SAMP_ENABLE: ret = "HCI_OPCODE_LE_SET_CONNLESS_IQ_SAMP_ENABLE"; break;
case HCI_OPCODE_LE_SET_CONN_CTE_RX_PARAMS: ret = "HCI_OPCODE_LE_SET_CONN_CTE_RX_PARAMS"; break;
case HCI_OPCODE_LE_SET_CONN_CTE_TX_PARAMS: ret = "HCI_OPCODE_LE_SET_CONN_CTE_TX_PARAMS"; break;
case HCI_OPCODE_LE_CONN_CTE_REQ_ENABLE: ret = "HCI_OPCODE_LE_CONN_CTE_REQ_ENABLE"; break;
case HCI_OPCODE_LE_CONN_CTE_RSP_ENABLE: ret = "HCI_OPCODE_LE_CONN_CTE_RSP_ENABLE"; break;
case HCI_OPCODE_LE_READ_ANTENNA_INFO: ret = "HCI_OPCODE_LE_READ_ANTENNA_INFO"; break;
case HCI_OPCODE_LE_SET_PER_ADV_RCV_ENABLE: ret = "HCI_OPCODE_LE_SET_PER_ADV_RCV_ENABLE"; break;
case HCI_OPCODE_LE_PER_ADV_SYNC_TRANSFER: ret = "HCI_OPCODE_LE_PER_ADV_SYNC_TRANSFER"; break;
case HCI_OPCODE_LE_PER_ADV_SET_INFO_TRANSFER: ret = "HCI_OPCODE_LE_PER_ADV_SET_INFO_TRANSFER"; break;
case HCI_OPCODE_LE_SET_PAST_PARAM: ret = "HCI_OPCODE_LE_SET_PAST_PARAM"; break;
case HCI_OPCODE_LE_SET_DEFAULT_PAST_PARAM: ret = "HCI_OPCODE_LE_SET_DEFAULT_PAST_PARAM"; break;
case HCI_OPCODE_LE_GENERATE_DHKEY_V2: ret = "HCI_OPCODE_LE_GENERATE_DHKEY_V2"; break;
case HCI_OPCODE_LE_MODIFY_SLEEP_CLK_ACC: ret = "HCI_OPCODE_LE_MODIFY_SLEEP_CLK_ACC"; break;
/* Version 5.2 */
case HCI_OPCODE_LE_READ_BUF_SIZE_V2: ret = "HCI_OPCODE_LE_READ_BUF_SIZE_V2"; break;
case HCI_OPCODE_LE_READ_ISO_TX_SYNC: ret = "HCI_OPCODE_LE_READ_ISO_TX_SYNC"; break;
case HCI_OPCODE_LE_SET_CIG_PARAMS: ret = "HCI_OPCODE_LE_SET_CIG_PARAMS"; break;
case HCI_OPCODE_LE_SET_CIG_PARAMS_TEST: ret = "HCI_OPCODE_LE_SET_CIG_PARAMS_TEST"; break;
case HCI_OPCODE_LE_CREATE_CIS: ret = "HCI_OPCODE_LE_CREATE_CIS"; break;
case HCI_OPCODE_LE_REMOVE_CIG: ret = "HCI_OPCODE_LE_REMOVE_CIG"; break;
case HCI_OPCODE_LE_ACCEPT_CIS_REQ: ret = "HCI_OPCODE_LE_ACCEPT_CIS_REQ"; break;
case HCI_OPCODE_LE_REJECT_CIS_REQ: ret = "HCI_OPCODE_LE_REJECT_CIS_REQ"; break;
case HCI_OPCODE_LE_CREATE_BIG: ret = "HCI_OPCODE_LE_CREATE_BIG"; break;
case HCI_OPCODE_LE_CREATE_BIG_TEST: ret = "HCI_OPCODE_LE_CREATE_BIG_TEST"; break;
case HCI_OPCODE_LE_TERMINATE_BIG: ret = "HCI_OPCODE_LE_TERMINATE_BIG"; break;
case HCI_OPCODE_LE_BIG_CREATE_SYNC: ret = "HCI_OPCODE_LE_BIG_CREATE_SYNC"; break;
case HCI_OPCODE_LE_BIG_TERMINATE_SYNC: ret = "HCI_OPCODE_LE_BIG_TERMINATE_SYNC"; break;
case HCI_OPCODE_LE_REQUEST_PEER_SCA: ret = "HCI_OPCODE_LE_REQUEST_PEER_SCA"; break;
case HCI_OPCODE_LE_SETUP_ISO_DATA_PATH: ret = "HCI_OPCODE_LE_SETUP_ISO_DATA_PATH"; break;
case HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH: ret = "HCI_OPCODE_LE_REMOVE_ISO_DATA_PATH"; break;
case HCI_OPCODE_LE_ISO_TX_TEST: ret = "HCI_OPCODE_LE_ISO_TX_TEST"; break;
case HCI_OPCODE_LE_ISO_RX_TEST: ret = "HCI_OPCODE_LE_ISO_RX_TEST"; break;
case HCI_OPCODE_LE_ISO_READ_TEST_COUNTERS: ret = "HCI_OPCODE_LE_ISO_READ_TEST_COUNTERS"; break;
case HCI_OPCODE_LE_ISO_TEST_END: ret = "HCI_OPCODE_LE_ISO_TEST_END"; break;
case HCI_OPCODE_LE_SET_HOST_FEATURE: ret = "HCI_OPCODE_LE_SET_HOST_FEATURE"; break;
case HCI_OPCODE_LE_READ_ISO_LINK_QUAL: ret = "HCI_OPCODE_LE_READ_ISO_LINK_QUAL"; break;
case HCI_OPCODE_LE_READ_ENHANCED_TX_POWER: ret = "HCI_OPCODE_LE_READ_ENHANCED_TX_POWER"; break;
case HCI_OPCODE_LE_READ_REMOTE_TX_POWER: ret = "HCI_OPCODE_LE_READ_REMOTE_TX_POWER"; break;
case HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_PARAMS: ret = "HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_PARAMS"; break;
case HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_ENABLE: ret = "HCI_OPCODE_LE_SET_PATH_LOSS_REPORTING_ENABLE"; break;
case HCI_OPCODE_LE_SET_TX_POWER_REPORT_ENABLE: ret = "HCI_OPCODE_LE_SET_TX_POWER_REPORT_ENABLE"; break;
}
#else // MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
static char ret[3] = "00";
sprintf(ret, "%02x", (int)opcode);
#endif // MBED_CONF_BLE_TRACE_HUMAN_READABLE_ENUMS
return ret;
}
#endif //MBED_CONF_MBED_TRACE_ENABLE
} // namespace ble

View File

@ -20,9 +20,23 @@
#include "ble/SecurityManager.h"
#include "mbed-trace/mbed_trace.h"
#include "pal/GapTypes.h"
#include "ble-host/include/dm_api.h"
namespace ble {
#if MBED_CONF_MBED_TRACE_ENABLE
const char* dm_callback_event_to_string(uint8_t event);
void trace_le_supported_features(uint64_t feat);
const char* hci_opcode_to_string(uint16_t opcode);
#endif //MBED_CONF_MBED_TRACE_ENABLE
template<typename T>
static inline const char* tr_as_array(T item)
{
return (mbed_trace_array)((const uint8_t*)&item, sizeof(item));
}
static inline constexpr const char* to_string(bool v)
{
if (v) {

View File

@ -29,4 +29,5 @@ target_sources(mbed-ble-cordio
stack_adaptation/wsf_cs.c
stack_adaptation/wsf_mbed_os_adaptation.c
stack_adaptation/wsf_os.c
stack_adaptation/mbed_wsf_trace.c
)

View File

@ -27,6 +27,11 @@
#include "bstream.h"
#include "hci_mbed_os_adaptation.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLHC"
#define HCI_RESET_RAND_CNT 4
namespace ble {
@ -69,12 +74,14 @@ CordioHCIDriver::CordioHCIDriver(CordioHCITransportDriver& transport_driver) :
void CordioHCIDriver::initialize()
{
tr_info("CordioHCIDriver initializing");
_transport_driver.initialize();
do_initialize();
}
void CordioHCIDriver::terminate()
{
tr_info("CordioHCIDriver terminating");
do_terminate();
_transport_driver.terminate();
}
@ -275,19 +282,34 @@ bool CordioHCIDriver::get_random_static_address(ble::address_t& address)
void CordioHCIDriver::signal_reset_sequence_done()
{
tr_debug("Signal cordio HCI reset sequence done");
hci_mbed_os_signal_reset_sequence_done();
}
uint16_t CordioHCIDriver::write(uint8_t type, uint16_t len, uint8_t *pData)
{
#if MBED_CONF_CORDIO_TRACE_HCI_PACKETS
const char *type_prefix;
switch(type) {
case 0x01: type_prefix = "CMD"; break;
case 0x02: type_prefix = "ACL"; break;
/* illegal packet */
default: type_prefix = "ERR"; break;
}
tr_debug("HOST->LL %s %s", type_prefix, trace_array(pData, len));
#endif
return _transport_driver.write(type, len, pData);
}
void CordioHCIDriver::on_host_stack_inactivity()
{
}
void CordioHCIDriver::handle_test_end(bool success, uint16_t packets)
{
MBED_ASSERT(_test_end_handler);
tr_info("LE receiver mode ended (success: %s)", to_string(success));
if (_test_end_handler) {
_test_end_handler(success, packets);
_test_end_handler = nullptr;
@ -299,10 +321,12 @@ ble_error_t CordioHCIDriver::rf_test_start_le_receiver_test(
)
{
if (_test_end_handler) {
tr_warning("Cannot start LE %s test mode - already started", "receiver");
return BLE_ERROR_INVALID_STATE;
}
if (!test_end_handler) {
tr_warning("Cannot start LE %s test mode - invalid handler", "receiver");
return BLE_ERROR_INVALID_PARAM;
}
@ -310,6 +334,8 @@ ble_error_t CordioHCIDriver::rf_test_start_le_receiver_test(
uint8_t *buf = hciCmdAlloc(HCI_OPCODE_LE_RECEIVER_TEST, HCI_LEN_LE_RECEIVER_TEST);
if (buf) {
tr_info("LE %s mode starter on channel %hhd", "receiver", channel);
uint8_t* p = buf + HCI_CMD_HDR_LEN;
UINT8_TO_BSTREAM(p, channel);
hciCmdSend(buf);
@ -325,10 +351,12 @@ ble_error_t CordioHCIDriver::rf_test_start_le_transmitter_test(
)
{
if (_test_end_handler) {
tr_warning("Cannot start LE %s test mode - already started", "transmitter");
return BLE_ERROR_INVALID_STATE;
}
if (!test_end_handler) {
tr_warning("Cannot start LE %s test mode - invalid handler", "transmitter");
return BLE_ERROR_INVALID_PARAM;
}
@ -336,6 +364,8 @@ ble_error_t CordioHCIDriver::rf_test_start_le_transmitter_test(
uint8_t *buf = hciCmdAlloc(HCI_OPCODE_LE_TRANSMITTER_TEST, HCI_LEN_LE_TRANSMITTER_TEST);
if (buf) {
tr_info("LE %s mode starter on channel %hhd", "transmitter", channel);
uint8_t* p = buf + HCI_CMD_HDR_LEN;
UINT8_TO_BSTREAM(p, channel);
UINT8_TO_BSTREAM(p, length);
@ -350,7 +380,10 @@ ble_error_t CordioHCIDriver::rf_test_start_le_transmitter_test(
ble_error_t CordioHCIDriver::rf_test_end()
{
MBED_ASSERT(_test_end_handler);
if (!_test_end_handler) {
tr_info("Cannot end LE transmitter mode test - missing handler (test never started?)");
return BLE_ERROR_INVALID_STATE;
}
@ -358,6 +391,7 @@ ble_error_t CordioHCIDriver::rf_test_end()
if (buf) {
hciCmdSend(buf);
tr_info("LE transmitter mode ended");
return BLE_ERROR_NONE;
}

View File

@ -21,6 +21,11 @@
#include "ble/driver/CordioHCITransportDriver.h"
#include "ble/driver/CordioHCIDriver.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLHC"
extern "C" void hciTrSerialRxIncoming(uint8_t *pBuf, uint8_t len);
namespace ble {
@ -40,6 +45,7 @@ void CordioHCITransportDriver::on_data_received(uint8_t* data, uint16_t len)
void CordioHCITransportDriver::set_data_received_handler(data_received_handler_t handler)
{
MBED_ASSERT(handler);
data_received_handler = handler;
}

View File

@ -81,6 +81,15 @@
"help": "Check connection complete event if it needs the addresses swapped due to bug in controller",
"value": null,
"macro_name": "CORDIO_RPA_SWAP_WORKAROUND"
},
"trace-hci-packets": {
"help": "If tracing is enabled at level DEBUG traces will include HCI packet traces.",
"value": false
},
"trace-cordio-wsf-traces": {
"help": "If tracing is enabled at level DEBUG traces will include WSF traces from Cordio packet traces.",
"value": false,
"macro_name": "WSF_TRACE_ENABLED"
}
},
"target_overrides": {

View File

@ -52,6 +52,11 @@
#include "hci_drv.h"
#include "bstream.h"
#include "stack_adaptation/mbed_wsf_trace.c"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLE "
using namespace std::chrono;
@ -85,11 +90,21 @@ extern "C" uint16_t hci_mbed_os_drv_write(uint8_t type, uint16_t len, uint8_t *p
extern "C" void hci_mbed_os_start_reset_sequence(void)
{
tr_debug("Cordio HCI reset started");
ble_cordio_get_hci_driver().start_reset_sequence();
}
extern "C" void hci_mbed_os_handle_reset_sequence(uint8_t *msg)
{
#if MBED_CONF_MBED_TRACE_ENABLE
if (*msg == HCI_CMD_CMPL_EVT) {
uint16_t opcode;
uint8_t *peek_msg = msg + (HCI_EVT_HDR_LEN + 1 /* skip num packets */);
BSTREAM_TO_UINT16(opcode, peek_msg);
tr_debug("Reset sequence command complete: %s", ble::hci_opcode_to_string(opcode));
}
#endif // MBED_CONF_MBED_TRACE_ENABLE
ble_cordio_get_hci_driver().handle_reset_sequence(msg);
}
@ -142,6 +157,7 @@ ble_error_t BLEInstanceBase::init(
{
switch (initialization_status) {
case NOT_INITIALIZED:
tr_info("Initialising BLE instance");
_timer.reset();
_timer.start();
_event_queue.initialize(this);
@ -150,6 +166,7 @@ ble_error_t BLEInstanceBase::init(
return BLE_ERROR_NONE;
case INITIALIZING:
tr_warning("Already initialising BLE instance");
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
case INITIALIZED:
@ -167,6 +184,7 @@ bool BLEInstanceBase::hasInitialized() const
ble_error_t BLEInstanceBase::shutdown()
{
tr_info("shutting down BLE");
if (initialization_status != INITIALIZED) {
return BLE_ERROR_INITIALIZATION_INCOMPLETE;
}
@ -343,6 +361,7 @@ void BLEInstanceBase::processEvents()
void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg)
{
if (msg == nullptr) {
tr_warning("stack_handler received NULL message");
return;
}
@ -366,17 +385,26 @@ void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg)
};
#if BLE_FEATURE_EXTENDED_ADVERTISING
// initialize extended module if supported
tr_info("Reset sequence complete. Controller supported features:");
#if MBED_CONF_MBED_TRACE_ENABLE
trace_le_supported_features(HciGetLeSupFeat());
#endif // MBED_CONF_MBED_TRACE_ENABLE
tr_info("Initialising extended features");
if (HciGetLeSupFeat() & HCI_LE_SUP_FEAT_LE_EXT_ADV) {
#if BLE_ROLE_BROADCASTER
tr_info("DmExtAdvInit");
DmExtAdvInit();
#endif // BLE_ROLE_BROADCASTER
#if BLE_ROLE_OBSERVER
tr_info("DmExtScanInit");
DmExtScanInit();
#endif // BLE_ROLE_OBSERVER
#if BLE_ROLE_CENTRAL
tr_info("DmExtConnMasterInit");
DmExtConnMasterInit();
#endif // BLE_ROLE_CENTRAL
#if BLE_ROLE_PERIPHERAL
tr_info("DmExtConnSlaveInit");
DmExtConnSlaveInit();
#endif // BLE_ROLE_PERIPHERAL
}
@ -394,6 +422,7 @@ void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg)
// upcast to unhandled command complete event to access the payload
hciUnhandledCmdCmplEvt_t *unhandled = (hciUnhandledCmdCmplEvt_t *) msg;
if (unhandled->hdr.status == HCI_SUCCESS && unhandled->hdr.param == HCI_OPCODE_LE_TEST_END) {
tr_info("Host received HCI_OPCODE_LE_TEST_END from controller - end test mode");
// unhandled events are not parsed so we need to parse the payload ourselves
uint8_t status;
uint16_t packet_number;
@ -414,6 +443,8 @@ void BLEInstanceBase::stack_handler(wsfEventMask_t event, wsfMsgHdr_t *msg)
void BLEInstanceBase::device_manager_cb(dmEvt_t *dm_event)
{
tr_debug("stack_handler received %s", dm_callback_event_to_string(dm_event->hdr.event));
#if BLE_FEATURE_CONNECTABLE
if (dm_event->hdr.status == HCI_SUCCESS && dm_event->hdr.event == DM_CONN_DATA_LEN_CHANGE_IND) {
// this event can only happen after a connection has been established therefore gap is present
@ -444,11 +475,13 @@ void BLEInstanceBase::connection_handler(dmEvt_t *dm_event)
switch (dm_event->hdr.event) {
case DM_CONN_OPEN_IND:
tr_debug("Connection %d - Initialise CCC table", connId);
/* set up CCC table with uninitialized (all zero) values */
AttsCccInitTable(connId, nullptr);
break;
case DM_CONN_CLOSE_IND:
/* clear CCC table on connection close */
tr_debug("Connection %d - Clear CCC table", connId);
AttsCccClearTable(connId);
break;
default:
@ -465,10 +498,16 @@ void BLEInstanceBase::stack_setup()
{
MBED_ASSERT(_hci_driver != nullptr);
#if MBED_CONF_MBED_TRACE_ENABLE
wsf_mbed_trace_init();
#endif // MBED_CONF_MBED_TRACE_ENABLE
wsfHandlerId_t handlerId;
buf_pool_desc_t buf_pool_desc = _hci_driver->get_buffer_pool_description();
tr_info("Allocated %d bytes for Cordio", buf_pool_desc.buffer_size);
// use the buffer for the WSF heap
SystemHeapStart = buf_pool_desc.buffer_memory;
SystemHeapSize = buf_pool_desc.buffer_size;
@ -489,6 +528,54 @@ void BLEInstanceBase::stack_setup()
buf_pool_desc.buffer_size - bytes_used);
}
tr_info("BLE features enabled:"
#if BLE_FEATURE_EXTENDED_ADVERTISING
" EXTENDED_ADVERTISING"
#endif
#if BLE_FEATURE_GATT_CLIENT
" GATT_CLIENT"
#endif
#if BLE_FEATURE_GATT_SERVER
" GATT_SERVER"
#endif
#if BLE_FEATURE_PERIODIC_ADVERTISING
" PERIODIC_ADVERTISING"
#endif
#if BLE_FEATURE_PHY_MANAGEMENT
" PHY_MANAGEMENT"
#endif
#if BLE_FEATURE_PRIVACY
" PRIVACY"
#endif
#if BLE_FEATURE_SECURE_CONNECTIONS
" SECURE_CONNECTIONS"
#endif
#if BLE_FEATURE_SECURITY
" SECURITY"
#endif
#if BLE_FEATURE_SIGNING
" SIGNING"
#endif
#if BLE_FEATURE_WHITELIST
" WHITELIST"
#endif
);
tr_info("BLE roles enabled:"
#if BLE_ROLE_PERIPHERAL
" PERIPHERAL"
#elif BLE_ROLE_BROADCASTER
" BROADCASTER"
#endif
#if BLE_ROLE_CENTRAL
" CENTRAL"
#elif BLE_ROLE_OBSERVER
" OBSERVER"
#endif
);
tr_info("Initialising Cordio host stack");
WsfTimerInit();
// Note: SecInit required for RandInit.
@ -502,9 +589,11 @@ void BLEInstanceBase::stack_setup()
#endif
handlerId = WsfOsSetNextHandler(HciHandler);
tr_debug("HCI handler id: %x", handlerId);
HciHandlerInit(handlerId);
handlerId = WsfOsSetNextHandler(DmHandler);
tr_debug("DM handler id: %x", handlerId);
#if BLE_ROLE_BROADCASTER
DmAdvInit();
@ -546,6 +635,7 @@ void BLEInstanceBase::stack_setup()
#if BLE_ROLE_PERIPHERAL
handlerId = WsfOsSetNextHandler(L2cSlaveHandler);
tr_debug("L2C slave handler id: %x", handlerId);
L2cSlaveHandlerInit(handlerId);
#endif
@ -563,6 +653,7 @@ void BLEInstanceBase::stack_setup()
#if BLE_FEATURE_ATT
handlerId = WsfOsSetNextHandler(AttHandler);
tr_debug("ATT handler id: %x", handlerId);
AttHandlerInit(handlerId);
#if BLE_FEATURE_GATT_SERVER
@ -587,6 +678,7 @@ void BLEInstanceBase::stack_setup()
#if BLE_FEATURE_SECURITY
handlerId = WsfOsSetNextHandler(SmpHandler);
tr_debug("SMP handler id: %x", handlerId);
SmpHandlerInit(handlerId);
#if BLE_ROLE_PERIPHERAL
@ -606,6 +698,7 @@ void BLEInstanceBase::stack_setup()
#endif // BLE_FEATURE_SECURITY
stack_handler_id = WsfOsSetNextHandler(&BLEInstanceBase::stack_handler);
tr_debug("stack handler id: %x", stack_handler_id);
HciSetMaxRxAclLen(MBED_CONF_CORDIO_RX_ACL_BUFFER_SIZE);

View File

@ -203,10 +203,7 @@ PalPrivateAddressController& PalPrivateAddressController::instance()
bool PalPrivateAddressController::cordio_handler(const wsfMsgHdr_t *msg)
{
if (msg == nullptr) {
tr_warning("Privacy handler received null message");
return false;
}
MBED_ASSERT(msg);
auto* handler = instance()._event_handler;

View File

@ -592,11 +592,12 @@ bool PalSecurityManager::sm_handler(const wsfMsgHdr_t *msg)
PalSecurityManager &self = get_security_manager();
PalSecurityManagerEventHandler *handler = self.get_event_handler();
if ((msg == nullptr) || (handler == nullptr)) {
tr_warning("PAL Event handler: invalid message (%p) or handler (%p)", msg, handler);
if (handler == nullptr) {
return false;
}
MBED_ASSERT(msg);
switch (msg->event) {
case DM_SEC_PAIR_CMPL_IND: {
tr_info("Handling event DM_SEC_PAIR_CMPL_IND");

View File

@ -0,0 +1,57 @@
/* mbed Microcontroller Library
* Copyright (c) 2021 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if MBED_CONF_MBED_TRACE_ENABLE
#include "wsf_types.h"
#include "wsf_trace.h"
#include "mbed-trace/mbed_trace.h"
#include "mbed_wsf_trace.h"
#include "platform/mbed_critical.h"
#define TRACE_GROUP "BLCO"
static bool_t wsf_mbed_trace_printf_cb(const uint8_t *pBuf, uint32_t len)
{
#if defined(MBED_TRAP_ERRORS_ENABLED) && MBED_TRAP_ERRORS_ENABLED && defined(MBED_CONF_RTOS_PRESENT)
if (core_util_is_isr_active() || !core_util_are_interrupts_enabled()) {
return FALSE;
}
#endif
/* we need to strip the newline at the end*/
if (len > 1) {
tr_debug("%.*s", (int) (len - 1), pBuf);
}
return TRUE;
}
void wsf_mbed_trace_init()
{
tr_info("WSF Cordio tracing enabled");
WsfTraceEnable(true);
WsfTraceRegisterHandler(&wsf_mbed_trace_printf_cb);
}
#if MBED_CONF_CORDIO_TRACE_HCI_PACKETS
#define TRACE_GROUP "BLHC"
void wsf_mbed_trace_hci(const uint8_t *pBuf, uint32_t len, const uint8_t *prefix)
{
tr_debug("LL->HOST %s %s", prefix, trace_array(pBuf, len));
}
#endif // MBED_CONF_CORDIO_TRACE_HCI_PACKETS
#endif // MBED_CONF_MBED_TRACE_ENABLE

View File

@ -0,0 +1,37 @@
/* mbed Microcontroller Library
* Copyright (c) 2021 ARM Limited
* SPDX-License-Identifier: Apache-2.0
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MBED_WSF_TRACE_H_
#define MBED_WSF_TRACE_H_
#if MBED_CONF_MBED_TRACE_ENABLE
void wsf_mbed_trace_init();
#if MBED_CONF_CORDIO_TRACE_HCI_PACKETS
void wsf_mbed_trace_hci(const uint8_t *pBuf, uint32_t len, const uint8_t *prefix);
#define HCI_PDUMP_CMD(len, pBuf) wsf_mbed_trace_hci(len, pBuf, "CMD")
#define HCI_PDUMP_EVT(len, pBuf) wsf_mbed_trace_hci(len, pBuf, "EVT")
#define HCI_PDUMP_TX_ACL(len, pBuf) wsf_mbed_trace_hci(len, pBuf, "ACL_TX")
#define HCI_PDUMP_RX_ACL(len, pBuf) wsf_mbed_trace_hci(len, pBuf, "ACL_RX")
#define HCI_PDUMP_TX_ISO(len, pBuf) wsf_mbed_trace_hci(len, pBuf, "ISO_TX")
#define HCI_PDUMP_RX_ISO(len, pBuf) wsf_mbed_trace_hci(len, pBuf, "ISO_RX")
#endif // MBED_CONF_CORDIO_TRACE_HCI_PACKETS
#endif // MBED_CONF_MBED_TRACE_ENABLE
#endif // MBED_WSF_TRACE_H_

View File

@ -20,6 +20,11 @@
#include "FileSecurityDb.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLDB"
namespace ble {
const uint16_t DB_VERSION = 1;
@ -73,6 +78,7 @@ typedef SecurityDb::entry_handle_t entry_handle_t;
FileSecurityDb::FileSecurityDb(FILE *db_file)
: SecurityDb(),
_db_file(db_file) {
tr_info("File Security DB initialised to store %d entries", get_entry_count());
/* init the offset in entries so they point to file positions */
for (size_t i = 0; i < get_entry_count(); i++) {
_entries[i].file_offset = DB_OFFSET_STORES + i * DB_SIZE_STORE;
@ -87,6 +93,7 @@ FileSecurityDb::~FileSecurityDb()
FILE* FileSecurityDb::open_db_file(const char *db_path)
{
if (!db_path) {
tr_error("Invalid security DB path");
return nullptr;
}
@ -96,9 +103,11 @@ FILE* FileSecurityDb::open_db_file(const char *db_path)
if (!db_file) {
/* file doesn't exist, create it */
db_file = fopen(db_path, "wb+");
tr_warning("Security DB didn't exist, creating new one");
}
if (!db_file) {
tr_error("Failed to create security DB");
/* failed to create a file, abort */
return nullptr;
}
@ -115,9 +124,11 @@ FILE* FileSecurityDb::open_db_file(const char *db_path)
/* if file size differs from database size init the file */
fseek(db_file, 0, SEEK_END);
if (ftell(db_file) != DB_SIZE) {
tr_warning("Invalid security DB, reinit");
init = true;
}
} else {
tr_info("Empty security DB, reinit");
init = true;
}
@ -130,6 +141,7 @@ FILE* FileSecurityDb::open_db_file(const char *db_path)
FILE* FileSecurityDb::erase_db_file(FILE* db_file)
{
tr_info("Erasing security DB");
fseek(db_file, 0, SEEK_SET);
/* zero the file */
@ -137,6 +149,7 @@ FILE* FileSecurityDb::erase_db_file(FILE* db_file)
size_t count = DB_SIZE / 4;
while (count--) {
if (fwrite(&zero, sizeof(zero), 1, db_file) != 1) {
tr_error("Failed to write Security DB to file");
fclose(db_file);
return nullptr;
}
@ -144,6 +157,7 @@ FILE* FileSecurityDb::erase_db_file(FILE* db_file)
if (fflush(db_file)) {
fclose(db_file);
tr_error("Failed to write Security DB to file");
return nullptr;
}
@ -172,6 +186,7 @@ void FileSecurityDb::set_entry_local_ltk(
entry->flags.ltk_sent = true;
tr_info("Write DB entry %d: local ltk %s", get_index(db_handle), tr_as_array(ltk));
db_write(&ltk, entry->file_offset + DB_STORE_OFFSET_LOCAL_KEYS_LTK);
}
@ -186,6 +201,7 @@ void FileSecurityDb::set_entry_local_ediv_rand(
return;
}
tr_info("Write DB entry %d: local ediv %s rand %s", get_index(db_handle), tr_as_array(ediv), tr_as_array(rand));
db_write(&ediv, entry->file_offset + DB_STORE_OFFSET_LOCAL_KEYS_EDIV);
db_write(&rand, entry->file_offset + DB_STORE_OFFSET_LOCAL_KEYS_RAND);
}
@ -206,6 +222,7 @@ void FileSecurityDb::set_entry_peer_ltk(
entry->flags.ltk_stored = true;
tr_info("Write DB entry %d: peer ltk %s", get_index(db_handle), tr_as_array(ltk));
db_write(&ltk, entry->file_offset + DB_STORE_OFFSET_PEER_KEYS_LTK);
}
@ -220,6 +237,7 @@ void FileSecurityDb::set_entry_peer_ediv_rand(
return;
}
tr_info("Write DB entry %d: peer ediv %s rand %s", get_index(db_handle), tr_as_array(ediv), tr_as_array(rand));
db_write(&ediv, entry->file_offset + DB_STORE_OFFSET_PEER_KEYS_EDIV);
db_write(&rand, entry->file_offset + DB_STORE_OFFSET_PEER_KEYS_RAND);
}
@ -236,6 +254,7 @@ void FileSecurityDb::set_entry_peer_irk(
entry->flags.irk_stored = true;
tr_info("Write DB entry %d: peer irk %s", get_index(db_handle), tr_as_array(irk));
db_write(&irk, entry->file_offset + DB_STORE_OFFSET_PEER_IDENTITY_IRK);
}
@ -250,6 +269,7 @@ void FileSecurityDb::set_entry_peer_bdaddr(
return;
}
tr_info("Write DB entry %d: %s peer address %s", get_index(db_handle), address_is_public? "public" : "private", tr_as_array(peer_address));
db_write(&peer_address, entry->file_offset + DB_STORE_OFFSET_PEER_IDENTITY_ADDRESS);
db_write(&address_is_public, entry->file_offset + DB_STORE_OFFSET_PEER_IDENTITY_ADDRESS_IS_PUBLIC);
}
@ -266,6 +286,7 @@ void FileSecurityDb::set_entry_peer_csrk(
entry->flags.csrk_stored = true;
tr_info("Write DB entry %d: peer csrk %s", get_index(db_handle), tr_as_array(csrk));
db_write(&csrk, entry->file_offset + DB_STORE_OFFSET_PEER_SIGNING);
}
@ -285,6 +306,8 @@ void FileSecurityDb::set_local_csrk(
)
{
this->SecurityDb::set_local_csrk(csrk);
tr_info("Write DB: local csrk %s", tr_as_array(csrk));
db_write(&_local_csrk, DB_OFFSET_LOCAL_CSRK);
}
@ -295,6 +318,8 @@ void FileSecurityDb::set_local_identity(
)
{
this->SecurityDb::set_local_identity(irk, identity_address, public_address);
tr_info("Write DB: %s peer address %s", public_address? "public" : "private", tr_as_array(identity_address));
db_write(&_local_identity, DB_OFFSET_LOCAL_IDENTITY);
}
@ -313,6 +338,7 @@ void FileSecurityDb::restore()
return;
}
tr_info("Valid DB file - restoring security DB from file");
db_read(&_local_identity, DB_OFFSET_LOCAL_IDENTITY);
db_read(&_local_csrk, DB_OFFSET_LOCAL_CSRK);
db_read(&_local_sign_counter, DB_OFFSET_LOCAL_SIGN_COUNT);
@ -332,6 +358,7 @@ void FileSecurityDb::sync(entry_handle_t db_handle)
return;
}
tr_info("Synchronising security DB entry %d with file", get_index(db_handle));
db_write(&entry->peer_sign_counter, entry->file_offset + DB_STORE_OFFSET_PEER_SIGNING_COUNT);
db_write(&entry->flags, entry->file_offset + DB_STORE_OFFSET_FLAGS);
db_write(&_local_sign_counter, DB_OFFSET_LOCAL_SIGN_COUNT);
@ -339,6 +366,7 @@ void FileSecurityDb::sync(entry_handle_t db_handle)
void FileSecurityDb::set_restore(bool reload)
{
tr_info("Security DB set to restore on reset: %s", to_string(reload));
db_write(&reload, DB_OFFSET_RESTORE);
}
@ -365,6 +393,8 @@ void FileSecurityDb::reset_entry(entry_handle_t db_entry)
return;
}
tr_info("Reseting security DB entry %d", get_index(db_entry));
fseek(_db_file, entry->file_offset, SEEK_SET);
const uint32_t zero = 0;
size_t count = DB_SIZE_STORE / 4;

View File

@ -24,6 +24,9 @@
#include <stdio.h>
#include "SecurityDb.h"
#include "mbed-trace/mbed_trace.h"
#define TRACE_GROUP "BLDB"
namespace ble {
@ -38,7 +41,11 @@ private:
};
static entry_t* as_entry(entry_handle_t db_handle) {
return reinterpret_cast<entry_t*>(db_handle);
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
if (!entry) {
tr_error("Invalid security DB handle used");
}
return entry;
}
template<class T>
@ -161,6 +168,11 @@ private:
*/
static FILE* erase_db_file(FILE* db_file);
uint8_t get_index(const entry_handle_t db_handle) const
{
return reinterpret_cast<entry_t*>(db_handle) - _entries;
}
private:
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
FILE *_db_file;

View File

@ -19,6 +19,9 @@
#if BLE_SECURITY_DATABASE_KVSTORE
#include "KVStoreSecurityDb.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLDB"
namespace ble {
@ -51,6 +54,7 @@ typedef SecurityDb::entry_handle_t entry_handle_t;
KVStoreSecurityDb::KVStoreSecurityDb()
: SecurityDb() {
tr_info("KFStore Security DB initialised to store " STR(BLE_SECURITY_DATABASE_MAX_ENTRIES) " entries");
memset(_entries, 0, sizeof(_entries));
}
@ -68,11 +72,13 @@ bool KVStoreSecurityDb::open_db()
/* kvstore problem (check if it's been successfully initialised before this call) */
if (ret != MBED_ERROR_ITEM_NOT_FOUND && (ret != MBED_SUCCESS || size != sizeof(uint8_t))) {
tr_error("Failed to read KV store, check if it's initialised");
return false;
}
/* wipe the db if it's the wrong version or it doesn't exist */
if (version != KVSTORESECURITYDB_VERSION) {
tr_warning("Security missing or invalid, reinit");
return erase_db();
}
@ -81,6 +87,7 @@ bool KVStoreSecurityDb::open_db()
bool KVStoreSecurityDb::erase_db()
{
tr_info("Erasing security DB in KV store");
union zero_t {
int dummy; /* we need a dummy for initialisation */
uint8_t buffer[sizeof(SecurityEntryKeys_t)];
@ -111,7 +118,11 @@ bool KVStoreSecurityDb::erase_db()
version = 0;
db_read(&version, DB_VERSION);
return (version == KVSTORESECURITYDB_VERSION);
bool success = (version == KVSTORESECURITYDB_VERSION);
if (!success) {
tr_error("failed to write security DB in KV store");
}
return success;
}
SecurityDistributionFlags_t* KVStoreSecurityDb::get_distribution_flags(
@ -139,6 +150,7 @@ void KVStoreSecurityDb::set_entry_local_ltk(
SecurityEntryKeys_t* current_entry = read_in_entry_local_keys(db_handle);
current_entry->ltk = ltk;
tr_info("Write DB entry %d: local ltk %s", get_index(db_handle), tr_as_array(ltk));
db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, get_index(entry));
}
@ -157,6 +169,7 @@ void KVStoreSecurityDb::set_entry_local_ediv_rand(
current_entry->ediv = ediv;
current_entry->rand = rand;
tr_info("Write DB entry %d: local ediv %s rand %s", get_index(db_handle), tr_as_array(ediv), tr_as_array(rand));
db_write_entry(current_entry, DB_ENTRY_LOCAL_KEYS, get_index(entry));
}
@ -179,6 +192,7 @@ void KVStoreSecurityDb::set_entry_peer_ltk(
SecurityEntryKeys_t* current_entry = read_in_entry_peer_keys(db_handle);
current_entry->ltk = ltk;
tr_info("Write DB entry %d: peer ltk %s", get_index(db_handle), tr_as_array(ltk));
db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, get_index(entry));
}
@ -197,6 +211,7 @@ void KVStoreSecurityDb::set_entry_peer_ediv_rand(
current_entry->ediv = ediv;
current_entry->rand = rand;
tr_info("Write DB entry %d: peer ediv %s rand %s", get_index(db_handle), tr_as_array(ediv), tr_as_array(rand));
db_write_entry(current_entry, DB_ENTRY_PEER_KEYS, get_index(entry));
}
@ -215,6 +230,7 @@ void KVStoreSecurityDb::set_entry_peer_irk(
SecurityEntryIdentity_t* current_entry = read_in_entry_peer_identity(db_handle);
current_entry->irk = irk;
tr_info("Write DB entry %d: peer irk %s", get_index(db_handle), tr_as_array(irk));
db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, get_index(entry));
}
@ -233,6 +249,7 @@ void KVStoreSecurityDb::set_entry_peer_bdaddr(
current_entry->identity_address = peer_address;
current_entry->identity_address_is_public = address_is_public;
tr_info("Write DB entry %d: %s peer address %s", get_index(db_handle), address_is_public? "public" : "private", tr_as_array(peer_address));
db_write_entry(current_entry, DB_ENTRY_PEER_IDENTITY, get_index(entry));
}
@ -251,6 +268,7 @@ void KVStoreSecurityDb::set_entry_peer_csrk(
SecurityEntrySigning_t* current_entry = read_in_entry_peer_signing(db_handle);
current_entry->csrk = csrk;
tr_info("Write DB entry %d: peer csrk %s", get_index(db_handle), tr_as_array(csrk));
db_write_entry(current_entry, DB_ENTRY_PEER_SIGNING, get_index(entry));
}
@ -270,6 +288,7 @@ void KVStoreSecurityDb::set_local_csrk(
)
{
this->SecurityDb::set_local_csrk(csrk);
tr_info("Write DB: local csrk %s", tr_as_array(csrk));
db_write(&_local_csrk, DB_LOCAL_CSRK);
}
@ -280,6 +299,7 @@ void KVStoreSecurityDb::set_local_identity(
)
{
this->SecurityDb::set_local_identity(irk, identity_address, public_address);
tr_info("Write DB: %s peer address %s", public_address? "public" : "private", tr_as_array(identity_address));
db_write(&_local_identity, DB_LOCAL_IDENTITY);
}
@ -296,6 +316,7 @@ void KVStoreSecurityDb::restore()
return;
}
tr_info("Valid DB in KV store - restoring security DB");
db_read(&_entries, DB_ENTRIES);
db_read(&_local_identity, DB_LOCAL_IDENTITY);
db_read(&_local_csrk, DB_LOCAL_CSRK);
@ -309,6 +330,7 @@ void KVStoreSecurityDb::sync(entry_handle_t db_handle)
return;
}
tr_info("Synchronising security DB with KV store");
/* all entries are stored in a single key so we store them all*/
db_write(&_entries, DB_ENTRIES);
db_write(&_local_identity, DB_LOCAL_IDENTITY);
@ -318,6 +340,7 @@ void KVStoreSecurityDb::sync(entry_handle_t db_handle)
void KVStoreSecurityDb::set_restore(bool reload)
{
tr_info("Security DB set to restore on reset: %s", to_string(reload));
db_write(&reload, DB_RESTORE);
}

View File

@ -25,10 +25,13 @@
#include "mbed_error.h"
#include "SecurityDb.h"
#include "mbed-trace/mbed_trace.h"
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
#define TRACE_GROUP "BLDB"
namespace ble {
/** Filesystem implementation */
@ -64,7 +67,11 @@ private:
static constexpr char DB_RESTORE[DB_KEY_SIZE] = { 'r','e','s' };
static entry_t* as_entry(entry_handle_t db_handle) {
return reinterpret_cast<entry_t*>(db_handle);
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
if (!entry) {
tr_error("Invalid security DB handle used");
}
return entry;
}
template<class T>

View File

@ -21,6 +21,15 @@
#include "SecurityDb.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLDB"
#define _STR(x) #x
#define STR(x) _STR(x)
namespace ble {
/** Naive memory implementation for verification. */
@ -37,11 +46,19 @@ private:
static entry_t* as_entry(entry_handle_t db_handle)
{
return reinterpret_cast<entry_t*>(db_handle);
entry_t* entry = reinterpret_cast<entry_t*>(db_handle);
if (!entry) {
tr_error("Invalid security DB handle used");
}
return entry;
}
public:
MemorySecurityDb() : SecurityDb() { }
MemorySecurityDb() : SecurityDb()
{
tr_info("Using memory security DB (capacity " STR(BLE_SECURITY_DATABASE_MAX_ENTRIES) " entries) - no persistence across reset");
}
~MemorySecurityDb() override = default;
SecurityDistributionFlags_t* get_distribution_flags(
@ -59,6 +76,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: local ltk %s", get_index(db_handle), tr_as_array(ltk));
entry->flags.ltk_sent = true;
entry->local_keys.ltk = ltk;
}
@ -71,6 +89,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: local ediv %s rand %s", get_index(db_handle), tr_as_array(ediv), tr_as_array(rand));
entry->local_keys.ediv = ediv;
entry->local_keys.rand = rand;
}
@ -86,6 +105,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: peer ltk %s", get_index(db_handle), tr_as_array(ltk));
entry->peer_keys.ltk = ltk;
entry->flags.ltk_stored = true;
}
@ -98,6 +118,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: peer ediv %s rand %s", get_index(db_handle), tr_as_array(ediv), tr_as_array(rand));
entry->peer_keys.ediv = ediv;
entry->peer_keys.rand = rand;
}
@ -109,6 +130,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: peer irk %s", get_index(db_handle), tr_as_array(irk));
entry->peer_identity.irk = irk;
entry->flags.irk_stored = true;
}
@ -121,6 +143,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: %s peer address %s", get_index(db_handle), address_is_public? "public" : "private", tr_as_array(peer_address));
entry->peer_identity.identity_address = peer_address;
entry->peer_identity.identity_address_is_public = address_is_public;
}
@ -132,6 +155,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: peer csrk %s", get_index(db_handle), tr_as_array(csrk));
entry->flags.csrk_stored = true;
entry->peer_signing.csrk = csrk;
}
@ -143,6 +167,7 @@ public:
) override {
entry_t *entry = as_entry(db_handle);
if (entry) {
tr_info("Write DB entry %d: sign counter %lu", get_index(db_handle), sign_counter);
entry->peer_signing.counter = sign_counter;
}
}
@ -185,6 +210,11 @@ private:
return &entry->peer_signing;
};
uint8_t get_index(const entry_handle_t db_handle) const
{
return reinterpret_cast<entry_t*>(db_handle) - _entries;
}
private:
entry_t _entries[BLE_SECURITY_DATABASE_MAX_ENTRIES];
};

View File

@ -25,6 +25,11 @@
#include "ble/common/BLETypes.h"
#include "ble/Gap.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLDB"
namespace ble {
/**
@ -180,9 +185,11 @@ public:
// Maybe this isn't the correct entry, try to find one that matches
entry_handle_t correct_handle = find_entry_by_peer_ediv_rand(ediv, rand);
if (!correct_handle) {
tr_warn("Failed to find ltk matching given ediv&rand");
cb(*db_handle, NULL);
return;
}
tr_warn("Found ltk matching given ediv&rand but it belonged to a different identity, update entry with new identity");
// Note: keys should never be null as a matching entry has been retrieved
SecurityEntryKeys_t* keys = read_in_entry_local_keys(correct_handle);
MBED_ASSERT(keys);
@ -505,6 +512,7 @@ public:
) {
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
if (db_handle) {
tr_debug("Found old DB entry (connected to peer previously)");
((SecurityDistributionFlags_t*)db_handle)->connected = true;
return db_handle;
}
@ -637,6 +645,7 @@ public:
peer_address_type_t peer_address_type,
const address_t &peer_address
) {
tr_info("Clearing entry for address %s", to_string(peer_address));
entry_handle_t db_handle = find_entry_by_peer_address(peer_address_type, peer_address);
if (db_handle) {
reset_entry(db_handle);
@ -647,6 +656,7 @@ public:
* Remove all entries from the security DB.
*/
virtual void clear_entries() {
tr_info("Clearing all entries");
for (size_t i = 0; i < get_entry_count(); i++) {
entry_handle_t db_handle = get_entry_handle_by_index(i);
reset_entry(db_handle);
@ -777,6 +787,7 @@ private:
*/
virtual SecurityDistributionFlags_t* get_free_entry_flags() {
/* get a free one if available */
tr_debug("Retrieve a disconnected entry to use as a new entry in DB.");
SecurityDistributionFlags_t* match = nullptr;
for (size_t i = 0; i < get_entry_count(); i++) {
entry_handle_t db_handle = get_entry_handle_by_index(i);
@ -790,6 +801,7 @@ private:
&& !flags->ltk_sent
&& !flags->irk_stored) {
/* empty one found, stop looking*/
tr_debug("Using a previously unused entry as a new entry in DB.");
break;
}
}
@ -803,7 +815,7 @@ private:
}
/**
* How many entries can be stored in the databes.
* How many entries can be stored in the database.
* @return max number of entries
*/
virtual uint8_t get_entry_count() = 0;

View File

@ -121,7 +121,7 @@ ble_error_t SecurityManager::init(
bool secure_connections;
_pal.get_secure_connections_support(secure_connections);
tr_debug("Secure connection support: %s", to_string(secure_connection));
tr_debug("Secure connection support: %s", to_string(secure_connections));
_default_authentication.set_bondable(bondable);
_default_authentication.set_mitm(mitm);

View File

@ -42,6 +42,11 @@
#include "rtos/Semaphore.h"
#include "rtos/Mutex.h"
#include "mbed-trace/mbed_trace.h"
#include "common/ble_trace_helpers.h"
#define TRACE_GROUP "BLHC"
#define HCI_RESET_RAND_CNT 4
#define VENDOR_SPECIFIC_EVENT 0xFF

View File

@ -70,9 +70,6 @@
// #undef TRACE_LEVEL_DEBUG
// #define TRACE_LEVEL_DEBUG 0
/* tr_debug : add data content in console print */
#define PRINT_HCI_DATA 0
/******************************************************************************
* BLE config parameters
******************************************************************************/
@ -177,11 +174,6 @@ public:
/* if event is a command complete event */
if (*pMsg == HCI_CMD_CMPL_EVT) {
tr_debug("Command Complete Event Command");
#if (PRINT_HCI_DATA)
for (uint8_t i = 0; i < 20; i++) {
tr_debug(" %02X", *((uint8_t *)pMsg + i));
}
#endif
/* parse parameters */
tr_debug(" HCI_EVT_HDR_LEN=%d", HCI_EVT_HDR_LEN);
pMsg += HCI_EVT_HDR_LEN;
@ -579,11 +571,6 @@ private:
tr_debug(" Type %#x", bleCmdBuf->cmdserial.type);
tr_debug(" Cmd %#x", bleCmdBuf->cmdserial.cmd.cmdcode);
tr_debug(" Len %#x", bleCmdBuf->cmdserial.cmd.plen);
#if (PRINT_HCI_DATA)
for (uint8_t i = 0; i < bleCmdBuf->cmdserial.cmd.plen; i++) {
tr_debug(" %02X", *(((uint8_t *)&bleCmdBuf->cmdserial.cmd.payload) + i));
}
#endif
TL_BLE_SendCmd(NULL, 0); // unused parameters for now
break;
case 2://ACL DATA
@ -597,11 +584,6 @@ private:
memcpy(aclDataBuffer + + sizeof(TL_PacketHeader_t) + sizeof(type), pData, len);
TL_BLE_SendAclData(NULL, 0); // unused parameters for now
tr_info("TX>> BLE ACL");
#if (PRINT_HCI_DATA)
for (uint8_t i = 0; i < len + 1 + 8; i++) {
tr_debug(" %02x", *(((uint8_t *) aclDataBuffer) + i));
}
#endif
break;
}
return len;