feat(bt/bluedroid): add api to setnd vendor hci command

This commit is contained in:
zhiweijian 2024-04-09 15:31:54 +08:00
parent eefcec929e
commit 070f6b4c9a
10 changed files with 196 additions and 2 deletions

View File

@ -1599,3 +1599,31 @@ esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, con
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}
#endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE)
esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cmd_param)
{
btc_msg_t msg = {0};
btc_ble_gap_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_INVALID_ARG;
}
// If command is not a VSC, return error
if ((vendor_cmd_param->opcode & VENDOR_HCI_CMD_MASK) != VENDOR_HCI_CMD_MASK) {
return ESP_ERR_INVALID_ARG;
}
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_GAP_BLE;
msg.act = BTC_GAP_BLE_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_ble_gap_args_t), btc_gap_ble_arg_deep_copy, btc_gap_ble_arg_deep_free)
== BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL);
}

View File

@ -224,6 +224,7 @@ typedef enum {
ESP_GAP_BLE_DTM_TEST_UPDATE_EVT, /*!< when direct test mode state changes, the event comes */
// BLE_INCLUDED
ESP_GAP_BLE_ADV_CLEAR_COMPLETE_EVT, /*!< When clear advertising complete, the event comes */
ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT, /*!< When vendor hci command complete, the event comes */
ESP_GAP_BLE_EVT_MAX, /*!< when maximum advertising event complete, the event comes */
} esp_gap_ble_cb_event_t;
@ -238,6 +239,8 @@ typedef uint8_t esp_gap_ble_channels[ESP_GAP_BLE_CHANNELS_LEN];
/// Scan response data maximum length
#define ESP_BLE_SCAN_RSP_DATA_LEN_MAX 31
#define VENDOR_HCI_CMD_MASK (0x3F << 10) /**!< 0xFC00 */
/* relate to BTM_BLE_AD_TYPE_xxx in stack/btm_ble_api.h */
/// The type of advertising data(not adv_type)
typedef enum {
@ -364,6 +367,15 @@ typedef enum {
DTM_TEST_STOP_EVT,
} esp_ble_dtm_update_evt_t;
/**
* @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_ble_vendor_cmd_params_t;
#if (BLE_42_FEATURE_SUPPORT == TRUE)
/**
* @brief DTM TX parameters
@ -1471,6 +1483,14 @@ typedef union {
esp_ble_dtm_update_evt_t update_evt; /*!< DTM state change event, 0x00: DTM TX start, 0x01: DTM RX start, 0x02:DTM end */
uint16_t num_of_pkt; /*!< number of packets received, only valid if update_evt is DTM_TEST_STOP_EVT and shall be reported as 0 for a transmitter */
} dtm_state_update; /*!< Event parameter of ESP_GAP_BLE_DTM_TEST_UPDATE_EVT */
/**
* @brief ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT
*/
struct vendor_cmd_cmpl_evt_param {
uint16_t opcode; /*!< vendor hci command opcode */
uint16_t param_len; /*!< The length of parameter buffer */
uint8_t *p_param_buf; /*!< The point of parameter buffer */
} vendor_cmd_cmpl; /*!< Event parameter of ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT */
} esp_ble_gap_cb_param_t;
/**
@ -2540,6 +2560,19 @@ esp_err_t esp_ble_dtm_stop(void);
*/
esp_err_t esp_ble_gap_clear_advertising(void);
/**
* @brief This function is called to send vendor hci command.
*
*
*
* @param[in] vendor_cmd_param: vendor hci command parameters
*
* @return
* - ESP_OK : success
* - other : failed
*/
esp_err_t esp_ble_gap_vendor_command_send(esp_ble_vendor_cmd_params_t *vendor_cmd_param);
#ifdef __cplusplus
}
#endif

View File

@ -707,6 +707,14 @@ void bta_dm_get_dev_name (tBTA_DM_MSG *p_data)
}
}
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

View File

@ -202,6 +202,21 @@ void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback)
}
}
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)

View File

@ -59,6 +59,7 @@ 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 */
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_acl_pkt_types, /* BTA_DM_API_SET_ACL_PKT_TYPES_EVT */

View File

@ -54,6 +54,7 @@ enum {
BTA_DM_API_DISABLE_EVT,
BTA_DM_API_SET_NAME_EVT,
BTA_DM_API_GET_NAME_EVT,
BTA_DM_API_SEND_VENDOR_HCI_CMD_EVT,
#if (CLASSIC_BT_INCLUDED == TRUE)
BTA_DM_API_CONFIG_EIR_EVT,
BTA_DM_API_SET_ACL_PKT_TYPES_EVT,
@ -251,6 +252,14 @@ typedef struct {
tBTA_GET_DEV_NAME_CBACK *p_cback;
} tBTA_DM_API_GET_NAME;
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;
@ -1132,6 +1141,7 @@ typedef union {
tBTA_DM_API_SET_NAME set_name;
tBTA_DM_API_GET_NAME get_name;
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;
@ -1641,6 +1651,7 @@ 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);
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_acl_pkt_types (tBTA_DM_MSG *p_data);

View File

@ -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;
@ -1720,6 +1724,8 @@ extern void BTA_DmSetDeviceName(const char *p_name);
*******************************************************************************/
extern void BTA_DmGetDeviceName(tBTA_GET_DEV_NAME_CBACK *p_cback);
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

View File

@ -1249,6 +1249,42 @@ void btc_dtm_stop_callback(void *p1)
}
}
static void btc_ble_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_ble_gap_cb_param_t param = {0};
bt_status_t ret;
btc_msg_t msg = {0};
msg.sig = BTC_SIG_API_CB;
msg.pid = BTC_PID_GAP_BLE;
msg.act = ESP_GAP_BLE_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, &param, sizeof(esp_ble_gap_cb_param_t), btc_gap_ble_cb_deep_copy, btc_gap_ble_cb_deep_free);
if (ret != BT_STATUS_SUCCESS) {
BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__);
}
}
void btc_get_whitelist_size(uint16_t *length)
{
BTM_BleGetWhiteListSize(length);
@ -1591,6 +1627,19 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
break;
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: {
btc_ble_gap_args_t *src = (btc_ble_gap_args_t *)p_src;
btc_ble_gap_args_t *dst = (btc_ble_gap_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;
@ -1599,7 +1648,22 @@ void btc_gap_ble_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
void btc_gap_ble_cb_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
{
esp_ble_gap_cb_param_t *src = (esp_ble_gap_cb_param_t *)p_src;
esp_ble_gap_cb_param_t *dst = (esp_ble_gap_cb_param_t *) p_dest;
switch (msg->act) {
case ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT: {
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;
@ -1697,6 +1761,13 @@ void btc_gap_ble_arg_deep_free(btc_msg_t *msg)
break;
}
#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT: {
uint8_t *p_param_buf = ((btc_ble_gap_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;
@ -1714,6 +1785,13 @@ void btc_gap_ble_cb_deep_free(btc_msg_t *msg)
}
break;
}
case ESP_GAP_BLE_VENDOR_CMD_COMPLETE_EVT: {
uint8_t *value = ((esp_ble_gap_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", msg->act);
break;
@ -2185,6 +2263,12 @@ void btc_gap_ble_call_handler(btc_msg_t *msg)
btc_ble_dtm_enhance_rx_start(arg_5->dtm_enh_rx_start.rx_channel, arg_5->dtm_enh_rx_start.phy, arg_5->dtm_enh_rx_start.modulation_index, btc_dtm_rx_start_callback);
break;
#endif // if (BLE_50_FEATURE_SUPPORT == TRUE)
case BTC_GAP_BLE_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_ble_vendor_hci_cmd_complete_callback);
break;
default:
break;
}

View File

@ -102,6 +102,7 @@ typedef enum {
#if (BLE_42_FEATURE_SUPPORT == TRUE)
BTC_GAP_BLE_ACT_CLEAR_ADV,
#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE)
BTC_GAP_BLE_ACT_VENDOR_HCI_CMD_EVT,
} btc_gap_ble_act_t;
/* btc_ble_gap_args_t */
@ -248,6 +249,12 @@ typedef union {
struct dtm_rx_start_args {
uint8_t rx_channel;
} dtm_rx_start;
//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_ble_gap_args_t;
#if (BLE_50_FEATURE_SUPPORT == TRUE)

View File

@ -723,8 +723,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 */
@ -735,7 +736,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
}
/*******************************************************************************