mirror of
https://github.com/espressif/esp-idf
synced 2025-03-09 17:19:09 -04:00
Merge branch 'feature/support_get_play_status_in_avrcp' into 'master'
feat(bt/bluedroid): Support get play status in AVRCP CT See merge request espressif/esp-idf!35674
This commit is contained in:
commit
6109542fb5
@ -232,6 +232,31 @@ 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;
|
||||
}
|
||||
|
||||
esp_err_t esp_avrc_ct_send_get_play_status_cmd(uint8_t tl)
|
||||
{
|
||||
if (esp_bluedroid_get_status() != ESP_BLUEDROID_STATUS_ENABLED) {
|
||||
return ESP_ERR_INVALID_STATE;
|
||||
}
|
||||
|
||||
if (tl > ESP_AVRC_TRANS_LABEL_MAX) {
|
||||
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_STATUS_API_SND_GET_PLAY_STATUS_EVT;
|
||||
|
||||
btc_avrc_args_t arg;
|
||||
memset(&arg, 0, sizeof(btc_avrc_args_t));
|
||||
|
||||
arg.get_play_status_cmd.tl = tl;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
|
||||
esp_err_t esp_avrc_ct_cover_art_connect(uint16_t mtu)
|
||||
|
@ -323,6 +323,15 @@ typedef union {
|
||||
int attr_length; /*!< attribute character length */
|
||||
} meta_rsp; /*!< metadata attributes response */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_PLAY_STATUS_RSP_EVT
|
||||
*/
|
||||
struct avrc_ct_get_play_status_rsp_param {
|
||||
uint32_t song_length; /*!< total length of the playing song in milliseconds */
|
||||
uint32_t song_position; /*!< current position of the playing song in milliseconds elapsed */
|
||||
esp_avrc_playback_stat_t play_status; /*!< current status of playing */
|
||||
} play_status_rsp; /*!< get play status command response */
|
||||
|
||||
/**
|
||||
* @brief ESP_AVRC_CT_CHANGE_NOTIFY_EVT
|
||||
*/
|
||||
@ -586,6 +595,18 @@ esp_err_t esp_avrc_ct_send_metadata_cmd(uint8_t tl, uint8_t attr_mask);
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state);
|
||||
|
||||
/**
|
||||
* @brief Send get play status command to AVRCP target. This function should be called after
|
||||
* ESP_AVRC_CT_CONNECTION_STATE_EVT is received and AVRCP connection is established.
|
||||
*
|
||||
* @param[in] tl : transaction label, 0 to 15, consecutive commands should use different values.
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK: success
|
||||
* - ESP_ERR_INVALID_STATE: if bluetooth stack is not yet enabled
|
||||
* - ESP_FAIL: others
|
||||
*/
|
||||
esp_err_t esp_avrc_ct_send_get_play_status_cmd(uint8_t tl);
|
||||
|
||||
/**
|
||||
* @brief Register application callbacks to AVRCP target module. This function should be
|
||||
|
@ -700,6 +700,18 @@ static void handle_rc_set_absolute_volume_rsp(tAVRC_SET_VOLUME_RSP *rsp)
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_SET_ABSOLUTE_VOLUME_RSP_EVT, ¶m);
|
||||
}
|
||||
|
||||
static void handle_rc_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP *rsp)
|
||||
{
|
||||
esp_avrc_ct_cb_param_t param;
|
||||
memset(¶m, 0, sizeof(esp_avrc_ct_cb_param_t));
|
||||
|
||||
param.play_status_rsp.song_length = rsp->song_len;
|
||||
param.play_status_rsp.song_position = rsp->song_pos;
|
||||
param.play_status_rsp.play_status = rsp->play_status;
|
||||
|
||||
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_PLAY_STATUS_RSP_EVT, ¶m);
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* Function handle_rc_metamsg_cmd
|
||||
*
|
||||
@ -898,6 +910,9 @@ static void handle_rc_metamsg_rsp (tBTA_AV_META_MSG *p_meta_msg)
|
||||
handle_rc_set_absolute_volume_rsp(&avrc_response.volume);
|
||||
}
|
||||
break;
|
||||
case AVRC_PDU_GET_PLAY_STATUS:
|
||||
handle_rc_get_play_status_rsp(&avrc_response.get_play_status);
|
||||
break;
|
||||
default:
|
||||
BTC_TRACE_WARNING("%s: unhandled meta rsp: pdu 0x%x", __FUNCTION__, avrc_response.rsp.pdu);
|
||||
}
|
||||
@ -1333,6 +1348,38 @@ static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
|
||||
return status;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_get_play_status_cmd(uint8_t tl)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
|
||||
avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
|
||||
avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
|
||||
|
||||
if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_STATUS, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
#else
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
@ -1550,6 +1597,10 @@ void btc_avrc_ct_call_handler(btc_msg_t *msg)
|
||||
btc_avrc_ct_send_metadata_cmd(arg->md_cmd.tl, arg->md_cmd.attr_mask);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_STATUS_API_SND_GET_PLAY_STATUS_EVT: {
|
||||
btc_avrc_ct_send_get_play_status_cmd(arg->get_play_status_cmd.tl);
|
||||
break;
|
||||
}
|
||||
case BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT: {
|
||||
btc_avrc_ct_send_get_rn_caps_cmd(arg->get_caps_cmd.tl);
|
||||
break;
|
||||
|
@ -37,6 +37,7 @@ typedef enum {
|
||||
BTC_AVRC_STATUS_API_SND_META_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_PLAY_STATUS_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_GET_RN_CAPS_EVT,
|
||||
BTC_AVRC_STATUS_API_SND_GET_PLAY_STATUS_EVT,
|
||||
BTC_AVRC_NOTIFY_API_SND_REG_NOTIFY_EVT,
|
||||
BTC_AVRC_CTRL_API_SND_SET_PLAYER_SETTING_EVT,
|
||||
BTC_AVRC_CTRL_API_SND_SET_ABSOLUTE_VOLUME_EVT,
|
||||
@ -76,6 +77,10 @@ typedef struct {
|
||||
uint8_t tl;
|
||||
} get_caps_cmd_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t tl;
|
||||
} get_play_status_cmd_t;
|
||||
|
||||
#define BTC_AVRC_MIN_VOLUME 0x00
|
||||
#define BTC_AVRC_MAX_VOLUME 0x7f
|
||||
|
||||
@ -113,6 +118,7 @@ typedef union {
|
||||
rn_cmd_t rn_cmd;
|
||||
ps_cmd_t ps_cmd;
|
||||
get_caps_cmd_t get_caps_cmd;
|
||||
get_play_status_cmd_t get_play_status_cmd;
|
||||
set_abs_vol_cmd_t set_abs_vol_cmd;
|
||||
#if BTC_AV_CA_INCLUDED
|
||||
ca_conn_t ca_conn;
|
||||
|
@ -956,7 +956,7 @@
|
||||
|
||||
/* The number of security records for services. 32 AS Default*/
|
||||
#ifndef BTM_SEC_MAX_SERVICE_RECORDS
|
||||
#define BTM_SEC_MAX_SERVICE_RECORDS 8 // 32
|
||||
#define BTM_SEC_MAX_SERVICE_RECORDS 32
|
||||
#endif
|
||||
|
||||
/* If True, force a retrieval of remote device name for each bond in case it's changed */
|
||||
|
@ -50,7 +50,7 @@ static tAVRC_STS avrc_bld_next_cmd (tAVRC_NEXT_CMD *p_cmd, BT_HDR *p_pkt)
|
||||
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
p_data = p_start + 2; /* pdu + rsvd */
|
||||
|
||||
/* add fixed lenth 1 - pdu_id (1) */
|
||||
/* add fixed length 1 - pdu_id (1) */
|
||||
UINT16_TO_BE_STREAM(p_data, 1);
|
||||
UINT8_TO_BE_STREAM(p_data, p_cmd->target_pdu);
|
||||
p_pkt->len = (p_data - p_start);
|
||||
@ -81,7 +81,7 @@ static tAVRC_STS avrc_bld_set_abs_volume_cmd (tAVRC_SET_VOLUME_CMD *p_cmd, BT_HD
|
||||
/* get the existing length, if any, and also the num attributes */
|
||||
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
p_data = p_start + 2; /* pdu + rsvd */
|
||||
/* add fixed lenth 1 - volume (1) */
|
||||
/* add fixed length 1 - volume (1) */
|
||||
UINT16_TO_BE_STREAM(p_data, 1);
|
||||
UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_cmd->volume));
|
||||
p_pkt->len = (p_data - p_start);
|
||||
@ -163,7 +163,7 @@ static BT_HDR *avrc_bld_init_cmd_buffer(tAVRC_COMMAND *p_cmd)
|
||||
/* reserved 0, packet_type 0 */
|
||||
UINT8_TO_BE_STREAM(p_data, 0);
|
||||
/* continue to the next "case to add length */
|
||||
/* add fixed lenth - 0 */
|
||||
/* add fixed length - 0 */
|
||||
UINT16_TO_BE_STREAM(p_data, 0);
|
||||
break;
|
||||
}
|
||||
@ -237,6 +237,20 @@ static tAVRC_STS avrc_bld_get_element_attr_cmd (tAVRC_GET_ELEM_ATTRS_CMD *p_cmd,
|
||||
return AVRC_STS_NO_ERROR;
|
||||
}
|
||||
|
||||
static tAVRC_STS avrc_bld_get_play_status_cmd(tAVRC_CMD *p_cmd, BT_HDR *p_pkt)
|
||||
{
|
||||
UINT8 *p_data, *p_start;
|
||||
|
||||
AVRC_TRACE_API("avrc_bld_get_play_status");
|
||||
/* get the existing length */
|
||||
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
p_data = p_start + 2; /* pdu + rsvd */
|
||||
/* add parameter length 0 */
|
||||
UINT16_TO_BE_STREAM(p_data, 0);
|
||||
p_pkt->len = (p_data - p_start);
|
||||
return AVRC_STS_NO_ERROR;
|
||||
}
|
||||
|
||||
static tAVRC_STS avrc_bld_get_caps_cmd(tAVRC_GET_CAPS_CMD *p_cmd, BT_HDR *p_pkt)
|
||||
{
|
||||
UINT8 *p_data, *p_start;
|
||||
@ -309,6 +323,10 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt)
|
||||
status = avrc_bld_get_element_attr_cmd(&p_cmd->get_elem_attrs, p_pkt);
|
||||
break;
|
||||
|
||||
case AVRC_PDU_GET_PLAY_STATUS: /* 0x30 */
|
||||
status = avrc_bld_get_play_status_cmd(&p_cmd->get_play_status, p_pkt);
|
||||
break;
|
||||
|
||||
case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
|
||||
status = avrc_bld_register_change_notfn(p_cmd->reg_notif.event_id, p_cmd->reg_notif.param, p_pkt);
|
||||
break;
|
||||
|
@ -113,6 +113,19 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
|
||||
}
|
||||
}
|
||||
break;
|
||||
case AVRC_PDU_GET_PLAY_STATUS:
|
||||
if (p_msg->hdr.ctype == AVRC_RSP_IMPL_STBL) {
|
||||
BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
|
||||
BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
|
||||
BE_STREAM_TO_UINT8(p_result->get_play_status.play_status, p);
|
||||
}
|
||||
else {
|
||||
/* got error response */
|
||||
p_result->get_play_status.song_len = 0;
|
||||
p_result->get_play_status.song_pos = 0;
|
||||
p_result->get_play_status.play_status = AVRC_PLAYSTATE_ERROR;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
status = AVRC_STS_BAD_CMD;
|
||||
break;
|
||||
|
@ -359,7 +359,7 @@ UINT16 GOEPC_RequestAddHeader(UINT16 handle, UINT8 header_id, const UINT8 *data,
|
||||
break;
|
||||
}
|
||||
|
||||
if ((data == NULL) ^ (data_len == 0)) {
|
||||
if ((data == NULL && data_len != 0) || (data != NULL && data_len == 0)) {
|
||||
ret = GOEP_INVALID_PARAM;
|
||||
break;
|
||||
}
|
||||
|
@ -491,7 +491,7 @@ UINT16 OBEX_AppendHeaderRaw(BT_HDR *pkt, UINT8 header_id, const UINT8 *data, UIN
|
||||
return OBEX_INVALID_PARAM;
|
||||
}
|
||||
|
||||
if ((data == NULL) ^ (data_len == 0)) {
|
||||
if ((data == NULL && data_len != 0) || (data != NULL && data_len == 0)) {
|
||||
return OBEX_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user