From d0e0928138ab2b8f4e869d6669022910d8b9812e Mon Sep 17 00:00:00 2001 From: Jin Cheng Date: Fri, 1 Sep 2023 09:49:20 +0800 Subject: [PATCH] feat(bt/Bluedroid): Implemented esp_coex_status_set/clear using vendor HCI --- components/bt/host/bluedroid/Kconfig.in | 7 ++++ .../bt/host/bluedroid/api/esp_bt_device.c | 21 +++++++++++ .../bluedroid/api/include/api/esp_bt_device.h | 37 +++++++++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 19 ++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 25 +++++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 18 +++++++-- .../bluedroid/bta/dm/include/bta_dm_int.h | 18 +++++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 14 +++++++ .../bt/host/bluedroid/btc/core/btc_dev.c | 11 ++++++ .../host/bluedroid/btc/include/btc/btc_dev.h | 14 ++++++- .../include/common/bluedroid_user_config.h | 7 ++++ .../common/include/common/bt_target.h | 6 +++ .../bt/host/bluedroid/stack/btm/btm_devctl.c | 13 +++++++ .../bluedroid/stack/include/stack/btm_api.h | 37 +++++++++++++++++++ 14 files changed, 242 insertions(+), 5 deletions(-) diff --git a/components/bt/host/bluedroid/Kconfig.in b/components/bt/host/bluedroid/Kconfig.in index c9a0c0f147..079080bf3a 100644 --- a/components/bt/host/bluedroid/Kconfig.in +++ b/components/bt/host/bluedroid/Kconfig.in @@ -40,6 +40,13 @@ config BT_BLUEDROID_MEM_DEBUG help Bluedroid memory debug +config BT_BLUEDROID_ESP_COEX_VSC + bool "Enable Espressif Vendor-specific HCI commands for coexist status configuration" + depends on BT_BLUEDROID_ENABLED + default y + help + Enable Espressif Vendor-specific HCI commands for coexist status configuration + config BT_CLASSIC_ENABLED bool "Classic Bluetooth" depends on BT_BLUEDROID_ENABLED && IDF_TARGET_ESP32 diff --git a/components/bt/host/bluedroid/api/esp_bt_device.c b/components/bt/host/bluedroid/api/esp_bt_device.c index e9369b20fc..0a323cfe29 100644 --- a/components/bt/host/bluedroid/api/esp_bt_device.c +++ b/components/bt/host/bluedroid/api/esp_bt_device.c @@ -47,3 +47,24 @@ esp_err_t esp_bt_dev_set_device_name(const char *name) return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } + +#if (ESP_COEX_VSC_INCLUDED == TRUE) +esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_coex_op_t op, uint8_t status) +{ + btc_msg_t msg = {0}; + btc_dev_args_t arg; + + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_DEV; + msg.act = BTC_DEV_ACT_CFG_COEX_STATUS; + arg.cfg_coex_status.type = type; + arg.cfg_coex_status.op = op; + arg.cfg_coex_status.status = status; + + return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_device.h b/components/bt/host/bluedroid/api/include/api/esp_bt_device.h index 20826b76dd..997d827f65 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_device.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_device.h @@ -16,6 +16,27 @@ extern "C" { #endif +// coexist status for MESH +#define ESP_BT_DEV_COEX_BLE_ST_MESH_CONFIG 0x08 +#define ESP_BT_DEV_COEX_BLE_ST_MESH_TRAFFIC 0x10 +#define ESP_BT_DEV_COEX_BLE_ST_MESH_STANDBY 0x20 +// coexist status for A2DP +#define ESP_BT_DEV_COEX_BT_ST_A2DP_STREAMING 0x10 +#define ESP_BT_DEV_COEX_BT_ST_A2DP_PAUSED 0x20 + +// coexist operation +#define ESP_BT_DEV_COEX_OP_CLEAR 0x00 +#define ESP_BT_DEV_COEX_OP_SET 0x01 +typedef uint8_t esp_bt_dev_coex_op_t; + +/** + * @brief Bluetooth device coex type + */ +typedef enum { + ESP_BT_DEV_COEX_TYPE_BLE = 1, + ESP_BT_DEV_COEX_TYPE_BT, +} esp_bt_dev_coex_type_t; + /** * * @brief Get bluetooth device address. Must use after "esp_bluedroid_enable". @@ -42,6 +63,22 @@ const uint8_t *esp_bt_dev_get_address(void); */ esp_err_t esp_bt_dev_set_device_name(const char *name); +/** + * @brief Config bluetooth device coexis status. This function should be called after esp_bluedroid_enable() + * completes successfully. + * + * @param[in] type : coexist type to operate on + * @param[in] op : clear or set coexist status + * @param[in] status : coexist status to be configured + * + * @return + * - ESP_OK : Succeed + * - ESP_ERR_INVALID_ARG : if name is NULL pointer or empty, or string length out of limit + * - ESP_ERR_INVALID_STATE : if bluetooth stack is not yet enabled + * - ESP_FAIL : others + */ +esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_coex_op_t op, uint8_t status); + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c index b967ba3889..c07bf996c1 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -692,6 +692,25 @@ void bta_dm_get_dev_name (tBTA_DM_MSG *p_data) } } +/******************************************************************************* +** +** Function bta_dm_cfg_coex_status +** +** Description config coexistance status +** +** +** Returns void +** +*******************************************************************************/ +#if (ESP_COEX_VSC_INCLUDED == TRUE) +void bta_dm_cfg_coex_status (tBTA_DM_MSG *p_data) +{ + BTM_ConfigCoexStatus(p_data->cfg_coex_status.op, + p_data->cfg_coex_status.type, + p_data->cfg_coex_status.status); +} +#endif + /******************************************************************************* ** ** Function bta_dm_set_afh_channels diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c index e896846e25..a214fa038b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -202,6 +202,31 @@ void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback) } } +/******************************************************************************* +** +** Function BTA_DmCfgCoexStatus +** +** Description This function configures the coexist status +** +** +** Returns void +** +*******************************************************************************/ +#if (ESP_COEX_VSC_INCLUDED == TRUE) +void BTA_DmCfgCoexStatus(UINT8 op, UINT8 type, UINT8 status) +{ + tBTA_DM_API_CFG_COEX_STATUS *p_msg; + + if ((p_msg = (tBTA_DM_API_CFG_COEX_STATUS *) osi_malloc(sizeof(tBTA_DM_API_CFG_COEX_STATUS))) != NULL) { + p_msg->hdr.event = BTA_DM_API_CFG_COEX_ST_EVT; + p_msg->op = op; + p_msg->type = type; + p_msg->status = status; + bta_sys_sendmsg(p_msg); + } +} +#endif + #if (CLASSIC_BT_INCLUDED == TRUE) void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config) diff --git a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c index 51201c9171..81866380c6 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -25,6 +25,9 @@ #include "bta/bta_api.h" #include "bta/bta_sys.h" #include "bta_dm_int.h" +#if (ESP_COEX_VSC_INCLUDED == TRUE) +#include "stack/btm_api.h" +#endif #include "osi/allocator.h" #include @@ -59,6 +62,9 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_disable, /* BTA_DM_API_DISABLE_EVT */ bta_dm_set_dev_name, /* BTA_DM_API_SET_NAME_EVT */ bta_dm_get_dev_name, /* BTA_DM_API_GET_NAME_EVT */ +#if (ESP_COEX_VSC_INCLUDED == TRUE) + bta_dm_cfg_coex_status, /* BTA_DM_API_CFG_COEX_ST_EVT */ +#endif #if (CLASSIC_BT_INCLUDED == TRUE) bta_dm_config_eir, /* BTA_DM_API_CONFIG_EIR_EVT */ bta_dm_set_page_timeout, /* BTA_DM_API_PAGE_TO_SET_EVT */ @@ -464,12 +470,16 @@ void BTA_DmCoexEventTrigger(uint32_t event) case BTA_COEX_EVT_ACL_DISCONNECTED: break; case BTA_COEX_EVT_STREAMING_STARTED: - esp_coex_status_bit_set(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_STREAMING); - esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_PAUSED); +#if (ESP_COEX_VSC_INCLUDED == TRUE) + BTM_ConfigCoexStatus(BTM_COEX_OP_SET, BTM_COEX_TYPE_BT, BTM_COEX_BT_ST_A2DP_STREAMING); + BTM_ConfigCoexStatus(BTM_COEX_OP_CLEAR, BTM_COEX_TYPE_BT, BTM_COEX_BT_ST_A2DP_PAUSED); +#endif break; case BTA_COEX_EVT_STREAMING_STOPPED: - esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_STREAMING); - esp_coex_status_bit_clear(ESP_COEX_ST_TYPE_BT, ESP_COEX_BT_ST_A2DP_PAUSED); +#if (ESP_COEX_VSC_INCLUDED == TRUE) + BTM_ConfigCoexStatus(BTM_COEX_OP_CLEAR, BTM_COEX_TYPE_BT, BTM_COEX_BT_ST_A2DP_STREAMING); + BTM_ConfigCoexStatus(BTM_COEX_OP_CLEAR, BTM_COEX_TYPE_BT, BTM_COEX_BT_ST_A2DP_PAUSED); +#endif break; default: break; diff --git a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h index 40b7e8e909..386df1354c 100644 --- a/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h +++ b/components/bt/host/bluedroid/bta/dm/include/bta_dm_int.h @@ -54,6 +54,9 @@ enum { BTA_DM_API_DISABLE_EVT, BTA_DM_API_SET_NAME_EVT, BTA_DM_API_GET_NAME_EVT, +#if (ESP_COEX_VSC_INCLUDED == TRUE) + BTA_DM_API_CFG_COEX_ST_EVT, +#endif #if (CLASSIC_BT_INCLUDED == TRUE) BTA_DM_API_CONFIG_EIR_EVT, BTA_DM_API_PAGE_TO_SET_EVT, @@ -244,6 +247,15 @@ typedef struct { tBTA_GET_DEV_NAME_CBACK *p_cback; } tBTA_DM_API_GET_NAME; +#if (ESP_COEX_VSC_INCLUDED == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 op; + UINT8 type; + UINT8 status; +} tBTA_DM_API_CFG_COEX_STATUS; +#endif + /* data type for BTA_DM_API_CONFIG_EIR_EVT */ typedef struct { BT_HDR hdr; @@ -1090,6 +1102,9 @@ typedef union { tBTA_DM_API_SET_NAME set_name; tBTA_DM_API_GET_NAME get_name; +#if (ESP_COEX_VSC_INCLUDED == TRUE) + tBTA_DM_API_CFG_COEX_STATUS cfg_coex_status; +#endif tBTA_DM_API_CONFIG_EIR config_eir; tBTA_DM_API_SET_AFH_CHANNELS set_afh_channels; @@ -1593,6 +1608,9 @@ extern void bta_dm_enable (tBTA_DM_MSG *p_data); extern void bta_dm_disable (tBTA_DM_MSG *p_data); extern void bta_dm_set_dev_name (tBTA_DM_MSG *p_data); extern void bta_dm_get_dev_name (tBTA_DM_MSG *p_data); +#if (ESP_COEX_VSC_INCLUDED == TRUE) +extern void bta_dm_cfg_coex_status(tBTA_DM_MSG *p_data); +#endif #if (CLASSIC_BT_INCLUDED == TRUE) extern void bta_dm_config_eir (tBTA_DM_MSG *p_data); extern void bta_dm_set_page_timeout (tBTA_DM_MSG *p_data); diff --git a/components/bt/host/bluedroid/bta/include/bta/bta_api.h b/components/bt/host/bluedroid/bta/include/bta/bta_api.h index 5b8899fc6e..fd0d2350aa 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -1713,6 +1713,20 @@ extern void BTA_DmSetDeviceName(const char *p_name); *******************************************************************************/ extern void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback); +/******************************************************************************* +** +** Function BTA_DmCfgCoexStatus +** +** Description This function configures coexist status. +** +** +** Returns void +** +*******************************************************************************/ +#if (ESP_COEX_VSC_INCLUDED == TRUE) +extern void BTA_DmCfgCoexStatus(UINT8 op, UINT8 type, UINT8 status); +#endif + /******************************************************************************* ** ** Function BTA_DmGetRemoteName diff --git a/components/bt/host/bluedroid/btc/core/btc_dev.c b/components/bt/host/bluedroid/btc/core/btc_dev.c index 88d15c8584..1aceface6a 100644 --- a/components/bt/host/bluedroid/btc/core/btc_dev.c +++ b/components/bt/host/bluedroid/btc/core/btc_dev.c @@ -23,6 +23,10 @@ void btc_dev_arg_deep_free(btc_msg_t *msg) } break; } +#if (ESP_COEX_VSC_INCLUDED == TRUE) + case BTC_DEV_ACT_CFG_COEX_STATUS: + break; +#endif default: BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act); break; @@ -39,6 +43,13 @@ void btc_dev_call_handler(btc_msg_t *msg) case BTC_DEV_ACT_SET_DEVICE_NAME: BTA_DmSetDeviceName(arg->set_dev_name.device_name); break; +#if (ESP_COEX_VSC_INCLUDED == TRUE) + case BTC_DEV_ACT_CFG_COEX_STATUS: + BTA_DmCfgCoexStatus(arg->cfg_coex_status.op, + arg->cfg_coex_status.type, + arg->cfg_coex_status.status); + break; +#endif default: break; } diff --git a/components/bt/host/bluedroid/btc/include/btc/btc_dev.h b/components/bt/host/bluedroid/btc/include/btc/btc_dev.h index e87766b9dc..4cf085d7de 100644 --- a/components/bt/host/bluedroid/btc/include/btc/btc_dev.h +++ b/components/bt/host/bluedroid/btc/include/btc/btc_dev.h @@ -12,7 +12,10 @@ #include "btc/btc_task.h" typedef enum { - BTC_DEV_ACT_SET_DEVICE_NAME + BTC_DEV_ACT_SET_DEVICE_NAME, +#if (ESP_COEX_VSC_INCLUDED == TRUE) + BTC_DEV_ACT_CFG_COEX_STATUS, +#endif } btc_dev_act_t; /* btc_dev_args_t */ @@ -21,6 +24,15 @@ typedef union { struct set_bt_dev_name_args { char *device_name; } set_dev_name; + +#if (ESP_COEX_VSC_INCLUDED == TRUE) + // BTC_DEV_ACT_CFG_COEX_STATUS + struct cfg_bt_dev_coex_st_args { + esp_bt_dev_coex_type_t type; + esp_bt_dev_coex_op_t op; + uint8_t status; + } cfg_coex_status; +#endif } btc_dev_args_t; void btc_dev_call_handler(btc_msg_t *msg); diff --git a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h index 08034e4a90..8b99588dfc 100644 --- a/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h +++ b/components/bt/host/bluedroid/common/include/common/bluedroid_user_config.h @@ -361,6 +361,13 @@ #define UC_BT_BLUEDROID_MEM_DEBUG FALSE #endif +//ESP COEXIST VSC +#ifdef CONFIG_BT_BLUEDROID_ESP_COEX_VSC +#define UC_BT_BLUEDROID_ESP_COEX_VSC CONFIG_BT_BLUEDROID_ESP_COEX_VSC +#else +#define UC_BT_BLUEDROID_ESP_COEX_VSC FALSE +#endif + /********************************************************** * Trace reference diff --git a/components/bt/host/bluedroid/common/include/common/bt_target.h b/components/bt/host/bluedroid/common/include/common/bt_target.h index d3b828ca0b..75f128927e 100644 --- a/components/bt/host/bluedroid/common/include/common/bt_target.h +++ b/components/bt/host/bluedroid/common/include/common/bt_target.h @@ -45,6 +45,12 @@ /* OS Configuration from User config (eg: sdkconfig) */ #define BT_BTU_TASK_STACK_SIZE UC_BTU_TASK_STACK_SIZE +#if (UC_BT_BLUEDROID_ESP_COEX_VSC == TRUE) +#define ESP_COEX_VSC_INCLUDED TRUE +#else +#define ESP_COEX_VSC_INCLUDED FALSE +#endif + /****************************************************************************** ** ** Classic BT features diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 88a2bee956..0656f18f99 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -688,6 +688,19 @@ tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 param_len, } +#if (ESP_COEX_VSC_INCLUDED == TRUE) +tBTM_STATUS BTM_ConfigCoexStatus(tBTM_COEX_OPERATION op, tBTM_COEX_TYPE type, UINT8 status) +{ + UINT8 param[3]; + UINT8 *p = (UINT8 *)param; + + UINT8_TO_STREAM(p, type); + UINT8_TO_STREAM(p, op); + UINT8_TO_STREAM(p, status); + + return BTM_VendorSpecificCommand(HCI_VENDOR_COMMON_COEX_STATUS_CMD_OPCODE, 3, param, NULL); +} +#endif /******************************************************************************* ** diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_api.h index 6db5e7d629..5120259ecc 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -195,6 +195,28 @@ typedef void (tBTM_UPDATE_WHITELIST_CBACK) (UINT8 status, tBTM_WL_OPERATION wl_o typedef void (tBTM_SET_LOCAL_PRIVACY_CBACK) (UINT8 status); +/******************************* +** Device Coexist status +********************************/ +#if (ESP_COEX_VSC_INCLUDED == TRUE) +// coexist status for MESH +#define BTM_COEX_BLE_ST_MESH_CONFIG 0x08 +#define BTM_COEX_BLE_ST_MESH_TRAFFIC 0x10 +#define BTM_COEX_BLE_ST_MESH_STANDBY 0x20 +// coexist status for A2DP +#define BTM_COEX_BT_ST_A2DP_STREAMING 0x10 +#define BTM_COEX_BT_ST_A2DP_PAUSED 0x20 + +// coexist operation +#define BTM_COEX_OP_CLEAR 0x00 +#define BTM_COEX_OP_SET 0x01 +typedef UINT8 tBTM_COEX_OPERATION; + +typedef enum { + BTM_COEX_TYPE_BLE = 1, + BTM_COEX_TYPE_BT, +} tBTM_COEX_TYPE; +#endif /***************************************************************************** ** DEVICE DISCOVERY - Inquiry, Remote Name, Discovery, Class of Device @@ -2150,6 +2172,21 @@ tBTM_STATUS BTM_VendorSpecificCommand(UINT16 opcode, UINT8 *p_param_buf, tBTM_VSC_CMPL_CB *p_cb); +/******************************************************************************* +** +** Function BTM_ConfigCoexStatus +** +** Description Config coexist status through vendor specific HCI command. +** +** Returns +** BTM_SUCCESS Command sent. Does not expect command complete +** event. (command cmpl callback param is NULL) +** BTM_NO_RESOURCES Command not sent. No resources. +** +*******************************************************************************/ +#if (ESP_COEX_VSC_INCLUDED == TRUE) +tBTM_STATUS BTM_ConfigCoexStatus(tBTM_COEX_OPERATION op, tBTM_COEX_TYPE type, UINT8 status); +#endif /******************************************************************************* **