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 d9bdc03558..3be35b2300 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 06c72514d1..350068acb4 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 @@ -924,6 +964,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) @@ -1393,6 +1454,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; /** @@ -2388,14 +2457,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 c5530b5ec3..c83b7607ec 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_act.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_act.c @@ -5647,6 +5647,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) { @@ -5657,6 +5672,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 ef8e4f56eb..f65bc4dd6f 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_api.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_api.c @@ -2501,6 +2501,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 /******************************************************************************* @@ -3181,6 +3224,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 2f4fc9071e..1190743079 100644 --- a/components/bt/host/bluedroid/bta/dm/bta_dm_main.c +++ b/components/bt/host/bluedroid/bta/dm/bta_dm_main.c @@ -202,6 +202,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 */ @@ -210,6 +212,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 e922675d8d..30a42427c3 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 @@ -199,6 +199,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, @@ -207,6 +209,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 @@ -845,6 +850,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; @@ -906,6 +930,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) @@ -1213,6 +1253,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; @@ -1220,6 +1262,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 @@ -1652,9 +1698,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 090fa7a6a7..2f65ecce30 100644 --- a/components/bt/host/bluedroid/bta/include/bta/bta_api.h +++ b/components/bt/host/bluedroid/bta/include/bta/bta_api.h @@ -424,6 +424,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; @@ -2789,6 +2791,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 @@ -3043,6 +3049,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 23e3d1fe01..0075f483b6 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) { @@ -2045,6 +2162,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 fb998687b9..a427be142c 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 e8ce10ca6b..0324002792 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 768fb7fa96..a9a919e466 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 e3ad87465e..f64500656b 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 @@ -2700,6 +2700,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)