diff options
author | AnubhavGupta <anubhavg@codeaurora.org> | 2015-04-14 18:37:45 +0530 |
---|---|---|
committer | Linux Build Service Account <lnxbuild@localhost> | 2015-10-06 03:21:52 -0600 |
commit | c0f2898de4248bbd254acedf97be16170b87b544 (patch) | |
tree | e3d962c4f09ce474e4c7f49faf75ea16483657bd /stack | |
parent | 2626f0a4260c37742db898539b91f04cb758cc66 (diff) | |
download | android_system_bt-c0f2898de4248bbd254acedf97be16170b87b544.tar.gz android_system_bt-c0f2898de4248bbd254acedf97be16170b87b544.tar.bz2 android_system_bt-c0f2898de4248bbd254acedf97be16170b87b544.zip |
Bluetooth: Support for Avrcp 1.3 Controller
- support for SDP registration
- support for sending vendor dependant commands
- support for abs vol
- support for receiving vendor dependant response
- serialization of connection and rc_features callback
Change-Id: I108b270b2f7a1c2a035ac2e4811639238455b367
Diffstat (limited to 'stack')
-rw-r--r-- | stack/avrc/avrc_api.c | 16 | ||||
-rw-r--r-- | stack/avrc/avrc_bld_ct.c | 234 | ||||
-rw-r--r-- | stack/avrc/avrc_bld_tg.c | 37 | ||||
-rw-r--r-- | stack/avrc/avrc_pars_ct.c | 188 | ||||
-rw-r--r-- | stack/avrc/avrc_pars_tg.c | 99 | ||||
-rw-r--r-- | stack/avrc/avrc_sdp.c | 18 | ||||
-rw-r--r-- | stack/avrc/avrc_utils.c | 1 | ||||
-rw-r--r-- | stack/include/avrc_api.h | 28 | ||||
-rw-r--r-- | stack/include/avrc_defs.h | 2 |
9 files changed, 598 insertions, 25 deletions
diff --git a/stack/avrc/avrc_api.c b/stack/avrc/avrc_api.c index 5162ec860..56ce7297c 100644 --- a/stack/avrc/avrc_api.c +++ b/stack/avrc/avrc_api.c @@ -375,6 +375,7 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_ BT_HDR *p_pkt = *pp_pkt; UINT8 *p_data; UINT8 drop_code = 0; + BOOLEAN buf_overflow = FALSE; BT_HDR *p_rsp = NULL; BT_HDR *p_cmd = NULL; BOOLEAN req_continue = FALSE; @@ -466,6 +467,7 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_ AVRC_TRACE_WARNING("Fragmented message too big! - report the partial message"); p_pkt->len = buf_len - p_rcb->p_rmsg->offset; pkt_type = AVRC_PKT_END; + buf_overflow = true; } /* copy contents of p_pkt to p_rx_msg */ @@ -529,6 +531,20 @@ static UINT8 avrc_proc_far_msg(UINT8 handle, UINT8 label, UINT8 cr, BT_HDR **pp_ AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd); } } + /* + * Drop it if we are out of buffer + */ + else if (cr == AVCT_RSP && req_continue == FALSE && buf_overflow == TRUE) + { + avrc_cmd.pdu = AVRC_PDU_ABORT_CONTINUATION_RSP; + avrc_cmd.status = AVRC_STS_NO_ERROR; + avrc_cmd.target_pdu = p_rcb->rasm_pdu; + if (AVRC_BldCommand ((tAVRC_COMMAND *)&avrc_cmd, &p_cmd) == AVRC_STS_NO_ERROR) + { + drop_code = 4; + AVRC_MsgReq (handle, (UINT8)(label), AVRC_CMD_CTRL, p_cmd); + } + } } return drop_code; diff --git a/stack/avrc/avrc_bld_ct.c b/stack/avrc/avrc_bld_ct.c index 7e2396768..3e2d4f8ef 100644 --- a/stack/avrc/avrc_bld_ct.c +++ b/stack/avrc/avrc_bld_ct.c @@ -1,5 +1,7 @@ /****************************************************************************** * + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution * Copyright (C) 2006-2013 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -88,27 +90,214 @@ static tAVRC_STS avrc_bld_set_abs_volume_cmd (tAVRC_SET_VOLUME_CMD *p_cmd, BT_HD /******************************************************************************* ** -** Function avrc_bld_vol_change_notfn +** Function avrc_bld_register_notifn ** -** Description This function builds the register notification for volume change. +** Description This function builds the register notification. ** ** Returns AVRC_STS_NO_ERROR, if the command is built successfully ** Otherwise, the error code. ** *******************************************************************************/ -static tAVRC_STS avrc_bld_vol_change_notfn(BT_HDR * p_pkt) +static tAVRC_STS avrc_bld_register_notifn(BT_HDR * p_pkt, UINT8 event_id, UINT32 event_param) { UINT8 *p_data, *p_start; - AVRC_TRACE_API("avrc_bld_vol_change"); + AVRC_TRACE_API("avrc_bld_register_notifn"); /* get the existing length, if any, and also the num attributes */ // Set the notify value p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; p_data = p_start + 2; /* pdu + rsvd */ /* add fixed length 5 -*/ UINT16_TO_BE_STREAM(p_data, 5); - UINT8_TO_BE_STREAM(p_data,AVRC_EVT_VOLUME_CHANGE); - UINT32_TO_BE_STREAM(p_data, 0); + UINT8_TO_BE_STREAM(p_data,event_id); + UINT32_TO_BE_STREAM(p_data, event_param); + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_get_capability_cmd +** +** Description This function builds the get capability command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_get_capability_cmd(BT_HDR * p_pkt, UINT8 cap_id) +{ + UINT8 *p_data, *p_start; + + AVRC_TRACE_API("avrc_bld_get_capability_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* add fixed length 1 -*/ + UINT16_TO_BE_STREAM(p_data, 1); + UINT8_TO_BE_STREAM(p_data,cap_id); + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_list_player_app_attr_cmd +** +** Description This function builds the list player app attrib command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_list_player_app_attr_cmd(BT_HDR * p_pkt) +{ + UINT8 *p_data, *p_start; + + AVRC_TRACE_API("avrc_bld_list_player_app_attr_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* add fixed length 1 -*/ + UINT16_TO_BE_STREAM(p_data, 0); + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_list_player_app_values_cmd +** +** Description This function builds the list player app values command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_list_player_app_values_cmd(BT_HDR * p_pkt, UINT8 attrib_id) +{ + UINT8 *p_data, *p_start; + + AVRC_TRACE_API("avrc_bld_list_player_app_values_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* add fixed length 1 -*/ + UINT16_TO_BE_STREAM(p_data, 1); + UINT8_TO_BE_STREAM(p_data,attrib_id); + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_get_current_player_app_values_cmd +** +** Description This function builds the get current player app setting values command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_get_current_player_app_values_cmd(BT_HDR * p_pkt, UINT8 num_attrib_id, UINT8* attrib_ids) +{ + UINT8 *p_data, *p_start; + UINT8 param_len = 0, count = 0; + + AVRC_TRACE_API("avrc_bld_get_current_player_app_values_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + param_len = num_attrib_id + 1; // 1 additional to hold num attributes feild + /* add length -*/ + UINT16_TO_BE_STREAM(p_data, param_len); + UINT8_TO_BE_STREAM(p_data,num_attrib_id); + for(count = 0; count < num_attrib_id && count < AVRC_MAX_APP_ATTR_SIZE; count ++) + { + UINT8_TO_BE_STREAM(p_data,attrib_ids[count]); + } + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_set_current_player_app_values_cmd +** +** Description This function builds the set current player app setting values command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_set_current_player_app_values_cmd(BT_HDR * p_pkt, UINT8 num_attrib_id, tAVRC_APP_SETTING* p_val) +{ + UINT8 *p_data, *p_start; + UINT8 param_len = 0, count = 0; + + AVRC_TRACE_API("avrc_bld_set_current_player_app_values_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* we have to store attrib- value pair + * 1 additional to store num elements + */ + param_len = (2*num_attrib_id) + 1; + /* add length */ + UINT16_TO_BE_STREAM(p_data, param_len); + UINT8_TO_BE_STREAM(p_data,num_attrib_id); + for(count = 0; count < num_attrib_id; count ++) + { + UINT8_TO_BE_STREAM(p_data,p_val[count].attr_id); + UINT8_TO_BE_STREAM(p_data,p_val[count].attr_val); + } + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_get_element_attr_cmd +** +** Description This function builds the get element attribute command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_get_element_attr_cmd(BT_HDR * p_pkt, UINT8 num_attrib, UINT32* attrib_ids) +{ + UINT8 *p_data, *p_start; + UINT8 param_len = 0, count = 0; + + AVRC_TRACE_API("avrc_bld_get_element_attr_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* we have to store attrib- value pair + * 1 additional to store num elements + */ + param_len = (4*num_attrib) + 9; + /* add length */ + UINT16_TO_BE_STREAM(p_data, param_len); + /* 8 bytes of identifier as 0 (playing)*/ + UINT32_TO_BE_STREAM(p_data,0); + UINT32_TO_BE_STREAM(p_data,0); + UINT8_TO_BE_STREAM(p_data,num_attrib); + for(count = 0; count < num_attrib && count < AVRC_MAX_ELEM_ATTR_SIZE; count ++) + { + UINT32_TO_BE_STREAM(p_data,attrib_ids[count]); + } + p_pkt->len = (p_data - p_start); + return AVRC_STS_NO_ERROR; +} +/******************************************************************************* +** +** Function avrc_bld_get_play_status_cmd +** +** Description This function builds the get play status command. +** +** Returns AVRC_STS_NO_ERROR, if the command is built successfully +** Otherwise, the error code. +** +*******************************************************************************/ +static tAVRC_STS avrc_bld_get_play_status_cmd(BT_HDR * p_pkt) +{ + UINT8 *p_data, *p_start; + + AVRC_TRACE_API("avrc_bld_list_player_app_attr_cmd"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + p_data = p_start + 2; /* pdu + rsvd */ + /* add fixed length 1 -*/ + UINT16_TO_BE_STREAM(p_data, 0); p_pkt->len = (p_data - p_start); return AVRC_STS_NO_ERROR; } @@ -228,14 +417,35 @@ tAVRC_STS AVRC_BldCommand( tAVRC_COMMAND *p_cmd, BT_HDR **pp_pkt) status = avrc_bld_set_abs_volume_cmd(&p_cmd->volume, p_pkt); break; #endif - - case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */ #if (AVRC_ADV_CTRL_INCLUDED == TRUE) - if(AVRC_EVT_VOLUME_CHANGE==p_cmd->reg_notif.event_id) - status=avrc_bld_vol_change_notfn(p_pkt); -#endif + case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */ + status=avrc_bld_register_notifn(p_pkt,p_cmd->reg_notif.event_id,p_cmd->reg_notif.param); break; - + case AVRC_PDU_GET_CAPABILITIES: + status = avrc_bld_get_capability_cmd(p_pkt, p_cmd->get_caps.capability_id); + break; + case AVRC_PDU_LIST_PLAYER_APP_ATTR: + status = avrc_bld_list_player_app_attr_cmd(p_pkt); + break; + case AVRC_PDU_LIST_PLAYER_APP_VALUES: + status = avrc_bld_list_player_app_values_cmd(p_pkt,p_cmd->list_app_values.attr_id); + break; + case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: + status = avrc_bld_get_current_player_app_values_cmd(p_pkt, + p_cmd->get_cur_app_val.num_attr,p_cmd->get_cur_app_val.attrs); + break; + case AVRC_PDU_SET_PLAYER_APP_VALUE: + status = avrc_bld_set_current_player_app_values_cmd(p_pkt, + p_cmd->set_app_val.num_val,p_cmd->set_app_val.p_vals); + break; + case AVRC_PDU_GET_ELEMENT_ATTR: + status = avrc_bld_get_element_attr_cmd(p_pkt, + p_cmd->get_elem_attrs.num_attr,p_cmd->get_elem_attrs.attrs); + break; + case AVRC_PDU_GET_PLAY_STATUS: + status = avrc_bld_get_play_status_cmd(p_pkt); + break; +#endif } if (alloc && (status != AVRC_STS_NO_ERROR) ) diff --git a/stack/avrc/avrc_bld_tg.c b/stack/avrc/avrc_bld_tg.c index c4dfcf81e..4a12fc969 100644 --- a/stack/avrc/avrc_bld_tg.c +++ b/stack/avrc/avrc_bld_tg.c @@ -530,7 +530,6 @@ static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp, return AVRC_STS_NO_ERROR; } - /******************************************************************************* ** ** Function avrc_bld_notify_rsp @@ -549,7 +548,7 @@ static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt) UINT8 xx; tAVRC_STS status = AVRC_STS_NO_ERROR; - AVRC_TRACE_API("avrc_bld_notify_rsp"); + AVRC_TRACE_API("avrc_bld_notify_rsp event_id %d",p_rsp->event_id); p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; p_data = p_len = p_start + 2; /* pdu + rsvd */ @@ -656,7 +655,10 @@ static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt) case AVRC_EVT_NOW_PLAYING_CHANGE: len = EVT_NOW_PLAYING_CHANGE_RSP_LENGTH; break; - + case AVRC_EVT_VOLUME_CHANGE: + len = 2; + UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume)); + break; default: status = AVRC_STS_BAD_PARAM; AVRC_TRACE_ERROR("unknown event_id"); @@ -741,6 +743,31 @@ static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP *p_rsp, BT_HDR *p_pkt) return status; } +/***************************************************************************** +** +** Function avrc_bld_set_absolute_volume_rsp +** +** Description This function builds the set absolute volume response +** +** Returns AVRC_STS_NO_ERROR, if the response is build successfully +** Otherwise, the error code. +** +******************************************************************************/ +static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, BT_HDR *p_pkt) +{ + UINT8 *p_data, *p_start; + tAVRC_STS status = AVRC_STS_NO_ERROR; + + AVRC_TRACE_API(" avrc_bld_play_item_rsp"); + p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset; + /* To calculate length */ + p_data = p_start + 2; + /* add fixed lenth status(1) */ + UINT16_TO_BE_STREAM(p_data, 1); + UINT8_TO_BE_STREAM(p_data, abs_vol); + p_pkt->len = (p_data - p_start); + return status; +} /******************************************************************************* ** ** Function avrc_bld_group_navigation_rsp @@ -1258,6 +1285,10 @@ tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt case AVRC_PDU_PLAY_ITEM: status = avrc_bld_play_item_rsp(&p_rsp->play_item, p_pkt); break; + + case AVRC_PDU_SET_ABSOLUTE_VOLUME: + status = avrc_bld_set_absolute_volume_rsp(p_rsp->volume.volume, p_pkt); + break; } if (alloc && (status != AVRC_STS_NO_ERROR) ) diff --git a/stack/avrc/avrc_pars_ct.c b/stack/avrc/avrc_pars_ct.c index 24204eda5..85f93d776 100644 --- a/stack/avrc/avrc_pars_ct.c +++ b/stack/avrc/avrc_pars_ct.c @@ -1,5 +1,7 @@ /****************************************************************************** * + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution * Copyright (C) 2006-2013 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -102,6 +104,190 @@ static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p return status; } +#if (AVRC_ADV_CTRL_INCLUDED == TRUE) +/******************************************************************************* +** +** Function avrc_ctrl_pars_vendor_rsp +** +** Description This function parses the vendor specific commands defined by +** Bluetooth SIG +** +** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. +** Otherwise, the error code defined by AVRCP 1.4 +** +*******************************************************************************/ +static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result, UINT8* p_buf, UINT16* buf_len) +{ + tAVRC_STS status = AVRC_STS_NO_ERROR; + UINT8 *p = p_msg->p_vendor_data; + UINT16 len; + UINT8 xx, yy; + UINT8 eventid=0; + + BE_STREAM_TO_UINT8 (p_result->pdu, p); + p++; /* skip the reserved/packe_type byte */ + BE_STREAM_TO_UINT16 (len, p); + AVRC_TRACE_DEBUG("avrc_ctrl_pars_vendor_rsp() ctype:0x%x pdu:0x%x, len:%d", + p_msg->hdr.ctype, p_result->pdu, len); + if (p_msg->hdr.ctype == AVRC_RSP_REJ) + { + p_result->rsp.status = *p; + return p_result->rsp.status; + } + + switch (p_result->pdu) + { + /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */ + /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */ + + case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */ + if (len <= 0) + { + buf_len = 0; + break; + } + memcpy(p_buf,p,len); + *buf_len = len; + break; + + case AVRC_PDU_GET_CAPABILITIES: + if (len == 0) + { + p_result->get_caps.count = 0; + p_result->get_caps.capability_id = 0; + break; + } + BE_STREAM_TO_UINT8(p_result->get_caps.capability_id,p); + BE_STREAM_TO_UINT8(p_result->get_caps.count,p); + AVRC_TRACE_DEBUG("AVRC_PDU_GET_CAPABILITIES cap id =%d, cap_count = %d " + ,p_result->get_caps.capability_id,p_result->get_caps.count); + if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) + { + for(xx =0; ((xx<=p_result->get_caps.count) && (xx <AVRC_CAP_MAX_NUM_COMP_ID)); xx++) + { + BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx],p); + } + } + else if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED) + { + for(xx =0; ((xx<=p_result->get_caps.count) && (xx <AVRC_CAP_MAX_NUM_EVT_ID)); xx++) + { + BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx],p); + } + } + break; + case AVRC_PDU_LIST_PLAYER_APP_ATTR: + if (len <= 0) + { + p_result->list_app_attr.num_attr = 0; + break; + } + BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr,p); + AVRC_TRACE_DEBUG("AVRC_PDU_LIST_PLAYER_APP_ATTR count = %d ", + p_result->list_app_attr.num_attr); + for(xx = 0; xx < p_result->list_app_attr.num_attr;xx++) + { + BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx],p); + } + break; + case AVRC_PDU_LIST_PLAYER_APP_VALUES: + if (len <= 0) + { + p_result->list_app_values.num_val = 0; + break; + } + BE_STREAM_TO_UINT8(p_result->list_app_values.num_val,p); + AVRC_TRACE_DEBUG("AVRC_PDU_LIST_PLAYER_APP_ATTR count = %d ", + p_result->list_app_attr.num_attr); + for(xx = 0; xx < p_result->list_app_values.num_val; xx++) + { + BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx],p); + } + break; + case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: + { + tAVRC_APP_SETTING *app_sett; + if (len <= 0) + { + p_result->get_cur_app_val.num_val = 0; + break; + } + BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val,p); + app_sett = + (tAVRC_APP_SETTING*)GKI_getbuf(p_result->get_cur_app_val.num_val*sizeof(tAVRC_APP_SETTING)); + AVRC_TRACE_DEBUG("AVRC_PDU_GET_CUR_PLAYER_APP_VALUE count = %d " + ,p_result->get_cur_app_val.num_val); + for (xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) + { + BE_STREAM_TO_UINT8(app_sett[xx].attr_id,p); + BE_STREAM_TO_UINT8(app_sett[xx].attr_val,p); + } + p_result->get_cur_app_val.p_vals = app_sett; + } + break; + case AVRC_PDU_SET_PLAYER_APP_VALUE: + /* nothing comes as part of this rsp */ + break; + case AVRC_PDU_GET_ELEMENT_ATTR: + if (len <= 0) + { + p_result->get_elem_attrs.num_attr = 0; + break; + } + BE_STREAM_TO_UINT8(p_result->get_elem_attrs.num_attr,p); + memcpy(p_buf,p,len-1); // 1 byte of len already read. + *buf_len = len-1; + break; + case AVRC_PDU_GET_PLAY_STATUS: + if (len <= 0) + { + buf_len = 0; + break; + } + memcpy(p_buf,p,len); + *buf_len = len; + break; + + default: + status = AVRC_STS_BAD_CMD; + break; + } + + return status; +} +#endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */ +/******************************************************************************* +** +** Function AVRC_Ctrl_ParsResponse +** +** Description This function is a parse response for AVRCP Controller. +** +** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. +** Otherwise, the error code defined by AVRCP 1.4 +** +*******************************************************************************/ +tAVRC_STS AVRC_Ctrl_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16* buf_len) +{ + tAVRC_STS status = AVRC_STS_INTERNAL_ERR; + UINT16 id; + + if (p_msg && p_result) + { + switch (p_msg->hdr.opcode) + { + case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */ + status = avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf,buf_len); + break; + + default: + AVRC_TRACE_ERROR("AVRC_Ctrl_ParsResponse() unknown opcode:0x%x", p_msg->hdr.opcode); + break; + } + p_result->rsp.opcode = p_msg->hdr.opcode; + p_result->rsp.status = status; + } + return status; +} /******************************************************************************* ** @@ -145,6 +331,4 @@ tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 * } return status; } - - #endif /* (AVRC_METADATA_INCLUDED == TRUE) */ diff --git a/stack/avrc/avrc_pars_tg.c b/stack/avrc/avrc_pars_tg.c index b75ee907c..90bc5b30b 100644 --- a/stack/avrc/avrc_pars_tg.c +++ b/stack/avrc/avrc_pars_tg.c @@ -1,5 +1,7 @@ /****************************************************************************** * + * Copyright (c) 2015, The Linux Foundation. All rights reserved. + * Not a Contribution * Copyright (C) 2003-2013 Broadcom Corporation * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -27,6 +29,67 @@ *****************************************************************************/ #if (AVRC_METADATA_INCLUDED == TRUE) +#if (AVRC_CTLR_INCLUDED == TRUE) +/******************************************************************************* +** +** Function avrc_ctrl_pars_vendor_cmd +** +** Description This function parses the vendor specific commands defined by +** Bluetooth SIG for AVRCP Conroller. +** +** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. +** Otherwise, the error code defined by AVRCP 1.4 +** +*******************************************************************************/ +static tAVRC_STS avrc_ctrl_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_result, + UINT8 *p_buf, UINT16 buf_len) +{ + tAVRC_STS status = AVRC_STS_NO_ERROR; + UINT8 *p = p_msg->p_vendor_data; + UINT16 len; + + p_result->pdu = *p++; + AVRC_TRACE_DEBUG("avrc_ctrl_pars_vendor_cmd() pdu:0x%x", p_result->pdu); + if (!AVRC_IsValidAvcType (p_result->pdu, p_msg->hdr.ctype)) + { + AVRC_TRACE_DEBUG("avrc_ctrl_pars_vendor_cmd() detects wrong AV/C type!"); + status = AVRC_STS_BAD_CMD; + } + + p++; /* skip the reserved byte */ + BE_STREAM_TO_UINT16 (len, p); + if ((len+4) != (p_msg->vendor_len)) + { + status = AVRC_STS_INTERNAL_ERR; + } + + if (status != AVRC_STS_NO_ERROR) + return status; + + switch (p_result->pdu) + { + case AVRC_PDU_SET_ABSOLUTE_VOLUME: + { + if(len!=1) + status = AVRC_STS_INTERNAL_ERR; + else + { + BE_STREAM_TO_UINT8 (p_result->volume.volume, p); + p_result->volume.volume = AVRC_MAX_VOLUME & p_result->volume.volume; + } + break; + } + case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */ + BE_STREAM_TO_UINT8 (p_result->reg_notif.event_id, p); + BE_STREAM_TO_UINT32 (p_result->reg_notif.param, p); + break; + default: + status = AVRC_STS_BAD_CMD; + break; + } + return status; +} +#endif /******************************************************************************* ** ** Function avrc_pars_vendor_cmd @@ -299,7 +362,43 @@ static tAVRC_STS avrc_pars_vendor_cmd(tAVRC_MSG_VENDOR *p_msg, tAVRC_COMMAND *p_ return status; } +#if (AVRC_CTLR_INCLUDED == TRUE) +/******************************************************************************* +** +** Function AVRC_Ctrl_ParsCommand +** +** Description This function is used to parse cmds received for CTRL +** Currently it is for SetAbsVolume and Volume Change Notification.. +** +** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. +** Otherwise, the error code defined by AVRCP 1.4 +** +*******************************************************************************/ +tAVRC_STS AVRC_Ctrl_ParsCommand (tAVRC_MSG *p_msg, tAVRC_COMMAND *p_result, UINT8 *p_buf, UINT16 buf_len) +{ + tAVRC_STS status = AVRC_STS_INTERNAL_ERR; + UINT16 id; + + if (p_msg && p_result) + { + switch (p_msg->hdr.opcode) + { + case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */ + status = avrc_ctrl_pars_vendor_cmd(&p_msg->vendor, p_result, p_buf, buf_len); + break; + default: + AVRC_TRACE_ERROR("AVRC_ParsCommand() unknown opcode:0x%x", p_msg->hdr.opcode); + break; + } + p_result->cmd.opcode = p_msg->hdr.opcode; + p_result->cmd.status = status; + } + BTIF_TRACE_IMP("AVRC_Ctrl_ParsCommand() return status:0x%x", + __FUNCTION__, status); + return status; +} +#endif /******************************************************************************* ** ** Function AVRC_ParsCommand diff --git a/stack/avrc/avrc_sdp.c b/stack/avrc/avrc_sdp.c index 96582110b..e22314b6d 100644 --- a/stack/avrc/avrc_sdp.c +++ b/stack/avrc/avrc_sdp.c @@ -233,7 +233,8 @@ UINT16 AVRC_FindService(UINT16 service_uuid, BD_ADDR bd_addr, ** ******************************************************************************/ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, - char *p_provider_name, UINT16 categories, UINT32 sdp_handle) + char *p_provider_name, UINT16 categories, UINT32 sdp_handle, + BOOLEAN browse_supported) { UINT16 browse_list[1]; BOOLEAN result = TRUE; @@ -280,16 +281,21 @@ UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, /* add profile descriptor list */ #if SDP_AVRCP_1_5 == TRUE - /* additional protocol list to include browsing channel */ - result &= SDP_AddAdditionProtoLists( sdp_handle, AVRC_NUM_ADDL_PROTO_ELEMS, + if (browse_supported) + { + /* additional protocol list to include browsing channel */ + result &= SDP_AddAdditionProtoLists( sdp_handle, AVRC_NUM_ADDL_PROTO_ELEMS, (tSDP_PROTO_LIST_ELEM *)avrc_add_proto_list); + } result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_5); #else #if SDP_AVRCP_1_4 == TRUE - /* additional protocol list to include browsing channel */ - result &= SDP_AddAdditionProtoLists( sdp_handle, 1, (tSDP_PROTO_LIST_ELEM *)avrc_add_proto_list); - + if (browse_supported) + { + /* additional protocol list to include browsing channel */ + result &= SDP_AddAdditionProtoLists( sdp_handle, 1, (tSDP_PROTO_LIST_ELEM *)avrc_add_proto_list); + } result &= SDP_AddProfileDescriptorList(sdp_handle, UUID_SERVCLASS_AV_REMOTE_CONTROL, AVRC_REV_1_5); #else #if AVRC_METADATA_INCLUDED == TRUE diff --git a/stack/avrc/avrc_utils.c b/stack/avrc/avrc_utils.c index 9c9082f79..5656da713 100644 --- a/stack/avrc/avrc_utils.c +++ b/stack/avrc/avrc_utils.c @@ -61,6 +61,7 @@ BOOLEAN AVRC_IsValidAvcType(UINT8 pdu_id, UINT8 avc_type) case AVRC_PDU_ABORT_CONTINUATION_RSP: /* 0x41 */ case AVRC_PDU_SET_ADDRESSED_PLAYER: case AVRC_PDU_PLAY_ITEM: + case AVRC_PDU_SET_ABSOLUTE_VOLUME: if (avc_type == AVRC_CMD_CTRL) result=TRUE; break; diff --git a/stack/include/avrc_api.h b/stack/include/avrc_api.h index 12601ad47..b7d5a5cdb 100644 --- a/stack/include/avrc_api.h +++ b/stack/include/avrc_api.h @@ -204,7 +204,7 @@ extern "C" ** ******************************************************************************/ extern UINT16 AVRC_AddRecord(UINT16 service_uuid, char *p_service_name, - char *p_provider_name, UINT16 categories, UINT32 sdp_handle); + char *p_provider_name, UINT16 categories, UINT32 sdp_handle, BOOLEAN browse_supported); /****************************************************************************** ** @@ -558,6 +558,20 @@ extern void AVRC_Init(void); /******************************************************************************* ** +** Function AVRC_Ctrl_ParsCommand +** +** Description This function is used to parse cmds received for CTRL +** Currently it is for SetAbsVolume and Volume Change Notification.. +** +** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. +** Otherwise, the error code defined by AVRCP 1.4 +** +*******************************************************************************/ +extern tAVRC_STS AVRC_Ctrl_ParsCommand (tAVRC_MSG *p_msg, tAVRC_COMMAND *p_result, + UINT8 *p_buf, UINT16 buf_len); + +/******************************************************************************* +** ** Function AVRC_ParsCommand ** ** Description This function is used to parse the received command. @@ -584,6 +598,18 @@ extern tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, /******************************************************************************* ** +** Function AVRC_Ctrl_ParsResponse +** +** Description This function is a parse response for AVRCP Controller. +** +** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully. +** Otherwise, the error code defined by AVRCP 1.4 +** +*******************************************************************************/ +extern tAVRC_STS AVRC_Ctrl_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, + UINT8 *p_buf, UINT16* buf_len); +/******************************************************************************* +** ** Function AVRC_BldCommand ** ** Description This function builds the given AVRCP command to the given diff --git a/stack/include/avrc_defs.h b/stack/include/avrc_defs.h index 7d63a47b1..1c1a3f8a1 100644 --- a/stack/include/avrc_defs.h +++ b/stack/include/avrc_defs.h @@ -840,7 +840,7 @@ typedef union #define AVRC_IS_VALID_CAP_ID(a) (((a == AVRC_CAP_COMPANY_ID) || (a == AVRC_CAP_EVENTS_SUPPORTED)) ? TRUE : FALSE) #define AVRC_IS_VALID_EVENT_ID(a) (((a >= AVRC_EVT_PLAY_STATUS_CHANGE) && \ - (a <= AVRC_EVT_ADDR_PLAYER_CHANGE)) ? TRUE : FALSE) + (a <= AVRC_EVT_VOLUME_CHANGE)) ? TRUE : FALSE) #define AVRC_IS_VALID_ATTRIBUTE(a) (((((a > 0) && a <= AVRC_PLAYER_SETTING_SCAN)) || \ (a >= AVRC_PLAYER_SETTING_LOW_MENU_EXT)) ? TRUE : FALSE) |