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

This commit is contained in:
yangfeng
2026-04-16 19:15:08 +08:00
parent a52c67a67b
commit 4ecc25fae1
16 changed files with 330 additions and 111 deletions
@@ -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);
@@ -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;
}
@@ -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;
@@ -270,13 +278,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");
@@ -315,6 +324,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) {
@@ -110,6 +109,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;
@@ -118,7 +121,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++;
}
@@ -134,11 +139,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)) {
@@ -166,7 +173,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;
@@ -188,13 +197,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);
}
@@ -221,13 +229,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;