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