mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'bugfix/ai_review_avrcp_v6.0' into 'release/v6.0'
fix(bt): Fix the critical and high issues related to AVRCP from AI review report (v6.0) See merge request espressif/esp-idf!50020
This commit is contained in:
@@ -246,8 +246,12 @@ void bta_ar_reg_avrc(UINT16 service_uuid, char *service_name, char *provider_nam
|
||||
|
||||
if (service_uuid == UUID_SERVCLASS_AV_REM_CTRL_TARGET) {
|
||||
if (bta_ar_cb.sdp_tg_handle == 0) {
|
||||
UINT32 sdp_handle = SDP_CreateRecord();
|
||||
if (sdp_handle == 0) {
|
||||
return;
|
||||
}
|
||||
bta_ar_cb.tg_registered = mask;
|
||||
bta_ar_cb.sdp_tg_handle = SDP_CreateRecord();
|
||||
bta_ar_cb.sdp_tg_handle = sdp_handle;
|
||||
AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_tg_handle, browsing_en);
|
||||
bta_sys_add_uuid(service_uuid);
|
||||
}
|
||||
@@ -257,7 +261,12 @@ void bta_ar_reg_avrc(UINT16 service_uuid, char *service_name, char *provider_nam
|
||||
bta_ar_cb.ct_categories [mask - 1] = categories;
|
||||
categories = bta_ar_cb.ct_categories[0] | bta_ar_cb.ct_categories[1];
|
||||
if (bta_ar_cb.sdp_ct_handle == 0) {
|
||||
bta_ar_cb.sdp_ct_handle = SDP_CreateRecord();
|
||||
UINT32 sdp_handle = SDP_CreateRecord();
|
||||
if (sdp_handle == 0) {
|
||||
bta_ar_cb.ct_categories[mask - 1] = 0;
|
||||
return;
|
||||
}
|
||||
bta_ar_cb.sdp_ct_handle = sdp_handle;
|
||||
AVRC_AddRecord(service_uuid, service_name, provider_name, categories, bta_ar_cb.sdp_ct_handle, browsing_en);
|
||||
bta_sys_add_uuid(service_uuid);
|
||||
} else {
|
||||
|
||||
@@ -487,11 +487,15 @@ static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
|
||||
if (btc_rc_cb.rc_connected) {
|
||||
BTC_TRACE_ERROR("Got RC OPEN in connected state, Connected RC: %d \
|
||||
and Current RC: %d", btc_rc_cb.rc_handle, p_rc_open->rc_handle );
|
||||
if ((btc_rc_cb.rc_handle != p_rc_open->rc_handle)
|
||||
&& (bdcmp(btc_rc_cb.rc_addr, p_rc_open->peer_addr))) {
|
||||
BTC_TRACE_DEBUG("Got RC connected for some other handle");
|
||||
BTA_AvCloseRc(p_rc_open->rc_handle);
|
||||
return;
|
||||
if (btc_rc_cb.rc_handle != p_rc_open->rc_handle) {
|
||||
if (bdcmp(btc_rc_cb.rc_addr, p_rc_open->peer_addr) == 0) {
|
||||
/* same device reconnected with new handle - close stale one */
|
||||
BTA_AvCloseRc(btc_rc_cb.rc_handle);
|
||||
} else {
|
||||
BTC_TRACE_DEBUG("Got RC connected for some other handle");
|
||||
BTA_AvCloseRc(p_rc_open->rc_handle);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(btc_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
|
||||
@@ -526,7 +530,11 @@ static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
|
||||
} else {
|
||||
BTC_TRACE_ERROR("%s Connect failed with error code: %d",
|
||||
__FUNCTION__, p_rc_open->status);
|
||||
btc_rc_cb.rc_connected = FALSE;
|
||||
/* only clear state if the failure belongs to the active connection */
|
||||
if (p_rc_open->rc_handle == btc_rc_cb.rc_handle ||
|
||||
bdcmp(btc_rc_cb.rc_addr, p_rc_open->peer_addr) == 0) {
|
||||
btc_rc_cb.rc_connected = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -541,9 +549,18 @@ static void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
|
||||
static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
|
||||
{
|
||||
BTC_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
|
||||
if ((p_rc_close->rc_handle != btc_rc_cb.rc_handle)
|
||||
&& (bdcmp(btc_rc_cb.rc_addr, p_rc_close->peer_addr))) {
|
||||
BTC_TRACE_ERROR("Got disconnect of unknown device");
|
||||
if (!btc_rc_cb.rc_connected) {
|
||||
BTC_TRACE_WARNING("Got disconnect when not connected");
|
||||
return;
|
||||
}
|
||||
if (p_rc_close->rc_handle != btc_rc_cb.rc_handle) {
|
||||
if (bdcmp(btc_rc_cb.rc_addr, p_rc_close->peer_addr) != 0) {
|
||||
BTC_TRACE_ERROR("Got disconnect of unknown device");
|
||||
return;
|
||||
}
|
||||
/* ignore disconnect for superseded handle on same device */
|
||||
BTC_TRACE_DEBUG("Ignoring disconnect for stale rc_handle %d (current %d)",
|
||||
p_rc_close->rc_handle, btc_rc_cb.rc_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -640,6 +657,12 @@ static void handle_rc_attributes_rsp (tAVRC_MSG_VENDOR *vendor_msg)
|
||||
((uint32_t)vendor_msg->p_vendor_data[1 + attr_index] << 16) |
|
||||
((uint32_t)vendor_msg->p_vendor_data[attr_index] << 24);
|
||||
|
||||
if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(attr_id)) {
|
||||
BTC_TRACE_WARNING("invalid attr_id 0x%x, skip", attr_id);
|
||||
attr_index += attr_length + 8;
|
||||
continue;
|
||||
}
|
||||
|
||||
//Convert to mask id
|
||||
param[i].meta_rsp.attr_id = (1 << (attr_id - 1));
|
||||
|
||||
@@ -1153,6 +1176,11 @@ void btc_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
|
||||
***************************************************************************/
|
||||
BOOLEAN btc_rc_get_connected_peer(BD_ADDR peer_addr)
|
||||
{
|
||||
#if AVRC_DYNAMIC_MEMORY == TRUE
|
||||
if (btc_rc_cb_ptr == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
if (btc_rc_cb.rc_connected == TRUE) {
|
||||
bdcpy(peer_addr, btc_rc_cb.rc_addr);
|
||||
return TRUE;
|
||||
@@ -1257,7 +1285,7 @@ static void btc_avrc_ct_deinit(void)
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t attr_id, uint8_t value_id)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
bt_status_t ret = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
@@ -1265,6 +1293,7 @@ static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t att
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_APP_SETTING values = {0};
|
||||
tAVRC_STS cmd_status;
|
||||
|
||||
values.attr_id = attr_id;
|
||||
values.attr_val = value_id;
|
||||
@@ -1276,13 +1305,15 @@ static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t att
|
||||
avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
|
||||
|
||||
if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
cmd_status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (cmd_status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, BTA_AV_CMD_CTRL, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
ret = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
ret = BT_STATUS_FAIL;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
ret = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1290,18 +1321,19 @@ static bt_status_t btc_avrc_ct_send_set_player_value_cmd(uint8_t tl, uint8_t att
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_get_rn_caps_cmd(uint8_t tl)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
bt_status_t ret = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_STS cmd_status;
|
||||
|
||||
avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
|
||||
@@ -1309,13 +1341,15 @@ static bt_status_t btc_avrc_ct_send_get_rn_caps_cmd(uint8_t tl)
|
||||
avrc_cmd.get_caps.capability_id = AVRC_CAP_EVENTS_SUPPORTED;
|
||||
|
||||
if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
cmd_status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (cmd_status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_STATUS, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
ret = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
ret = BT_STATUS_FAIL;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
ret = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1323,18 +1357,19 @@ static bt_status_t btc_avrc_ct_send_get_rn_caps_cmd(uint8_t tl)
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_t event_id, uint32_t event_parameter)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
bt_status_t ret = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_STS cmd_status;
|
||||
|
||||
avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
|
||||
@@ -1343,13 +1378,15 @@ static bt_status_t btc_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_
|
||||
avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
|
||||
|
||||
if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
cmd_status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (cmd_status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_NOTIF, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
ret = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
ret = BT_STATUS_FAIL;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
ret = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1357,18 +1394,19 @@ static bt_status_t btc_avrc_ct_send_register_notification_cmd(uint8_t tl, uint8_
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t volume)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
bt_status_t ret = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_STS cmd_status;
|
||||
|
||||
avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
|
||||
@@ -1376,13 +1414,15 @@ static bt_status_t btc_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t
|
||||
avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
|
||||
|
||||
if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
cmd_status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (cmd_status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_CTRL, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
ret = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
ret = BT_STATUS_FAIL;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
ret = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1390,12 +1430,12 @@ static bt_status_t btc_avrc_ct_send_set_absolute_volume_cmd(uint8_t tl, uint8_t
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
bt_status_t ret = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
@@ -1403,6 +1443,7 @@ static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_STS cmd_status;
|
||||
|
||||
avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
|
||||
avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
|
||||
@@ -1418,13 +1459,15 @@ static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
|
||||
avrc_cmd.get_elem_attrs.num_attr = index;
|
||||
|
||||
if (btc_rc_cb.rc_features & BTA_AV_FEAT_METADATA) {
|
||||
status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (status == AVRC_STS_NO_ERROR) {
|
||||
cmd_status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (cmd_status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_STATUS, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
ret = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
ret = BT_STATUS_FAIL;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
ret = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1432,31 +1475,34 @@ static bt_status_t btc_avrc_ct_send_metadata_cmd (uint8_t tl, uint8_t attr_mask)
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_get_play_status_cmd(uint8_t tl)
|
||||
{
|
||||
tAVRC_STS status = BT_STATUS_UNSUPPORTED;
|
||||
bt_status_t ret = BT_STATUS_UNSUPPORTED;
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
CHECK_ESP_RC_CONNECTED;
|
||||
|
||||
tAVRC_COMMAND avrc_cmd = {0};
|
||||
BT_HDR *p_msg = NULL;
|
||||
tAVRC_STS cmd_status;
|
||||
|
||||
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) {
|
||||
cmd_status = AVRC_BldCommand(&avrc_cmd, &p_msg);
|
||||
if (cmd_status == AVRC_STS_NO_ERROR) {
|
||||
BTA_AvMetaCmd(btc_rc_cb.rc_handle, tl, AVRC_CMD_STATUS, p_msg);
|
||||
status = BT_STATUS_SUCCESS;
|
||||
ret = BT_STATUS_SUCCESS;
|
||||
} else {
|
||||
ret = BT_STATUS_FAIL;
|
||||
}
|
||||
} else {
|
||||
status = BT_STATUS_FAIL;
|
||||
ret = BT_STATUS_FAIL;
|
||||
BTC_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
|
||||
}
|
||||
|
||||
@@ -1464,7 +1510,7 @@ static bt_status_t btc_avrc_ct_send_get_play_status_cmd(uint8_t tl)
|
||||
BTC_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
|
||||
#endif
|
||||
|
||||
return status;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bt_status_t btc_avrc_ct_send_passthrough_cmd(uint8_t tl, uint8_t key_code, uint8_t key_state)
|
||||
@@ -1758,6 +1804,8 @@ void btc_avrc_ct_call_handler(btc_msg_t *msg)
|
||||
default:
|
||||
BTC_TRACE_WARNING("%s : unhandled event: %d\n", __FUNCTION__, msg->act);
|
||||
}
|
||||
|
||||
btc_avrc_arg_deep_free(msg);
|
||||
}
|
||||
|
||||
void btc_avrc_tg_call_handler(btc_msg_t *msg)
|
||||
|
||||
@@ -118,6 +118,9 @@ void AVCT_Deregister(void)
|
||||
|
||||
/* deregister PSM with L2CAP */
|
||||
L2CA_Deregister(AVCT_PSM);
|
||||
#if (AVCT_BROWSE_INCLUDED == TRUE)
|
||||
L2CA_Deregister(AVCT_BR_PSM);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -173,9 +176,14 @@ UINT16 AVCT_CreateConn(UINT8 *p_handle, tAVCT_CC *p_cc, BD_ADDR peer_addr)
|
||||
|
||||
if (result == AVCT_SUCCESS) {
|
||||
/* bind lcb to ccb */
|
||||
tAVCT_LCB_EVT evt;
|
||||
p_ccb->p_lcb = p_lcb;
|
||||
AVCT_TRACE_DEBUG("ch_state: %d", p_lcb->ch_state);
|
||||
avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
|
||||
evt.p_ccb = p_ccb;
|
||||
avct_lcb_event(p_lcb, AVCT_LCB_UL_BIND_EVT, &evt);
|
||||
if (!p_ccb->allocated) {
|
||||
result = AVCT_NOT_OPEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,7 +220,9 @@ UINT16 AVCT_RemoveConn(UINT8 handle)
|
||||
}
|
||||
/* send unbind event to lcb */
|
||||
else {
|
||||
avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, (tAVCT_LCB_EVT *) &p_ccb);
|
||||
tAVCT_LCB_EVT evt;
|
||||
evt.p_ccb = p_ccb;
|
||||
avct_lcb_event(p_ccb->p_lcb, AVCT_LCB_UL_UNBIND_EVT, &evt);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -234,6 +234,9 @@ void avct_l2c_config_cfm_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
|
||||
if ((p_lcb = avct_lcb_by_lcid(lcid)) != NULL) {
|
||||
AVCT_TRACE_DEBUG("avct_l2c_config_cfm_cback: 0x%x, ch_state: %d, res: %d",
|
||||
lcid, p_lcb->ch_state, p_cfg->result);
|
||||
if (p_lcb->conflict_lcid == lcid) {
|
||||
return;
|
||||
}
|
||||
/* if in correct state */
|
||||
if (p_lcb->ch_state == AVCT_CH_CFG) {
|
||||
/* if result successful */
|
||||
@@ -294,6 +297,10 @@ void avct_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
|
||||
p_cfg->result = L2CAP_CFG_OK;
|
||||
L2CA_ConfigRsp(lcid, p_cfg);
|
||||
|
||||
if (p_lcb->conflict_lcid == lcid) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* if first config ind */
|
||||
if ((p_lcb->ch_flags & AVCT_L2C_CFG_IND_DONE) == 0) {
|
||||
/* update flags */
|
||||
@@ -322,7 +329,7 @@ void avct_l2c_config_ind_cback(UINT16 lcid, tL2CAP_CFG_INFO *p_cfg)
|
||||
void avct_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
|
||||
{
|
||||
tAVCT_LCB *p_lcb;
|
||||
UINT16 result = AVCT_RESULT_FAIL;
|
||||
tAVCT_LCB_EVT evt;
|
||||
|
||||
/* look up lcb for this channel */
|
||||
if ((p_lcb = avct_lcb_by_lcid(lcid)) != NULL) {
|
||||
@@ -332,7 +339,13 @@ void avct_l2c_disconnect_ind_cback(UINT16 lcid, BOOLEAN ack_needed)
|
||||
L2CA_DisconnectRsp(lcid);
|
||||
}
|
||||
|
||||
avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, (tAVCT_LCB_EVT *) &result);
|
||||
if (p_lcb->conflict_lcid == lcid) {
|
||||
p_lcb->conflict_lcid = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
evt.result = AVCT_RESULT_FAIL;
|
||||
avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &evt);
|
||||
AVCT_TRACE_DEBUG("ch_state di: %d ", p_lcb->ch_state);
|
||||
}
|
||||
}
|
||||
@@ -356,6 +369,10 @@ void avct_l2c_disconnect_cfm_cback(UINT16 lcid, UINT16 result)
|
||||
if ((p_lcb = avct_lcb_by_lcid(lcid)) != NULL) {
|
||||
AVCT_TRACE_DEBUG("avct_l2c_disconnect_cfm_cback: 0x%x, ch_state: %d, res: %d",
|
||||
lcid, p_lcb->ch_state, result);
|
||||
if (p_lcb->conflict_lcid == lcid) {
|
||||
p_lcb->conflict_lcid = 0;
|
||||
return;
|
||||
}
|
||||
/* result value may be previously stored */
|
||||
res = (p_lcb->ch_result != 0) ? p_lcb->ch_result : result;
|
||||
p_lcb->ch_result = 0;
|
||||
|
||||
@@ -364,7 +364,7 @@ void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
|
||||
|
||||
AVCT_TRACE_DEBUG("%s Freeing LCB", __func__);
|
||||
osi_free(p_lcb->p_rx_msg);
|
||||
fixed_queue_free(p_lcb->tx_q, NULL);
|
||||
fixed_queue_free(p_lcb->tx_q, osi_free_func);
|
||||
memset(p_lcb, 0, sizeof(tAVCT_LCB));
|
||||
}
|
||||
|
||||
|
||||
@@ -425,7 +425,12 @@ void avct_lcb_chnl_disc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
|
||||
{
|
||||
UNUSED(p_data);
|
||||
|
||||
L2CA_DisconnectReq(p_lcb->ch_lcid);
|
||||
tAVCT_LCB_EVT evt;
|
||||
|
||||
if (!L2CA_DisconnectReq(p_lcb->ch_lcid)) {
|
||||
evt.result = AVCT_RESULT_FAIL;
|
||||
avct_lcb_event(p_lcb, AVCT_LCB_LL_CLOSE_EVT, &evt);
|
||||
}
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -474,6 +479,7 @@ void avct_lcb_cong_ind(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
|
||||
if (L2CA_DataWrite(p_lcb->ch_lcid, p_buf) == L2CAP_DW_CONGESTED)
|
||||
{
|
||||
p_lcb->cong = TRUE;
|
||||
event = AVCT_CONG_IND_EVT;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,31 @@ static const UINT8 avrc_ctrl_event_map[] = {
|
||||
#define AVRC_OP_SUB_UNIT_INFO_RSP_LEN 8
|
||||
#define AVRC_OP_REJ_MSG_LEN 11
|
||||
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
/******************************************************************************
|
||||
**
|
||||
** Function avrc_free_far_cb
|
||||
**
|
||||
** Description Free fragmentation/reassembly buffers for a connection.
|
||||
**
|
||||
******************************************************************************/
|
||||
static void avrc_free_far_cb(UINT8 handle)
|
||||
{
|
||||
if (handle >= AVCT_NUM_CONN) {
|
||||
return;
|
||||
}
|
||||
if (avrc_cb.fcb[handle].p_fmsg) {
|
||||
osi_free(avrc_cb.fcb[handle].p_fmsg);
|
||||
avrc_cb.fcb[handle].p_fmsg = NULL;
|
||||
}
|
||||
avrc_cb.fcb[handle].frag_enabled = FALSE;
|
||||
if (avrc_cb.rcb[handle].p_rmsg) {
|
||||
osi_free(avrc_cb.rcb[handle].p_rmsg);
|
||||
avrc_cb.rcb[handle].p_rmsg = NULL;
|
||||
}
|
||||
}
|
||||
#endif /* (AVRC_METADATA_INCLUDED == TRUE) */
|
||||
|
||||
/******************************************************************************
|
||||
**
|
||||
** Function avrc_ctrl_cback
|
||||
@@ -83,6 +108,13 @@ static void avrc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Release pending fragment/reassembly buffers on disconnect */
|
||||
if (event == AVCT_DISCONNECT_CFM_EVT || event == AVCT_DISCONNECT_IND_EVT) {
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
avrc_free_far_cb(handle);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (event <= AVRC_MAX_RCV_CTRL_EVT && avrc_cb.ccb[handle].p_ctrl_cback) {
|
||||
avrc_event = avrc_ctrl_event_map[event];
|
||||
if (event == AVCT_CONNECT_CFM_EVT) {
|
||||
@@ -298,6 +330,11 @@ static BT_HDR *avrc_proc_vendor_command(UINT8 handle, UINT8 label,
|
||||
if (p_msg->company_id == AVRC_CO_METADATA) {
|
||||
switch (*p_data) {
|
||||
case AVRC_PDU_ABORT_CONTINUATION_RSP:
|
||||
if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_ABORT_CONTINUATION_RSP_CMD_SIZE)) {
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
abort_frag = TRUE;
|
||||
break;
|
||||
}
|
||||
/* aborted by CT - send accept response */
|
||||
abort_frag = TRUE;
|
||||
p_begin = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
@@ -315,6 +352,11 @@ static BT_HDR *avrc_proc_vendor_command(UINT8 handle, UINT8 label,
|
||||
break;
|
||||
|
||||
case AVRC_PDU_REQUEST_CONTINUATION_RSP:
|
||||
if (p_pkt->len < (AVRC_VENDOR_HDR_SIZE + AVRC_REQUEST_CONTINUATION_RSP_CMD_SIZE)) {
|
||||
status = AVRC_STS_INTERNAL_ERR;
|
||||
abort_frag = TRUE;
|
||||
break;
|
||||
}
|
||||
if (*(p_data + 4) == p_fcb->frag_pdu) {
|
||||
avrc_send_continue_frag(handle, label);
|
||||
p_msg->hdr.opcode = AVRC_OP_DROP_N_FREE;
|
||||
@@ -435,18 +477,17 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_
|
||||
/* Free original START packet, replace with pointer to reassembly buffer */
|
||||
osi_free(p_pkt);
|
||||
*pp_pkt = p_rcb->p_rmsg;
|
||||
} else {
|
||||
/* Unable to allocate buffer for fragmented avrc message. Reuse START
|
||||
buffer for reassembly (re-assembled message may fit into ACL buf) */
|
||||
AVRC_TRACE_DEBUG ("Unable to allocate buffer for fragmented avrc message, \
|
||||
reusing START buffer for reassembly");
|
||||
p_rcb->rasm_offset = p_pkt->offset;
|
||||
p_rcb->p_rmsg = p_pkt;
|
||||
}
|
||||
|
||||
/* set offset to point to where to copy next - use the same re-asm logic as AVCT */
|
||||
p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
|
||||
req_continue = TRUE;
|
||||
/* set offset to point to where to copy next - use the same re-asm logic as AVCT */
|
||||
p_rcb->p_rmsg->offset += p_rcb->p_rmsg->len;
|
||||
req_continue = TRUE;
|
||||
} else {
|
||||
/* do not reuse START buffer; it is smaller than BT_DEFAULT_BUFFER_SIZE */
|
||||
AVRC_TRACE_ERROR("Unable to allocate buffer for fragmented avrc message");
|
||||
drop_code = 5;
|
||||
osi_free(p_pkt);
|
||||
*pp_pkt = NULL;
|
||||
}
|
||||
} else if (p_rcb->p_rmsg == NULL) {
|
||||
/* Received a CONTINUE/END, but no corresponding START
|
||||
(or previous fragmented response was dropped) */
|
||||
@@ -521,6 +562,14 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_
|
||||
if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR) {
|
||||
drop_code = 2;
|
||||
AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd);
|
||||
} else {
|
||||
AVRC_TRACE_ERROR("Failed to build continuation command");
|
||||
if (p_rcb->p_rmsg) {
|
||||
osi_free(p_rcb->p_rmsg);
|
||||
p_rcb->p_rmsg = NULL;
|
||||
*pp_pkt = NULL;
|
||||
}
|
||||
drop_code = 5;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -953,6 +1002,8 @@ UINT16 AVRC_Open(UINT8 *p_handle, tAVRC_CONN_CB *p_ccb, BD_ADDR_PTR peer_addr)
|
||||
if (status == AVCT_SUCCESS) {
|
||||
memcpy(&avrc_cb.ccb[*p_handle], p_ccb, sizeof(tAVRC_CONN_CB));
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
/* free fragmentation/reassembly buffers before memset clears pointers */
|
||||
avrc_free_far_cb(*p_handle);
|
||||
memset(&avrc_cb.fcb[*p_handle], 0, sizeof(tAVRC_FRAG_CB));
|
||||
memset(&avrc_cb.rcb[*p_handle], 0, sizeof(tAVRC_RASM_CB));
|
||||
#endif
|
||||
@@ -984,6 +1035,10 @@ UINT16 AVRC_Open(UINT8 *p_handle, tAVRC_CONN_CB *p_ccb, BD_ADDR_PTR peer_addr)
|
||||
UINT16 AVRC_Close(UINT8 handle)
|
||||
{
|
||||
AVRC_TRACE_DEBUG("AVRC_Close handle:%d", handle);
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
/* release pending fragment/reassembly buffers before removing connection */
|
||||
avrc_free_far_cb(handle);
|
||||
#endif
|
||||
return AVCT_RemoveConn(handle);
|
||||
}
|
||||
|
||||
@@ -1067,7 +1122,7 @@ UINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt)
|
||||
|
||||
/* AVRCP spec has not defined any control channel commands that needs fragmentation at this level
|
||||
* check for fragmentation only on the response */
|
||||
if ((cr == AVCT_RSP) && (chk_frag == TRUE)) {
|
||||
if ((cr == AVCT_RSP) && (chk_frag == TRUE) && (p_pkt->event == AVRC_OP_VENDOR)) {
|
||||
if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
|
||||
int offset_len = MAX(AVCT_MSG_OFFSET, p_pkt->offset);
|
||||
p_pkt_new = (BT_HDR *)osi_malloc((UINT16)(AVRC_PACKET_LEN + offset_len
|
||||
@@ -1099,6 +1154,9 @@ UINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt)
|
||||
p_pkt->len, len, p_fcb->p_fmsg->len );
|
||||
} else {
|
||||
AVRC_TRACE_ERROR ("AVRC_MsgReq no buffers for fragmentation" );
|
||||
if (p_pkt_new) {
|
||||
osi_free(p_pkt_new);
|
||||
}
|
||||
osi_free(p_pkt);
|
||||
return AVRC_NO_RESOURCES;
|
||||
}
|
||||
|
||||
@@ -336,9 +336,11 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt)
|
||||
status = avrc_bld_get_play_status_cmd(&p_cmd->get_play_status, p_pkt);
|
||||
break;
|
||||
|
||||
#if (AVRC_ADV_CTRL_INCLUDED == TRUE)
|
||||
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;
|
||||
#endif
|
||||
case AVRC_PDU_GET_CAPABILITIES:
|
||||
status = avrc_bld_get_caps_cmd(&p_cmd->get_caps, p_pkt);
|
||||
break;
|
||||
|
||||
@@ -87,15 +87,17 @@ static tAVRC_STS avrc_bld_get_capability_rsp (tAVRC_GET_CAPS_RSP *p_rsp, BT_HDR
|
||||
}
|
||||
len += count * 3;
|
||||
} else {
|
||||
UINT8 valid_count = 0;
|
||||
p_event_id = p_rsp->param.event_id;
|
||||
*p_count = 0;
|
||||
*p_count -= count;
|
||||
for (xx = 0; xx < count; xx++) {
|
||||
if (AVRC_IS_VALID_EVENT_ID(p_event_id[xx])) {
|
||||
(*p_count)++;
|
||||
valid_count++;
|
||||
UINT8_TO_BE_STREAM(p_data, p_event_id[xx]);
|
||||
}
|
||||
}
|
||||
len += (*p_count);
|
||||
*p_count += valid_count;
|
||||
len += valid_count;
|
||||
}
|
||||
UINT16_TO_BE_STREAM(p_len, len);
|
||||
p_pkt->len = (p_data - p_start);
|
||||
@@ -314,12 +316,6 @@ static tAVRC_STS avrc_bld_app_setting_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rs
|
||||
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
|
||||
p_data = p_len = p_start + 2; /* pdu + rsvd */
|
||||
|
||||
/*
|
||||
* NOTE: The buffer is allocated within avrc_bld_init_rsp_buffer(), and is
|
||||
* always of size BT_DEFAULT_BUFFER_SIZE.
|
||||
*/
|
||||
len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
|
||||
|
||||
BE_STREAM_TO_UINT16(len, p_data);
|
||||
p_count = p_data;
|
||||
|
||||
@@ -331,6 +327,7 @@ static tAVRC_STS avrc_bld_app_setting_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rs
|
||||
}
|
||||
|
||||
for (xx = 0; xx < p_rsp->num_attr; xx++) {
|
||||
len_left = (UINT16)(((UINT8 *)p_pkt + BT_DEFAULT_BUFFER_SIZE) - p_data);
|
||||
if (len_left < (p_rsp->p_attrs[xx].str_len + 4)) {
|
||||
AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp out of room %d(str_len:%d, left:%d)",
|
||||
xx, p_rsp->p_attrs[xx].str_len, len_left);
|
||||
@@ -926,6 +923,10 @@ tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt
|
||||
case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
|
||||
status = avrc_bld_set_absolute_volume_rsp(&p_rsp->volume, p_pkt);
|
||||
break;
|
||||
|
||||
default:
|
||||
status = AVRC_STS_BAD_PARAM;
|
||||
break;
|
||||
}
|
||||
|
||||
if (alloc && (status != AVRC_STS_NO_ERROR) ) {
|
||||
|
||||
@@ -52,9 +52,6 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
|
||||
tAVRC_APP_SETTING *p_app_set;
|
||||
|
||||
/* Check the vendor data */
|
||||
if (p_msg->vendor_len == 0) {
|
||||
return AVRC_STS_NO_ERROR;
|
||||
}
|
||||
if ((p_msg->p_vendor_data == NULL) || (p_msg->vendor_len < AVRC_CMD_FIXED_SIZE)) {
|
||||
return AVRC_STS_INTERNAL_ERR;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,11 @@ UINT16 AVRC_FindService(UINT16 service_uuid, BD_ADDR bd_addr,
|
||||
|
||||
/* perform service search */
|
||||
result = SDP_ServiceSearchAttributeRequest(bd_addr, p_db->p_db, avrc_sdp_cback);
|
||||
if (!result) {
|
||||
avrc_cb.service_uuid = 0;
|
||||
avrc_cb.p_db = NULL;
|
||||
avrc_cb.p_cback = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (result ? AVRC_SUCCESS : AVRC_FAIL);
|
||||
@@ -413,6 +418,17 @@ void AVRC_Deinit(void)
|
||||
{
|
||||
#if AVRC_DYNAMIC_MEMORY
|
||||
if (avrc_cb_ptr){
|
||||
#if (AVRC_METADATA_INCLUDED == TRUE)
|
||||
UINT8 i;
|
||||
for (i = 0; i < AVCT_NUM_CONN; i++) {
|
||||
if (avrc_cb_ptr->fcb[i].p_fmsg) {
|
||||
osi_free(avrc_cb_ptr->fcb[i].p_fmsg);
|
||||
}
|
||||
if (avrc_cb_ptr->rcb[i].p_rmsg) {
|
||||
osi_free(avrc_cb_ptr->rcb[i].p_rmsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
osi_free(avrc_cb_ptr);
|
||||
avrc_cb_ptr = NULL;
|
||||
}
|
||||
|
||||
@@ -325,10 +325,6 @@ static void bt_av_hdl_stack_evt(uint16_t event, void *p_param)
|
||||
esp_avrc_ct_init();
|
||||
esp_avrc_ct_register_callback(bt_app_rc_ct_cb);
|
||||
|
||||
esp_avrc_rn_evt_cap_mask_t evt_set = {0};
|
||||
esp_avrc_rn_evt_bit_mask_operation(ESP_AVRC_BIT_MASK_OP_SET, &evt_set, ESP_AVRC_RN_VOLUME_CHANGE);
|
||||
ESP_ERROR_CHECK(esp_avrc_tg_set_rn_evt_cap(&evt_set));
|
||||
|
||||
esp_a2d_source_init();
|
||||
esp_a2d_register_callback(&bt_app_a2d_cb);
|
||||
esp_a2d_source_register_data_callback(bt_app_a2d_data_cb);
|
||||
|
||||
Reference in New Issue
Block a user