1 /******************************************************************************
2 *
3 * Copyright 2003-2016 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
19 #define LOG_TAG "avrcp"
20
21 #include <bluetooth/log.h>
22
23 #include <cstdint>
24
25 #include "avrc_api.h"
26 #include "avrc_defs.h"
27 #include "avrc_int.h"
28 #include "stack/include/bt_types.h"
29
30 using namespace bluetooth;
31
32 /**************************************************************************
33 *
34 * Function AVRC_IsValidAvcType
35 *
36 * Description Check if correct AVC type is specified
37 *
38 * Returns returns true if it is valid
39 *
40 *
41 ******************************************************************************/
AVRC_IsValidAvcType(uint8_t pdu_id,uint8_t avc_type)42 bool AVRC_IsValidAvcType(uint8_t pdu_id, uint8_t avc_type) {
43 bool result = false;
44
45 if (avc_type < AVRC_RSP_NOT_IMPL) /* command msg */
46 {
47 switch (pdu_id) {
48 case AVRC_PDU_GET_CAPABILITIES: /* 0x10 */
49 case AVRC_PDU_LIST_PLAYER_APP_ATTR: /* 0x11 */
50 case AVRC_PDU_LIST_PLAYER_APP_VALUES: /* 0x12 */
51 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: /* 0x13 */
52 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: /* 0x15 */
53 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: /* 0x16 */
54 case AVRC_PDU_GET_ELEMENT_ATTR: /* 0x20 */
55 case AVRC_PDU_GET_PLAY_STATUS: /* 0x30 */
56 if (avc_type == AVRC_CMD_STATUS) {
57 result = true;
58 }
59 break;
60
61 case AVRC_PDU_SET_PLAYER_APP_VALUE: /* 0x14 */
62 case AVRC_PDU_INFORM_DISPLAY_CHARSET: /* 0x17 */
63 case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT: /* 0x18 */
64 case AVRC_PDU_REQUEST_CONTINUATION_RSP: /* 0x40 */
65 case AVRC_PDU_ABORT_CONTINUATION_RSP: /* 0x41 */
66 if (avc_type == AVRC_CMD_CTRL) {
67 result = true;
68 }
69 break;
70
71 case AVRC_PDU_GET_FOLDER_ITEMS: /* 0x71 */
72 result = true;
73 break;
74
75 case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
76 case AVRC_PDU_SET_ADDRESSED_PLAYER: /* 0x60 */
77 case AVRC_PDU_PLAY_ITEM: /* 0x74 */
78 case AVRC_PDU_ADD_TO_NOW_PLAYING: /* 0x90 */
79 if (avc_type == AVRC_CMD_CTRL) {
80 result = true;
81 }
82 break;
83
84 case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
85 if (avc_type == AVRC_CMD_NOTIF) {
86 result = true;
87 }
88 break;
89 }
90 } else /* response msg */
91 {
92 if (avc_type >= AVRC_RSP_NOT_IMPL && avc_type <= AVRC_RSP_INTERIM) {
93 result = true;
94 }
95 }
96
97 return result;
98 }
99
100 /*******************************************************************************
101 *
102 * Function avrc_is_valid_player_attrib_value
103 *
104 * Description Check if the given attrib value is valid for its attribute
105 *
106 * Returns returns true if it is valid
107 *
108 ******************************************************************************/
avrc_is_valid_player_attrib_value(uint8_t attrib,uint8_t value)109 bool avrc_is_valid_player_attrib_value(uint8_t attrib, uint8_t value) {
110 bool result = false;
111
112 switch (attrib) {
113 case AVRC_PLAYER_SETTING_EQUALIZER:
114 if ((value > 0) && (value <= AVRC_PLAYER_VAL_ON)) {
115 result = true;
116 }
117 break;
118
119 case AVRC_PLAYER_SETTING_REPEAT:
120 if ((value > 0) && (value <= AVRC_PLAYER_VAL_GROUP_REPEAT)) {
121 result = true;
122 }
123 break;
124
125 case AVRC_PLAYER_SETTING_SHUFFLE:
126 case AVRC_PLAYER_SETTING_SCAN:
127 if ((value > 0) && (value <= AVRC_PLAYER_VAL_GROUP_SHUFFLE)) {
128 result = true;
129 }
130 break;
131 }
132
133 if (attrib >= AVRC_PLAYER_SETTING_LOW_MENU_EXT) {
134 result = true;
135 }
136
137 if (!result) {
138 log::error("found not matching attrib(x{:x})-value(x{:x}) pair!", attrib, value);
139 }
140 return result;
141 }
142
143 /*******************************************************************************
144 *
145 * Function AVRC_IsValidPlayerAttr
146 *
147 * Description Check if the given attrib value is a valid one
148 *
149 * Returns returns true if it is valid
150 *
151 ******************************************************************************/
AVRC_IsValidPlayerAttr(uint8_t attr)152 bool AVRC_IsValidPlayerAttr(uint8_t attr) {
153 bool result = false;
154
155 if ((attr >= AVRC_PLAYER_SETTING_EQUALIZER && attr <= AVRC_PLAYER_SETTING_SCAN) ||
156 (attr >= AVRC_PLAYER_SETTING_LOW_MENU_EXT)) {
157 result = true;
158 }
159
160 return result;
161 }
162
163 /*******************************************************************************
164 *
165 * Function avrc_pars_pass_thru
166 *
167 * Description This function parses the pass thru commands defined by
168 * Bluetooth SIG
169 *
170 * Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed
171 * successfully.
172 * Otherwise, the error code defined by AVRCP 1.4
173 *
174 ******************************************************************************/
avrc_pars_pass_thru(tAVRC_MSG_PASS * p_msg,uint16_t * p_vendor_unique_id)175 tAVRC_STS avrc_pars_pass_thru(tAVRC_MSG_PASS* p_msg, uint16_t* p_vendor_unique_id) {
176 uint8_t* p_data;
177 uint32_t co_id;
178 uint16_t id;
179 tAVRC_STS status = AVRC_STS_BAD_CMD;
180
181 if (p_msg->op_id == AVRC_ID_VENDOR && p_msg->pass_len == AVRC_PASS_THRU_GROUP_LEN) {
182 p_data = p_msg->p_pass_data;
183 AVRC_BE_STREAM_TO_CO_ID(co_id, p_data);
184 if (co_id == AVRC_CO_METADATA) {
185 BE_STREAM_TO_UINT16(id, p_data);
186 if (AVRC_IS_VALID_GROUP(id)) {
187 *p_vendor_unique_id = id;
188 status = AVRC_STS_NO_ERROR;
189 }
190 }
191 }
192 return status;
193 }
194
195 /*******************************************************************************
196 *
197 * Function avrc_opcode_from_pdu
198 *
199 * Description This function returns the opcode of the given pdu
200 *
201 * Returns AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or AVRC_OP_BROWSE
202 *
203 ******************************************************************************/
avrc_opcode_from_pdu(uint8_t pdu)204 uint8_t avrc_opcode_from_pdu(uint8_t pdu) {
205 uint8_t opcode = 0;
206
207 switch (pdu) {
208 case AVRC_PDU_SET_BROWSED_PLAYER:
209 case AVRC_PDU_GET_FOLDER_ITEMS:
210 case AVRC_PDU_CHANGE_PATH:
211 case AVRC_PDU_GET_ITEM_ATTRIBUTES:
212 case AVRC_PDU_SEARCH:
213 case AVRC_PDU_GENERAL_REJECT:
214 case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS:
215 opcode = AVRC_OP_BROWSE;
216 break;
217
218 case AVRC_PDU_NEXT_GROUP:
219 case AVRC_PDU_PREV_GROUP: /* pass thru */
220 opcode = AVRC_OP_PASS_THRU;
221 break;
222
223 default: /* vendor */
224 opcode = AVRC_OP_VENDOR;
225 break;
226 }
227
228 return opcode;
229 }
230
231 /*******************************************************************************
232 *
233 * Function avrc_is_valid_opcode
234 *
235 * Description This function returns the opcode of the given pdu
236 *
237 * Returns AVRC_OP_VENDOR, AVRC_OP_PASS_THRU or AVRC_OP_BROWSE
238 *
239 ******************************************************************************/
avrc_is_valid_opcode(uint8_t opcode)240 bool avrc_is_valid_opcode(uint8_t opcode) {
241 bool is_valid = false;
242 switch (opcode) {
243 case AVRC_OP_BROWSE:
244 case AVRC_OP_PASS_THRU:
245 case AVRC_OP_VENDOR:
246 is_valid = true;
247 break;
248 }
249 return is_valid;
250 }
251