mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
feat(bt/common): Add bluerooth hci layer data stream record
This commit is contained in:
parent
db9ba9378f
commit
9a7b3f80b2
@ -25,10 +25,13 @@ if(CONFIG_BT_ENABLED)
|
|||||||
list(APPEND include_dirs
|
list(APPEND include_dirs
|
||||||
common/api/include/api
|
common/api/include/api
|
||||||
common/btc/profile/esp/blufi/include
|
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"
|
list(APPEND srcs "common/btc/core/btc_alarm.c"
|
||||||
"common/api/esp_blufi_api.c"
|
"common/api/esp_blufi_api.c"
|
||||||
|
"common/hci_log/bt_hci_log.c"
|
||||||
"common/btc/core/btc_manage.c"
|
"common/btc/core/btc_manage.c"
|
||||||
"common/btc/core/btc_task.c"
|
"common/btc/core/btc_task.c"
|
||||||
"common/btc/profile/esp/blufi/blufi_prf.c"
|
"common/btc/profile/esp/blufi/blufi_prf.c"
|
||||||
|
@ -57,6 +57,31 @@ menu "Bluetooth"
|
|||||||
source "$IDF_PATH/components/bt/host/nimble/Kconfig.in"
|
source "$IDF_PATH/components/bt/host/nimble/Kconfig.in"
|
||||||
endmenu
|
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
|
endmenu
|
||||||
|
|
||||||
menuconfig BLE_MESH
|
menuconfig BLE_MESH
|
||||||
|
334
components/bt/common/hci_log/bt_hci_log.c
Normal file
334
components/bt/common/hci_log/bt_hci_log.c
Normal file
@ -0,0 +1,334 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#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)
|
108
components/bt/common/hci_log/include/hci_log/bt_hci_log.h
Normal file
108
components/bt/common/hci_log/include/hci_log/bt_hci_log.h
Normal file
@ -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__ */
|
@ -72,6 +72,24 @@
|
|||||||
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
#define BT_BLE_DYNAMIC_ENV_MEMORY FALSE
|
||||||
#endif
|
#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) */
|
/* OS Configuration from User config (eg: sdkconfig) */
|
||||||
#define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE
|
#define TASK_PINNED_TO_CORE UC_TASK_PINNED_TO_CORE
|
||||||
#define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES
|
#define BT_TASK_MAX_PRIORITIES configMAX_PRIORITIES
|
||||||
|
@ -100,4 +100,22 @@
|
|||||||
#define UC_BT_BLUEDROID_MEM_DEBUG FALSE
|
#define UC_BT_BLUEDROID_MEM_DEBUG FALSE
|
||||||
#endif
|
#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__ */
|
#endif /* __BT_USER_CONFIG_H__ */
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
#include "esp_bt.h"
|
#include "esp_bt.h"
|
||||||
#include "osi/future.h"
|
#include "osi/future.h"
|
||||||
#include "osi/allocator.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_enable = false;
|
||||||
static bool bd_already_init = false;
|
static bool bd_already_init = false;
|
||||||
@ -165,6 +169,10 @@ esp_err_t esp_bluedroid_init(void)
|
|||||||
|
|
||||||
bd_already_init = true;
|
bd_already_init = true;
|
||||||
|
|
||||||
|
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||||
|
bt_hci_log_init();
|
||||||
|
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,6 +215,10 @@ esp_err_t esp_bluedroid_deinit(void)
|
|||||||
|
|
||||||
btc_deinit();
|
btc_deinit();
|
||||||
|
|
||||||
|
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||||
|
bt_hci_log_deinit();
|
||||||
|
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
|
||||||
|
|
||||||
bd_already_init = false;
|
bd_already_init = false;
|
||||||
|
|
||||||
return ESP_OK;
|
return ESP_OK;
|
||||||
|
@ -35,6 +35,10 @@
|
|||||||
#include "l2c_int.h"
|
#include "l2c_int.h"
|
||||||
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
|
#endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE
|
||||||
#include "stack/hcimsgs.h"
|
#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 HCI_BLE_EVENT 0x3e
|
||||||
#define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
|
#define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2)
|
||||||
@ -206,7 +210,9 @@ static uint16_t transmit_data(serial_data_type_t type,
|
|||||||
++length;
|
++length;
|
||||||
|
|
||||||
BTTRC_DUMP_BUFFER("Transmit Pkt", data, 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
|
// TX Data to target
|
||||||
esp_vhci_host_send_packet(data, length);
|
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;
|
uint8_t len = 0;
|
||||||
STREAM_TO_UINT8(len, stream);
|
STREAM_TO_UINT8(len, stream);
|
||||||
#endif
|
#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);
|
packet->len, len);
|
||||||
osi_free(packet);
|
osi_free(packet);
|
||||||
return;
|
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);
|
bool is_adv_rpt = host_recv_adv_packet(data);
|
||||||
|
|
||||||
if (!is_adv_rpt) {
|
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_size = BT_HDR_SIZE + len;
|
||||||
pkt = (BT_HDR *) osi_calloc(pkt_size);
|
pkt = (BT_HDR *) osi_calloc(pkt_size);
|
||||||
if (!pkt) {
|
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);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,6 +569,10 @@ static int host_recv_pkt_cb(uint8_t *data, uint16_t len)
|
|||||||
memcpy(pkt->data, data, len);
|
memcpy(pkt->data, data, len);
|
||||||
fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
|
fixed_queue_enqueue(hci_hal_env.rx_q, pkt, FIXED_QUEUE_MAX_TIMEOUT);
|
||||||
} else {
|
} 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
|
#if !BLE_ADV_REPORT_FLOW_CONTROL
|
||||||
// drop the packets if pkt_queue length goes beyond upper limit
|
// 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) {
|
if (pkt_queue_length(hci_hal_env.adv_rpt_q) > HCI_HAL_BLE_ADV_RPT_QUEUE_LEN_MAX) {
|
||||||
|
@ -30,6 +30,11 @@
|
|||||||
#include "esp_bt.h"
|
#include "esp_bt.h"
|
||||||
#include "freertos/semphr.h"
|
#include "freertos/semphr.h"
|
||||||
#include "esp_compiler.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 NIMBLE_VHCI_TIMEOUT_MS 2000
|
||||||
#define BLE_HCI_EVENT_HDR_LEN (2)
|
#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 (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);
|
esp_vhci_host_send_packet(cmd, len);
|
||||||
} else {
|
} else {
|
||||||
rc = BLE_HS_ETIMEOUT_HCI;
|
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);
|
len += OS_MBUF_PKTLEN(om);
|
||||||
|
|
||||||
if (xSemaphoreTake(vhci_send_sem, NIMBLE_VHCI_TIMEOUT_MS / portTICK_PERIOD_MS) == pdTRUE) {
|
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);
|
esp_vhci_host_send_packet(data, len);
|
||||||
} else {
|
} else {
|
||||||
rc = BLE_HS_ETIMEOUT_HCI;
|
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 */
|
/* 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 ((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);
|
evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_LO);
|
||||||
/* Skip advertising report if we're out of memory */
|
/* Skip advertising report if we're out of memory */
|
||||||
if (!evbuf) {
|
if (!evbuf) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} 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);
|
evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
|
||||||
assert(evbuf != NULL);
|
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);
|
rc = ble_hci_trans_ll_evt_tx(evbuf);
|
||||||
assert(rc == 0);
|
assert(rc == 0);
|
||||||
} else if (data[0] == BLE_HCI_UART_H4_ACL) {
|
} 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);
|
ble_hci_rx_acl(data + 1, len - 1);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -456,6 +476,10 @@ esp_err_t esp_nimble_hci_init(void)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if (BT_HCI_LOG_INCLUDED == TRUE)
|
||||||
|
bt_hci_log_init();
|
||||||
|
#endif // (BT_HCI_LOG_INCLUDED == TRUE)
|
||||||
|
|
||||||
xSemaphoreGive(vhci_send_sem);
|
xSemaphoreGive(vhci_send_sem);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@ -511,6 +535,11 @@ esp_err_t esp_nimble_hci_deinit(void)
|
|||||||
vSemaphoreDelete(vhci_send_sem);
|
vSemaphoreDelete(vhci_send_sem);
|
||||||
vhci_send_sem = NULL;
|
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();
|
esp_err_t ret = ble_hci_transport_deinit();
|
||||||
if (ret != ESP_OK) {
|
if (ret != ESP_OK) {
|
||||||
return ret;
|
return ret;
|
||||||
|
Loading…
Reference in New Issue
Block a user