forked from espressif/esp-idf
feat(bt/bluedroid): add api to setnd vendor hci command
This commit is contained in:
@@ -106,3 +106,31 @@ esp_err_t esp_bt_config_file_path_update(const char *file_path)
|
||||
|
||||
return btc_config_file_path_update(file_path);
|
||||
}
|
||||
|
||||
esp_err_t esp_bt_dev_vendor_command_send(esp_bt_dev_vendor_cmd_params_t *vendor_cmd_param)
|
||||
{
|
||||
btc_msg_t msg = {0};
|
||||
btc_dev_args_t arg;
|
||||
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (!vendor_cmd_param || !vendor_cmd_param->p_param_buf || !vendor_cmd_param->param_len) {
|
||||
return ESP_ERR_NOT_ALLOWED;
|
||||
}
|
||||
// If command is not a VSC, return error
|
||||
if ((vendor_cmd_param->opcode & VENDOR_HCI_CMD_MASK) != VENDOR_HCI_CMD_MASK) {
|
||||
return ESP_ERR_NOT_ALLOWED;
|
||||
}
|
||||
|
||||
msg.sig = BTC_SIG_API_CALL;
|
||||
msg.pid = BTC_PID_DEV;
|
||||
msg.act = BTC_DEV_ACT_VENDOR_HCI_CMD_EVT;
|
||||
arg.vendor_cmd_send.opcode = vendor_cmd_param->opcode;
|
||||
arg.vendor_cmd_send.param_len = vendor_cmd_param->param_len;
|
||||
arg.vendor_cmd_send.p_param_buf = vendor_cmd_param->p_param_buf;
|
||||
|
||||
return (btc_transfer_context(&msg, &arg, sizeof(btc_dev_args_t), btc_dev_call_arg_deep_copy, btc_dev_call_arg_deep_free)
|
||||
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
|
||||
}
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -29,6 +29,17 @@ extern "C" {
|
||||
#define ESP_BT_DEV_COEX_OP_SET 0x01
|
||||
typedef uint8_t esp_bt_dev_coex_op_t;
|
||||
|
||||
#define VENDOR_HCI_CMD_MASK (0x3F << 10) /**!< 0xFC00 */
|
||||
|
||||
/**
|
||||
* @brief Vendor HCI command parameters
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t opcode; /*!< vendor hci command opcode */
|
||||
uint8_t param_len; /*!< the length of parameter */
|
||||
uint8_t *p_param_buf; /*!< the point of parameter buffer */
|
||||
} esp_bt_dev_vendor_cmd_params_t;
|
||||
|
||||
/**
|
||||
* @brief Bluetooth device coex type
|
||||
*/
|
||||
@@ -40,6 +51,7 @@ typedef enum {
|
||||
/// BT device callback events
|
||||
typedef enum {
|
||||
ESP_BT_DEV_NAME_RES_EVT = 0, /*!< Device name result event */
|
||||
ESP_BT_DEV_VENDOR_CMD_COMPLETE_EVT, /*!< When vendor hci command complete, the event comes */
|
||||
ESP_BT_DEV_EVT_MAX,
|
||||
} esp_bt_dev_cb_event_t;
|
||||
|
||||
@@ -52,6 +64,14 @@ typedef union {
|
||||
esp_bt_status_t status; /*!< Status of getting device name */
|
||||
char *name; /*!< Name of Bluetooth device */
|
||||
} name_res; /*!< discovery result parameter struct */
|
||||
/**
|
||||
* @brief ESP_BT_DEV_VENDOR_CMD_COMPLETE_EVT
|
||||
*/
|
||||
struct vendor_cmd_cmpl_evt_param {
|
||||
uint16_t opcode; /*!< vendor hci command opcode */
|
||||
uint16_t param_len; /*!< The lenght of parameter buffer */
|
||||
uint8_t *p_param_buf; /*!< The point of parameter buffer */
|
||||
} vendor_cmd_cmpl; /*!< Event parameter of ESP_BT_DEV_VENDOR_CMD_COMPLETE_EVT */
|
||||
} esp_bt_dev_cb_param_t;
|
||||
|
||||
/**
|
||||
@@ -140,6 +160,19 @@ esp_err_t esp_bt_dev_coex_status_config(esp_bt_dev_coex_type_t type, esp_bt_dev_
|
||||
*/
|
||||
esp_err_t esp_bt_config_file_path_update(const char *file_path);
|
||||
|
||||
/**
|
||||
* @brief This function is called to send vendor hci comamnd.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @param[in] vendor_cmd_param: vendor hci command parameters
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK : success
|
||||
* - other : failed
|
||||
*/
|
||||
esp_err_t esp_bt_dev_vendor_command_send(esp_bt_dev_vendor_cmd_params_t *vendor_cmd_param);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@@ -724,6 +724,14 @@ void bta_dm_cfg_coex_status (tBTA_DM_MSG *p_data)
|
||||
}
|
||||
#endif
|
||||
|
||||
void bta_dm_send_vendor_hci(tBTA_DM_MSG *p_data)
|
||||
{
|
||||
BTM_VendorSpecificCommand(p_data->vendor_hci_cmd.opcode,
|
||||
p_data->vendor_hci_cmd.param_len,
|
||||
p_data->vendor_hci_cmd.p_param_buf,
|
||||
p_data->vendor_hci_cmd.vendor_hci_cb);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function bta_dm_set_afh_channels
|
||||
|
@@ -227,6 +227,21 @@ void BTA_DmCfgCoexStatus(UINT8 op, UINT8 type, UINT8 status)
|
||||
}
|
||||
#endif
|
||||
|
||||
void BTA_DmsendVendorHciCmd(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf, tBTA_SEND_VENDOR_HCI_CMPL_CBACK p_vendor_cmd_complete_cback)
|
||||
{
|
||||
tBTA_DM_API_SEND_VENDOR_HCI_CMD *p_msg;
|
||||
if ((p_msg = (tBTA_DM_API_SEND_VENDOR_HCI_CMD *)osi_malloc(sizeof(tBTA_DM_API_SEND_VENDOR_HCI_CMD) + param_len)) != NULL) {
|
||||
p_msg->hdr.event = BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT;
|
||||
p_msg->opcode = opcode;
|
||||
p_msg->param_len = param_len;
|
||||
p_msg->p_param_buf = (UINT8 *)(p_msg + 1);
|
||||
memcpy(p_msg->p_param_buf, p_param_buf, param_len);
|
||||
p_msg->vendor_hci_cb = p_vendor_cmd_complete_cback;
|
||||
|
||||
bta_sys_sendmsg(p_msg);
|
||||
}
|
||||
}
|
||||
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
|
||||
void BTA_DmConfigEir(tBTA_DM_EIR_CONF *eir_config)
|
||||
|
@@ -65,6 +65,7 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = {
|
||||
#if (ESP_COEX_VSC_INCLUDED == TRUE)
|
||||
bta_dm_cfg_coex_status, /* BTA_DM_API_CFG_COEX_ST_EVT */
|
||||
#endif
|
||||
bta_dm_send_vendor_hci, /* BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT */
|
||||
#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 */
|
||||
|
@@ -57,6 +57,7 @@ enum {
|
||||
#if (ESP_COEX_VSC_INCLUDED == TRUE)
|
||||
BTA_DM_API_CFG_COEX_ST_EVT,
|
||||
#endif
|
||||
BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT,
|
||||
#if (CLASSIC_BT_INCLUDED == TRUE)
|
||||
BTA_DM_API_CONFIG_EIR_EVT,
|
||||
BTA_DM_API_PAGE_TO_SET_EVT,
|
||||
@@ -265,6 +266,14 @@ typedef struct {
|
||||
} tBTA_DM_API_CFG_COEX_STATUS;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
UINT16 opcode;
|
||||
UINT8 param_len;
|
||||
UINT8 *p_param_buf;
|
||||
tBTA_SEND_VENDOR_HCI_CMPL_CBACK *vendor_hci_cb;
|
||||
}tBTA_DM_API_SEND_VENDOR_HCI_CMD;
|
||||
|
||||
/* data type for BTA_DM_API_CONFIG_EIR_EVT */
|
||||
typedef struct {
|
||||
BT_HDR hdr;
|
||||
@@ -1162,6 +1171,7 @@ typedef union {
|
||||
#if (ESP_COEX_VSC_INCLUDED == TRUE)
|
||||
tBTA_DM_API_CFG_COEX_STATUS cfg_coex_status;
|
||||
#endif
|
||||
tBTA_DM_API_SEND_VENDOR_HCI_CMD vendor_hci_cmd;
|
||||
tBTA_DM_API_CONFIG_EIR config_eir;
|
||||
|
||||
tBTA_DM_API_SET_AFH_CHANNELS set_afh_channels;
|
||||
@@ -1676,6 +1686,7 @@ 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
|
||||
extern void bta_dm_send_vendor_hci(tBTA_DM_MSG *p_data);
|
||||
#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);
|
||||
|
@@ -417,6 +417,8 @@ typedef void (tBTA_UPDATE_DUPLICATE_EXCEPTIONAL_LIST_CMPL_CBACK) (tBTA_STATUS st
|
||||
|
||||
typedef void (tBTA_SET_ADV_DATA_CMPL_CBACK) (tBTA_STATUS status);
|
||||
|
||||
typedef tBTM_VSC_CMPL_CB tBTA_SEND_VENDOR_HCI_CMPL_CBACK;
|
||||
|
||||
typedef tBTM_START_ADV_CMPL_CBACK tBTA_START_ADV_CMPL_CBACK;
|
||||
|
||||
typedef tBTM_START_STOP_ADV_CMPL_CBACK tBTA_START_STOP_ADV_CMPL_CBACK;
|
||||
@@ -433,6 +435,8 @@ typedef tBTM_SET_LOCAL_PRIVACY_CBACK tBTA_SET_LOCAL_PRIVACY_CBACK;
|
||||
|
||||
typedef tBTM_CMPL_CB tBTA_CMPL_CB;
|
||||
|
||||
typedef tBTM_VSC_CMPL tBTA_VSC_CMPL;
|
||||
|
||||
typedef tBTM_TX_POWER_RESULTS tBTA_TX_POWER_RESULTS;
|
||||
|
||||
typedef tBTM_RSSI_RESULTS tBTA_RSSI_RESULTS;
|
||||
@@ -1744,6 +1748,8 @@ extern void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback);
|
||||
extern void BTA_DmCfgCoexStatus(UINT8 op, UINT8 type, UINT8 status);
|
||||
#endif
|
||||
|
||||
extern void BTA_DmsendVendorHciCmd(UINT16 opcode, UINT8 param_len, UINT8 *p_param_buf, tBTA_SEND_VENDOR_HCI_CMPL_CBACK p_vendor_cmd_complete_cback);
|
||||
|
||||
/*******************************************************************************
|
||||
**
|
||||
** Function BTA_DmGetRemoteName
|
||||
|
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2023 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -48,6 +48,43 @@ static void btc_dev_get_dev_name_callback(UINT8 status, char *name)
|
||||
}
|
||||
}
|
||||
|
||||
static void btc_dev_vendor_hci_cmd_complete_callback(tBTA_VSC_CMPL *p_param)
|
||||
{
|
||||
bool param_invalid = false;
|
||||
if ((!p_param) || (!p_param->param_len) || (!p_param->p_param_buf)) {
|
||||
BTC_TRACE_ERROR("%s param error\n", __func__);
|
||||
param_invalid = true;
|
||||
}
|
||||
|
||||
esp_bt_dev_cb_param_t param = {0};
|
||||
bt_status_t ret;
|
||||
btc_msg_t msg = {0};
|
||||
|
||||
msg.sig = BTC_SIG_API_CB;
|
||||
msg.pid = BTC_PID_DEV;
|
||||
msg.act = ESP_BT_DEV_VENDOR_CMD_COMPLETE_EVT;
|
||||
if (!param_invalid) {
|
||||
param.vendor_cmd_cmpl.opcode = p_param->opcode;
|
||||
param.vendor_cmd_cmpl.param_len = p_param->param_len;
|
||||
param.vendor_cmd_cmpl.p_param_buf = p_param->p_param_buf;
|
||||
} else {
|
||||
if (p_param) {
|
||||
param.vendor_cmd_cmpl.opcode = p_param->opcode;
|
||||
} else {
|
||||
param.vendor_cmd_cmpl.opcode = 0;
|
||||
}
|
||||
param.vendor_cmd_cmpl.param_len = 0;
|
||||
param.vendor_cmd_cmpl.p_param_buf = NULL;
|
||||
}
|
||||
|
||||
ret = btc_transfer_context(&msg, ¶m, sizeof(esp_bt_dev_cb_param_t), btc_dev_cb_arg_deep_copy, btc_dev_cb_arg_deep_free);
|
||||
|
||||
if (ret != BT_STATUS_SUCCESS) {
|
||||
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void btc_dev_call_arg_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
BTC_TRACE_DEBUG("%s \n", __func__);
|
||||
@@ -65,12 +102,65 @@ void btc_dev_call_arg_deep_free(btc_msg_t *msg)
|
||||
case BTC_DEV_ACT_CFG_COEX_STATUS:
|
||||
#endif
|
||||
break;
|
||||
case BTC_DEV_ACT_VENDOR_HCI_CMD_EVT: {
|
||||
uint8_t *p_param_buf = ((btc_dev_args_t *)msg->arg)->vendor_cmd_send.p_param_buf;
|
||||
if (p_param_buf) {
|
||||
osi_free(p_param_buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_dev_call_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
switch (msg->act) {
|
||||
case BTC_DEV_ACT_VENDOR_HCI_CMD_EVT: {
|
||||
btc_dev_args_t *src = (btc_dev_args_t *)p_src;
|
||||
btc_dev_args_t *dst = (btc_dev_args_t *)p_dest;
|
||||
if (src->vendor_cmd_send.param_len) {
|
||||
dst->vendor_cmd_send.p_param_buf = osi_malloc(src->vendor_cmd_send.param_len);
|
||||
if (dst->vendor_cmd_send.p_param_buf) {
|
||||
memcpy(dst->vendor_cmd_send.p_param_buf, src->vendor_cmd_send.p_param_buf, src->vendor_cmd_send.param_len);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s %d no mem\n",__func__, msg->act);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BTC_TRACE_ERROR("Unhandled deep copy %d\n", msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_dev_cb_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
|
||||
{
|
||||
switch (msg->act) {
|
||||
case ESP_BT_DEV_VENDOR_CMD_COMPLETE_EVT: {
|
||||
esp_bt_dev_cb_param_t *src = (esp_bt_dev_cb_param_t *)p_src;
|
||||
esp_bt_dev_cb_param_t *dst = (esp_bt_dev_cb_param_t *) p_dest;
|
||||
|
||||
if (src->vendor_cmd_cmpl.param_len) {
|
||||
dst->vendor_cmd_cmpl.p_param_buf = osi_malloc(src->vendor_cmd_cmpl.param_len);
|
||||
if (dst->vendor_cmd_cmpl.p_param_buf) {
|
||||
memcpy(dst->vendor_cmd_cmpl.p_param_buf, src->vendor_cmd_cmpl.p_param_buf,
|
||||
src->vendor_cmd_cmpl.param_len);
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s, malloc failed\n", __func__);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BTC_TRACE_ERROR("%s, Unhandled deep copy %d\n", __func__, msg->act);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void btc_dev_cb_arg_deep_free(btc_msg_t *msg)
|
||||
{
|
||||
BTC_TRACE_DEBUG("%s \n", __func__);
|
||||
@@ -83,6 +173,13 @@ void btc_dev_cb_arg_deep_free(btc_msg_t *msg)
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ESP_BT_DEV_VENDOR_CMD_COMPLETE_EVT: {
|
||||
uint8_t *value = ((esp_bt_dev_cb_param_t *)msg->arg)->vendor_cmd_cmpl.p_param_buf;
|
||||
if (value) {
|
||||
osi_free(value);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
BTC_TRACE_DEBUG("Unhandled deep free %d\n", msg->act);
|
||||
break;
|
||||
@@ -109,6 +206,12 @@ void btc_dev_call_handler(btc_msg_t *msg)
|
||||
arg->cfg_coex_status.status);
|
||||
break;
|
||||
#endif
|
||||
case BTC_DEV_ACT_VENDOR_HCI_CMD_EVT:
|
||||
BTA_DmsendVendorHciCmd(arg->vendor_cmd_send.opcode,
|
||||
arg->vendor_cmd_send.param_len,
|
||||
arg->vendor_cmd_send.p_param_buf,
|
||||
btc_dev_vendor_hci_cmd_complete_callback);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@@ -17,6 +17,7 @@ typedef enum {
|
||||
#if (ESP_COEX_VSC_INCLUDED == TRUE)
|
||||
BTC_DEV_ACT_CFG_COEX_STATUS,
|
||||
#endif
|
||||
BTC_DEV_ACT_VENDOR_HCI_CMD_EVT,
|
||||
} btc_dev_act_t;
|
||||
|
||||
/* btc_dev_args_t */
|
||||
@@ -34,9 +35,21 @@ typedef union {
|
||||
uint8_t status;
|
||||
} cfg_coex_status;
|
||||
#endif
|
||||
|
||||
//BTC_DEV_VENDOR_HCI_CMD_EVT
|
||||
struct vendor_cmd_send_args {
|
||||
uint16_t opcode;
|
||||
uint8_t param_len;
|
||||
uint8_t *p_param_buf;
|
||||
} vendor_cmd_send;
|
||||
} btc_dev_args_t;
|
||||
|
||||
void btc_dev_call_handler(btc_msg_t *msg);
|
||||
void btc_dev_cb_handler(btc_msg_t *msg);
|
||||
void btc_dev_call_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
void btc_dev_call_arg_deep_free(btc_msg_t *msg);
|
||||
|
||||
void btc_dev_cb_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src);
|
||||
void btc_dev_cb_arg_deep_free(btc_msg_t *msg);
|
||||
|
||||
#endif /* __BTC_DEV_H__ */
|
||||
|
@@ -740,8 +740,9 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
break;
|
||||
}
|
||||
#endif // (BLE_INCLUDED == TRUE)
|
||||
tBTM_VSC_CMPL vcs_cplt_params;
|
||||
|
||||
/* If there was a callback address for vcs complete, call it */
|
||||
@@ -752,7 +753,7 @@ void btm_vsc_complete (UINT8 *p, UINT16 opcode, UINT16 evt_len,
|
||||
vcs_cplt_params.p_param_buf = p;
|
||||
(*p_vsc_cplt_cback)(&vcs_cplt_params); /* Call the VSC complete callback function */
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
|
Reference in New Issue
Block a user