From 9a7b3f80b20176cf83e8053d5531cdd128398587 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Mon, 8 Apr 2024 20:16:28 +0800 Subject: [PATCH] feat(bt/common): Add bluerooth hci layer data stream record --- components/bt/CMakeLists.txt | 5 +- components/bt/Kconfig | 25 ++ components/bt/common/hci_log/bt_hci_log.c | 334 ++++++++++++++++++ .../hci_log/include/hci_log/bt_hci_log.h | 108 ++++++ components/bt/common/include/bt_common.h | 18 + components/bt/common/include/bt_user_config.h | 18 + .../bt/host/bluedroid/api/esp_bt_main.c | 12 + components/bt/host/bluedroid/hci/hci_hal_h4.c | 20 +- .../host/nimble/esp-hci/src/esp_nimble_hci.c | 29 ++ 9 files changed, 565 insertions(+), 4 deletions(-) create mode 100644 components/bt/common/hci_log/bt_hci_log.c create mode 100644 components/bt/common/hci_log/include/hci_log/bt_hci_log.h diff --git a/components/bt/CMakeLists.txt b/components/bt/CMakeLists.txt index 4958cf6b44..4d63bb91a1 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -25,10 +25,13 @@ if(CONFIG_BT_ENABLED) list(APPEND include_dirs common/api/include/api common/btc/profile/esp/blufi/include - common/btc/profile/esp/include) + common/btc/profile/esp/include + common/hci_log/include) + list(APPEND srcs "common/btc/core/btc_alarm.c" "common/api/esp_blufi_api.c" + "common/hci_log/bt_hci_log.c" "common/btc/core/btc_manage.c" "common/btc/core/btc_task.c" "common/btc/profile/esp/blufi/blufi_prf.c" diff --git a/components/bt/Kconfig b/components/bt/Kconfig index 8a15de6b86..94761675ad 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -57,6 +57,31 @@ menu "Bluetooth" source "$IDF_PATH/components/bt/host/nimble/Kconfig.in" endmenu + config BT_HCI_LOG_DEBUG_EN + depends on BT_BLUEDROID_ENABLED || BT_NIMBLE_ENABLED + bool "Enable Bluetooth HCI debug mode" + default n + help + This option is used to enable bluetooth debug mode, which saves the hci layer data stream. + + config BT_HCI_LOG_DATA_BUFFER_SIZE + depends on BT_HCI_LOG_DEBUG_EN + int "Size of the cache used for HCI data in Bluetooth HCI debug mode (N*1024 bytes)" + range 1 100 + default 5 + help + This option is to configure the buffer size of the hci data steam cache in hci debug mode. + This is a ring buffer, the new data will overwrite the oldest data if the buffer is full. + + config BT_HCI_LOG_ADV_BUFFER_SIZE + depends on BT_HCI_LOG_DEBUG_EN + int "Size of the cache used for adv report in Bluetooth HCI debug mode (N*1024 bytes)" + range 1 100 + default 8 + help + This option is to configure the buffer size of the hci adv report cache in hci debug mode. + This is a ring buffer, the new data will overwrite the oldest data if the buffer is full. + endmenu menuconfig BLE_MESH diff --git a/components/bt/common/hci_log/bt_hci_log.c b/components/bt/common/hci_log/bt_hci_log.c new file mode 100644 index 0000000000..1cc95a46ce --- /dev/null +++ b/components/bt/common/hci_log/bt_hci_log.c @@ -0,0 +1,334 @@ +/* + * SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include +#include +#include +#include "hci_log/bt_hci_log.h" +#include "bt_common.h" +#include "osi/mutex.h" +#include "esp_attr.h" + +#if (BT_HCI_LOG_INCLUDED == TRUE) +#define BT_HCI_LOG_PRINT_TAG (1) +#define BT_HCI_LOG_DATA_BUF_SIZE (1024 * HCI_LOG_DATA_BUFFER_SIZE) +#define BT_HCI_LOG_ADV_BUF_SIZE (1024 * HCI_LOG_ADV_BUFFER_SIZE) + +typedef struct { + osi_mutex_t mutex_lock; + uint64_t log_record_in; + uint64_t log_record_out; + uint64_t buf_size; + uint8_t *p_hci_log_buffer; + uint8_t index; + bool overflow; +} bt_hci_log_t; + +static const char s_hex_to_char_mapping[16] = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' +}; + +bt_hci_log_t g_bt_hci_log_data_ctl = {0}; +bt_hci_log_t g_bt_hci_log_adv_ctl = {0}; + +esp_err_t bt_hci_log_init(void) +{ + uint8_t *g_bt_hci_log_data_buffer = NULL; + uint8_t *g_bt_hci_log_adv_buffer = NULL; + + g_bt_hci_log_data_buffer = malloc(BT_HCI_LOG_DATA_BUF_SIZE); + if (!g_bt_hci_log_data_buffer) { + return ESP_ERR_NO_MEM; + } + g_bt_hci_log_adv_buffer = malloc(BT_HCI_LOG_ADV_BUF_SIZE); + if (!g_bt_hci_log_adv_buffer) { + if (g_bt_hci_log_data_buffer) { + free(g_bt_hci_log_data_buffer); + g_bt_hci_log_data_buffer = NULL; + } + return ESP_ERR_NO_MEM; + } + + memset(g_bt_hci_log_data_buffer, 0, BT_HCI_LOG_DATA_BUF_SIZE); + memset(g_bt_hci_log_adv_buffer, 0, BT_HCI_LOG_ADV_BUF_SIZE); + + memset(&g_bt_hci_log_data_ctl, 0, sizeof(bt_hci_log_t)); + g_bt_hci_log_data_ctl.buf_size = BT_HCI_LOG_DATA_BUF_SIZE; + g_bt_hci_log_data_ctl.p_hci_log_buffer = g_bt_hci_log_data_buffer; + + memset(&g_bt_hci_log_adv_ctl, 0, sizeof(bt_hci_log_t)); + g_bt_hci_log_adv_ctl.buf_size = BT_HCI_LOG_ADV_BUF_SIZE; + g_bt_hci_log_adv_ctl.p_hci_log_buffer = g_bt_hci_log_adv_buffer; + + osi_mutex_new((osi_mutex_t *)&g_bt_hci_log_data_ctl.mutex_lock); + osi_mutex_new((osi_mutex_t *)&g_bt_hci_log_adv_ctl.mutex_lock); + + return ESP_OK; +} + +esp_err_t bt_hci_log_deinit(void) +{ + if (g_bt_hci_log_data_ctl.p_hci_log_buffer) { + free(g_bt_hci_log_data_ctl.p_hci_log_buffer); + g_bt_hci_log_data_ctl.p_hci_log_buffer = NULL; + } + + if (g_bt_hci_log_adv_ctl.p_hci_log_buffer) { + free(g_bt_hci_log_adv_ctl.p_hci_log_buffer); + g_bt_hci_log_adv_ctl.p_hci_log_buffer = NULL; + } + + osi_mutex_free((osi_mutex_t *)&g_bt_hci_log_data_ctl.mutex_lock); + osi_mutex_free((osi_mutex_t *)&g_bt_hci_log_adv_ctl.mutex_lock); + + memset(&g_bt_hci_log_data_ctl, 0, sizeof(bt_hci_log_t)); + memset(&g_bt_hci_log_adv_ctl, 0, sizeof(bt_hci_log_t)); + + return ESP_OK; +} + +#if (BT_HCI_LOG_PRINT_TAG) +static char IRAM_ATTR *bt_data_type_to_str(uint8_t data_type) +{ + char *tag = NULL; + switch (data_type) + { + case HCI_LOG_DATA_TYPE_COMMAND: + // hci cmd data + tag = "CMD"; + break; + case HCI_LOG_DATA_TYPE_H2C_ACL: + // host to controller hci acl data + tag = "HAL"; + break; + case HCI_LOG_DATA_TYPE_SCO: + // hci sco data + tag = "SCO"; + break; + case HCI_LOG_DATA_TYPE_EVENT: + // hci event + tag = "EVT"; + break; + case HCI_LOG_DATA_TYPE_ADV: + // controller adv report data + tag = "ADV"; + break; + case HCI_LOG_DATA_TYPE_C2H_ACL: + // controller to host hci acl data + tag = "CAL"; + break; + case HCI_LOG_DATA_TYPE_SELF_DEFINE: + // self-defining data + tag = "ST"; + break; + default: + // unknown data type + tag = "UK"; + break; + } + + return tag; +} +#endif + +void bt_hci_log_record_hex(bt_hci_log_t *p_hci_log_ctl, uint8_t *hex, uint8_t hex_len) +{ + uint8_t hci_log_char; + uint8_t *g_hci_log_buffer; + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + while (hex_len--) + { + hci_log_char = ((*hex) >> 4); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = s_hex_to_char_mapping [hci_log_char]; + + if (++ p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + hci_log_char = ((*hex) & 0x0f); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = s_hex_to_char_mapping [hci_log_char]; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = ' '; + + if (++ p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + ++ hex; + } +} + +void bt_hci_log_record_string(bt_hci_log_t *p_hci_log_ctl, char *string) +{ + uint8_t *g_hci_log_buffer; + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + while (*string != '\0') { + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = *string; + ++string; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + } +} + +esp_err_t IRAM_ATTR bt_hci_log_record_data(bt_hci_log_t *p_hci_log_ctl, char *str, uint8_t data_type, uint8_t *data, uint8_t data_len) +{ + osi_mutex_t mutex_lock; + uint8_t *g_hci_log_buffer; + + if (!p_hci_log_ctl->p_hci_log_buffer) { + return ESP_FAIL; + } + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + if (!g_hci_log_buffer) { + return ESP_FAIL; + } + + mutex_lock = p_hci_log_ctl->mutex_lock; + osi_mutex_lock(&mutex_lock, OSI_MUTEX_MAX_TIMEOUT); + +#if (1) + // Add hci data index + bt_hci_log_record_hex(p_hci_log_ctl, &p_hci_log_ctl->index, 1); +#endif + +#if (BT_HCI_LOG_PRINT_TAG) + char *tag = NULL; + tag = bt_data_type_to_str(data_type); + + if (tag) { + bt_hci_log_record_string(p_hci_log_ctl, tag); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = ':'; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + } +#endif + + if (str) { + bt_hci_log_record_string(p_hci_log_ctl, str); + } + + bt_hci_log_record_hex(p_hci_log_ctl, data, data_len); + + g_hci_log_buffer[p_hci_log_ctl->log_record_in] = '\n'; + + if (++p_hci_log_ctl->log_record_in >= p_hci_log_ctl->buf_size) { + p_hci_log_ctl->log_record_in = 0; + } + + if (p_hci_log_ctl->log_record_in == p_hci_log_ctl->log_record_out) { + p_hci_log_ctl->overflow = true; + } + + p_hci_log_ctl->index ++; + + osi_mutex_unlock(&mutex_lock); + + return ESP_OK; +} + +void bt_hci_log_data_show(bt_hci_log_t *p_hci_log_ctl) +{ + volatile uint64_t log_record_in,log_record_out; + uint8_t *g_hci_log_buffer; + + if (!p_hci_log_ctl->p_hci_log_buffer) { + return; + } + + osi_mutex_t mutex_lock = p_hci_log_ctl->mutex_lock; + + osi_mutex_lock(&mutex_lock, OSI_MUTEX_MAX_TIMEOUT); + + log_record_in = p_hci_log_ctl->log_record_in; + log_record_out = p_hci_log_ctl->log_record_out; + + g_hci_log_buffer = p_hci_log_ctl->p_hci_log_buffer; + + if (p_hci_log_ctl->overflow) { + log_record_out = log_record_in; + printf("%c",g_hci_log_buffer[log_record_out]); + + if (++log_record_out >= p_hci_log_ctl->buf_size) { + log_record_out = 0; + } + } + + while (log_record_in != log_record_out) + { + printf("%c",g_hci_log_buffer[log_record_out]); + + if (++log_record_out >= p_hci_log_ctl->buf_size) { + log_record_out = 0; + } + } + + p_hci_log_ctl->log_record_out = log_record_out; + p_hci_log_ctl->overflow = false; + + osi_mutex_unlock(&mutex_lock); +} + +esp_err_t IRAM_ATTR bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint8_t data_len) +{ + return bt_hci_log_record_data(&g_bt_hci_log_data_ctl, NULL, data_type, data, data_len); +} + +esp_err_t IRAM_ATTR bt_hci_log_record_custom_data(char *string, uint8_t *data, uint8_t data_len) +{ + return bt_hci_log_record_data(&g_bt_hci_log_data_ctl, string, HCI_LOG_DATA_TYPE_SELF_DEFINE, data, data_len); +} + +esp_err_t IRAM_ATTR bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len) +{ + return bt_hci_log_record_data(&g_bt_hci_log_adv_ctl, NULL, data_type, data, data_len); +} + +void bt_hci_log_hci_data_show(void) +{ + bt_hci_log_data_show(&g_bt_hci_log_data_ctl); +} + +void bt_hci_log_hci_adv_show(void) +{ + bt_hci_log_data_show(&g_bt_hci_log_adv_ctl); +} + +#endif // (BT_HCI_LOG_INCLUDED == TRUE) diff --git a/components/bt/common/hci_log/include/hci_log/bt_hci_log.h b/components/bt/common/hci_log/include/hci_log/bt_hci_log.h new file mode 100644 index 0000000000..512a307e44 --- /dev/null +++ b/components/bt/common/hci_log/include/hci_log/bt_hci_log.h @@ -0,0 +1,108 @@ +/* + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef __ESP_BT_HCI_LOG_H__ +#define __ESP_BT_HCI_LOG_H__ + +#include "esp_err.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +#define HCI_LOG_DATA_TYPE_COMMAND (1) +#define HCI_LOG_DATA_TYPE_H2C_ACL (2) +#define HCI_LOG_DATA_TYPE_SCO (3) +#define HCI_LOG_DATA_TYPE_EVENT (4) +#define HCI_LOG_DATA_TYPE_ADV (5) +#define HCI_LOG_DATA_TYPE_SELF_DEFINE (6) +#define HCI_LOG_DATA_TYPE_C2H_ACL (7) + +/** + * + * @brief This function is called to record self-defining data + * @param string : data identification + * @param data : data + * @param data_len : the length of data + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_record_custom_data(char *string, uint8_t *data, uint8_t data_len); +/** + * + * @brief This function is called to print all hci data record + * + * + * @return None + * + */ +void bt_hci_log_hci_data_show(void); + +/** + * + * @brief This function is called to print all adv report + * + * + * @return None + * + */ +void bt_hci_log_hci_adv_show(void); + +/** + * + * @brief This function is called to init hci log env + * + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_init(void); + +/** + * + * @brief This function is called to deinit hci debug mode, + * and can only be called internally by Bluetooth + * + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_deinit(void); + +/** + * + * @brief This function is called to record hci data without adv report event, + * and can only be called internally by Bluetooth + * + * @param str : data type, define in bt_data_type_to_str() + * @param data : data + * @param data_len : the length of data + * + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_record_hci_data(uint8_t data_type, uint8_t *data, uint8_t data_len); + +/** + * + * @brief This function is called to record hci adv report event only + * and can only be called internally by Bluetooth + * + * @param str : data type, define in bt_data_type_to_str() + * @param data : data + * @param data_len : the length of data + * @return ESP_OK - success, other - failed + * + */ +esp_err_t bt_hci_log_record_hci_adv(uint8_t data_type, uint8_t *data, uint8_t data_len); + +#ifdef __cplusplus +} +#endif + +#endif /* _ESP_BT_HCI_LOG_H__ */ diff --git a/components/bt/common/include/bt_common.h b/components/bt/common/include/bt_common.h index c2eff8777a..56723f7e7f 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -72,6 +72,24 @@ #define BT_BLE_DYNAMIC_ENV_MEMORY FALSE #endif +#if UC_BT_HCI_LOG_DEBUG_EN +#define BT_HCI_LOG_INCLUDED UC_BT_HCI_LOG_DEBUG_EN +#else +#define BT_HCI_LOG_INCLUDED FALSE +#endif + +#if UC_BT_HCI_LOG_DATA_BUFFER_SIZE +#define HCI_LOG_DATA_BUFFER_SIZE UC_BT_HCI_LOG_DATA_BUFFER_SIZE +#else +#define HCI_BUFFER_SIZE (5) +#endif + +#if UC_BT_HCI_ADV_BUFFER_SIZE +#define HCI_LOG_ADV_BUFFER_SIZE UC_BT_HCI_LOG_ADV_BUFFER_SIZE +#else +#define HCI_LOG_ADV_BUFFER_SIZE (5) +#endif + /* OS Configuration from User config (eg: sdkconfig) */ #define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE #define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES diff --git a/components/bt/common/include/bt_user_config.h b/components/bt/common/include/bt_user_config.h index c4380ccec1..2599af5144 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -100,4 +100,22 @@ #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +#ifdef CONFIG_BT_HCI_LOG_DEBUG_EN +#define UC_BT_HCI_LOG_DEBUG_EN TRUE +#else +#define UC_BT_HCI_LOG_DEBUG_EN FALSE +#endif + +#ifdef CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE +#define UC_BT_HCI_LOG_DATA_BUFFER_SIZE CONFIG_BT_HCI_LOG_DATA_BUFFER_SIZE +#else +#define UC_BT_HCI_LOG_DATA_BUFFER_SIZE (5) +#endif + +#ifdef CONFIG_BT_HCI_LOG_ADV_BUFFER_SIZE +#define UC_BT_HCI_LOG_ADV_BUFFER_SIZE CONFIG_BT_HCI_LOG_ADV_BUFFER_SIZE +#else +#define UC_BT_HCI_LOG_ADV_BUFFER_SIZE (5) +#endif + #endif /* __BT_USER_CONFIG_H__ */ diff --git a/components/bt/host/bluedroid/api/esp_bt_main.c b/components/bt/host/bluedroid/api/esp_bt_main.c index f0e07f84e7..5ebfce154b 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -19,6 +19,10 @@ #include "esp_bt.h" #include "osi/future.h" #include "osi/allocator.h" +#include "bt_common.h" +#if (BT_HCI_LOG_INCLUDED == TRUE) +#include "hci_log/bt_hci_log.h" +#endif static bool bd_already_enable = false; static bool bd_already_init = false; @@ -165,6 +169,10 @@ esp_err_t esp_bluedroid_init(void) bd_already_init = true; +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_init(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + return ESP_OK; } @@ -207,6 +215,10 @@ esp_err_t esp_bluedroid_deinit(void) btc_deinit(); +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_deinit(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + bd_already_init = false; return ESP_OK; diff --git a/components/bt/host/bluedroid/hci/hci_hal_h4.c b/components/bt/host/bluedroid/hci/hci_hal_h4.c index 4c6e09af34..e2b90a5498 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -35,6 +35,10 @@ #include "l2c_int.h" #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE #include "stack/hcimsgs.h" +#include "bt_common.h" +#if (BT_HCI_LOG_INCLUDED == TRUE) +#include "hci_log/bt_hci_log.h" +#endif #define HCI_BLE_EVENT 0x3e #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2) @@ -206,7 +210,9 @@ static uint16_t transmit_data(serial_data_type_t type, ++length; BTTRC_DUMP_BUFFER("Transmit Pkt", data, length); - +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], data, length); +#endif // TX Data to target esp_vhci_host_send_packet(data, length); @@ -433,7 +439,7 @@ static void hci_hal_h4_hdl_rx_packet(BT_HDR *packet) uint8_t len = 0; STREAM_TO_UINT8(len, stream); #endif - HCI_TRACE_ERROR("Workround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n", + HCI_TRACE_ERROR("Workaround stream corrupted during LE SCAN: pkt_len=%d ble_event_len=%d\n", packet->len, len); osi_free(packet); return; @@ -546,10 +552,14 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) bool is_adv_rpt = host_recv_adv_packet(data); if (!is_adv_rpt) { +#if (BT_HCI_LOG_INCLUDED == TRUE) + uint8_t data_type = ((data[0] == 2) ? HCI_LOG_DATA_TYPE_C2H_ACL : data[0]); + bt_hci_log_record_hci_data(data_type, data, len); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) pkt_size = BT_HDR_SIZE + len; pkt = (BT_HDR *) osi_calloc(pkt_size); if (!pkt) { - HCI_TRACE_ERROR("%s couldn't aquire memory for inbound data buffer.\n", __func__); + HCI_TRACE_ERROR("%s couldn't acquire memory for inbound data buffer.\n", __func__); assert(0); } @@ -559,6 +569,10 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len) memcpy(pkt->data, data, len); fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT); } else { +#if (BT_HCI_LOG_INCLUDED == TRUE) + // data type is adv report + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, data, len); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) #if !BLE_ADV_REPORT_FLOW_CONTROL // drop the packets if pkt_queue length goes beyond upper limit if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) { diff --git a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c index 087b056cb3..01e3a0121b 100644 --- a/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c +++ b/components/bt/host/nimble/esp-hci/src/esp_nimble_hci.c @@ -30,6 +30,11 @@ #include "esp_bt.h" #include "freertos/semphr.h" #include "esp_compiler.h" +#include "soc/soc_caps.h" +#include "bt_common.h" +#if (BT_HCI_LOG_INCLUDED == TRUE) +#include "hci_log/bt_hci_log.h" +#endif #define NIMBLE_VHCI_TIMEOUT_MS 2000 #define BLE_HCI_EVENT_HDR_LEN (2) @@ -95,6 +100,9 @@ int ble_hci_trans_hs_cmd_tx(uint8_t *cmd) } if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(cmd[0], cmd, len); +#endif esp_vhci_host_send_packet(cmd, len); } else { rc = BLE_HS_ETIMEOUT_HCI; @@ -134,6 +142,9 @@ int ble_hci_trans_hs_acl_tx(struct os_mbuf *om) len += OS_MBUF_PKTLEN(om); if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) { +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], data, len); +#endif esp_vhci_host_send_packet(data, len); } else { rc = BLE_HS_ETIMEOUT_HCI; @@ -368,12 +379,18 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) /* Allocate LE Advertising Report Event from lo pool only */ if ((data[1] == BLE_HCI_EVCODE_LE_META) && (data[3] == BLE_HCI_LE_SUBEV_ADV_RPT)) { +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_adv(HCI_LOG_DATA_TYPE_ADV, data, len); +#endif evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO); /* Skip advertising report if we're out of memory */ if (!evbuf) { return 0; } } else { +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(data[0], data, len); +#endif evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI); assert(evbuf != NULL); } @@ -384,6 +401,9 @@ static int host_rcv_pkt(uint8_t *data, uint16_t len) rc = ble_hci_trans_ll_evt_tx(evbuf); assert(rc == 0); } else if (data[0] == BLE_HCI_UART_H4_ACL) { +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_record_hci_data(HCI_LOG_DATA_TYPE_C2H_ACL, data, len); +#endif ble_hci_rx_acl(data + 1, len - 1); } return 0; @@ -456,6 +476,10 @@ esp_err_t esp_nimble_hci_init(void) goto err; } +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_init(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + xSemaphoreGive(vhci_send_sem); return ret; @@ -511,6 +535,11 @@ esp_err_t esp_nimble_hci_deinit(void) vSemaphoreDelete(vhci_send_sem); vhci_send_sem = NULL; } + +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_deinit(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + esp_err_t ret = ble_hci_transport_deinit(); if (ret != ESP_OK) { return ret;