1 /******************************************************************************
2 *
3 * Copyright 2006-2013 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_defs.h"
22 #include "avrc_int.h"
23 #include "bt_common.h"
24 #include "bt_utils.h"
25 #include "osi/include/log.h"
26 #include "osi/include/osi.h"
27
28 /*****************************************************************************
29 * Global data
30 ****************************************************************************/
31
32 #define MIN(x, y) ((x) < (y) ? (x) : (y))
33
34 /*******************************************************************************
35 *
36 * Function avrc_pars_vendor_rsp
37 *
38 * Description This function parses the vendor specific commands defined by
39 * Bluetooth SIG
40 *
41 * Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed
42 * successfully.
43 * Otherwise, the error code defined by AVRCP 1.4
44 *
45 ******************************************************************************/
avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR * p_msg,tAVRC_RESPONSE * p_result)46 static tAVRC_STS avrc_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
47 tAVRC_RESPONSE* p_result) {
48 tAVRC_STS status = AVRC_STS_NO_ERROR;
49 uint8_t* p;
50 uint16_t len;
51 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
52 uint8_t eventid = 0;
53 #endif
54
55 /* Check the vendor data */
56 if (p_msg->vendor_len == 0) return AVRC_STS_NO_ERROR;
57 if (p_msg->p_vendor_data == NULL) return AVRC_STS_INTERNAL_ERR;
58
59 if (p_msg->vendor_len < 4) {
60 android_errorWriteLog(0x534e4554, "111450531");
61 AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 4",
62 __func__, p_msg->vendor_len);
63 return AVRC_STS_INTERNAL_ERR;
64 }
65 p = p_msg->p_vendor_data;
66 BE_STREAM_TO_UINT8(p_result->pdu, p);
67 p++; /* skip the reserved/packe_type byte */
68 BE_STREAM_TO_UINT16(len, p);
69 AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d/0x%x vendor_len=0x%x",
70 __func__, p_msg->hdr.ctype, p_result->pdu, len, len,
71 p_msg->vendor_len);
72 if (p_msg->vendor_len < len + 4) {
73 android_errorWriteLog(0x534e4554, "111450531");
74 AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d",
75 __func__, p_msg->vendor_len, len + 4);
76 return AVRC_STS_INTERNAL_ERR;
77 }
78
79 if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
80 if (len < 1) {
81 android_errorWriteLog(0x534e4554, "111450531");
82 AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least 1",
83 __func__, len);
84 return AVRC_STS_INTERNAL_ERR;
85 }
86 p_result->rsp.status = *p;
87 return p_result->rsp.status;
88 }
89
90 switch (p_result->pdu) {
91 /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
92 /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */
93
94 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
95 case AVRC_PDU_SET_ABSOLUTE_VOLUME: /* 0x50 */
96 if (len != 1)
97 status = AVRC_STS_INTERNAL_ERR;
98 else {
99 BE_STREAM_TO_UINT8(p_result->volume.volume, p);
100 }
101 break;
102 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
103
104 case AVRC_PDU_REGISTER_NOTIFICATION: /* 0x31 */
105 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
106 if (len < 1) {
107 android_errorWriteLog(0x534e4554, "111450531");
108 AVRC_TRACE_WARNING(
109 "%s: invalid parameter length %d: must be at least 1", __func__,
110 len);
111 return AVRC_STS_INTERNAL_ERR;
112 }
113 BE_STREAM_TO_UINT8(eventid, p);
114 if (AVRC_EVT_VOLUME_CHANGE == eventid &&
115 (AVRC_RSP_CHANGED == p_msg->hdr.ctype ||
116 AVRC_RSP_INTERIM == p_msg->hdr.ctype ||
117 AVRC_RSP_REJ == p_msg->hdr.ctype ||
118 AVRC_RSP_NOT_IMPL == p_msg->hdr.ctype)) {
119 if (len < 2) {
120 android_errorWriteLog(0x534e4554, "111450531");
121 AVRC_TRACE_WARNING(
122 "%s: invalid parameter length %d: must be at least 2", __func__,
123 len);
124 return AVRC_STS_INTERNAL_ERR;
125 }
126 p_result->reg_notif.status = p_msg->hdr.ctype;
127 p_result->reg_notif.event_id = eventid;
128 BE_STREAM_TO_UINT8(p_result->reg_notif.param.volume, p);
129 }
130 AVRC_TRACE_DEBUG("%s PDU reg notif response:event %x, volume %x",
131 __func__, eventid, p_result->reg_notif.param.volume);
132 #endif /* (AVRC_ADV_CTRL_INCLUDED == TRUE) */
133 break;
134 default:
135 status = AVRC_STS_BAD_CMD;
136 break;
137 }
138
139 return status;
140 }
141
avrc_parse_notification_rsp(uint8_t * p_stream,uint16_t len,tAVRC_REG_NOTIF_RSP * p_rsp)142 tAVRC_STS avrc_parse_notification_rsp(uint8_t* p_stream, uint16_t len,
143 tAVRC_REG_NOTIF_RSP* p_rsp) {
144 uint16_t min_len = 1;
145
146 if (len < min_len) goto length_error;
147 BE_STREAM_TO_UINT8(p_rsp->event_id, p_stream);
148 switch (p_rsp->event_id) {
149 case AVRC_EVT_PLAY_STATUS_CHANGE:
150 min_len += 1;
151 if (len < min_len) goto length_error;
152 BE_STREAM_TO_UINT8(p_rsp->param.play_status, p_stream);
153 break;
154
155 case AVRC_EVT_TRACK_CHANGE:
156 min_len += 8;
157 if (len < min_len) goto length_error;
158 BE_STREAM_TO_ARRAY(p_stream, p_rsp->param.track, 8);
159 break;
160
161 case AVRC_EVT_APP_SETTING_CHANGE:
162 min_len += 1;
163 if (len < min_len) goto length_error;
164 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.num_attr, p_stream);
165 if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS) {
166 android_errorWriteLog(0x534e4554, "73782082");
167 p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
168 }
169 min_len += p_rsp->param.player_setting.num_attr * 2;
170 if (len < min_len) goto length_error;
171 for (int index = 0; index < p_rsp->param.player_setting.num_attr;
172 index++) {
173 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_id[index],
174 p_stream);
175 BE_STREAM_TO_UINT8(p_rsp->param.player_setting.attr_value[index],
176 p_stream);
177 }
178 break;
179
180 case AVRC_EVT_NOW_PLAYING_CHANGE:
181 break;
182
183 case AVRC_EVT_AVAL_PLAYERS_CHANGE:
184 break;
185
186 case AVRC_EVT_ADDR_PLAYER_CHANGE:
187 min_len += 4;
188 if (len < min_len) goto length_error;
189 BE_STREAM_TO_UINT16(p_rsp->param.addr_player.player_id, p_stream);
190 BE_STREAM_TO_UINT16(p_rsp->param.addr_player.uid_counter, p_stream);
191 break;
192
193 case AVRC_EVT_PLAY_POS_CHANGED:
194 min_len += 4;
195 if (len < min_len) goto length_error;
196 BE_STREAM_TO_UINT32(p_rsp->param.play_pos, p_stream);
197 break;
198
199 case AVRC_EVT_UIDS_CHANGE:
200 break;
201
202 case AVRC_EVT_TRACK_REACHED_END:
203 case AVRC_EVT_TRACK_REACHED_START:
204 case AVRC_EVT_BATTERY_STATUS_CHANGE:
205 case AVRC_EVT_SYSTEM_STATUS_CHANGE:
206 default:
207 break;
208 }
209
210 return AVRC_STS_NO_ERROR;
211
212 length_error:
213 android_errorWriteLog(0x534e4554, "111450417");
214 AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
215 __func__, len, min_len);
216 return AVRC_STS_INTERNAL_ERR;
217 }
218
avrc_pars_browse_rsp(tAVRC_MSG_BROWSE * p_msg,tAVRC_RESPONSE * p_rsp)219 static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg,
220 tAVRC_RESPONSE* p_rsp) {
221 tAVRC_STS status = AVRC_STS_NO_ERROR;
222 uint8_t pdu;
223
224 if (p_msg->browse_len == 0) {
225 AVRC_TRACE_ERROR("%s length ", p_msg->browse_len);
226 return AVRC_STS_BAD_PARAM;
227 }
228
229 uint8_t* p = p_msg->p_browse_data;
230
231 /* read the pdu */
232 if (p_msg->browse_len < 3) {
233 android_errorWriteLog(0x534e4554, "111451066");
234 AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 3",
235 __func__, p_msg->browse_len);
236 return AVRC_STS_BAD_PARAM;
237 }
238 BE_STREAM_TO_UINT8(pdu, p);
239 uint16_t pkt_len;
240 int min_len = 0;
241 /* read the entire packet len */
242 BE_STREAM_TO_UINT16(pkt_len, p);
243
244 AVRC_TRACE_DEBUG("%s pdu:%d, pkt_len:%d", __func__, pdu, pkt_len);
245
246 if (p_msg->browse_len < (pkt_len + 3)) {
247 android_errorWriteLog(0x534e4554, "111451066");
248 AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d",
249 __func__, p_msg->browse_len, pkt_len + 3);
250 return AVRC_STS_INTERNAL_ERR;
251 }
252
253 switch (pdu) {
254 case AVRC_PDU_GET_FOLDER_ITEMS: {
255 tAVRC_GET_ITEMS_RSP* get_item_rsp = &(p_rsp->get_items);
256 /* Copy back the PDU */
257 get_item_rsp->pdu = pdu;
258
259 min_len += 1;
260 if (pkt_len < min_len) goto browse_length_error;
261 /* read the status */
262 BE_STREAM_TO_UINT8(get_item_rsp->status, p);
263 if (get_item_rsp->status != AVRC_STS_NO_ERROR) {
264 AVRC_TRACE_WARNING("%s returning error %d", __func__,
265 get_item_rsp->status);
266 return get_item_rsp->status;
267 }
268
269 min_len += 4;
270 if (pkt_len < min_len) goto browse_length_error;
271 /* read the UID counter */
272 BE_STREAM_TO_UINT16(get_item_rsp->uid_counter, p);
273 /* read the number of items */
274 BE_STREAM_TO_UINT16(get_item_rsp->item_count, p);
275
276 AVRC_TRACE_DEBUG(
277 "%s pdu %d status %d pkt_len %d uid counter %d item count %d",
278 __func__, get_item_rsp->pdu, get_item_rsp->status, pkt_len,
279 get_item_rsp->uid_counter, get_item_rsp->item_count);
280
281 /* get each of the items */
282 get_item_rsp->p_item_list = (tAVRC_ITEM*)osi_malloc(
283 get_item_rsp->item_count * (sizeof(tAVRC_ITEM)));
284 tAVRC_ITEM* curr_item = get_item_rsp->p_item_list;
285 for (int i = 0; i < get_item_rsp->item_count; i++) {
286 min_len += 1;
287 if (pkt_len < min_len) goto browse_length_error;
288 BE_STREAM_TO_UINT8(curr_item->item_type, p);
289 AVRC_TRACE_DEBUG("%s item type %d", __func__, curr_item->item_type);
290 switch (curr_item->item_type) {
291 case AVRC_ITEM_PLAYER: {
292 /* Handle player */
293 tAVRC_ITEM_PLAYER* player = &(curr_item->u.player);
294 uint8_t player_len;
295 min_len += 10 + AVRC_FEATURE_MASK_SIZE;
296 if (pkt_len < min_len) goto browse_length_error;
297 BE_STREAM_TO_UINT16(player_len, p);
298 BE_STREAM_TO_UINT16(player->player_id, p);
299 BE_STREAM_TO_UINT8(player->major_type, p);
300 BE_STREAM_TO_UINT32(player->sub_type, p);
301 BE_STREAM_TO_UINT8(player->play_status, p);
302 BE_STREAM_TO_ARRAY(p, player->features, AVRC_FEATURE_MASK_SIZE);
303
304 /* read str */
305 min_len += 4;
306 if (pkt_len < min_len) goto browse_length_error;
307 BE_STREAM_TO_UINT16(player->name.charset_id, p);
308 BE_STREAM_TO_UINT16(player->name.str_len, p);
309 min_len += player->name.str_len;
310 if (pkt_len < min_len) goto browse_length_error;
311 player->name.p_str = (uint8_t*)osi_calloc(
312 (player->name.str_len + 1) * sizeof(uint8_t));
313 BE_STREAM_TO_ARRAY(p, player->name.p_str, player->name.str_len);
314 AVRC_TRACE_DEBUG(
315 "%s type %d id %d mtype %d stype %d ps %d cs %d name len %d",
316 __func__, curr_item->item_type, player->player_id,
317 player->major_type, player->sub_type, player->play_status,
318 player->name.charset_id, player->name.str_len);
319 } break;
320
321 case AVRC_ITEM_FOLDER: {
322 tAVRC_ITEM_FOLDER* folder = &(curr_item->u.folder);
323 uint16_t folder_len;
324 min_len += 4 + AVRC_UID_SIZE;
325 if (pkt_len < min_len) goto browse_length_error;
326 BE_STREAM_TO_UINT16(folder_len, p);
327
328 BE_STREAM_TO_ARRAY(p, folder->uid, AVRC_UID_SIZE);
329 BE_STREAM_TO_UINT8(folder->type, p);
330 BE_STREAM_TO_UINT8(folder->playable, p);
331
332 /* read str, encoding to be handled by upper layers */
333 min_len += 4;
334 if (pkt_len < min_len) goto browse_length_error;
335 BE_STREAM_TO_UINT16(folder->name.charset_id, p);
336 BE_STREAM_TO_UINT16(folder->name.str_len, p);
337 min_len += folder->name.str_len;
338 if (pkt_len < min_len) goto browse_length_error;
339 folder->name.p_str = (uint8_t*)osi_calloc(
340 (folder->name.str_len + 1) * sizeof(uint8_t));
341 BE_STREAM_TO_ARRAY(p, folder->name.p_str, folder->name.str_len);
342 AVRC_TRACE_DEBUG("%s type %d playable %d cs %d name len %d",
343 __func__, folder->type, folder->playable,
344 folder->name.charset_id, folder->name.str_len);
345 } break;
346
347 case AVRC_ITEM_MEDIA: {
348 tAVRC_ITEM_MEDIA* media = &(curr_item->u.media);
349 uint8_t media_len;
350 min_len += 3 + AVRC_UID_SIZE;
351 if (pkt_len < min_len) goto browse_length_error;
352 BE_STREAM_TO_UINT16(media_len, p);
353 BE_STREAM_TO_ARRAY(p, media->uid, AVRC_UID_SIZE);
354 BE_STREAM_TO_UINT8(media->type, p);
355
356 /* read str, encoding to be handled by upper layers */
357 min_len += 4;
358 if (pkt_len < min_len) goto browse_length_error;
359 BE_STREAM_TO_UINT16(media->name.charset_id, p);
360 BE_STREAM_TO_UINT16(media->name.str_len, p);
361 min_len += 1 + media->name.str_len;
362 if (pkt_len < min_len) goto browse_length_error;
363 media->name.p_str =
364 (uint8_t*)osi_malloc((media->name.str_len) * sizeof(uint8_t));
365 BE_STREAM_TO_ARRAY(p, media->name.p_str, media->name.str_len);
366
367 BE_STREAM_TO_UINT8(media->attr_count, p);
368 AVRC_TRACE_DEBUG("%s media type %d charset id %d len %d attr ct %d",
369 __func__, media->type, media->name.charset_id,
370 media->name.str_len, media->attr_count);
371
372 media->p_attr_list = (tAVRC_ATTR_ENTRY*)osi_malloc(
373 media->attr_count * sizeof(tAVRC_ATTR_ENTRY));
374 for (int jk = 0; jk < media->attr_count; jk++) {
375 tAVRC_ATTR_ENTRY* attr_entry = &(media->p_attr_list[jk]);
376 min_len += 8;
377 if (pkt_len < min_len) goto browse_length_error;
378 BE_STREAM_TO_UINT32(attr_entry->attr_id, p);
379
380 /* Parse the name now */
381 BE_STREAM_TO_UINT16(attr_entry->name.charset_id, p);
382 BE_STREAM_TO_UINT16(attr_entry->name.str_len, p);
383 min_len += attr_entry->name.str_len;
384 if (pkt_len < min_len) goto browse_length_error;
385 attr_entry->name.p_str = (uint8_t*)osi_malloc(
386 attr_entry->name.str_len * sizeof(uint8_t));
387 BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str,
388 attr_entry->name.str_len);
389 AVRC_TRACE_DEBUG("%s media attr id %d cs %d name len %d",
390 __func__, attr_entry->attr_id,
391 attr_entry->name.charset_id,
392 attr_entry->name.str_len);
393 }
394 } break;
395
396 default:
397 AVRC_TRACE_ERROR("%s item type not handled %d", __func__,
398 curr_item->item_type);
399 return AVRC_STS_INTERNAL_ERR;
400 }
401
402 AVRC_TRACE_DEBUG("%s pkt_len %d min_len %d", __func__, pkt_len,
403 min_len);
404
405 /* advance to populate the next item */
406 curr_item++;
407 }
408 break;
409 }
410
411 case AVRC_PDU_CHANGE_PATH: {
412 tAVRC_CHG_PATH_RSP* change_path_rsp = &(p_rsp->chg_path);
413 min_len += 5;
414 if (pkt_len < min_len) goto browse_length_error;
415 /* Copyback the PDU */
416 change_path_rsp->pdu = pdu;
417 /* Read the status */
418 BE_STREAM_TO_UINT8(change_path_rsp->status, p);
419 /* Read the number of items in folder */
420 BE_STREAM_TO_UINT32(change_path_rsp->num_items, p);
421
422 AVRC_TRACE_DEBUG("%s pdu %d status %d item count %d", __func__,
423 change_path_rsp->pdu, change_path_rsp->status,
424 change_path_rsp->num_items);
425 break;
426 }
427
428 case AVRC_PDU_GET_ITEM_ATTRIBUTES: {
429 tAVRC_GET_ATTRS_RSP* get_attr_rsp = &(p_rsp->get_attrs);
430 get_attr_rsp->pdu = pdu;
431 min_len += 2;
432 if (pkt_len < min_len) {
433 android_errorWriteLog(0x534e4554, "179162665");
434 goto browse_length_error;
435 }
436 BE_STREAM_TO_UINT8(get_attr_rsp->status, p)
437 BE_STREAM_TO_UINT8(get_attr_rsp->num_attrs, p);
438 get_attr_rsp->p_attrs = (tAVRC_ATTR_ENTRY*)osi_malloc(
439 get_attr_rsp->num_attrs * sizeof(tAVRC_ATTR_ENTRY));
440 for (int i = 0; i < get_attr_rsp->num_attrs; i++) {
441 tAVRC_ATTR_ENTRY* attr_entry = &(get_attr_rsp->p_attrs[i]);
442 min_len += 8;
443 if (pkt_len < min_len) goto browse_length_error;
444 BE_STREAM_TO_UINT32(attr_entry->attr_id, p);
445 BE_STREAM_TO_UINT16(attr_entry->name.charset_id, p);
446 BE_STREAM_TO_UINT16(attr_entry->name.str_len, p);
447 min_len += attr_entry->name.str_len;
448 if (pkt_len < min_len) goto browse_length_error;
449 attr_entry->name.p_str =
450 (uint8_t*)osi_malloc(attr_entry->name.str_len * sizeof(uint8_t));
451 BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str, attr_entry->name.str_len);
452 AVRC_TRACE_DEBUG("%s media attr id %d cs %d name len %d", __func__,
453 attr_entry->attr_id, attr_entry->name.charset_id,
454 attr_entry->name.str_len);
455 }
456
457 break;
458 }
459 case AVRC_PDU_SET_BROWSED_PLAYER: {
460 tAVRC_SET_BR_PLAYER_RSP* set_br_pl_rsp = &(p_rsp->br_player);
461 /* Copyback the PDU */
462 set_br_pl_rsp->pdu = pdu;
463
464 /* Read the status */
465 min_len += 10;
466 if (pkt_len < min_len) goto browse_length_error;
467 BE_STREAM_TO_UINT8(set_br_pl_rsp->status, p);
468
469 if (set_br_pl_rsp->status != AVRC_STS_NO_ERROR) {
470 AVRC_TRACE_ERROR(
471 "%s Stopping further parsing because player not browsable sts %d",
472 __func__, set_br_pl_rsp->status);
473 break;
474 }
475 BE_STREAM_TO_UINT16(set_br_pl_rsp->uid_counter, p);
476 BE_STREAM_TO_UINT32(set_br_pl_rsp->num_items, p);
477 BE_STREAM_TO_UINT16(set_br_pl_rsp->charset_id, p);
478 BE_STREAM_TO_UINT8(set_br_pl_rsp->folder_depth, p);
479 AVRC_TRACE_DEBUG(
480 "%s AVRC_PDU_SET_BROWSED_PLAYER status %d items %d cs %d depth %d",
481 __func__, set_br_pl_rsp->status, set_br_pl_rsp->num_items,
482 set_br_pl_rsp->charset_id, set_br_pl_rsp->folder_depth);
483
484 set_br_pl_rsp->p_folders = (tAVRC_NAME*)osi_malloc(
485 set_br_pl_rsp->folder_depth * sizeof(tAVRC_NAME));
486
487 /* Read each of the folder in the depth */
488 for (uint32_t i = 0; i < set_br_pl_rsp->folder_depth; i++) {
489 tAVRC_NAME* folder_name = &(set_br_pl_rsp->p_folders[i]);
490 min_len += 2;
491 if (pkt_len < min_len) goto browse_length_error;
492 BE_STREAM_TO_UINT16(folder_name->str_len, p);
493 min_len += folder_name->str_len;
494 if (pkt_len < min_len) goto browse_length_error;
495 AVRC_TRACE_DEBUG("%s AVRC_PDU_SET_BROWSED_PLAYER item: %d len: %d",
496 __func__, i, folder_name->str_len);
497 folder_name->p_str =
498 (uint8_t*)osi_calloc((folder_name->str_len + 1) * sizeof(uint8_t));
499 BE_STREAM_TO_ARRAY(p, folder_name->p_str, folder_name->str_len);
500 }
501 break;
502 }
503
504 default:
505 AVRC_TRACE_ERROR("%s pdu %d not handled", __func__, pdu);
506 }
507
508 return status;
509
510 browse_length_error:
511 android_errorWriteLog(0x534e4554, "111451066");
512 AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
513 __func__, pkt_len, min_len);
514 return AVRC_STS_BAD_CMD;
515 }
516
517 /*******************************************************************************
518 *
519 * Function avrc_ctrl_pars_vendor_rsp
520 *
521 * Description This function parses the vendor specific commands defined by
522 * Bluetooth SIG
523 *
524 * Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed
525 * successfully.
526 * Otherwise, the error code defined by AVRCP 1.4
527 *
528 ******************************************************************************/
avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR * p_msg,tAVRC_RESPONSE * p_result,uint8_t * p_buf,uint16_t * buf_len)529 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
530 tAVRC_RESPONSE* p_result,
531 uint8_t* p_buf, uint16_t* buf_len) {
532 if (p_msg->vendor_len < 4) {
533 android_errorWriteLog(0x534e4554, "111450417");
534 AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 4",
535 __func__, p_msg->vendor_len);
536 return AVRC_STS_INTERNAL_ERR;
537 }
538
539 uint8_t* p = p_msg->p_vendor_data;
540 BE_STREAM_TO_UINT8(p_result->pdu, p);
541 p++; /* skip the reserved/packe_type byte */
542
543 uint16_t len;
544 uint16_t min_len = 0;
545 BE_STREAM_TO_UINT16(len, p);
546 AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d vendor_len=0x%x", __func__,
547 p_msg->hdr.ctype, p_result->pdu, len, p_msg->vendor_len);
548 if (p_msg->vendor_len < len + 4) {
549 android_errorWriteLog(0x534e4554, "111450417");
550 AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d",
551 __func__, p_msg->vendor_len, len + 4);
552 return AVRC_STS_INTERNAL_ERR;
553 }
554 /* Todo: Issue in handling reject, check */
555 if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
556 min_len += 1;
557 if (len < min_len) goto length_error;
558 p_result->rsp.status = *p;
559 return p_result->rsp.status;
560 }
561
562 /* TODO: Break the big switch into functions. */
563 switch (p_result->pdu) {
564 /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
565 /* case AVRC_PDU_ABORT_CONTINUATION_RSP: 0x41 */
566
567 case AVRC_PDU_REGISTER_NOTIFICATION:
568 return avrc_parse_notification_rsp(p, len, &p_result->reg_notif);
569
570 case AVRC_PDU_GET_CAPABILITIES:
571 if (len == 0) {
572 p_result->get_caps.count = 0;
573 p_result->get_caps.capability_id = 0;
574 break;
575 }
576 min_len += 2;
577 if (len < min_len) goto length_error;
578 BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
579 BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
580 AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ", __func__,
581 p_result->get_caps.capability_id,
582 p_result->get_caps.count);
583 if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
584 if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_COMP_ID) {
585 android_errorWriteLog(0x534e4554, "205837191");
586 return AVRC_STS_INTERNAL_ERR;
587 }
588 min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_COMP_ID) * 3;
589 if (len < min_len) goto length_error;
590 for (int xx = 0; ((xx < p_result->get_caps.count) &&
591 (xx < AVRC_CAP_MAX_NUM_COMP_ID));
592 xx++) {
593 BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
594 }
595 } else if (p_result->get_caps.capability_id ==
596 AVRC_CAP_EVENTS_SUPPORTED) {
597 if (p_result->get_caps.count > AVRC_CAP_MAX_NUM_EVT_ID) {
598 android_errorWriteLog(0x534e4554, "205837191");
599 return AVRC_STS_INTERNAL_ERR;
600 }
601 min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_EVT_ID);
602 if (len < min_len) goto length_error;
603 for (int xx = 0; ((xx < p_result->get_caps.count) &&
604 (xx < AVRC_CAP_MAX_NUM_EVT_ID));
605 xx++) {
606 BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
607 }
608 }
609 break;
610
611 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
612 if (len == 0) {
613 p_result->list_app_attr.num_attr = 0;
614 break;
615 }
616 min_len += 1;
617 BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
618 AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
619 p_result->list_app_attr.num_attr);
620
621 if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
622 android_errorWriteLog(0x534e4554, "63146237");
623 p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
624 }
625
626 min_len += p_result->list_app_attr.num_attr;
627 if (len < min_len) goto length_error;
628 for (int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) {
629 BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
630 }
631 break;
632
633 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
634 if (len == 0) {
635 p_result->list_app_values.num_val = 0;
636 break;
637 }
638 min_len += 1;
639 BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
640 if (p_result->list_app_values.num_val > AVRC_MAX_APP_ATTR_SIZE) {
641 android_errorWriteLog(0x534e4554, "78526423");
642 p_result->list_app_values.num_val = AVRC_MAX_APP_ATTR_SIZE;
643 }
644
645 AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
646 p_result->list_app_values.num_val);
647 min_len += p_result->list_app_values.num_val;
648 if (len < min_len) goto length_error;
649 for (int xx = 0; xx < p_result->list_app_values.num_val; xx++) {
650 BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
651 }
652 break;
653
654 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: {
655 if (len == 0) {
656 p_result->get_cur_app_val.num_val = 0;
657 break;
658 }
659 min_len += 1;
660 BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
661 AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
662 p_result->get_cur_app_val.num_val);
663
664 if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
665 android_errorWriteLog(0x534e4554, "63146237");
666 p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
667 }
668
669 min_len += p_result->get_cur_app_val.num_val * 2;
670 if (len < min_len) {
671 p_result->get_cur_app_val.num_val = 0;
672 goto length_error;
673 }
674 tAVRC_APP_SETTING* app_sett = (tAVRC_APP_SETTING*)osi_calloc(
675 p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING));
676 for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) {
677 BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
678 BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
679 }
680 p_result->get_cur_app_val.p_vals = app_sett;
681 } break;
682
683 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: {
684 uint8_t num_attrs;
685
686 if (len == 0) {
687 p_result->get_app_attr_txt.num_attr = 0;
688 break;
689 }
690 min_len += 1;
691 BE_STREAM_TO_UINT8(num_attrs, p);
692 if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
693 num_attrs = AVRC_MAX_APP_ATTR_SIZE;
694 }
695 AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
696 p_result->get_app_attr_txt.num_attr);
697 p_result->get_app_attr_txt.num_attr = num_attrs;
698
699 p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(
700 num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
701 for (int xx = 0; xx < num_attrs; xx++) {
702 min_len += 4;
703 if (len < min_len) {
704 for (int j = 0; j < xx; j++) {
705 osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str);
706 }
707 osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs);
708 p_result->get_app_attr_txt.num_attr = 0;
709 goto length_error;
710 }
711 BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
712 BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id,
713 p);
714 BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
715 min_len += p_result->get_app_attr_txt.p_attrs[xx].str_len;
716 if (len < min_len) {
717 for (int j = 0; j < xx; j++) {
718 osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str);
719 }
720 osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs);
721 p_result->get_app_attr_txt.num_attr = 0;
722 goto length_error;
723 }
724 if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0) {
725 uint8_t* p_str = (uint8_t*)osi_calloc(
726 p_result->get_app_attr_txt.p_attrs[xx].str_len);
727 BE_STREAM_TO_ARRAY(p, p_str,
728 p_result->get_app_attr_txt.p_attrs[xx].str_len);
729 p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
730 } else {
731 p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
732 }
733 }
734 } break;
735
736 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
737 uint8_t num_vals;
738
739 if (len == 0) {
740 p_result->get_app_val_txt.num_attr = 0;
741 break;
742 }
743 min_len += 1;
744 BE_STREAM_TO_UINT8(num_vals, p);
745 if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
746 num_vals = AVRC_MAX_APP_ATTR_SIZE;
747 }
748 p_result->get_app_val_txt.num_attr = num_vals;
749 AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
750 p_result->get_app_val_txt.num_attr);
751
752 p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(
753 num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
754 for (int i = 0; i < num_vals; i++) {
755 min_len += 4;
756 if (len < min_len) {
757 for (int j = 0; j < i; j++) {
758 osi_free(p_result->get_app_val_txt.p_attrs[j].p_str);
759 }
760 osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs);
761 p_result->get_app_val_txt.num_attr = 0;
762 goto length_error;
763 }
764 BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
765 BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
766 BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
767 min_len += p_result->get_app_val_txt.p_attrs[i].str_len;
768 if (len < min_len) {
769 for (int j = 0; j < i; j++) {
770 osi_free(p_result->get_app_val_txt.p_attrs[j].p_str);
771 }
772 osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs);
773 p_result->get_app_val_txt.num_attr = 0;
774 goto length_error;
775 }
776 if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
777 uint8_t* p_str = (uint8_t*)osi_calloc(
778 p_result->get_app_val_txt.p_attrs[i].str_len);
779 BE_STREAM_TO_ARRAY(p, p_str,
780 p_result->get_app_val_txt.p_attrs[i].str_len);
781 p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
782 } else {
783 p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
784 }
785 }
786 } break;
787
788 case AVRC_PDU_SET_PLAYER_APP_VALUE:
789 /* nothing comes as part of this rsp */
790 break;
791
792 case AVRC_PDU_GET_ELEMENT_ATTR: {
793 uint8_t num_attrs;
794
795 if (len <= 0) {
796 p_result->get_attrs.num_attrs = 0;
797 break;
798 }
799 min_len += 1;
800 BE_STREAM_TO_UINT8(num_attrs, p);
801 p_result->get_attrs.num_attrs = num_attrs;
802 if (num_attrs) {
803 tAVRC_ATTR_ENTRY* p_attrs =
804 (tAVRC_ATTR_ENTRY*)osi_calloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
805 for (int i = 0; i < num_attrs; i++) {
806 min_len += 8;
807 if (len < min_len) {
808 for (int j = 0; j < i; j++) {
809 osi_free(p_attrs[j].name.p_str);
810 }
811 osi_free(p_attrs);
812 p_result->get_attrs.num_attrs = 0;
813 goto length_error;
814 }
815 BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
816 BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
817 BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
818 min_len += p_attrs[i].name.str_len;
819 if (len < min_len) {
820 for (int j = 0; j < i; j++) {
821 osi_free(p_attrs[j].name.p_str);
822 }
823 osi_free(p_attrs);
824 p_result->get_attrs.num_attrs = 0;
825 goto length_error;
826 }
827 if (p_attrs[i].name.str_len > 0) {
828 p_attrs[i].name.p_str =
829 (uint8_t*)osi_calloc(p_attrs[i].name.str_len);
830 BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str,
831 p_attrs[i].name.str_len);
832 } else {
833 p_attrs[i].name.p_str = NULL;
834 }
835 }
836 p_result->get_attrs.p_attrs = p_attrs;
837 }
838 } break;
839
840 case AVRC_PDU_GET_PLAY_STATUS:
841 if (len == 0) {
842 break;
843 }
844 min_len += 9;
845 if (len < min_len) goto length_error;
846 BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
847 BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
848 BE_STREAM_TO_UINT8(p_result->get_play_status.play_status, p);
849 break;
850
851 case AVRC_PDU_SET_ADDRESSED_PLAYER:
852 if (len != 1) {
853 AVRC_TRACE_ERROR("%s pdu: %d len %d", __func__, p_result->pdu, len);
854 return AVRC_STS_BAD_CMD;
855 }
856 BE_STREAM_TO_UINT8(p_result->rsp.status, p);
857 break;
858
859 default:
860 return AVRC_STS_BAD_CMD;
861 }
862 return AVRC_STS_NO_ERROR;
863
864 length_error:
865 android_errorWriteLog(0x534e4554, "111450417");
866 AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
867 __func__, len, min_len);
868 return AVRC_STS_INTERNAL_ERR;
869 }
870
871 /*******************************************************************************
872 *
873 * Function AVRC_Ctrl_ParsResponse
874 *
875 * Description This function is a parse response for AVRCP Controller.
876 *
877 * Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed
878 * successfully.
879 * Otherwise, the error code defined by AVRCP 1.4
880 *
881 ******************************************************************************/
AVRC_Ctrl_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result,uint8_t * p_buf,uint16_t * buf_len)882 tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
883 uint8_t* p_buf, uint16_t* buf_len) {
884 tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
885 if (p_msg && p_result) {
886 switch (p_msg->hdr.opcode) {
887 case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */
888 status =
889 avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf, buf_len);
890 break;
891
892 case AVRC_OP_BROWSE: /* 0xff Browse commands */
893 status = avrc_pars_browse_rsp(&p_msg->browse, p_result);
894 break;
895
896 default:
897 AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
898 break;
899 }
900 p_result->rsp.opcode = p_msg->hdr.opcode;
901 p_result->rsp.status = status;
902 }
903 return status;
904 }
905
906 /*******************************************************************************
907 *
908 * Function AVRC_ParsResponse
909 *
910 * Description This function is a superset of AVRC_ParsMetadata to parse
911 * the response.
912 *
913 * Returns AVRC_STS_NO_ERROR, if the message in p_data is parsed
914 * successfully.
915 * Otherwise, the error code defined by AVRCP 1.4
916 *
917 ******************************************************************************/
AVRC_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result,UNUSED_ATTR uint8_t * p_buf,UNUSED_ATTR uint16_t buf_len)918 tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
919 UNUSED_ATTR uint8_t* p_buf,
920 UNUSED_ATTR uint16_t buf_len) {
921 tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
922 uint16_t id;
923
924 if (p_msg && p_result) {
925 switch (p_msg->hdr.opcode) {
926 case AVRC_OP_VENDOR: /* 0x00 Vendor-dependent commands */
927 status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
928 break;
929
930 case AVRC_OP_PASS_THRU: /* 0x7C panel subunit opcode */
931 status = avrc_pars_pass_thru(&p_msg->pass, &id);
932 if (status == AVRC_STS_NO_ERROR) {
933 p_result->pdu = (uint8_t)id;
934 }
935 break;
936
937 default:
938 AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
939 break;
940 }
941 p_result->rsp.opcode = p_msg->hdr.opcode;
942 p_result->rsp.status = status;
943 }
944 return status;
945 }
946