1 /******************************************************************************
3 * Copyright (C) 2006-2013 Broadcom Corporation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
17 ******************************************************************************/
20 #include "bt_common.h"
22 #include "avrc_defs.h"
27 /*****************************************************************************
29 *****************************************************************************/
31 #if (AVRC_METADATA_INCLUDED == TRUE)
33 /*******************************************************************************
35 ** Function avrc_pars_vendor_rsp
37 ** Description This function parses the vendor specific commands defined by
40 ** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
41 ** Otherwise, the error code defined by AVRCP 1.4
43 *******************************************************************************/
44 static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result)
46 tAVRC_STS status = AVRC_STS_NO_ERROR;
49 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
53 /* Check the vendor data */
54 if (p_msg->vendor_len == 0)
55 return AVRC_STS_NO_ERROR;
56 if (p_msg->p_vendor_data == NULL)
57 return AVRC_STS_INTERNAL_ERR;
59 p = p_msg->p_vendor_data;
60 BE_STREAM_TO_UINT8 (p_result->pdu, p);
61 p++; /* skip the reserved/packe_type byte */
62 BE_STREAM_TO_UINT16 (len, p);
63 AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d/0x%x",
64 __func__, p_msg->hdr.ctype, p_result->pdu, len, len);
65 if (p_msg->hdr.ctype == AVRC_RSP_REJ)
67 p_result->rsp.status = *p;
68 return p_result->rsp.status;
71 switch (p_result->pdu)
73 /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
74 /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */
76 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
77 case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
79 status = AVRC_STS_INTERNAL_ERR;
82 BE_STREAM_TO_UINT8 (p_result->volume.volume, p);
85 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
87 case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
88 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
89 BE_STREAM_TO_UINT8 (eventid, p);
90 if(AVRC_EVT_VOLUME_CHANGE==eventid
91 && (AVRC_RSP_CHANGED==p_msg->hdr.ctype || AVRC_RSP_INTERIM==p_msg->hdr.ctype
92 || AVRC_RSP_REJ==p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL==p_msg->hdr.ctype))
94 p_result->reg_notif.status=p_msg->hdr.ctype;
95 p_result->reg_notif.event_id=eventid;
96 BE_STREAM_TO_UINT8 (p_result->reg_notif.param.volume, p);
98 AVRC_TRACE_DEBUG("%s PDU reg notif response:event %x, volume %x",
99 __func__, eventid, p_result->reg_notif.param.volume);
100 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
103 status = AVRC_STS_BAD_CMD;
110 void avrc_parse_notification_rsp (UINT8 *p_stream, tAVRC_REG_NOTIF_RSP *p_rsp)
112 BE_STREAM_TO_UINT8(p_rsp->event_id, p_stream);
113 switch (p_rsp->event_id)
115 case AVRC_EVT_PLAY_STATUS_CHANGE:
116 BE_STREAM_TO_UINT8(p_rsp->param.play_status, p_stream);
119 case AVRC_EVT_TRACK_CHANGE:
120 BE_STREAM_TO_ARRAY(p_stream, p_rsp->param.track, 8);
123 case AVRC_EVT_APP_SETTING_CHANGE:
124 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream);
125 for (int index = 0; index < p_rsp->param.player_setting.num_attr; index++)
127 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index], p_stream);
128 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_value[index], p_stream);
132 case AVRC_EVT_NOW_PLAYING_CHANGE:
135 case AVRC_EVT_AVAL_PLAYERS_CHANGE:
138 case AVRC_EVT_ADDR_PLAYER_CHANGE:
141 case AVRC_EVT_UIDS_CHANGE:
144 case AVRC_EVT_TRACK_REACHED_END:
145 case AVRC_EVT_TRACK_REACHED_START:
146 case AVRC_EVT_PLAY_POS_CHANGED:
147 case AVRC_EVT_BATTERY_STATUS_CHANGE:
148 case AVRC_EVT_SYSTEM_STATUS_CHANGE:
154 #if (AVRC_CTLR_INCLUDED == TRUE)
155 /*******************************************************************************
157 ** Function avrc_ctrl_pars_vendor_rsp
159 ** Description This function parses the vendor specific commands defined by
162 ** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
163 ** Otherwise, the error code defined by AVRCP 1.4
165 *******************************************************************************/
166 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(
167 tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result, UINT8* p_buf, UINT16* buf_len)
169 UINT8 *p = p_msg->p_vendor_data;
170 BE_STREAM_TO_UINT8 (p_result->pdu, p);
171 p++; /* skip the reserved/packe_type byte */
174 BE_STREAM_TO_UINT16 (len, p);
175 AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d",
176 __func__, p_msg->hdr.ctype, p_result->pdu, len);
177 /* Todo: Issue in handling reject, check */
178 if (p_msg->hdr.ctype == AVRC_RSP_REJ)
180 p_result->rsp.status = *p;
181 return p_result->rsp.status;
184 /* TODO: Break the big switch into functions. */
185 switch (p_result->pdu)
187 /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
188 /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */
190 case AVRC_PDU_REGISTER_NOTIFICATION:
191 avrc_parse_notification_rsp(p, &p_result->reg_notif);
194 case AVRC_PDU_GET_CAPABILITIES:
197 p_result->get_caps.count = 0;
198 p_result->get_caps.capability_id = 0;
201 BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
202 BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
203 AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ",
204 __func__, p_result->get_caps.capability_id, p_result->get_caps.count);
205 if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID)
207 for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_COMP_ID));
210 BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
213 else if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED)
215 for(int xx = 0; ((xx < p_result->get_caps.count) && (xx < AVRC_CAP_MAX_NUM_EVT_ID));
218 BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
223 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
226 p_result->list_app_attr.num_attr = 0;
229 BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
231 if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
232 android_errorWriteLog(0x534e4554, "63146237");
233 p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
236 AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->list_app_attr.num_attr);
237 for(int xx = 0; xx < p_result->list_app_attr.num_attr; xx++)
239 BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
243 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
246 p_result->list_app_values.num_val = 0;
249 BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
250 AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->list_app_values.num_val);
251 for(int xx = 0; xx < p_result->list_app_values.num_val; xx++)
253 BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
257 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
261 p_result->get_cur_app_val.num_val = 0;
264 BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
265 tAVRC_APP_SETTING *app_sett =
266 (tAVRC_APP_SETTING*)osi_malloc(p_result->get_cur_app_val.num_val*sizeof(tAVRC_APP_SETTING));
267 AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_cur_app_val.num_val);
270 if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
271 android_errorWriteLog(0x534e4554, "63146237");
272 p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
275 for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++)
277 BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
278 BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
280 p_result->get_cur_app_val.p_vals = app_sett;
284 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
290 p_result->get_app_attr_txt.num_attr = 0;
293 BE_STREAM_TO_UINT8(num_attrs, p);
294 if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
295 num_attrs = AVRC_MAX_APP_ATTR_SIZE;
297 AVRC_TRACE_DEBUG("%s attr count = %d ", __func__, p_result->get_app_attr_txt.num_attr);
298 p_result->get_app_attr_txt.num_attr = num_attrs;
299 p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)
300 osi_malloc(num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
301 for (int xx = 0; xx < num_attrs; xx++)
303 BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
304 BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id, p);
305 BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
306 if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0)
308 UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_attr_txt.p_attrs[xx].str_len);
309 BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_attr_txt.p_attrs[xx].str_len);
310 p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
312 p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
318 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
324 p_result->get_app_val_txt.num_attr = 0;
327 BE_STREAM_TO_UINT8(num_vals, p);
328 if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
329 num_vals = AVRC_MAX_APP_ATTR_SIZE;
331 p_result->get_app_val_txt.num_attr = num_vals;
332 AVRC_TRACE_DEBUG("%s value count = %d ", __func__, p_result->get_app_val_txt.num_attr);
334 p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT *)
335 osi_malloc(num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
336 for (int i = 0; i < num_vals; i++) {
337 BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
338 BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
339 BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
340 if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
341 UINT8 *p_str = (UINT8 *)osi_malloc(p_result->get_app_val_txt.p_attrs[i].str_len);
342 BE_STREAM_TO_ARRAY(p, p_str, p_result->get_app_val_txt.p_attrs[i].str_len);
343 p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
345 p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
351 case AVRC_PDU_SET_PLAYER_APP_VALUE:
352 /* nothing comes as part of this rsp */
355 case AVRC_PDU_GET_ELEMENT_ATTR:
361 p_result->get_elem_attrs.num_attr = 0;
364 BE_STREAM_TO_UINT8(num_attrs, p);
365 p_result->get_elem_attrs.num_attr = num_attrs;
368 tAVRC_ATTR_ENTRY *p_attrs =
369 (tAVRC_ATTR_ENTRY*)osi_malloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
370 for (int i = 0; i < num_attrs; i++) {
371 BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
372 BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
373 BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
374 if (p_attrs[i].name.str_len > 0) {
375 p_attrs[i].name.p_str = (UINT8 *)osi_malloc(p_attrs[i].name.str_len);
376 BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str, p_attrs[i].name.str_len);
379 p_result->get_elem_attrs.p_attrs = p_attrs;
384 case AVRC_PDU_GET_PLAY_STATUS:
389 BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
390 BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
391 BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
395 return AVRC_STS_BAD_CMD;
397 return AVRC_STS_NO_ERROR;
400 /*******************************************************************************
402 ** Function AVRC_Ctrl_ParsResponse
404 ** Description This function is a parse response for AVRCP Controller.
406 ** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
407 ** Otherwise, the error code defined by AVRCP 1.4
409 *******************************************************************************/
410 tAVRC_STS AVRC_Ctrl_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16* buf_len)
412 tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
413 if (p_msg && p_result)
415 switch (p_msg->hdr.opcode)
417 case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */
418 status = avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf,buf_len);
422 AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
425 p_result->rsp.opcode = p_msg->hdr.opcode;
426 p_result->rsp.status = status;
430 #endif /* (AVRC_CTRL_INCLUDED) == TRUE) */
431 /*******************************************************************************
433 ** Function AVRC_ParsResponse
435 ** Description This function is a superset of AVRC_ParsMetadata to parse the response.
437 ** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
438 ** Otherwise, the error code defined by AVRCP 1.4
440 *******************************************************************************/
441 tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result, UINT8 *p_buf, UINT16 buf_len)
443 tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
448 if (p_msg && p_result)
450 switch (p_msg->hdr.opcode)
452 case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */
453 status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
456 case AVRC_OP_PASS_THRU: /* 0x7C panel subunit opcode */
457 status = avrc_pars_pass_thru(&p_msg->pass, &id);
458 if (status == AVRC_STS_NO_ERROR)
460 p_result->pdu = (UINT8)id;
465 AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
468 p_result->rsp.opcode = p_msg->hdr.opcode;
469 p_result->rsp.status = status;
473 #endif /* (AVRC_METADATA_INCLUDED == TRUE) */