fix(bt): fix AVRCP component issues reported by AI review

This commit is contained in:
yangfeng
2026-03-20 19:57:43 +08:00
parent 6af995cb00
commit d997218dbc
16 changed files with 327 additions and 108 deletions
@@ -624,6 +624,10 @@ esp_err_t esp_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_rn_
return ESP_ERR_NOT_SUPPORTED;
}
if (param == NULL) {
return ESP_ERR_INVALID_ARG;
}
btc_msg_t msg;
msg.sig = BTC_SIG_API_CALL;
msg.pid = BTC_PID_AVRC_TG;
@@ -48,18 +48,24 @@ static UINT8 get_rcb_idx(tBTA_AV_RCB *p_rcb)
return (p_rcb - &bta_av_cb.rcb[0]);
}
static void get_peer_bd_addr(tBTA_AV_RCB *p_rcb, BD_ADDR out_addr)
static BOOLEAN get_peer_bd_addr(tBTA_AV_RCB *p_rcb, BD_ADDR out_addr)
{
/* check if this rcb is related to a scb */
if (p_rcb->shdl && p_rcb->shdl <= BTA_AV_NUM_STRS) {
tBTA_AV_SCB *p_scb = bta_av_cb.p_scb[p_rcb->shdl - 1];
bdcpy(out_addr, p_scb->peer_addr);
if (p_scb != NULL) {
bdcpy(out_addr, p_scb->peer_addr);
return TRUE;
}
}
/* else, try get peer addr from lcb */
else if (p_rcb->lidx && p_rcb->lidx <= BTA_AV_NUM_LINKS + 1)
{
bdcpy(out_addr, bta_av_cb.lcb[p_rcb->lidx-1].addr);
return TRUE;
}
return FALSE;
}
static void report_data_event(BT_HDR *pkt, UINT8 *p_data, UINT16 data_len, BOOLEAN final)
@@ -131,7 +137,8 @@ static void close_goepc_and_disconnect(tBTA_AV_RCB *p_rcb)
tBTA_AV_DATA *p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA));
if (p_data == NULL) {
assert(0);
APPL_TRACE_ERROR("close_goepc_and_disconnect ENOMEM");
return;
}
p_data->hdr.event = BTA_AV_CA_GOEP_DISCONNECT_EVT;
p_data->hdr.layer_specific = get_rcb_idx(p_rcb);
@@ -154,6 +161,11 @@ void bta_av_ca_goep_event_handler(UINT16 handle, UINT8 event, tGOEPC_MSG *p_msg)
{
tBTA_AV_DATA *p_data = NULL;
UINT16 rcb_idx;
if (p_msg == NULL) {
goto error;
}
if (!find_rcb_idx_by_goep_handle(handle, &rcb_idx)) {
/* can not find a rcb, go error */
goto error;
@@ -161,7 +173,9 @@ void bta_av_ca_goep_event_handler(UINT16 handle, UINT8 event, tGOEPC_MSG *p_msg)
if (event == GOEPC_RESPONSE_EVT || event == GOEPC_OPENED_EVT || event == GOEPC_CLOSED_EVT) {
p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA));
assert(p_data != NULL);
if (p_data == NULL) {
goto error;
}
}
switch (event)
@@ -208,7 +222,7 @@ error:
if (p_data != NULL) {
osi_free(p_data);
}
if (event == GOEPC_RESPONSE_EVT && p_msg->response.pkt != NULL) {
if (event == GOEPC_RESPONSE_EVT && p_msg && p_msg->response.pkt != NULL) {
osi_free(p_msg->response.pkt);
}
if (event != GOEPC_CLOSED_EVT) {
@@ -225,13 +239,19 @@ void bta_av_ca_api_open(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
/* reuse the security mask store in bta_av_cb, when support multi connection, this may need change */
svr.l2cap.sec_mask = bta_av_cb.sec_mask;
p_rcb->cover_art_max_rx = p_data->api_ca_open.mtu;
get_peer_bd_addr(p_rcb, svr.l2cap.addr);
if (!get_peer_bd_addr(p_rcb, svr.l2cap.addr)) {
goto error;
}
if (GOEPC_Open(&svr, bta_av_ca_goep_event_handler, &p_rcb->cover_art_goep_hdl) != GOEP_SUCCESS) {
/* open failed */
if ((p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA))) == NULL) {
assert(0);
}
goto error;
}
return;
error:
if ((p_data = (tBTA_AV_DATA *) osi_malloc(sizeof(tBTA_AV_DATA))) != NULL) {
p_data->hdr.event = BTA_AV_CA_GOEP_DISCONNECT_EVT;
p_data->hdr.layer_specific = get_rcb_idx(p_rcb);
p_data->ca_disconnect.reason = BT_STATUS_FAIL;
@@ -271,7 +291,7 @@ void bta_av_ca_api_get(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
break;
default:
/* should not go here */
assert(0);
goto error;
break;
}
image_handle_to_utf16(p_data->api_ca_get.image_handle, image_handle_utf16);
@@ -307,19 +327,21 @@ void bta_av_ca_response(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
{
case OBEX_HEADER_ID_BODY:
/* actually,END_OF_BODY should not in this continue response */
case OBEX_HEADER_ID_END_OF_BODY:
case OBEX_HEADER_ID_END_OF_BODY: {
UINT16 hdr_len = OBEX_GetHeaderLength(header);
UINT16 seg_len = (hdr_len >= 3) ? (UINT16)(hdr_len - 3) : 0;
if (body_data == NULL) {
/* first body header */
body_data = header + 3; /* skip opcode, length */
body_data_len = OBEX_GetHeaderLength(header) - 3;
}
else {
body_data_len = seg_len;
} else {
/* another body header found */
report_data_event(NULL, body_data, body_data_len, FALSE);
body_data = header + 3; /* skip opcode, length */
body_data_len = OBEX_GetHeaderLength(header) - 3;
body_data_len = seg_len;
}
break;
}
default:
break;
}
@@ -395,19 +417,21 @@ void bta_av_ca_response_final(tBTA_AV_RCB *p_rcb, tBTA_AV_DATA *p_data)
{
/* actually, BODY should not in this final response */
case OBEX_HEADER_ID_BODY:
case OBEX_HEADER_ID_END_OF_BODY:
case OBEX_HEADER_ID_END_OF_BODY: {
UINT16 hdr_len = OBEX_GetHeaderLength(header);
UINT16 seg_len = (hdr_len >= 3) ? (UINT16)(hdr_len - 3) : 0;
if (body_data == NULL) {
/* first body header */
body_data = header + 3; /* skip opcode, length */
body_data_len = OBEX_GetHeaderLength(header) - 3;
}
else {
body_data_len = seg_len;
} else {
/* another body header found */
report_data_event(NULL, body_data, body_data_len, FALSE);
body_data = header + 3; /* skip opcode, length */
body_data_len = OBEX_GetHeaderLength(header) - 3;
body_data_len = seg_len;
}
break;
}
default:
break;
}
@@ -153,6 +153,18 @@ void bta_av_ca_sm_execute(tBTA_AV_RCB *p_rcb, UINT16 event, tBTA_AV_DATA *p_data
{
tBTA_AV_CA_ST_TBL state_table;
UINT8 action;
if (p_rcb == NULL ||
p_rcb->cover_art_state >= (sizeof(bta_av_ca_st_tbl) / sizeof(bta_av_ca_st_tbl[0]))) {
APPL_TRACE_WARNING("ca_sm_exec: EINVAL p_rcb");
return;
}
if (event < BTA_AV_CA_FIRST_SM_EVT || event > BTA_AV_CA_LAST_SM_EVT) {
APPL_TRACE_WARNING("ca_sm_exec: evt %u OOR", event);
return;
}
/* look up the state table for the current state */
state_table = bta_av_ca_st_tbl[p_rcb->cover_art_state];
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -25,6 +25,8 @@
#include "btc_avrc.h"
#if BTC_AV_INCLUDED
#define AVRC_TG_SUPPORTED_CMD_ARRAY_SIZE (8)
/*******************************************************************************
**
** Function bta_avrc_co_cmd_allowed
@@ -37,10 +39,13 @@
*******************************************************************************/
BOOLEAN bta_avrc_co_cmd_allowed(tBTA_AV_RC rc_id)
{
if (rc_id >= BTA_AV_VENDOR) {
if (rc_id >= BTA_AV_VENDOR || (rc_id >> 4) >= AVRC_TG_SUPPORTED_CMD_ARRAY_SIZE) {
return FALSE;
}
const uint16_t *rc_cmd = btc_avrc_tg_get_supported_command();
if (rc_cmd == NULL) {
return FALSE;
}
if (rc_cmd[rc_id >> 4] & ((uint16_t)1 << (rc_id & 0x0F))) {
return TRUE;
} else {
@@ -52,7 +57,7 @@ BOOLEAN bta_avrc_co_cmd_allowed(tBTA_AV_RC rc_id)
**
** Function bta_avrc_co_rn_evt_cap
**
** Description get the event notifcation capabilities on AVRCP target
** Description get the event notification capabilities on AVRCP target
**
** Returns number of event_ids supported
**
@@ -65,7 +70,7 @@ UINT8 bta_avrc_co_rn_evt_cap(UINT8 *event_ids)
UINT16 event_bits = btc_avrc_tg_get_rn_supported_evt();
UINT8 count = 0;
for (UINT8 i = 0; i < 16; ++i, event_bits >>= 1) {
for (UINT8 i = 0; i < AVRC_CAP_MAX_NUM_EVT_ID; ++i, event_bits >>= 1) {
if (event_bits & 0x01) {
event_ids[count++] = i;
}
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@@ -145,6 +145,9 @@ bool btc_avrc_tg_check_rn_supported_evt(uint16_t evt_set)
bool btc_avrc_tg_rn_evt_supported(uint8_t event_id)
{
if (event_id > MAX_RC_NOTIFICATIONS) {
return false;
}
uint16_t event_bits = s_rn_supported_evt;
return ((event_bits >> event_id) & 0x0001) ?
true : false;
@@ -152,6 +155,9 @@ bool btc_avrc_tg_rn_evt_supported(uint8_t event_id)
bool btc_avrc_ct_rn_evt_supported(uint8_t event_id)
{
if (event_id > MAX_RC_NOTIFICATIONS) {
return false;
}
uint16_t event_bits = cs_ct_rn_supported_evt;
return ((event_bits >> event_id) & 0x0001) ?
true : false;
@@ -198,8 +204,10 @@ void btc_avrc_arg_deep_copy(btc_msg_t *msg, void *p_dest, void *p_src)
dst->ca_get_img.image_descriptor = (uint8_t *)osi_malloc(len);
if (dst->ca_get_img.image_descriptor) {
memcpy(dst->ca_get_img.image_descriptor, src->ca_get_img.image_descriptor, len);
dst->ca_get_img.image_descriptor_len = len;
} else {
BTC_TRACE_ERROR("%s %d no mem\n", __FUNCTION__, msg->act);
dst->ca_get_img.image_descriptor_len = 0;
}
break;
#endif
@@ -361,23 +369,26 @@ static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
/* if response is for register_notification, make sure the rc has actually registered for this */
if ((p_meta_rsp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED)) {
UINT8 event_id = p_meta_rsp->reg_notif.event_id;
BOOLEAN notify = (btc_rc_cb.rc_connected) && (btc_rc_cb.rc_ntf[event_id - 1].registered);
if (event_id == 0 || event_id > MAX_RC_NOTIFICATIONS) {
BTC_TRACE_WARNING("snd_metamsg_rsp: EINVAL reg_ntf evt_id 0x%x", event_id);
} else {
BOOLEAN notify = (btc_rc_cb.rc_connected) && (btc_rc_cb.rc_ntf[event_id - 1].registered);
/* de-register this notification for a CHANGED response */
btc_rc_cb.rc_ntf[event_id - 1].registered = FALSE;
BTC_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d deregistered", __FUNCTION__,
btc_rc_cb.rc_handle, event_id);
if (notify) {
BT_HDR *p_msg = NULL;
tAVRC_STS status = AVRC_BldResponse(btc_rc_cb.rc_handle, p_meta_rsp, &p_msg);
/* de-register this notification for a CHANGED response */
btc_rc_cb.rc_ntf[event_id - 1].registered = FALSE;
BTC_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d deregistered", __FUNCTION__,
btc_rc_cb.rc_handle, event_id);
if (notify) {
BT_HDR *p_msg = NULL;
tAVRC_STS status = AVRC_BldResponse(btc_rc_cb.rc_handle, p_meta_rsp, &p_msg);
if (status == AVRC_STS_NO_ERROR) {
BTC_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
__FUNCTION__, btc_rc_cb.rc_handle, event_id);
BTA_AvMetaRsp(btc_rc_cb.rc_handle, btc_rc_cb.rc_ntf[event_id - 1].label, ctype, p_msg);
} else {
BTC_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
__FUNCTION__, status);
if (status == AVRC_STS_NO_ERROR) {
BTC_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
__FUNCTION__, btc_rc_cb.rc_handle, event_id);
BTA_AvMetaRsp(btc_rc_cb.rc_handle, btc_rc_cb.rc_ntf[event_id - 1].label, ctype, p_msg);
} else {
BTC_TRACE_WARNING("snd_metamsg_rsp: bld_rsp failed stat: 0x%02x", status);
}
}
}
} else {
@@ -536,6 +547,9 @@ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
return;
}
BD_ADDR peer_bda;
memcpy(peer_bda, btc_rc_cb.rc_addr, sizeof(BD_ADDR));
tBTA_AV_FEAT rc_features = btc_rc_cb.rc_features;
// clean up the state
@@ -567,15 +581,15 @@ static void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
esp_avrc_ct_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
param.conn_stat.connected = false;
memcpy(param.conn_stat.remote_bda, btc_rc_cb.rc_addr, sizeof(esp_bd_addr_t));
memcpy(param.conn_stat.remote_bda, peer_bda, sizeof(esp_bd_addr_t));
btc_avrc_ct_cb_to_app(ESP_AVRC_CT_CONNECTION_STATE_EVT, &param);
}
if (btc_avrc_tg_init_p()) {
esp_avrc_tg_cb_param_t param;
memset(&param, 0, sizeof(esp_avrc_ct_cb_param_t));
memset(&param, 0, sizeof(esp_avrc_tg_cb_param_t));
param.conn_stat.connected = false;
memcpy(param.conn_stat.remote_bda, btc_rc_cb.rc_addr, sizeof(esp_bd_addr_t));
memcpy(param.conn_stat.remote_bda, peer_bda, sizeof(esp_bd_addr_t));
btc_avrc_tg_cb_to_app(ESP_AVRC_TG_CONNECTION_STATE_EVT, &param);
}
}
@@ -586,6 +600,7 @@ static void handle_rc_attributes_rsp (tAVRC_MSG_VENDOR *vendor_msg)
int attr_index = 5;
int attr_length = 0;
uint32_t attr_id = 0;
esp_avrc_ct_cb_param_t *param = NULL;
if (!vendor_msg || !vendor_msg->p_vendor_data ||
(vendor_msg->vendor_len < AVRC_GET_ELEMENT_ATTR_RSP_SIZE_MIN)) {
@@ -597,27 +612,33 @@ static void handle_rc_attributes_rsp (tAVRC_MSG_VENDOR *vendor_msg)
return;
}
esp_avrc_ct_cb_param_t param[attr_count];
memset(&param[0], 0, sizeof(esp_avrc_ct_cb_param_t) * attr_count);
param = (esp_avrc_ct_cb_param_t *)osi_calloc(attr_count * sizeof(esp_avrc_ct_cb_param_t));
if (param == NULL) {
BTC_TRACE_ERROR("handle_rc_attributes_rsp ENOMEM");
return;
}
for (int i = 0; i < attr_count; i++) {
if (vendor_msg->vendor_len < attr_index + 8) {
return;
goto error;
}
attr_length = (int) vendor_msg->p_vendor_data[7 + attr_index] | vendor_msg->p_vendor_data[6 + attr_index] << 8;
attr_length = (int)(((uint16_t)vendor_msg->p_vendor_data[7 + attr_index]) |
((uint16_t)vendor_msg->p_vendor_data[6 + attr_index] << 8));
if (vendor_msg->vendor_len < attr_index + attr_length + 8) {
return;
goto error;
}
//Received attribute text is not null terminated, so it's useful to know it's length
param[i].meta_rsp.attr_length = attr_length;
param[i].meta_rsp.attr_text = &vendor_msg->p_vendor_data[8 + attr_index];
attr_id = vendor_msg->p_vendor_data[3 + attr_index] |
vendor_msg->p_vendor_data[2 + attr_index] << 8 | vendor_msg->p_vendor_data[1 + attr_index] << 16 |
vendor_msg->p_vendor_data[attr_index] << 24;
attr_id = ((uint32_t)vendor_msg->p_vendor_data[3 + attr_index]) |
((uint32_t)vendor_msg->p_vendor_data[2 + attr_index] << 8) |
((uint32_t)vendor_msg->p_vendor_data[1 + attr_index] << 16) |
((uint32_t)vendor_msg->p_vendor_data[attr_index] << 24);
//Convert to mask id
param[i].meta_rsp.attr_id = (1 << (attr_id - 1));
@@ -626,6 +647,9 @@ static void handle_rc_attributes_rsp (tAVRC_MSG_VENDOR *vendor_msg)
attr_index += attr_length + 8;
}
error:
osi_free(param);
}
static void handle_rc_notification_rsp (tAVRC_MSG_VENDOR *vendor_msg)
@@ -850,7 +874,7 @@ static void btc_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 c
break;
case AVRC_PDU_REGISTER_NOTIFICATION: {
UINT8 event_id = pavrc_cmd->reg_notif.event_id;
if (event_id > MAX_RC_NOTIFICATIONS) {
if (event_id == 0 || event_id > MAX_RC_NOTIFICATIONS) {
BTC_TRACE_WARNING("Invalid event_id: 0x%x", event_id);
break;
}
@@ -889,7 +913,20 @@ static void handle_rc_metamsg_rsp (tBTA_AV_META_MSG *p_meta_msg)
{
tAVRC_RESPONSE avrc_response = {0};
tAVRC_STS status;
tAVRC_MSG_VENDOR *vendor_msg = &p_meta_msg->p_msg->vendor;
tAVRC_MSG_VENDOR *vendor_msg;
if (p_meta_msg == NULL || p_meta_msg->p_msg == NULL) {
BTC_TRACE_WARNING("handle_rc_metamsg_rsp: EINVAL p_meta_msg");
return;
}
vendor_msg = &p_meta_msg->p_msg->vendor;
if (vendor_msg->p_vendor_data == NULL ||
vendor_msg->vendor_len <= AVRC_RSP_OPCODE_OFFSET) {
BTC_TRACE_WARNING("handle_rc_metamsg_rsp: EINVAL vendor_data (%u)", vendor_msg->vendor_len);
return;
}
BTC_TRACE_DEBUG("%s: opcode %d, pdu 0x%x, code %d", __FUNCTION__, p_meta_msg->p_msg->hdr.opcode, vendor_msg->p_vendor_data[AVRC_RSP_OPCODE_OFFSET],
p_meta_msg->code);
if ( p_meta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR) {
@@ -1491,6 +1528,9 @@ static void btc_avrc_ct_cover_art_get_image_properties(UINT8 *image_handle)
static void btc_avrc_ct_cover_art_get_image(UINT8 *image_handle, UINT8 *image_descriptor, UINT16 image_descriptor_len)
{
if (image_descriptor == NULL || image_descriptor_len == 0) {
return;
}
if (btc_rc_cb.rc_cover_art_connected) {
BTA_AvCaGet(btc_rc_cb.rc_handle, BTA_AV_CA_GET_IMAGE, image_handle, image_descriptor, image_descriptor_len);
}
@@ -1618,6 +1658,11 @@ static void btc_avrc_tg_send_rn_rsp(esp_avrc_rn_event_ids_t event_id, esp_avrc_r
return;
}
if (event_id == 0 || event_id > MAX_RC_NOTIFICATIONS) {
BTC_TRACE_ERROR("btc_avrc_tg_send_rn_rsp: EINVAL evt_id 0x%x", event_id);
return;
}
if (btc_rc_cb.rc_ntf[event_id - 1].registered == FALSE) {
BTC_TRACE_ERROR("Event id not registered: event_id = %x", event_id);
return;
@@ -151,7 +151,7 @@ typedef enum {
BTC_TRACE_DEBUG("## %s ##", __FUNCTION__); \
if (btc_rc_cb.rc_connected == FALSE) { \
BTC_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
return ESP_ERR_INVALID_STATE; \
return BT_STATUS_FAIL; \
} \
} while (0)
@@ -79,6 +79,10 @@ static void avrc_ctrl_cback(UINT8 handle, UINT8 event, UINT16 result,
{
UINT8 avrc_event;
if (handle >= AVCT_NUM_CONN) {
return;
}
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) {
@@ -151,6 +155,10 @@ static void avrc_prep_end_frag(UINT8 handle)
UINT8 *p_data, *p_orig_data;
UINT8 rsp_type;
if (handle >= AVCT_NUM_CONN) {
return;
}
AVRC_TRACE_DEBUG ("avrc_prep_end_frag" );
p_fcb = &avrc_cb.fcb[handle];
@@ -192,9 +200,17 @@ static void avrc_send_continue_frag(UINT8 handle, UINT8 label)
UINT8 cr = AVCT_RSP;
tAVRC_RSP rej_rsp;
if (handle >= AVCT_NUM_CONN) {
return;
}
p_fcb = &avrc_cb.fcb[handle];
p_pkt = p_fcb->p_fmsg;
if (p_pkt == NULL) {
return;
}
AVRC_TRACE_DEBUG("%s handle = %u label = %u len = %d",
__func__, handle, label, p_pkt->len);
if (p_pkt->len > AVRC_MAX_CTRL_DATA_LEN) {
@@ -262,6 +278,10 @@ static BT_HDR *avrc_proc_vendor_command(UINT8 handle, UINT8 label,
tAVRC_STS status = AVRC_STS_NO_ERROR;
tAVRC_FRAG_CB *p_fcb;
if (handle >= AVCT_NUM_CONN) {
return NULL;
}
p_begin = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
p_data = p_begin + AVRC_VENDOR_HDR_SIZE;
pkt_type = *(p_data + 1) & AVRC_PKT_TYPE_MASK;
@@ -365,6 +385,10 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_
tAVRC_RASM_CB *p_rcb;
tAVRC_NEXT_CMD avrc_cmd;
if (handle >= AVCT_NUM_CONN) {
return 0;
}
p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
/* Skip over vendor header (ctype, subunit*, opcode, CO_ID) */
@@ -390,14 +414,22 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_
/* Allocate buffer for re-assembly */
p_rcb->rasm_pdu = *p_data;
if ((p_rcb->p_rmsg = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE)) != NULL) {
UINT16 buf_payload_max = (UINT16)(BT_DEFAULT_BUFFER_SIZE - sizeof(BT_HDR));
UINT16 copy_len = p_pkt->len;
if (copy_len > buf_payload_max) {
AVRC_TRACE_WARNING("copy_len(%u) > buf_payload_max(%u)",
(unsigned)copy_len, (unsigned)buf_payload_max);
copy_len = buf_payload_max;
}
/* Copy START packet to buffer for re-assembling fragments*/
memcpy(p_rcb->p_rmsg, p_pkt, sizeof(BT_HDR)); /* Copy bt hdr */
/* Copy metadata message */
memcpy((UINT8 *)(p_rcb->p_rmsg + 1),
(UINT8 *)(p_pkt + 1) + p_pkt->offset, p_pkt->len);
(UINT8 *)(p_pkt + 1) + p_pkt->offset, copy_len);
/* offset of start of metadata response in reassembly buffer */
p_rcb->p_rmsg->len = copy_len;
p_rcb->p_rmsg->offset = p_rcb->rasm_offset = 0;
/* Free original START packet, replace with pointer to reassembly buffer */
@@ -525,6 +557,11 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
#endif
tAVRC_MSG_VENDOR *p_msg = &msg.vendor;
if (handle >= AVCT_NUM_CONN) {
osi_free(p_pkt);
return;
}
if (cr == AVCT_CMD &&
(p_pkt->layer_specific & AVCT_DATA_CTRL && AVRC_PACKET_LEN < p_pkt->len)) {
/* Ignore the invalid AV/C command frame */
@@ -577,6 +614,10 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
if (cr == AVCT_CMD) {
/* send the response to the peer */
p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_UNIT_INFO_RSP_LEN);
if (p_rsp == NULL) {
drop = TRUE;
break;
}
p_rsp_data = avrc_get_data_ptr(p_rsp);
*p_rsp_data = AVRC_RSP_IMPL_STBL;
/* check & set the offset. set response code, set subunit_type & subunit_id,
@@ -614,6 +655,10 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
if (cr == AVCT_CMD) {
/* send the response to the peer */
p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_SUB_UNIT_INFO_RSP_LEN);
if (p_rsp == NULL) {
drop = TRUE;
break;
}
p_rsp_data = avrc_get_data_ptr(p_rsp);
*p_rsp_data = AVRC_RSP_IMPL_STBL;
/* check & set the offset. set response code, set (subunit_type & subunit_id),
@@ -756,13 +801,17 @@ static void avrc_msg_cback(UINT8 handle, UINT8 label, UINT8 cr,
if (reject) {
/* reject unsupported opcode */
p_rsp = avrc_copy_packet(p_pkt, AVRC_OP_REJ_MSG_LEN);
p_rsp_data = avrc_get_data_ptr(p_rsp);
*p_rsp_data = AVRC_RSP_REJ;
if (p_rsp == NULL) {
drop = TRUE;
} else {
p_rsp_data = avrc_get_data_ptr(p_rsp);
*p_rsp_data = AVRC_RSP_REJ;
#if (BT_USE_TRACES == TRUE)
p_drop_msg = "rejected";
p_drop_msg = "rejected";
#endif
cr = AVCT_RSP;
drop = TRUE;
cr = AVCT_RSP;
drop = TRUE;
}
}
if (p_rsp) {
@@ -970,6 +1019,10 @@ UINT16 AVRC_MsgReq (UINT8 handle, UINT8 label, UINT8 ctype, BT_HDR *p_pkt)
return AVRC_BAD_PARAM;
}
if (handle >= AVCT_NUM_CONN) {
return AVRC_BAD_HANDLE;
}
AVRC_TRACE_DEBUG("%s handle = %u label = %u ctype = %u len = %d",
__func__, handle, label, ctype, p_pkt->len);
@@ -188,6 +188,10 @@ static tAVRC_STS avrc_bld_set_player_value_cmd(tAVRC_SET_APP_VALUE_CMD *p_cmd, B
{
UINT8 *p_data, *p_start;
if (p_cmd->p_vals == NULL) {
return AVRC_STS_BAD_PARAM;
}
/* 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 */
@@ -217,6 +221,10 @@ static tAVRC_STS avrc_bld_get_element_attr_cmd (tAVRC_GET_ELEM_ATTRS_CMD *p_cmd,
int i;
UINT8 *p_data, *p_start;
if (p_cmd->num_attr > AVRC_MAX_ELEM_ATTR_SIZE) {
return AVRC_STS_BAD_PARAM;
}
AVRC_TRACE_API("avrc_bld_get_element_attr_cmd num_attr: %d", p_cmd->num_attr);
/* get the existing length, if any, and also the num attributes */
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
@@ -284,13 +292,14 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt)
BT_HDR *p_pkt;
BOOLEAN alloc = FALSE;
AVRC_TRACE_API("AVRC_BldCommand: pdu=%x status=%x", p_cmd->cmd.pdu, p_cmd->cmd.status);
if (!p_cmd || !pp_pkt) {
AVRC_TRACE_API("AVRC_BldCommand. Invalid parameters passed. p_cmd=%p, pp_pkt=%p",
p_cmd, pp_pkt);
return AVRC_STS_BAD_PARAM;
}
AVRC_TRACE_API("AVRC_BldCommand: pdu=%x status=%x", p_cmd->cmd.pdu, p_cmd->cmd.status);
if (*pp_pkt == NULL) {
if ((*pp_pkt = avrc_bld_init_cmd_buffer(p_cmd)) == NULL) {
AVRC_TRACE_API("AVRC_BldCommand: Failed to initialize command buffer");
@@ -333,6 +342,10 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt)
case AVRC_PDU_GET_CAPABILITIES:
status = avrc_bld_get_caps_cmd(&p_cmd->get_caps, p_pkt);
break;
default:
status = AVRC_STS_BAD_PARAM;
break;
}
if (alloc && (status != AVRC_STS_NO_ERROR) ) {
@@ -47,6 +47,7 @@ static tAVRC_STS avrc_bld_get_capability_rsp (tAVRC_GET_CAPS_RSP *p_rsp, BT_HDR
UINT8 xx;
UINT32 *p_company_id;
UINT8 *p_event_id;
UINT8 count;
tAVRC_STS status = AVRC_STS_NO_ERROR;
if (!(AVRC_IS_VALID_CAP_ID(p_rsp->capability_id))) {
@@ -64,25 +65,31 @@ static tAVRC_STS avrc_bld_get_capability_rsp (tAVRC_GET_CAPS_RSP *p_rsp, BT_HDR
UINT8_TO_BE_STREAM(p_data, p_rsp->capability_id);
p_count = p_data;
if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
count = (p_rsp->count > AVRC_CAP_MAX_NUM_COMP_ID) ? AVRC_CAP_MAX_NUM_COMP_ID : p_rsp->count;
} else {
count = (p_rsp->count > AVRC_CAP_MAX_NUM_EVT_ID) ? AVRC_CAP_MAX_NUM_EVT_ID : p_rsp->count;
}
if (len == 0) {
*p_count = p_rsp->count;
*p_count = count;
p_data++;
len = 2; /* move past the capability_id and count */
} else {
p_data = p_start + p_pkt->len;
*p_count += p_rsp->count;
*p_count += count;
}
if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
p_company_id = p_rsp->param.company_id;
for (xx = 0; xx < p_rsp->count; xx++) {
for (xx = 0; xx < count; xx++) {
UINT24_TO_BE_STREAM(p_data, p_company_id[xx]);
}
len += p_rsp->count * 3;
len += count * 3;
} else {
p_event_id = p_rsp->param.event_id;
*p_count = 0;
for (xx = 0; xx < p_rsp->count; xx++) {
for (xx = 0; xx < count; xx++) {
if (AVRC_IS_VALID_EVENT_ID(p_event_id[xx])) {
(*p_count)++;
UINT8_TO_BE_STREAM(p_data, p_event_id[xx]);
@@ -113,6 +120,12 @@ static tAVRC_STS avrc_bld_list_app_settings_attr_rsp (tAVRC_LIST_APP_ATTR_RSP *p
UINT8 *p_data, *p_start, *p_len, *p_num;
UINT16 len = 0;
UINT8 xx;
UINT8 num_attr;
num_attr = p_rsp->num_attr;
if (num_attr > AVRC_MAX_APP_ATTR_SIZE) {
num_attr = AVRC_MAX_APP_ATTR_SIZE;
}
AVRC_TRACE_API("avrc_bld_list_app_settings_attr_rsp");
/* get the existing length, if any, and also the num attributes */
@@ -129,7 +142,7 @@ static tAVRC_STS avrc_bld_list_app_settings_attr_rsp (tAVRC_LIST_APP_ATTR_RSP *p
p_data = p_start + p_pkt->len;
}
for (xx = 0; xx < p_rsp->num_attr; xx++) {
for (xx = 0; xx < num_attr; xx++) {
if (AVRC_IsValidPlayerAttr(p_rsp->attrs[xx])) {
(*p_num)++;
UINT8_TO_BE_STREAM(p_data, p_rsp->attrs[xx]);
@@ -160,6 +173,12 @@ static tAVRC_STS avrc_bld_list_app_settings_values_rsp (tAVRC_LIST_APP_VALUES_RS
UINT8 *p_data, *p_start, *p_len, *p_num;
UINT8 xx;
UINT16 len;
UINT8 num_val;
num_val = p_rsp->num_val;
if (num_val > AVRC_MAX_APP_ATTR_SIZE) {
num_val = AVRC_MAX_APP_ATTR_SIZE;
}
AVRC_TRACE_API("avrc_bld_list_app_settings_values_rsp");
@@ -171,15 +190,15 @@ static tAVRC_STS avrc_bld_list_app_settings_values_rsp (tAVRC_LIST_APP_VALUES_RS
p_num = p_data;
/* first time initialize the attribute count */
if (len == 0) {
*p_num = p_rsp->num_val;
*p_num = num_val;
p_data++;
} else {
p_data = p_start + p_pkt->len;
*p_num += p_rsp->num_val;
*p_num += num_val;
}
for (xx = 0; xx < p_rsp->num_val; xx++) {
for (xx = 0; xx < num_val; xx++) {
UINT8_TO_BE_STREAM(p_data, p_rsp->vals[xx]);
}
@@ -206,6 +225,7 @@ static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp (tAVRC_GET_CUR_APP_VALUE
UINT8 *p_data, *p_start, *p_len, *p_count;
UINT16 len;
UINT8 xx;
UINT8 num_val;
if (!p_rsp->p_vals) {
AVRC_TRACE_ERROR("avrc_bld_get_cur_app_setting_value_rsp NULL parameter");
@@ -227,7 +247,12 @@ static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp (tAVRC_GET_CUR_APP_VALUE
p_data = p_start + p_pkt->len;
}
for (xx = 0; xx < p_rsp->num_val; xx++) {
num_val = p_rsp->num_val;
if (num_val > AVRC_MAX_APP_ATTR_SIZE) {
num_val = AVRC_MAX_APP_ATTR_SIZE;
}
for (xx = 0; xx < num_val; xx++) {
if (avrc_is_valid_player_attrib_value(p_rsp->p_vals[xx].attr_id, p_rsp->p_vals[xx].attr_val)) {
(*p_count)++;
UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_id);
@@ -424,7 +449,11 @@ static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, B
{
UINT8 *p_data, *p_start, *p_len, *p_count;
UINT16 len;
UINT16 len_left;
UINT8 xx;
UINT8 num_attr;
UINT16 str_len;
tAVRC_STS sts = AVRC_STS_NO_ERROR;
AVRC_TRACE_API("avrc_bld_get_elem_attrs_rsp");
if (!p_rsp->p_attrs) {
@@ -432,6 +461,11 @@ static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, B
return AVRC_STS_BAD_PARAM;
}
num_attr = p_rsp->num_attr;
if (num_attr > AVRC_MAX_ELEM_ATTR_SIZE) {
num_attr = AVRC_MAX_ELEM_ATTR_SIZE;
}
/* get the existing length, if any, and also the num attributes */
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
p_data = p_len = p_start + 2; /* pdu + rsvd */
@@ -446,24 +480,37 @@ static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, B
p_data = p_start + p_pkt->len;
}
for (xx = 0; xx < p_rsp->num_attr; xx++) {
for (xx = 0; xx < num_attr; xx++) {
if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_rsp->p_attrs[xx].attr_id)) {
AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp invalid attr id[%d]: %d", xx, p_rsp->p_attrs[xx].attr_id);
continue;
}
if ( !p_rsp->p_attrs[xx].name.p_str ) {
p_rsp->p_attrs[xx].name.str_len = 0;
str_len = p_rsp->p_attrs[xx].name.str_len;
if (str_len > 0 && p_rsp->p_attrs[xx].name.p_str == NULL) {
sts = AVRC_STS_BAD_PARAM;
break;
}
len_left = (UINT16)(((UINT8 *)p_pkt + BT_DEFAULT_BUFFER_SIZE) - p_data);
if (len_left < 8 || (UINT32)str_len > (UINT32)len_left - 8) {
sts = AVRC_STS_INTERNAL_ERR;
break;
}
UINT32_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.charset_id);
UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.str_len);
ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, p_rsp->p_attrs[xx].name.str_len);
UINT16_TO_BE_STREAM(p_data, str_len);
if (str_len > 0) {
ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, str_len);
}
(*p_count)++;
}
len = p_data - p_count;
UINT16_TO_BE_STREAM(p_len, len);
p_pkt->len = (p_data - p_start);
return AVRC_STS_NO_ERROR;
if (sts == AVRC_STS_NO_ERROR) {
len = p_data - p_count;
UINT16_TO_BE_STREAM(p_len, len);
p_pkt->len = (p_data - p_start);
}
return sts;
}
/*******************************************************************************
@@ -485,7 +532,7 @@ static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp,
p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
p_data = p_start + 2;
/* add fixed lenth - song len(4) + song position(4) + status(1) */
/* add fixed length - song len(4) + song position(4) + status(1) */
UINT16_TO_BE_STREAM(p_data, 9);
UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
@@ -582,7 +629,6 @@ static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
} else {
AVRC_TRACE_ERROR("bad player app seeting attribute or value");
status = AVRC_STS_BAD_PARAM;
break;
}
@@ -740,6 +786,9 @@ static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
case AVRC_OP_VENDOR:
offset = AVRC_MSG_VENDOR_OFFSET;
break;
default:
return NULL;
}
/* allocate and initialize the buffer */
@@ -763,7 +812,7 @@ static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
/* 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;
}
@@ -65,11 +65,11 @@ static BT_HDR *avrc_vendor_msg(tAVRC_MSG_VENDOR *p_msg)
}
#if AVRC_METADATA_INCLUDED == TRUE
if ((AVRC_META_CMD_BUF_SIZE > AVRC_MIN_VENDOR_CMD_LEN + p_msg->vendor_len) &&
if ((AVRC_META_CMD_BUF_SIZE >= AVRC_MIN_VENDOR_CMD_LEN + p_msg->vendor_len) &&
((p_cmd = (BT_HDR *) osi_malloc(AVRC_META_CMD_BUF_SIZE)) != NULL))
#else
if ((AVRC_CMD_BUF_SIZE > (AVRC_MIN_VENDOR_CMD_LEN + p_msg->vendor_len)) &&
(p_cmd = (BT_HDR *) osi_malloc(AVRC_CMD_BUF_SIZE)) != NULL)
if ((AVRC_CMD_BUF_SIZE >= (AVRC_MIN_VENDOR_CMD_LEN + p_msg->vendor_len)) &&
((p_cmd = (BT_HDR *) osi_malloc(AVRC_CMD_BUF_SIZE)) != NULL))
#endif
{
p_cmd->offset = AVCT_MSG_OFFSET;
@@ -80,6 +80,9 @@ static BT_HDR *avrc_vendor_msg(tAVRC_MSG_VENDOR *p_msg)
AVRC_CO_ID_TO_BE_STREAM(p_data, p_msg->company_id);
if (p_msg->vendor_len && p_msg->p_vendor_data) {
memcpy(p_data, p_msg->p_vendor_data, p_msg->vendor_len);
} else if (p_msg->vendor_len && p_msg->p_vendor_data == NULL) {
osi_free(p_cmd);
return NULL;
}
p_cmd->len = (UINT16) (p_data + p_msg->vendor_len - (UINT8 *)(p_cmd + 1) - p_cmd->offset);
p_cmd->layer_specific = AVCT_DATA_CTRL;
@@ -103,7 +103,7 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
BE_STREAM_TO_UINT8 (eventid, p);
if (AVRC_EVT_VOLUME_CHANGE == eventid
&& (AVRC_RSP_CHANGED == p_msg->hdr.ctype || AVRC_RSP_INTERIM == p_msg->hdr.ctype
|| AVRC_RSP_REJ == p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) {
|| AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) {
if (len < 2) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least 2", len);
return AVRC_STS_INTERNAL_ERR;
@@ -114,8 +114,8 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
}
// todo: parse the response for other event_ids
AVRC_TRACE_DEBUG("avrc_pars_vendor_rsp PDU reg notif response:event 0x%x", eventid);
break;
#endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
break;
case AVRC_PDU_GET_CAPABILITIES: /* 0x10 */
if (len < 2) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least 2", len);
@@ -137,8 +137,7 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p
if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) {
status = AVRC_STS_INTERNAL_ERR;
} else {
if (len < 2 + p_result->get_caps.count * 6) {
AVRC_TRACE_WARNING("invalid message length %u: must be at least %d", len, 2 + p_result->get_caps.count * 6);
if (len < 2 + p_result->get_caps.count * 3) {
return AVRC_STS_INTERNAL_ERR;
}
for (int i = 0; i < p_result->get_caps.count; ++i) {
@@ -50,7 +50,6 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
UINT16 *p_u16;
UINT32 u32, u32_2, *p_u32;
tAVRC_APP_SETTING *p_app_set;
UINT16 size_needed;
/* Check the vendor data */
if (p_msg->vendor_len == 0) {
@@ -114,6 +113,10 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
status = AVRC_STS_INTERNAL_ERR;
} else {
BE_STREAM_TO_UINT8 (p_result->get_cur_app_val.num_attr, p);
if (p_result->get_cur_app_val.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
status = AVRC_STS_INTERNAL_ERR;
break;
}
if (len != (p_result->get_cur_app_val.num_attr + 1)) {
status = AVRC_STS_INTERNAL_ERR;
break;
@@ -122,7 +125,9 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
for (xx = 0, yy = 0; xx < p_result->get_cur_app_val.num_attr; xx++) {
/* only report the valid player app attributes */
if (AVRC_IsValidPlayerAttr(*p)) {
p_u8[yy++] = *p;
if (yy < AVRC_MAX_APP_ATTR_SIZE) {
p_u8[yy++] = *p;
}
}
p++;
}
@@ -138,11 +143,13 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
status = AVRC_STS_INTERNAL_ERR;
} else {
BE_STREAM_TO_UINT8 (p_result->set_app_val.num_val, p);
size_needed = sizeof(tAVRC_APP_SETTING);
if (p_buf && (len == ((p_result->set_app_val.num_val << 1) + 1))) {
p_result->set_app_val.p_vals = (tAVRC_APP_SETTING *)p_buf;
p_app_set = p_result->set_app_val.p_vals;
for (xx = 0; ((xx < p_result->set_app_val.num_val) && (buf_len > size_needed)); xx++) {
for (xx = 0; xx < p_result->set_app_val.num_val; xx++) {
if (buf_len < (UINT16)((xx + 1) * sizeof(tAVRC_APP_SETTING))) {
break;
}
p_app_set[xx].attr_id = *p++;
p_app_set[xx].attr_val = *p++;
if (!avrc_is_valid_player_attrib_value(p_app_set[xx].attr_id, p_app_set[xx].attr_val)) {
@@ -170,7 +177,9 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
status = AVRC_STS_BAD_PARAM;
} else {
BE_STREAM_TO_UINT8 (p_result->get_app_val_txt.num_val, p);
if ( (len - 2/* attr_id & num_val */) != p_result->get_app_val_txt.num_val) {
if (p_result->get_app_val_txt.num_val > AVRC_MAX_APP_ATTR_SIZE) {
status = AVRC_STS_INTERNAL_ERR;
} else if ( (len - 2/* attr_id & num_val */) != p_result->get_app_val_txt.num_val) {
status = AVRC_STS_INTERNAL_ERR;
} else {
p_u8 = p_result->get_app_val_txt.vals;
@@ -192,13 +201,12 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
status = AVRC_STS_INTERNAL_ERR;
} else {
BE_STREAM_TO_UINT8 (p_result->inform_charset.num_id, p);
if ( (len - 1/* num_id */) != p_result->inform_charset.num_id * 2) {
if (p_result->inform_charset.num_id > AVRC_MAX_CHARSET_SIZE) {
status = AVRC_STS_INTERNAL_ERR;
} else if ( (len - 1/* num_id */) != p_result->inform_charset.num_id * 2) {
status = AVRC_STS_INTERNAL_ERR;
} else {
p_u16 = p_result->inform_charset.charsets;
if (p_result->inform_charset.num_id > AVRC_MAX_CHARSET_SIZE) {
p_result->inform_charset.num_id = AVRC_MAX_CHARSET_SIZE;
}
for (xx = 0; xx < p_result->inform_charset.num_id; xx++) {
BE_STREAM_TO_UINT16 (p_u16[xx], p);
}
@@ -225,13 +233,12 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_
BE_STREAM_TO_UINT32 (u32_2, p);
if (u32 == 0 && u32_2 == 0) {
BE_STREAM_TO_UINT8 (p_result->get_elem_attrs.num_attr, p);
if ( (len - 9/* UID/8 and num_attr/1 */) != (p_result->get_elem_attrs.num_attr * 4)) {
if (p_result->get_elem_attrs.num_attr > AVRC_MAX_ELEM_ATTR_SIZE) {
status = AVRC_STS_INTERNAL_ERR;
} else if ( (len - 9/* UID/8 and num_attr/1 */) != (p_result->get_elem_attrs.num_attr * 4)) {
status = AVRC_STS_INTERNAL_ERR;
} else {
p_u32 = p_result->get_elem_attrs.attrs;
if (p_result->get_elem_attrs.num_attr > AVRC_MAX_ELEM_ATTR_SIZE) {
p_result->get_elem_attrs.num_attr = AVRC_MAX_ELEM_ATTR_SIZE;
}
for (xx = 0; xx < p_result->get_elem_attrs.num_attr; xx++) {
BE_STREAM_TO_UINT32 (p_u32[xx], p);
}
@@ -110,7 +110,9 @@ static void avrc_sdp_cback(UINT16 status)
avrc_cb.service_uuid = 0;
/* return info from sdp record in app callback function */
(*avrc_cb.p_cback) (status);
if (avrc_cb.p_cback != NULL) {
(*avrc_cb.p_cback) (status);
}
return;
}
@@ -171,7 +171,8 @@ tAVRC_STS avrc_pars_pass_thru(tAVRC_MSG_PASS *p_msg, UINT16 *p_vendor_unique_id)
UINT16 id;
tAVRC_STS status = AVRC_STS_BAD_CMD;
if (p_msg->op_id == AVRC_ID_VENDOR && p_msg->pass_len == AVRC_PASS_THRU_GROUP_LEN) {
if (p_msg && p_msg->p_pass_data && p_msg->op_id == AVRC_ID_VENDOR &&
p_msg->pass_len == AVRC_PASS_THRU_GROUP_LEN) {
p_data = p_msg->p_pass_data;
AVRC_BE_STREAM_TO_CO_ID (co_id, p_data);
if (co_id == AVRC_CO_METADATA) {
@@ -180,15 +180,16 @@ extern "C"
** Function SDP_InitDiscoveryDb
**
** Description This function is called to initialize a discovery database.
** It will no longer use p_attr_list and p_uuid_list after calling it.
**
** Returns TRUE if successful, FALSE if one or more parameters are bad
**
*******************************************************************************/
extern BOOLEAN SDP_InitDiscoveryDb (tSDP_DISCOVERY_DB *p_db, UINT32 len,
UINT16 num_uuid,
tSDP_UUID *p_uuid_list,
const tSDP_UUID *p_uuid_list,
UINT16 num_attr,
UINT16 *p_attr_list);
const UINT16 *p_attr_list);
/*******************************************************************************
**
@@ -46,6 +46,7 @@
** Function SDP_InitDiscoveryDb
**
** Description This function is called to initialize a discovery database.
** It will no longer use p_attr_list and p_uuid_list after calling it.
**
** Parameters: p_db - (input) address of an area of memory where the
** discovery database is managed.
@@ -63,7 +64,7 @@
**
*******************************************************************************/
BOOLEAN SDP_InitDiscoveryDb (tSDP_DISCOVERY_DB *p_db, UINT32 len, UINT16 num_uuid,
tSDP_UUID *p_uuid_list, UINT16 num_attr, UINT16 *p_attr_list)
const tSDP_UUID *p_uuid_list, UINT16 num_attr, const UINT16 *p_attr_list)
{
#if SDP_CLIENT_ENABLED == TRUE
UINT16 xx;