diff --git a/components/bt/host/bluedroid/api/esp_avrc_api.c b/components/bt/host/bluedroid/api/esp_avrc_api.c index 125bfff111..e1769c281a 100644 --- a/components/bt/host/bluedroid/api/esp_avrc_api.c +++ b/components/bt/host/bluedroid/api/esp_avrc_api.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -617,4 +617,19 @@ esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_ } +esp_err_t esp_avrc_get_profile_status(esp_avrc_profile_status_t *profile_status) +{ + if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) { + return ESP_ERR_INVALID_STATE; + } + if (profile_status == NULL) { + return ESP_ERR_INVALID_ARG; + } + + memset(profile_status, 0, sizeof(esp_avrc_profile_status_t)); + btc_avrc_get_profile_status(profile_status); + + return ESP_OK; +} + #endif /* #if BTC_AV_INCLUDED */ diff --git a/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h b/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h index 1c1e34ab2a..0c3828ddda 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_avrc_api.h @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -294,6 +294,15 @@ typedef struct { uint8_t attr_val; /*!< player application attribute value */ } esp_avrc_set_app_value_param_t; +/** + * @brief AVRCP profile status parameters + */ +typedef struct { + bool avrc_ct_inited; /*!< AVRCP CT initialization */ + bool avrc_tg_inited; /*!< AVRCP TG initialization */ + uint8_t ct_cover_art_conn_num; /*!< Number of cover art client connections */ +} esp_avrc_profile_status_t; + /// AVRC controller callback parameters typedef union { /** @@ -849,6 +858,16 @@ esp_err_t esp_avrc_ct_cover_art_get_image(uint8_t *image_handle, uint8_t *image_ */ esp_err_t esp_avrc_ct_cover_art_get_linked_thumbnail(uint8_t *image_handle); +/** + * @brief This function is used to get the status of AVRCP + * + * @param[out] profile_status - AVRCP status + * + * @return + * - ESP_OK: success + * - other: failed + */ +esp_err_t esp_avrc_get_profile_status(esp_avrc_profile_status_t *profile_status); #ifdef __cplusplus } diff --git a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h index 9e5c357128..64762fd074 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h +++ b/components/bt/host/bluedroid/api/include/api/esp_bt_defs.h @@ -306,6 +306,8 @@ typedef uint8_t esp_ble_key_mask_t; /* the key mask type */ #define ESP_BLE_ADV_NAME_LEN_MAX 29 +#define ESP_INVALID_CONN_HANDLE 0xfff + #ifdef __cplusplus } #endif diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h index 66954ef411..885a2b4418 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_ag_api.h @@ -78,7 +78,8 @@ typedef enum /// HFP AG profile status parameters typedef struct { bool hfp_ag_inited; /*!< hfp ag initialization */ - uint8_t conn_num; /*!< Number of connections */ + uint8_t slc_conn_num; /*!< Number of Service Level Connections */ + uint8_t sync_conn_num; /*!< Number of (e)SCO Connections */ } esp_hf_profile_status_t; /// HFP AG callback parameters diff --git a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h index e4ea1daec0..a373dc5c74 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hf_client_api.h @@ -47,7 +47,8 @@ typedef enum { */ typedef struct { bool hf_client_inited; /*!< hf client initialization */ - uint8_t conn_num; /*!< Number of connections */ + uint8_t slc_conn_num; /*!< Number of Service Level Connections */ + uint8_t sync_conn_num; /*!< Number of (e)SCO Connections */ } esp_hf_client_profile_status_t; /* features masks of AG */ diff --git a/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h b/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h index 393f76f24e..5250779d0d 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hidd_api.h @@ -151,6 +151,8 @@ typedef enum { typedef struct { bool hidd_inited; /*!< HID device initialization */ uint8_t conn_num; /*!< Number of connections */ + uint8_t plug_vc_dev_num; /*!< Number of plugged virtual cable devices */ + uint8_t reg_app_num; /*!< Number of HID device application registrations */ } esp_hidd_profile_status_t; /** diff --git a/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h b/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h index e7c581d52f..51a0d43f7b 100644 --- a/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h +++ b/components/bt/host/bluedroid/api/include/api/esp_hidh_api.h @@ -139,6 +139,7 @@ typedef struct { typedef struct { bool hidh_inited; /*!< HID host initialization */ uint8_t conn_num; /*!< Number of connections */ + uint8_t plug_vc_dev_num; /*!< Number of plugged virtual cable devices*/ } esp_hidh_profile_status_t; /** diff --git a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c index a783d5e350..9f1a0cb54f 100644 --- a/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c +++ b/components/bt/host/bluedroid/btc/profile/std/avrc/btc_avrc.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -1625,4 +1625,25 @@ void btc_avrc_tg_call_handler(btc_msg_t *msg) btc_avrc_tg_arg_deep_free(msg); } +void btc_avrc_get_profile_status(esp_avrc_profile_status_t *param) +{ + param->avrc_ct_inited = false; + param->avrc_tg_inited = false; + +#if AVRC_DYNAMIC_MEMORY == TRUE + if (btc_rc_cb_ptr) +#endif + { + if (btc_avrc_tg_init_p()) { + param->avrc_tg_inited = true; + } + if (btc_avrc_ct_init_p()) { + param->avrc_ct_inited = true; + } + if (btc_rc_cb.rc_cover_art_connected) { + param->ct_cover_art_conn_num++; + } + } +} + #endif /* #if BTC_AV_INCLUDED */ diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c index 25249fcdc9..e1b070c24b 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_ag/btc_hf_ag.c @@ -351,6 +351,9 @@ bt_status_t btc_hf_init(void) #endif clear_phone_state(); memset(&hf_local_param[idx].btc_hf_cb, 0, sizeof(btc_hf_cb_t)); + for (int i = 0; i < BTC_HF_NUM_CB; i++) { + hf_local_param[i].btc_hf_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE; + } // set audio path #if (BT_CONTROLLER_INCLUDED == TRUE) #if BTM_SCO_HCI_INCLUDED @@ -1411,6 +1414,7 @@ void btc_hf_cb_handler(btc_msg_t *msg) do { param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED; memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + hf_local_param[idx].btc_hf_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle; param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m); } while(0); @@ -1424,6 +1428,7 @@ void btc_hf_cb_handler(btc_msg_t *msg) do { param.audio_stat.state = ESP_HF_AUDIO_STATE_CONNECTED_MSBC; memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda,sizeof(esp_bd_addr_t)); + hf_local_param[idx].btc_hf_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle; param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m); } while (0); @@ -1435,6 +1440,7 @@ void btc_hf_cb_handler(btc_msg_t *msg) CHECK_HF_IDX(idx); do { param.audio_stat.state = ESP_HF_AUDIO_STATE_DISCONNECTED; + hf_local_param[idx].btc_hf_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE; memcpy(param.audio_stat.remote_addr, &hf_local_param[idx].btc_hf_cb.connected_bda, sizeof(esp_bd_addr_t)); param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_cb_to_app(ESP_HF_AUDIO_STATE_EVT, ¶m); @@ -1669,18 +1675,21 @@ void btc_hf_cb_handler(btc_msg_t *msg) void btc_hf_get_profile_status(esp_hf_profile_status_t *param) { - int idx = 0; - param->hfp_ag_inited = false; // Not initialized by default #if HFP_DYNAMIC_MEMORY == TRUE if (hf_local_param) #endif { - if (hf_local_param[idx].btc_hf_cb.initialized) { - param->hfp_ag_inited = true; - if (hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED) { - param->conn_num++; + for (int idx = 0; idx < BTC_HF_NUM_CB; idx++) { + if (hf_local_param[idx].btc_hf_cb.initialized) { + param->hfp_ag_inited = true; + if (hf_local_param[idx].btc_hf_cb.connection_state == ESP_HF_CONNECTION_STATE_SLC_CONNECTED) { + param->slc_conn_num++; + if (hf_local_param[idx].btc_hf_cb.sync_conn_hdl != ESP_INVALID_CONN_HANDLE) { + param->sync_conn_num++; + } + } } } } diff --git a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c index b7f39cc908..e56c7a04b5 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c +++ b/components/bt/host/bluedroid/btc/profile/std/hf_client/btc_hf_client.c @@ -114,6 +114,7 @@ static inline void btc_hf_client_cb_to_app(esp_hf_client_cb_event_t event, esp_h static void clear_state(void) { memset(&hf_client_local_param.btc_hf_client_cb, 0, sizeof(btc_hf_client_cb_t)); + hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE; } static BOOLEAN is_connected(bt_bdaddr_t *bd_addr) @@ -1076,6 +1077,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED; memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda, sizeof(esp_bd_addr_t)); + hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle; param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m); } while (0); @@ -1085,6 +1087,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_CONNECTED_MSBC; memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda, sizeof(esp_bd_addr_t)); + hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = p_data->hdr.sync_conn_handle; param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m); } while (0); @@ -1094,6 +1097,7 @@ void btc_hf_client_cb_handler(btc_msg_t *msg) param.audio_stat.state = ESP_HF_CLIENT_AUDIO_STATE_DISCONNECTED; memcpy(param.audio_stat.remote_bda, &hf_client_local_param.btc_hf_client_cb.connected_bda, sizeof(esp_bd_addr_t)); + hf_client_local_param.btc_hf_client_cb.sync_conn_hdl = ESP_INVALID_CONN_HANDLE; param.audio_stat.sync_conn_handle = p_data->hdr.sync_conn_handle; btc_hf_client_cb_to_app(ESP_HF_CLIENT_AUDIO_STATE_EVT, ¶m); } while (0); @@ -1211,7 +1215,10 @@ void btc_hf_client_get_profile_status(esp_hf_client_profile_status_t *param) if (hf_client_local_param.btc_hf_client_cb.initialized) { param->hf_client_inited = true; if (hf_client_local_param.btc_hf_client_cb.state == ESP_HF_CLIENT_CONNECTION_STATE_SLC_CONNECTED) { - param->conn_num++; + param->slc_conn_num++; + if (hf_client_local_param.btc_hf_client_cb.sync_conn_hdl != ESP_INVALID_CONN_HANDLE) { + param->sync_conn_num++; + } } } } diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c index dccbc450b6..82ff2b8d5c 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hd.c @@ -844,6 +844,7 @@ void btc_hd_cb_handler(btc_msg_t *msg) // } // btc_storage_set_hidd((bt_bdaddr_t *)&p_data->conn.bda); btc_hd_cb.status = BTC_HD_CONNECTED; + btc_hd_cb.in_use = TRUE; } else if (p_data->conn.conn_status == BTA_HD_CONN_STATE_DISCONNECTED) { btc_hd_cb.status = BTC_HD_DISCONNECTED; } @@ -916,6 +917,8 @@ void btc_hd_cb_handler(btc_msg_t *msg) btc_hd_cb_to_app(ESP_HIDD_CLOSE_EVT, ¶m); } + btc_hd_cb.in_use = FALSE; + param.vc_unplug.status = p_data->conn.status; param.vc_unplug.conn_status = p_data->conn.conn_status; btc_hd_cb_to_app(ESP_HIDD_VC_UNPLUG_EVT, ¶m); @@ -966,6 +969,12 @@ void btc_hd_get_profile_status(esp_hidd_profile_status_t *param) if (btc_hd_cb.status == BTC_HD_CONNECTED) { param->conn_num++; } + if (btc_hd_cb.in_use) { + param->plug_vc_dev_num++; + } + if (btc_hd_cb.app_registered) { + param->reg_app_num++; + } } else { param->hidd_inited = false; } diff --git a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c index 9695a360e8..55fe3f69b3 100644 --- a/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c +++ b/components/bt/host/bluedroid/btc/profile/std/hid/btc_hh.c @@ -1582,6 +1582,11 @@ void btc_hh_get_profile_status(esp_hidh_profile_status_t *param) if (btc_hh_cb.status == BTC_HH_DEV_CONNECTED) { param->conn_num++; } + for (int i = 0; i < BTC_HH_MAX_ADDED_DEV; i++) { + if (memcmp(btc_hh_cb.added_devices[i].bd_addr, bd_addr_null, BD_ADDR_LEN) != 0) { + param->plug_vc_dev_num++; + } + } } else { param->hidh_inited = false; } diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h index a78a7af1db..805ca99e4d 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_avrc.h @@ -220,6 +220,7 @@ bool btc_avrc_tg_check_rn_supported_evt(uint16_t evt_set); bool btc_avrc_tg_rn_evt_supported(uint8_t event_id); bool btc_avrc_ct_rn_evt_supported(uint8_t event_id); bool btc_avrc_ct_check_cover_art_support(void); +void btc_avrc_get_profile_status(esp_avrc_profile_status_t *param); #endif ///BTC_AV_INCLUDED == TRUE diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h index 06491da266..15b59393a3 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hd.h @@ -55,6 +55,7 @@ typedef struct { bool app_registered; bool service_dereg_active; bool forced_disc; + bool in_use; tBTA_HD_APP_INFO app_info; tBTA_HD_QOS_INFO in_qos; tBTA_HD_QOS_INFO out_qos; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h index 770153039a..4eea402274 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_ag.h @@ -211,6 +211,7 @@ typedef struct { bool initialized; UINT16 handle; + UINT16 sync_conn_hdl; bt_bdaddr_t connected_bda; tBTA_AG_PEER_FEAT peer_feat; tBTA_AG_CHLD_FEAT chld_feat; diff --git a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h index d959e93753..59ca288b2a 100644 --- a/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h +++ b/components/bt/host/bluedroid/btc/profile/std/include/btc_hf_client.h @@ -134,6 +134,7 @@ typedef struct { bool initialized; UINT16 handle; + UINT16 sync_conn_hdl; bt_bdaddr_t connected_bda; esp_hf_client_connection_state_t state; esp_hf_vr_state_t vr_state;