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 ******************************************************************************/
36bool 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 ******************************************************************************/
94bool 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 ******************************************************************************/
131bool 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 ******************************************************************************/
155tAVRC_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 ******************************************************************************/
186uint8_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 ******************************************************************************/
222bool 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