1 /******************************************************************************
2 *
3 * Copyright (C) 2006-2013 Broadcom Corporation
4 *
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:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
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.
16 *
17 ******************************************************************************/
18 #include <string.h>
19 #include "common/bt_target.h"
20 #include "stack/avrc_api.h"
21 #include "stack/avrc_defs.h"
22 #include "avrc_int.h"
23 #include "common/bt_defs.h"
24
25 #if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE)
26
27 /*****************************************************************************
28 ** Global data
29 *****************************************************************************/
30
31 #if (AVRC_METADATA_INCLUDED == TRUE)
32
33 /*******************************************************************************
34 **
35 ** Function avrc_pars_vendor_rsp
36 **
37 ** Description This function parses the vendor specific commands defined by
38 ** Bluetooth SIG
39 **
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
42 **
43 *******************************************************************************/
avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR * p_msg,tAVRC_RESPONSE * p_result)44 static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR *p_msg, tAVRC_RESPONSE *p_result)
45 {
46 tAVRC_STS status = AVRC_STS_NO_ERROR;
47 UINT8 *p;
48 UINT16 len;
49 UINT8 eventid = 0;
50
51 /* Check the vendor data */
52 if (p_msg->vendor_len == 0) {
53 return AVRC_STS_NO_ERROR;
54 }
55 if (p_msg->p_vendor_data == NULL) {
56 return AVRC_STS_INTERNAL_ERR;
57 }
58
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("avrc_pars_vendor_rsp() ctype:0x%x pdu:0x%x, len:%d/0x%x", p_msg->hdr.ctype, p_result->pdu, len, len);
64 if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
65 p_result->rsp.status = *p;
66 return p_result->rsp.status;
67 }
68
69 switch (p_result->pdu) {
70 /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
71 /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */
72
73 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
74 case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
75 if (len != 1) {
76 status = AVRC_STS_INTERNAL_ERR;
77 } else {
78 BE_STREAM_TO_UINT8 (p_result->volume.volume, p);
79 }
80 break;
81 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
82
83 case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
84 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
85 BE_STREAM_TO_UINT8 (eventid, p);
86 if (AVRC_EVT_VOLUME_CHANGE == eventid
87 && (AVRC_RSP_CHANGED == p_msg->hdr.ctype || AVRC_RSP_INTERIM == p_msg->hdr.ctype
88 || AVRC_RSP_REJ == p_msg->hdr.ctype || AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) {
89 p_result->reg_notif.status = p_msg->hdr.ctype;
90 p_result->reg_notif.event_id = eventid;
91 BE_STREAM_TO_UINT8 (p_result->reg_notif.param.volume, p);
92 }
93 // todo: parse the response for other event_ids
94 AVRC_TRACE_DEBUG("avrc_pars_vendor_rsp PDU reg notif response:event 0x%x", eventid);
95 break;
96 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
97 case AVRC_PDU_GET_CAPABILITIES: /* 0x10 */
98 BE_STREAM_TO_UINT8 (p_result->get_caps.capability_id, p);
99 BE_STREAM_TO_UINT8 (p_result->get_caps.count, p);
100 if (p_result->get_caps.capability_id == AVRC_CAP_EVENTS_SUPPORTED) {
101 if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_EVT_ID) {
102 status = AVRC_STS_INTERNAL_ERR;
103 } else {
104 BE_STREAM_TO_ARRAY(p, p_result->get_caps.param.event_id, p_result->get_caps.count);
105 }
106 } else if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
107 if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) {
108 status = AVRC_STS_INTERNAL_ERR;
109 } else {
110 for (int i = 0; i < p_result->get_caps.count; ++i) {
111 BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[i], p);
112 }
113 }
114 }
115 break;
116 default:
117 status = AVRC_STS_BAD_CMD;
118 break;
119 }
120
121 return status;
122 }
123
124 /*******************************************************************************
125 **
126 ** Function AVRC_ParsResponse
127 **
128 ** Description This function is a superset of AVRC_ParsMetadata to parse the response.
129 **
130 ** Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed successfully.
131 ** Otherwise, the error code defined by AVRCP 1.4
132 **
133 *******************************************************************************/
AVRC_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result)134 tAVRC_STS AVRC_ParsResponse (tAVRC_MSG *p_msg, tAVRC_RESPONSE *p_result)
135 {
136 tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
137 UINT16 id;
138
139 if (p_msg && p_result) {
140 switch (p_msg->hdr.opcode) {
141 case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */
142 status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
143 break;
144
145 case AVRC_OP_PASS_THRU: /* 0x7C panel subunit opcode */
146 status = avrc_pars_pass_thru(&p_msg->pass, &id);
147 if (status == AVRC_STS_NO_ERROR) {
148 p_result->pdu = (UINT8)id;
149 }
150 break;
151
152 default:
153 AVRC_TRACE_ERROR("AVRC_ParsResponse() unknown opcode:0x%x", p_msg->hdr.opcode);
154 break;
155 }
156 p_result->rsp.opcode = p_msg->hdr.opcode;
157 p_result->rsp.status = status;
158 }
159 return status;
160 }
161
162
163 #endif /* (AVRC_METADATA_INCLUDED == TRUE) */
164
165 #endif /* #if (defined(AVRC_INCLUDED) && AVRC_INCLUDED == TRUE) */
166