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