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