From 1e72b8b803908a901322b5ab71f40043a31cb383 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Thu, 7 Sep 2023 20:38:12 +0800 Subject: [PATCH 1/5] feat(ble/bluedroid): Add APIs for BLE direct test mode on bluedroid host --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 99 ++++++++++++- .../api/include/api/esp_gap_ble_api.h | 135 ++++++++++++++++- .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 27 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 76 ++++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 5 + .../bluedroid/bta/dm/include/bta_dm_int.h | 51 +++++++ .../host/bluedroid/bta/include/bta/bta_api.h | 10 ++ .../btc/profile/std/gap/btc_gap_ble.c | 138 +++++++++++++++++- .../btc/profile/std/include/btc_gap_ble.h | 29 +++- .../bt/host/bluedroid/stack/hcic/hciblecmds.c | 8 +- .../bluedroid/stack/include/stack/btm_api.h | 2 + .../stack/include/stack/btm_ble_api.h | 5 + 12 files changed, 578 insertions(+), 7 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 9cc9394f9dba..7baf8986b9a3 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -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 */ @@ -839,6 +839,103 @@ esp_err_t esp_gap_ble_set_authorization(esp_bd_addr_t bd_addr, bool authorize) return ESP_FAIL; } +#if (BLE_42_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!tx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_TX_START; + + memcpy(&arg.dtm_tx_start, tx_params, sizeof(esp_ble_dtm_tx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!rx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_RX_START; + + memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_rx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!tx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_ENH_TX_START; + + memcpy(&arg.dtm_tx_start, tx_params, sizeof(esp_ble_dtm_enh_tx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + +esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params) +{ + btc_msg_t msg = {0}; + btc_ble_gap_args_t arg; + + if (!rx_params) { + return ESP_ERR_INVALID_ARG; + } + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_ENH_RX_START; + + memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_enh_rx_t)); + + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +esp_err_t esp_ble_dtm_stop(void) +{ + btc_msg_t msg = {0}; + + ESP_BLUEDROID_STATUS_CHECK(ESP_BLUEDROID_STATUS_ENABLED); + + msg.sig = BTC_SIG_API_CALL; + msg.pid = BTC_PID_GAP_BLE; + msg.act = BTC_GAP_BLE_DTM_STOP; + + return (btc_transfer_context(&msg, NULL, 0, NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); +} + #if (BLE_50_FEATURE_SUPPORT == TRUE) esp_err_t esp_ble_gap_read_phy(esp_bd_addr_t bd_addr) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 8e24120e4e4f..93080a33f680 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -208,6 +208,8 @@ typedef enum { ESP_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS_COMPLETE_EVT, /*!< when periodic advertising set info transfer complete, the event comes */ ESP_GAP_BLE_SET_PAST_PARAMS_COMPLETE_EVT, /*!< when set periodic advertising sync transfer params complete, the event comes */ ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT, /*!< when periodic advertising sync transfer received, the event comes */ + // DTM + 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_EVT_MAX, /*!< when maximum advertising event complete, the event comes */ @@ -341,7 +343,45 @@ typedef enum { ESP_BLE_SM_MAX_PARAM, } esp_ble_sm_param_t; +typedef enum { + /// DTM TX start event + DTM_TX_START_EVT = 0x00, + ///DTM RX start event + DTM_RX_START_EVT, + ///DTM test end event + DTM_TEST_STOP_EVT, +} esp_ble_dtm_update_evt_t; + +typedef enum { + BLE_DTM_PKT_PAYLOAD_0x00, /*!< PRBS9 sequence ‘11111111100000111101...’ (in transmission order) as described in [Vol 6] Part F, Section 4.1.5 */ + BLE_DTM_PKT_PAYLOAD_0x01, /*!< Repeated ‘11110000’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ + BLE_DTM_PKT_PAYLOAD_0x02, /*!< Repeated ‘10101010’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ + BLE_DTM_PKT_PAYLOAD_0x03, /*!< PRBS15 sequence as described in [Vol 6] Part F, Section 4.1.5 */ + BLE_DTM_PKT_PAYLOAD_0x04, /*!< Repeated ‘11111111’ (in transmission order) sequence */ + BLE_DTM_PKT_PAYLOAD_0x05, /*!< Repeated ‘00000000’ (in transmission order) sequence */ + BLE_DTM_PKT_PAYLOAD_0x06, /*!< Repeated ‘00001111’ (in transmission order) sequence */ + BLE_DTM_PKT_PAYLOAD_0x07, /*!< Repeated ‘01010101’ (in transmission order) sequence */ + BLE_DTM_PKT_PAYLOAD_MAX, /*!< 0x08 ~ 0xFF, Reserved for future use */ +} esp_ble_dtm_pkt_payload_t; + #if (BLE_42_FEATURE_SUPPORT == TRUE) +/** +* @brief DTM TX parameters +*/ +typedef struct +{ + uint8_t tx_channel; /*!< channel for sending test data, tx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + uint8_t len_of_data; /*!< length in bytes of payload data in each packet */ + esp_ble_dtm_pkt_payload_t pkt_payload; /*!< packet payload type. value range: 0x00-0x07 */ +} esp_ble_dtm_tx_t; +/** +* @brief DTM RX parameters +*/ +typedef struct +{ + uint8_t rx_channel; /*!< channel for test data reception, rx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ +} esp_ble_dtm_rx_t; + /// Advertising parameters typedef struct { uint16_t adv_int_min; /*!< Minimum advertising interval for @@ -933,6 +973,27 @@ typedef struct { uint8_t adv_clk_accuracy; /*!< periodic advertising clock accuracy */ } esp_ble_gap_periodic_adv_sync_estab_t; +/** +* @brief DTM TX parameters +*/ +typedef struct +{ + uint8_t tx_channel; /*!< channel for sending test data, tx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + uint8_t len_of_data; /*!< length in bytes of payload data in each packet */ + esp_ble_dtm_pkt_payload_t pkt_payload; /*!< packet payload type. value range: 0x00-0x07 */ + esp_ble_gap_phy_t phy; /*!< the phy type used by the transmitter, coded phy with S=2:0x04 */ +} esp_ble_dtm_enh_tx_t; + +/** +* @brief DTM RX parameters +*/ +typedef struct +{ + uint8_t rx_channel; /*!< channel for test data reception, rx_channel = (Frequency -2402)/2, tx_channel range:0x00-0x27, Frequency range: 2402 MHz to 2480 MHz */ + esp_ble_gap_phy_t phy; /*!< the phy type used by the receiver, 1M phy: 0x01, 2M phy:0x02, coded phy:0x03 */ + uint8_t modulation_idx; /*!< modulation index, 0x00:standard modulation index, 0x01:stable modulation index */ +} esp_ble_dtm_enh_rx_t; + #endif //#if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) @@ -1402,6 +1463,14 @@ typedef union { uint8_t adv_clk_accuracy; /*!< Periodic advertising clock accuracy */ } past_received; /*!< Event parameter of ESP_GAP_BLE_PERIODIC_ADV_SYNC_TRANS_RECV_EVT */ #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + /** + * @brief ESP_GAP_BLE_DTM_TEST_UPDATE_EVT + */ + struct ble_dtm_state_update_evt_param { + esp_bt_status_t status; /*!< Indicate DTM operation success status */ + 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 */ } esp_ble_gap_cb_param_t; /** @@ -2397,14 +2466,78 @@ esp_err_t esp_ble_gap_set_periodic_adv_sync_trans_params(esp_bd_addr_t addr, const esp_ble_gap_past_params_t *params); #endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_42_FEATURE_SUPPORT == TRUE) + /** -* @brief This function is used to clear legacy advertising +* @brief This function is used to start a test where the DUT generates reference packets +* at a fixed interval. * +* @param[in] tx_params : DTM Transmitter parameters * * @return - ESP_OK : success * - other : failed * */ +esp_err_t esp_ble_dtm_tx_start(const esp_ble_dtm_tx_t *tx_params); + +/** +* @brief This function is used to start a test where the DUT receives test reference packets +* at a fixed interval. +* +* @param[in] rx_params : DTM Receiver parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params); +#endif //#if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to start a test where the DUT generates reference packets +* at a fixed interval. +* +* @param[in] tx_params : DTM Transmitter parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params); + +/** +* @brief This function is used to start a test where the DUT receives test reference packets +* at a fixed interval. +* +* @param[in] rx_params : DTM Receiver parameters +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params); +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +/** +* @brief This function is used to stop any test which is in progress +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ +esp_err_t esp_ble_dtm_stop(void); + +/** +* @brief This function is used to clear legacy advertising +* +* +* @return - ESP_OK : success +* - other : failed +* +*/ esp_err_t esp_ble_gap_clear_advertising(void); #ifdef __cplusplus 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 3998c510ae33..5454fde74048 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5704,6 +5704,21 @@ void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data) } } +void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleTransmitterTest(p_data->dtm_tx_start.tx_channel, p_data->dtm_tx_start.len_of_data, p_data->dtm_tx_start.pkt_payload, p_data->dtm_tx_start.p_dtm_cmpl_cback); +} + +void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleReceiverTest(p_data->dtm_rx_start.rx_channel, p_data->dtm_rx_start.p_dtm_cmpl_cback); +} + +void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data) +{ + BTM_BleTestEnd(p_data->dtm_stop.p_dtm_cmpl_cback); +} + void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data) { if (BTM_BleClearAdv(p_data->ble_clear_adv.p_clear_adv_cback) == FALSE) { @@ -5714,6 +5729,18 @@ void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data) } #if (BLE_50_FEATURE_SUPPORT == TRUE) +void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleEnhancedTransmitterTest(p_data->dtm_enh_tx_start.tx_channel, p_data->dtm_enh_tx_start.len_of_data, + p_data->dtm_enh_tx_start.pkt_payload, p_data->dtm_enh_tx_start.phy, p_data->dtm_enh_tx_start.p_dtm_cmpl_cback); +} + +void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data) +{ + BTM_BleEnhancedReceiverTest(p_data->dtm_enh_rx_start.rx_channel, p_data->dtm_enh_rx_start.phy, + p_data->dtm_enh_rx_start.modulation_index, p_data->dtm_enh_rx_start.p_dtm_cmpl_cback); +} + void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data) { //tBTM_STATUS btm_status = 0; 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 1a1ce85b075d..f57e80cf8d01 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2526,6 +2526,49 @@ void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_S } } +void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_TX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_TX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_TX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_TX_START_EVT; + p_msg->tx_channel = tx_channel; + p_msg->len_of_data = len_of_data; + p_msg->pkt_payload = pkt_payload; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_RX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_RX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_RX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_RX_START_EVT; + p_msg->rx_channel= rx_channel; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_STOP *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_STOP *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_STOP))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_STOP_EVT; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + #endif /******************************************************************************* @@ -3206,6 +3249,39 @@ void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_add } +void BTA_DmBleDtmEnhTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_ENH_TX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_ENH_TX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_ENH_TX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_ENH_TX_START_EVT; + p_msg->tx_channel = tx_channel; + p_msg->len_of_data = len_of_data; + p_msg->pkt_payload = pkt_payload; + p_msg->phy = phy; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + +void BTA_DmBleDtmEnhRxStart(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + tBTA_DM_API_BLE_DTM_ENH_RX_START *p_msg; + + if ((p_msg = (tBTA_DM_API_BLE_DTM_ENH_RX_START *)osi_malloc(sizeof(tBTA_DM_API_BLE_DTM_ENH_RX_START))) + != NULL) { + p_msg->hdr.event = BTA_DM_API_DTM_ENH_RX_START_EVT; + p_msg->rx_channel= rx_channel; + p_msg->phy = phy; + p_msg->modulation_index = modulation_index; + p_msg->p_dtm_cmpl_cback = p_dtm_cmpl_cback; + + bta_sys_sendmsg(p_msg); + } +} + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) 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 08b014e9c022..ce83c9fc3428 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -204,6 +204,8 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_ext_scan, /* BTA_DM_API_START_EXT_SCAN_EVT */ bta_dm_ble_gap_set_prefer_ext_conn_params, /* BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT */ NULL, /* BTA_DM_API_EXT_CONN_EVT */ + bta_dm_ble_gap_dtm_enhance_tx_start, /* BTA_DM_API_DTM_ENH_TX_START_EVT */ + bta_dm_ble_gap_dtm_enhance_rx_start, /* BTA_DM_API_DTM_ENH_RX_START_EVT */ #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) bta_dm_ble_gap_periodic_adv_recv_enable, /* BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT */ @@ -212,6 +214,9 @@ const tBTA_DM_ACTION bta_dm_action[BTA_DM_MAX_EVT] = { bta_dm_ble_gap_set_periodic_adv_sync_trans_params, /* BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT */ #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #if BLE_INCLUDED == TRUE + bta_dm_ble_gap_dtm_tx_start, /* BTA_DM_API_DTM_TX_START_EVT */ + bta_dm_ble_gap_dtm_rx_start, /* BTA_DM_API_DTM_RX_START_EVT */ + bta_dm_ble_gap_dtm_stop, /* BTA_DM_API_DTM_STOP_EVT */ bta_dm_ble_gap_clear_adv, /* BTA_DM_API_BLE_CLEAR_ADV_EVT */ #endif }; 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 1d8e16d7ea95..7448287dd491 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 @@ -200,6 +200,8 @@ enum { BTA_DM_API_START_EXT_SCAN_EVT, BTA_DM_API_SET_PERF_EXT_CONN_PARAMS_EVT, BTA_DM_API_EXT_CONN_EVT, + BTA_DM_API_DTM_ENH_TX_START_EVT, + BTA_DM_API_DTM_ENH_RX_START_EVT, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) BTA_DM_API_PERIODIC_ADV_RECV_ENABLE_EVT, @@ -208,6 +210,9 @@ enum { BTA_DM_API_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS_EVT, #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) #if BLE_INCLUDED == TRUE + BTA_DM_API_DTM_TX_START_EVT, + BTA_DM_API_DTM_RX_START_EVT, + BTA_DM_API_DTM_STOP_EVT, BTA_DM_API_BLE_CLEAR_ADV_EVT, #endif BTA_DM_MAX_EVT @@ -855,6 +860,25 @@ typedef struct { BD_ADDR remote_bda; } tBTA_DM_API_BLE_DISCONNECT; +typedef struct { + BT_HDR hdr; + UINT8 tx_channel; + UINT8 len_of_data; + UINT8 pkt_payload; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_TX_START; + +typedef struct { + BT_HDR hdr; + UINT8 rx_channel; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_RX_START; + +typedef struct { + BT_HDR hdr; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_STOP; + typedef struct { BT_HDR hdr; tBTA_CLEAR_ADV_CMPL_CBACK *p_clear_adv_cback; @@ -916,6 +940,22 @@ typedef struct { #endif #if (BLE_50_FEATURE_SUPPORT == TRUE) +typedef struct { + BT_HDR hdr; + UINT8 tx_channel; + UINT8 len_of_data; + UINT8 pkt_payload; + UINT8 phy; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_ENH_TX_START; +typedef struct { + BT_HDR hdr; + UINT8 rx_channel; + UINT8 phy; + UINT8 modulation_index; + tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback; +} tBTA_DM_API_BLE_DTM_ENH_RX_START; + #define BTA_PHY_1M_MASK (1 << 0) #define BTA_PHY_2M_MASK (1 << 1) #define BTAS_PHY_CODED_MASK (1 << 2) @@ -1224,6 +1264,8 @@ typedef union { tBTA_DM_API_SET_EXT_SCAN_PARAMS ble_set_ext_scan_params; tBTA_DM_API_EXT_SCAN ble_ext_scan; tBTA_DM_API_SET_PER_EXT_CONN_PARAMS ble_set_per_ext_conn_params; + tBTA_DM_API_BLE_DTM_ENH_TX_START dtm_enh_tx_start; + tBTA_DM_API_BLE_DTM_ENH_RX_START dtm_enh_rx_start; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) tBTA_DM_API_PERIODIC_ADV_RECV_ENABLE ble_periodic_adv_recv_enable; @@ -1231,6 +1273,10 @@ typedef union { tBTA_DM_API_PERIODIC_ADV_SET_INFO_TRANS ble_periodic_adv_set_info_trans; tBTA_DM_API_SET_PAST_PARAMS ble_set_past_params; #endif // #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) + + tBTA_DM_API_BLE_DTM_TX_START dtm_tx_start; + tBTA_DM_API_BLE_DTM_RX_START dtm_rx_start; + tBTA_DM_API_BLE_DTM_STOP dtm_stop; tBTA_DM_API_CLEAR_ADV ble_clear_adv; #endif @@ -1664,9 +1710,14 @@ extern void btm_dm_ble_multi_adv_disable(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_data(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_upd_param(tBTA_DM_MSG *p_data); extern void bta_dm_ble_multi_adv_enb(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_dtm_tx_start(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_dtm_rx_start(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_dtm_stop(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_clear_adv(tBTA_DM_MSG *p_data); #if (BLE_50_FEATURE_SUPPORT == TRUE) +extern void bta_dm_ble_gap_dtm_enhance_tx_start(tBTA_DM_MSG *p_data); +extern void bta_dm_ble_gap_dtm_enhance_rx_start(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_read_phy(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_default_phy(tBTA_DM_MSG *p_data); extern void bta_dm_ble_gap_set_prefer_phy(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 7768eda46fb6..febad16d9400 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -425,6 +425,8 @@ typedef tBTM_UPDATE_WHITELIST_CBACK tBTA_UPDATE_WHITELIST_CBACK; typedef tBTM_SET_PKT_DATA_LENGTH_CBACK tBTA_SET_PKT_DATA_LENGTH_CBACK; +typedef tBTM_DTM_CMD_CMPL_CBACK tBTA_DTM_CMD_CMPL_CBACK; + typedef tBTM_SET_RAND_ADDR_CBACK tBTA_SET_RAND_ADDR_CBACK; typedef tBTM_SET_LOCAL_PRIVACY_CBACK tBTA_SET_LOCAL_PRIVACY_CBACK; @@ -2808,6 +2810,10 @@ extern void BTA_DmBleDisconnect(BD_ADDR bd_addr); *******************************************************************************/ extern void BTA_DmBleSetDataLength(BD_ADDR remote_device, UINT16 tx_data_length, tBTA_SET_PKT_DATA_LENGTH_CBACK *p_set_pkt_data_cback); +extern void BTA_DmBleDtmTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); +extern void BTA_DmBleDtmRxStart(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); +extern void BTA_DmBleDtmStop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); + /******************************************************************************* ** ** Function BTA_DmBleSetStorageParams @@ -3062,6 +3068,10 @@ extern void BTA_DmBleGapPreferExtConnectParamsSet(BD_ADDR bd_addr, const tBTA_DM_BLE_CONN_PARAMS *phy_coded_conn_params); extern void BTA_DmBleGapExtConnect(tBLE_ADDR_TYPE own_addr_type, const BD_ADDR peer_addr); + +extern void BTA_DmBleDtmEnhTxStart(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); + +extern void BTA_DmBleDtmEnhRxStart(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback); #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index a90083f30e5f..d5be086a3231 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -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 */ @@ -1164,6 +1164,91 @@ static void btc_ble_5_gap_callback(tBTA_DM_BLE_5_GAP_EVENT event, } } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +void btc_dtm_tx_start_callback(void *p1) +{ + UINT8 status; + UINT8 *p; + p = (UINT8*) p1; + if (p1) { + STREAM_TO_UINT8(status, p); + BTC_TRACE_DEBUG("DTM TX start, status 0x%x\n", status); + esp_ble_gap_cb_param_t param; + 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_DTM_TEST_UPDATE_EVT; + param.dtm_state_update.status = status; + param.dtm_state_update.update_evt = DTM_TX_START_EVT; + param.dtm_state_update.num_of_pkt = 0; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } + } +} + +void btc_dtm_rx_start_callback(void *p1) +{ + + UINT8 status; + UINT8 *p; + p = (UINT8*) p1; + if (p1) { + STREAM_TO_UINT8(status, p); + BTC_TRACE_DEBUG("DTM RX start, status 0x%x\n", status); + esp_ble_gap_cb_param_t param; + 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_DTM_TEST_UPDATE_EVT; + param.dtm_state_update.status = status; + param.dtm_state_update.update_evt = DTM_RX_START_EVT; + param.dtm_state_update.num_of_pkt = 0; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + if (ret != BT_STATUS_SUCCESS) { + BTC_TRACE_ERROR("%s btc_transfer_context failed\n", __func__); + } + } +} + +void btc_dtm_stop_callback(void *p1) +{ + UINT8 status; + UINT16 num_pkt; + UINT8 *p; + p = (UINT8*) p1; + if (p1) { + STREAM_TO_UINT8(status, p); + STREAM_TO_UINT16(num_pkt, p); + BTC_TRACE_DEBUG("DTM stop, status 0x%x num_pkt %d\n", status, num_pkt); + esp_ble_gap_cb_param_t param; + 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_DTM_TEST_UPDATE_EVT; + param.dtm_state_update.status = status; + param.dtm_state_update.update_evt = DTM_TEST_STOP_EVT; + param.dtm_state_update.num_of_pkt = num_pkt; + + ret = btc_transfer_context(&msg, ¶m, + sizeof(esp_ble_gap_cb_param_t), NULL, NULL); + + 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); @@ -1297,6 +1382,38 @@ static void btc_gap_ble_set_channels(esp_gap_ble_channels channels) BTA_DmBleSetChannels(channels, btc_gap_ble_set_channels_cmpl_callback); } +#if (BLE_42_FEATURE_SUPPORT == TRUE) +static void btc_ble_dtm_tx_start(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + BTA_DmBleDtmTxStart(tx_channel, len_of_data, pkt_payload, p_dtm_cmpl_cback); +} + +static void btc_ble_dtm_rx_start(uint8_t rx_channel, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + + BTA_DmBleDtmRxStart(rx_channel, p_dtm_cmpl_cback); +} +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + +#if (BLE_50_FEATURE_SUPPORT == TRUE) +static void btc_ble_dtm_enhance_tx_start(uint8_t tx_channel, uint8_t len_of_data, uint8_t pkt_payload, uint8_t phy, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + BTA_DmBleDtmEnhTxStart(tx_channel, len_of_data, pkt_payload, phy, p_dtm_cmpl_cback); +} + +static void btc_ble_dtm_enhance_rx_start(uint8_t rx_channel, uint8_t phy, uint8_t modulation_index, tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + + BTA_DmBleDtmEnhRxStart(rx_channel, phy, modulation_index, p_dtm_cmpl_cback); +} +#endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) + +static void btc_ble_dtm_stop(tBTA_DTM_CMD_CMPL_CBACK *p_dtm_cmpl_cback) +{ + + BTA_DmBleDtmStop(p_dtm_cmpl_cback); +} + void btc_gap_ble_cb_handler(btc_msg_t *msg) { @@ -2049,6 +2166,25 @@ void btc_gap_ble_call_handler(btc_msg_t *msg) (tBTA_DM_BLE_PAST_PARAMS *)&arg_5->set_periodic_adv_sync_trans_params.params); break; #endif +#if (BLE_42_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_DTM_TX_START: + btc_ble_dtm_tx_start(arg->dtm_tx_start.tx_channel, arg->dtm_tx_start.len_of_data, arg->dtm_tx_start.pkt_payload, btc_dtm_tx_start_callback); + break; + case BTC_GAP_BLE_DTM_RX_START: + btc_ble_dtm_rx_start(arg->dtm_rx_start.rx_channel, btc_dtm_rx_start_callback); + break; +#endif // if (BLE_42_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_DTM_STOP: + btc_ble_dtm_stop(btc_dtm_stop_callback); + break; +#if (BLE_50_FEATURE_SUPPORT == TRUE) + case BTC_GAP_BLE_DTM_ENH_TX_START: + btc_ble_dtm_enhance_tx_start(arg_5->dtm_enh_tx_start.tx_channel, arg_5->dtm_enh_tx_start.len_of_data, arg_5->dtm_enh_tx_start.pkt_payload, arg_5->dtm_enh_tx_start.phy, btc_dtm_tx_start_callback); + break; + case BTC_GAP_BLE_DTM_ENH_RX_START: + 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) default: break; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index fb998687b9bd..a427be142ca7 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -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 */ @@ -84,6 +84,8 @@ typedef enum { BTC_GAP_BLE_START_EXT_SCAN, BTC_GAP_BLE_STOP_EXT_SCAN, BTC_GAP_BLE_SET_EXT_PEFER_CONNET_PARAMS, + BTC_GAP_BLE_DTM_ENH_TX_START, + BTC_GAP_BLE_DTM_ENH_RX_START, #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_ACT_GET_DEV_NAME, #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) @@ -92,6 +94,11 @@ typedef enum { BTC_GAP_BLE_PERIODIC_ADV_SET_INFO_TRANS, BTC_GAP_BLE_SET_PERIODIC_ADV_SYNC_TRANS_PARAMS, #endif //#if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) +#if (BLE_42_FEATURE_SUPPORT == TRUE) + BTC_GAP_BLE_DTM_TX_START, + BTC_GAP_BLE_DTM_RX_START, +#endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) + BTC_GAP_BLE_DTM_STOP, #if (BLE_42_FEATURE_SUPPORT == TRUE) BTC_GAP_BLE_ACT_CLEAR_ADV, #endif // #if (BLE_42_FEATURE_SUPPORT == TRUE) @@ -233,6 +240,14 @@ typedef union { struct set_channels_args { esp_gap_ble_channels channels; } set_channels; + struct dtm_tx_start_args { + uint8_t tx_channel; + uint8_t len_of_data; + uint8_t pkt_payload; + } dtm_tx_start; + struct dtm_rx_start_args { + uint8_t rx_channel; + } dtm_rx_start; } btc_ble_gap_args_t; #if (BLE_50_FEATURE_SUPPORT == TRUE) @@ -376,7 +391,17 @@ typedef union { esp_ble_gap_past_params_t params; } set_periodic_adv_sync_trans_params; #endif - + struct dtm_enh_tx_start_args { + uint8_t tx_channel; + uint8_t len_of_data; + uint8_t pkt_payload; + uint8_t phy; + } dtm_enh_tx_start; + struct dtm_enh_rx_start_args { + uint8_t rx_channel; + uint8_t phy; + uint8_t modulation_index; + } dtm_enh_rx_start; } btc_ble_5_gap_args_t; #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c index 7e52c236eb6a..0f6408f0826e 100644 --- a/components/bt/host/bluedroid/stack/hcic/hciblecmds.c +++ b/components/bt/host/bluedroid/stack/hcic/hciblecmds.c @@ -1190,7 +1190,9 @@ UINT8 btsnd_hcic_ble_enhand_rx_test(UINT8 rx_channel, UINT8 phy, UINT8_TO_STREAM(pp, phy); UINT8_TO_STREAM(pp, modulation_idx); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; } UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len, @@ -1212,7 +1214,9 @@ UINT8 btsnd_hcic_ble_enhand_tx_test(UINT8 tx_channel, UINT8 len, UINT8_TO_STREAM(pp, packect); UINT8_TO_STREAM(pp, phy); - return btu_hcif_send_cmd_sync(LOCAL_BR_EDR_CONTROLLER_ID, p); + btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p); + + return TRUE; } UINT8 btsnd_hcic_ble_set_extend_rand_address(UINT8 adv_handle, BD_ADDR rand_addr) 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 ece2e29710d0..523af8ed63a3 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_api.h @@ -189,6 +189,8 @@ typedef void (tBTM_UPDATE_CONN_PARAM_CBACK) (UINT8 status, BD_ADDR bd_addr, tBTM typedef void (tBTM_SET_PKT_DATA_LENGTH_CBACK) (UINT8 status, tBTM_LE_SET_PKT_DATA_LENGTH_PARAMS *data_length_params); +typedef void (tBTM_DTM_CMD_CMPL_CBACK) (void *p1); + typedef void (tBTM_SET_RAND_ADDR_CBACK) (UINT8 status); typedef void (tBTM_UPDATE_WHITELIST_CBACK) (UINT8 status, tBTM_WL_OPERATION wl_opration); diff --git a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h index cfc54c4537bc..a3085361da1f 100644 --- a/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h +++ b/components/bt/host/bluedroid/stack/include/stack/btm_ble_api.h @@ -2704,6 +2704,11 @@ tBTM_STATUS BTM_BleSetExtendedScanParams(tBTM_BLE_EXT_SCAN_PARAMS *params); tBTM_STATUS BTM_BleExtendedScan(BOOLEAN enable, UINT16 duration, UINT16 period); void BTM_BleSetPreferExtenedConnParams(BD_ADDR bd_addr, tBTM_EXT_CONN_PARAMS *params); + +void BTM_BleEnhancedReceiverTest(UINT8 rx_freq, UINT8 phy, UINT8 modulation_index, tBTM_CMPL_CB *p_cmd_cmpl_cback); + +void BTM_BleEnhancedTransmitterTest(UINT8 tx_freq, UINT8 test_data_len, UINT8 packet_payload, UINT8 phy, tBTM_CMPL_CB *p_cmd_cmpl_cback); + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_FEAT_PERIODIC_ADV_SYNC_TRANSFER == TRUE) From 304be189d8c20fb4eaeabc3bc0e1d279b745d456 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Sat, 7 Oct 2023 12:17:56 +0800 Subject: [PATCH 2/5] fix(ble/bluedroid): fixed bluedroid host DTM API --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 14 +++++------ .../api/include/api/esp_gap_ble_api.h | 24 +++++++++---------- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 7baf8986b9a3..74fe793400aa 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -875,7 +875,7 @@ esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params) msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_DTM_RX_START; - memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_rx_t)); + memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_rx_t)); return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } @@ -885,7 +885,7 @@ esp_err_t esp_ble_dtm_rx_start(const esp_ble_dtm_rx_t *rx_params) esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params) { btc_msg_t msg = {0}; - btc_ble_gap_args_t arg; + btc_ble_5_gap_args_t arg; if (!tx_params) { return ESP_ERR_INVALID_ARG; @@ -897,15 +897,15 @@ esp_err_t esp_ble_dtm_enh_tx_start(const esp_ble_dtm_enh_tx_t *tx_params) msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_DTM_ENH_TX_START; - memcpy(&arg.dtm_tx_start, tx_params, sizeof(esp_ble_dtm_enh_tx_t)); + memcpy(&arg.dtm_enh_tx_start, tx_params, sizeof(esp_ble_dtm_enh_tx_t)); - return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params) { btc_msg_t msg = {0}; - btc_ble_gap_args_t arg; + btc_ble_5_gap_args_t arg; if (!rx_params) { return ESP_ERR_INVALID_ARG; @@ -917,9 +917,9 @@ esp_err_t esp_ble_dtm_enh_rx_start(const esp_ble_dtm_enh_rx_t *rx_params) msg.pid = BTC_PID_GAP_BLE; msg.act = BTC_GAP_BLE_DTM_ENH_RX_START; - memcpy(&arg.dtm_rx_start, rx_params, sizeof(esp_ble_dtm_enh_rx_t)); + memcpy(&arg.dtm_enh_rx_start, rx_params, sizeof(esp_ble_dtm_enh_rx_t)); - return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); + return (btc_transfer_context(&msg, &arg, sizeof(btc_ble_5_gap_args_t), NULL, NULL) == BT_STATUS_SUCCESS ? ESP_OK : ESP_FAIL); } #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index 93080a33f680..d23479c4f6bd 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -125,6 +125,18 @@ typedef uint8_t esp_ble_auth_req_t; /*!< combination of the above bit typedef uint8_t esp_ble_io_cap_t; /*!< combination of the io capability */ +#define BLE_DTM_PKT_PAYLOAD_0x00 0x00 /*!< PRBS9 sequence ‘11111111100000111101...’ (in transmission order) as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x01 0x01 /*!< Repeated ‘11110000’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x02 0x02 /*!< Repeated ‘10101010’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x03 0x03 /*!< PRBS15 sequence as described in [Vol 6] Part F, Section 4.1.5 */ +#define BLE_DTM_PKT_PAYLOAD_0x04 0x04 /*!< Repeated ‘11111111’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x05 0x05 /*!< Repeated ‘00000000’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x06 0x06 /*!< Repeated ‘00001111’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_0x07 0x07 /*!< Repeated ‘01010101’ (in transmission order) sequence */ +#define BLE_DTM_PKT_PAYLOAD_MAX 0x08 /*!< 0x08 ~ 0xFF, Reserved for future use */ + +typedef uint8_t esp_ble_dtm_pkt_payload_t; + /// GAP BLE callback event type typedef enum { //BLE_42_FEATURE_SUPPORT @@ -352,18 +364,6 @@ typedef enum { DTM_TEST_STOP_EVT, } esp_ble_dtm_update_evt_t; -typedef enum { - BLE_DTM_PKT_PAYLOAD_0x00, /*!< PRBS9 sequence ‘11111111100000111101...’ (in transmission order) as described in [Vol 6] Part F, Section 4.1.5 */ - BLE_DTM_PKT_PAYLOAD_0x01, /*!< Repeated ‘11110000’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ - BLE_DTM_PKT_PAYLOAD_0x02, /*!< Repeated ‘10101010’ (in transmission order) sequence as described in [Vol 6] Part F, Section 4.1.5 */ - BLE_DTM_PKT_PAYLOAD_0x03, /*!< PRBS15 sequence as described in [Vol 6] Part F, Section 4.1.5 */ - BLE_DTM_PKT_PAYLOAD_0x04, /*!< Repeated ‘11111111’ (in transmission order) sequence */ - BLE_DTM_PKT_PAYLOAD_0x05, /*!< Repeated ‘00000000’ (in transmission order) sequence */ - BLE_DTM_PKT_PAYLOAD_0x06, /*!< Repeated ‘00001111’ (in transmission order) sequence */ - BLE_DTM_PKT_PAYLOAD_0x07, /*!< Repeated ‘01010101’ (in transmission order) sequence */ - BLE_DTM_PKT_PAYLOAD_MAX, /*!< 0x08 ~ 0xFF, Reserved for future use */ -} esp_ble_dtm_pkt_payload_t; - #if (BLE_42_FEATURE_SUPPORT == TRUE) /** * @brief DTM TX parameters From 57665f7246e4528457d8ecf057b656418a1a5254 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 9 Apr 2024 15:31:54 +0800 Subject: [PATCH 3/5] feat(bt/bluedroid): add api to setnd vendor hci command --- .../bt/host/bluedroid/api/esp_gap_ble_api.c | 28 +++++++ .../api/include/api/esp_gap_ble_api.h | 33 ++++++++ .../bt/host/bluedroid/bta/dm/bta_dm_act.c | 8 ++ .../bt/host/bluedroid/bta/dm/bta_dm_api.c | 15 ++++ .../bt/host/bluedroid/bta/dm/bta_dm_main.c | 1 + .../bluedroid/bta/dm/include/bta_dm_int.h | 11 +++ .../host/bluedroid/bta/include/bta/bta_api.h | 6 ++ .../btc/profile/std/gap/btc_gap_ble.c | 84 +++++++++++++++++++ .../btc/profile/std/include/btc_gap_ble.h | 7 ++ .../bt/host/bluedroid/stack/btm/btm_devctl.c | 5 +- 10 files changed, 196 insertions(+), 2 deletions(-) diff --git a/components/bt/host/bluedroid/api/esp_gap_ble_api.c b/components/bt/host/bluedroid/api/esp_gap_ble_api.c index 74fe793400aa..393d6b0d3f52 100644 --- a/components/bt/host/bluedroid/api/esp_gap_ble_api.c +++ b/components/bt/host/bluedroid/api/esp_gap_ble_api.c @@ -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); +} diff --git a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h index d23479c4f6bd..e7f8cc67d046 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_gap_ble_api.h @@ -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 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 5454fde74048..c11f9230105b 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -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 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 f57e80cf8d01..816b2134969d 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,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) 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 ce83c9fc3428..7f5b52a69ac0 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -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 */ 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 7448287dd491..7d61b7080c20 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,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); 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 febad16d9400..ad362ba045f9 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -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 diff --git a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c index d5be086a3231..33e5c2952a3e 100644 --- a/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c +++ b/components/bt/host/bluedroid/btc/profile/std/gap/btc_gap_ble.c @@ -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, ¶m, 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; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h index a427be142ca7..71d89359d9b1 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_gap_ble.h @@ -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) diff --git a/components/bt/host/bluedroid/stack/btm/btm_devctl.c b/components/bt/host/bluedroid/stack/btm/btm_devctl.c index 09dd024f086d..a80fcebda4c6 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_devctl.c +++ b/components/bt/host/bluedroid/stack/btm/btm_devctl.c @@ -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 + } /******************************************************************************* From c755433922e92d9a76239201395125b3481e49f9 Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Mon, 8 Apr 2024 20:16:28 +0800 Subject: [PATCH 4/5] feat(bt/common): Add bluerooth hci layer data stream record --- components/bt/CMakeLists.txt | 2 + 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 | 20 +- components/bt/common/include/bt_user_config.h | 20 +- .../bt/host/bluedroid/api/esp_bt_main.c | 12 +- components/bt/host/bluedroid/hci/hci_hal_h4.c | 17 +- .../host/nimble/esp-hci/src/esp_nimble_hci.c | 27 +- 9 files changed, 558 insertions(+), 7 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 747d5cfb8aad..df0da6a31694 100644 --- a/components/bt/CMakeLists.txt +++ b/components/bt/CMakeLists.txt @@ -41,11 +41,13 @@ if(CONFIG_BT_ENABLED) common/api/include/api common/btc/profile/esp/blufi/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 152ce7b38667..afd16ed89332 100644 --- a/components/bt/Kconfig +++ b/components/bt/Kconfig @@ -79,6 +79,31 @@ menu "Bluetooth" We cannot split the memory into 3 different regions (IRAM, BLE-IRAM, DRAM). So this option will disable the PMP (ESP_SYSTEM_PMP_IDRAM_SPLIT) + 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 000000000000..1cc95a46ce22 --- /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 000000000000..512a307e440c --- /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 134cf33c5dd6..f3c5ba0e0da5 100644 --- a/components/bt/common/include/bt_common.h +++ b/components/bt/common/include/bt_common.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -64,6 +64,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 9f6df2bdd4ba..eef09e0afb1b 100644 --- a/components/bt/common/include/bt_user_config.h +++ b/components/bt/common/include/bt_user_config.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -92,4 +92,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 911897a89b40..2767e2e52e3d 100644 --- a/components/bt/host/bluedroid/api/esp_bt_main.c +++ b/components/bt/host/bluedroid/api/esp_bt_main.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -11,6 +11,8 @@ #include "esp_bt.h" #include "osi/future.h" #include "osi/allocator.h" +#include "hci_log/bt_hci_log.h" +#include "bt_common.h" static bool bd_already_enable = false; static bool bd_already_init = false; @@ -157,6 +159,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; } @@ -199,6 +205,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 cbdf9adbe073..4fd1f90aeab7 100644 --- a/components/bt/host/bluedroid/hci/hci_hal_h4.c +++ b/components/bt/host/bluedroid/hci/hci_hal_h4.c @@ -39,6 +39,7 @@ #include "l2c_int.h" #endif ///C2H_FLOW_CONTROL_INCLUDED == TRUE #include "stack/hcimsgs.h" +#include "hci_log/bt_hci_log.h" #define HCI_BLE_EVENT 0x3e #define PACKET_TYPE_TO_INBOUND_INDEX(type) ((type) - 2) @@ -210,7 +211,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); @@ -437,7 +440,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; @@ -550,10 +553,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); } @@ -563,6 +570,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 392de69fce9f..4fb5458dc9e7 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 @@ -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 */ @@ -19,6 +19,8 @@ #include "freertos/semphr.h" #include "esp_compiler.h" #include "soc/soc_caps.h" +#include "bt_common.h" +#include "hci_log/bt_hci_log.h" #define NIMBLE_VHCI_TIMEOUT_MS 2000 #define BLE_HCI_EVENT_HDR_LEN (2) @@ -84,6 +86,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; @@ -123,6 +128,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; @@ -362,12 +370,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 || data[3] == BLE_HCI_LE_SUBEV_EXT_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); } @@ -378,6 +392,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; @@ -450,6 +467,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); #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) @@ -498,6 +519,10 @@ esp_err_t esp_nimble_hci_deinit(void) ble_buf_free(); +#if (BT_HCI_LOG_INCLUDED == TRUE) + bt_hci_log_deinit(); +#endif // (BT_HCI_LOG_INCLUDED == TRUE) + #if MYNEWT_VAL(BLE_QUEUE_CONG_CHECK) ble_adv_list_deinit(); #endif From 70f84cfca91dc250004aa87ca1a913d9200ab33e Mon Sep 17 00:00:00 2001 From: zhiweijian Date: Tue, 12 Mar 2024 11:48:14 +0800 Subject: [PATCH 5/5] fix(ble/bluedroid): Fixed adv not restart due to disconnection reason 0x3e --- .../host/bluedroid/stack/btm/btm_ble_5_gap.c | 8 ++++---- .../bt/host/bluedroid/stack/l2cap/l2c_link.c | 20 ++++++++++++------- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c index 40b52eeaeb1d..f22229a8216c 100644 --- a/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c +++ b/components/bt/host/bluedroid/stack/btm/btm_ble_5_gap.c @@ -330,7 +330,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvRandaddr(UINT8 instance, BD_ADDR rand_addr) __func__, btm_ble_hci_status_to_str(err), err); status = BTM_ILLEGAL_VALUE; } else { - // set random address success, update address infor + // set random address success, update address info if(extend_adv_cb.inst[instance].configured && extend_adv_cb.inst[instance].connetable) { BTM_BleSetStaticAddr(rand_addr); BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); @@ -414,7 +414,7 @@ tBTM_STATUS BTM_BleSetExtendedAdvParams(UINT8 instance, tBTM_BLE_GAP_EXT_ADV_PAR BTM_TRACE_ERROR("LE EA SetParams: cmd err=0x%x", err); status = BTM_ILLEGAL_VALUE; } else { - // set addr success, update address infor + // set addr success, update address info BTM_UpdateAddrInfor(BLE_ADDR_RANDOM, rand_addr); } } @@ -590,12 +590,12 @@ tBTM_STATUS BTM_BleStartExtAdvRestart(uint8_t con_handle) } } - if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid) || (adv_record[index].retry_count > GATTC_CONNECT_RETRY_COUNT)) { + if((index >= MAX_BLE_ADV_INSTANCE) || (!adv_record[index].invalid)) { return BTM_WRONG_MODE; } adv_record[index].retry_count ++; - BTM_TRACE_DEBUG("remote device did not reveive aux connect response, retatrt the extend adv to reconnect, adv handle %d con_handle %d\n", index, con_handle); + BTM_TRACE_DEBUG("remote device did not receive aux connect response, retatrt the extend adv to reconnect, adv handle %d con_handle %d\n", index, con_handle); ext_adv.instance = adv_record[index].instance; ext_adv.duration = adv_record[index].duration; ext_adv.max_events = adv_record[index].max_events; diff --git a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c index 4b81b4b3b252..c3118fdd5c72 100644 --- a/components/bt/host/bluedroid/stack/l2cap/l2c_link.c +++ b/components/bt/host/bluedroid/stack/l2cap/l2c_link.c @@ -367,6 +367,11 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) if (reason != HCI_ERR_DIRECTED_ADVERTISING_TIMEOUT) { BTM_Recovery_Pre_State(); } + #if (BLE_50_FEATURE_SUPPORT == TRUE) + if(btm_ble_inter_get() && reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT) { + BTM_BleStartExtAdvRestart(handle); + } + #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #endif ///BLE_INCLUDED == TRUE status = FALSE; } else { @@ -438,7 +443,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) #endif { #if (L2CAP_NUM_FIXED_CHNLS > 0) - /* If we are going to re-use the LCB without dropping it, release all fixed channels + /* If we are going to reuse the LCB without dropping it, release all fixed channels here */ int xx; for (xx = 0; xx < L2CAP_NUM_FIXED_CHNLS; xx++) { @@ -463,9 +468,9 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) } p_lcb->p_pending_ccb = NULL; -#if (BLE_INCLUDED == TRUE && GATTC_CONNECT_RETRY_EN == TRUE) +#if (BLE_INCLUDED == TRUE) if(reason == HCI_ERR_CONN_FAILED_ESTABLISHMENT && p_lcb->transport == BT_TRANSPORT_LE) { - + #if (GATTC_CONNECT_RETRY_EN == TRUE) if(p_lcb->link_role == HCI_ROLE_MASTER && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) { L2CAP_TRACE_DEBUG("master retry connect, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); p_lcb->retry_create_con ++; @@ -475,9 +480,10 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) lcb_is_free = FALSE; /* still using this lcb */ } } + #endif // (GATTC_CONNECT_RETRY_EN == TRUE) #if (BLE_50_FEATURE_SUPPORT == TRUE) - if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) { + if(btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) { p_lcb->retry_create_con ++; L2CAP_TRACE_DEBUG("slave restart extend adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); BTM_BleStartExtAdvRestart(handle); @@ -485,7 +491,7 @@ BOOLEAN l2c_link_hci_disc_comp (UINT16 handle, UINT8 reason) #endif // #if (BLE_50_FEATURE_SUPPORT == TRUE) #if (BLE_42_FEATURE_SUPPORT == TRUE) - if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE && p_lcb->retry_create_con < GATTC_CONNECT_RETRY_COUNT) { + if(!btm_ble_inter_get() && p_lcb->link_role == HCI_ROLE_SLAVE) { p_lcb->retry_create_con ++; L2CAP_TRACE_DEBUG("slave resatrt adv, retry count %d reason 0x%x\n", p_lcb->retry_create_con, reason); btm_ble_start_adv(); @@ -909,7 +915,7 @@ UINT8 l2c_link_pkts_rcvd (UINT16 *num_pkts, UINT16 *handles) ** ** Function l2c_link_role_changed ** -** Description This function is called whan a link's master/slave role change +** Description This function is called when a link's master/slave role change ** event is received. It simply updates the link control block. ** ** Returns void @@ -947,7 +953,7 @@ void l2c_link_role_changed (BD_ADDR bd_addr, UINT8 new_role, UINT8 hci_status) ** ** Function l2c_pin_code_request ** -** Description This function is called whan a pin-code request is received +** Description This function is called when a pin-code request is received ** on a connection. If there are no channels active yet on the ** link, it extends the link first connection timer. Make sure ** that inactivity timer is not extended if PIN code happens