Skip to content

Commit

Permalink
Merge branch 'feature/support_bt_avrcp_cover_art' into 'master'
Browse files Browse the repository at this point in the history
feat(bt/bluedroid): Support BT AVRCP Cover Art

Closes BT-3231

See merge request espressif/esp-idf!32538
  • Loading branch information
wmy-espressif committed Sep 14, 2024
2 parents 48b1cd5 + eb2307a commit cda2846
Show file tree
Hide file tree
Showing 43 changed files with 5,220 additions and 71 deletions.
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
[codespell]
skip = build,*.yuv,components/fatfs/src/*,alice.txt,*.rgb,components/wpa_supplicant/*,components/esp_wifi/*,*.pem
ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel,ot,fane,assertIn
ignore-words-list = ser,dout,rsource,fram,inout,shs,ans,aci,unstall,unstalling,hart,wheight,wel,ot,fane,assertIn,registr
write-changes = true
9 changes: 9 additions & 0 deletions components/bt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ if(CONFIG_BT_ENABLED)
host/bluedroid/stack/avdt/include
host/bluedroid/stack/a2dp/include
host/bluedroid/stack/rfcomm/include
host/bluedroid/stack/obex/include
host/bluedroid/stack/goep/include
host/bluedroid/stack/include
host/bluedroid/common/include
host/bluedroid/config/include)
Expand Down Expand Up @@ -183,6 +185,8 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/bta/av/bta_av_aact.c"
"host/bluedroid/bta/av/bta_av_act.c"
"host/bluedroid/bta/av/bta_av_api.c"
"host/bluedroid/bta/av/bta_av_ca_act.c"
"host/bluedroid/bta/av/bta_av_ca_sm.c"
"host/bluedroid/bta/av/bta_av_cfg.c"
"host/bluedroid/bta/av/bta_av_ci.c"
"host/bluedroid/bta/av/bta_av_main.c"
Expand Down Expand Up @@ -378,6 +382,8 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/stack/gatt/gatt_sr.c"
"host/bluedroid/stack/gatt/gatt_sr_hash.c"
"host/bluedroid/stack/gatt/gatt_utils.c"
"host/bluedroid/stack/goep/goepc_api.c"
"host/bluedroid/stack/goep/goepc_main.c"
"host/bluedroid/stack/hcic/hciblecmds.c"
"host/bluedroid/stack/hcic/hcicmds.c"
"host/bluedroid/stack/l2cap/l2c_api.c"
Expand All @@ -389,6 +395,9 @@ if(CONFIG_BT_ENABLED)
"host/bluedroid/stack/l2cap/l2c_ucd.c"
"host/bluedroid/stack/l2cap/l2c_utils.c"
"host/bluedroid/stack/l2cap/l2cap_client.c"
"host/bluedroid/stack/obex/obex_api.c"
"host/bluedroid/stack/obex/obex_main.c"
"host/bluedroid/stack/obex/obex_tl_l2cap.c"
"host/bluedroid/stack/rfcomm/port_api.c"
"host/bluedroid/stack/rfcomm/port_rfc.c"
"host/bluedroid/stack/rfcomm/port_utils.c"
Expand Down
31 changes: 29 additions & 2 deletions components/bt/host/bluedroid/Kconfig.in
Original file line number Diff line number Diff line change
Expand Up @@ -84,9 +84,30 @@ config BT_A2DP_ENABLE
bool "A2DP"
depends on BT_CLASSIC_ENABLED
default n
select BT_AVRCP_ENABLED
help
Advanced Audio Distribution Profile

config BT_AVRCP_ENABLED
bool
depends on BT_A2DP_ENABLE
default y
help
Audio/Video Remote Control Profile, AVRCP and A2DP are coupled in Bluedroid,
AVRCP still controlled by A2DP option, this is a dummy option currently

menu "AVRCP Features"
depends on BT_AVRCP_ENABLED

config BT_AVRCP_CT_COVER_ART_ENABLED
bool "AVRCP CT Cover Art"
default y
select BT_GOEPC_ENABLED
help
This enable Cover Art feature of AVRCP CT role

endmenu

config BT_SPP_ENABLED
bool "SPP"
depends on BT_CLASSIC_ENABLED
Expand Down Expand Up @@ -143,13 +164,12 @@ endchoice

config BT_HFP_WBS_ENABLE
bool "Wide Band Speech"
depends on BT_HFP_AUDIO_DATA_PATH_HCI
depends on BT_HFP_ENABLE && BT_HFP_AUDIO_DATA_PATH_HCI
default y
help
This enables Wide Band Speech. Should disable it when SCO data path is PCM.
Otherwise there will be no data transmitted via GPIOs.


menuconfig BT_HID_ENABLED
bool "Classic BT HID"
depends on BT_CLASSIC_ENABLED
Expand All @@ -170,6 +190,13 @@ config BT_HID_DEVICE_ENABLED
help
This enables the BT HID Device

config BT_GOEPC_ENABLED
bool
depends on BT_CLASSIC_ENABLED
default n
help
This enables the BT GOEP Profile Client role

config BT_BLE_ENABLED
bool "Bluetooth Low Energy"
depends on BT_BLUEDROID_ENABLED
Expand Down
145 changes: 144 additions & 1 deletion components/bt/host/bluedroid/api/esp_avrc_api.c
Original file line number Diff line number Diff line change
@@ -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
*/
Expand Down Expand Up @@ -232,6 +232,149 @@ esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

#if BTC_AV_CA_INCLUDED

esp_err_t esp_avrc_ct_cover_art_connect(uint16_t mtu)
{
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
(!btc_avrc_ct_connected_p())) {
return ESP_ERR_INVALID_STATE;
}

if (!btc_avrc_ct_check_cover_art_support()) {
return ESP_ERR_NOT_SUPPORTED;
}

if (mtu > ESP_AVRC_CA_MTU_MAX || mtu < ESP_AVRC_CA_MTU_MIN) {
mtu = ESP_AVRC_CA_MTU_MAX;
}

btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC_CT;
msg.act = BTC_AVRC_CT_API_COVER_ART_CONNECT_EVT;

btc_avrc_args_t arg;
memset(&arg, 0, sizeof(btc_avrc_args_t));
arg.ca_conn.mtu = mtu;

/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_avrc_ct_cover_art_disconnect(void)
{
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
return ESP_ERR_INVALID_STATE;
}

if (!btc_avrc_ct_check_cover_art_support()) {
return ESP_ERR_NOT_SUPPORTED;
}

btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC_CT;
msg.act = BTC_AVRC_CT_API_COVER_ART_DISCONNECT_EVT;

/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, NULL, 0, NULL, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_avrc_ct_cover_art_get_image_properties(uint8_t *image_handle)
{
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
(!btc_avrc_ct_connected_p())) {
return ESP_ERR_INVALID_STATE;
}

if (!btc_avrc_ct_check_cover_art_support()) {
return ESP_ERR_NOT_SUPPORTED;
}

if (image_handle == NULL) {
return ESP_ERR_INVALID_ARG;
}

btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC_CT;
msg.act = BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_PROPERTIES_EVT;

btc_avrc_args_t arg;
memset(&arg, 0, sizeof(btc_avrc_args_t));
memcpy(arg.ca_get_img_prop.image_handle, image_handle, ESP_AVRC_CA_IMAGE_HANDLE_LEN);

/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_avrc_ct_cover_art_get_image(uint8_t *image_handle, uint8_t *image_descriptor, uint16_t image_descriptor_len)
{
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
(!btc_avrc_ct_connected_p())) {
return ESP_ERR_INVALID_STATE;
}

if (!btc_avrc_ct_check_cover_art_support()) {
return ESP_ERR_NOT_SUPPORTED;
}

if (image_handle == NULL || image_descriptor == NULL || image_descriptor_len == 0) {
return ESP_ERR_INVALID_ARG;
}

btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC_CT;
msg.act = BTC_AVRC_CT_API_COVER_ART_GET_IMAGE_EVT;

btc_avrc_args_t arg;
memset(&arg, 0, sizeof(btc_avrc_args_t));

memcpy(arg.ca_get_img.image_handle, image_handle, ESP_AVRC_CA_IMAGE_HANDLE_LEN);
arg.ca_get_img.image_descriptor_len = image_descriptor_len;
arg.ca_get_img.image_descriptor = image_descriptor;

/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), btc_avrc_arg_deep_copy, btc_avrc_arg_deep_free);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

esp_err_t esp_avrc_ct_cover_art_get_linked_thumbnail(uint8_t *image_handle)
{
if ((esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) ||
(!btc_avrc_ct_connected_p())) {
return ESP_ERR_INVALID_STATE;
}

if (!btc_avrc_ct_check_cover_art_support()) {
return ESP_ERR_NOT_SUPPORTED;
}

if (image_handle == NULL) {
return ESP_ERR_INVALID_ARG;
}

btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC_CT;
msg.act = BTC_AVRC_CT_API_COVER_ART_GET_LINKED_THUMBNAIL_EVT;

btc_avrc_args_t arg;
memset(&arg, 0, sizeof(btc_avrc_args_t));
memcpy(arg.ca_get_lk_thn.image_handle, image_handle, ESP_AVRC_CA_IMAGE_HANDLE_LEN);

/* Switch to BTC context */
bt_status_t stat = btc_transfer_context(&msg, &arg, sizeof(btc_avrc_args_t), NULL, NULL);
return (stat == BT_STATUS_SUCCESS) ? ESP_OK : ESP_FAIL;
}

#endif /* #if BTC_AV_CA_INCLUDED */

/*********************************************************************************************/
/** following is the API of AVRCP target role **/
/*********************************************************************************************/
Expand Down
Loading

0 comments on commit cda2846

Please sign in to comment.