• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "log/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_malloc(
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_malloc(
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_SET_BROWSED_PLAYER: {
429       tAVRC_SET_BR_PLAYER_RSP* set_br_pl_rsp = &(p_rsp->br_player);
430       /* Copyback the PDU */
431       set_br_pl_rsp->pdu = pdu;
432 
433       /* Read the status */
434       min_len += 10;
435       if (pkt_len < min_len) goto browse_length_error;
436       BE_STREAM_TO_UINT8(set_br_pl_rsp->status, p);
437 
438       if (set_br_pl_rsp->status != AVRC_STS_NO_ERROR) {
439         AVRC_TRACE_ERROR(
440             "%s Stopping further parsing because player not browsable sts %d",
441             __func__, set_br_pl_rsp->status);
442         break;
443       }
444       BE_STREAM_TO_UINT16(set_br_pl_rsp->uid_counter, p);
445       BE_STREAM_TO_UINT32(set_br_pl_rsp->num_items, p);
446       BE_STREAM_TO_UINT16(set_br_pl_rsp->charset_id, p);
447       BE_STREAM_TO_UINT8(set_br_pl_rsp->folder_depth, p);
448       AVRC_TRACE_DEBUG(
449           "%s AVRC_PDU_SET_BROWSED_PLAYER status %d items %d cs %d depth %d",
450           __func__, set_br_pl_rsp->status, set_br_pl_rsp->num_items,
451           set_br_pl_rsp->charset_id, set_br_pl_rsp->folder_depth);
452 
453       set_br_pl_rsp->p_folders = (tAVRC_NAME*)osi_malloc(
454           set_br_pl_rsp->folder_depth * sizeof(tAVRC_NAME));
455 
456       /* Read each of the folder in the depth */
457       for (uint32_t i = 0; i < set_br_pl_rsp->folder_depth; i++) {
458         tAVRC_NAME* folder_name = &(set_br_pl_rsp->p_folders[i]);
459         min_len += 2;
460         if (pkt_len < min_len) goto browse_length_error;
461         BE_STREAM_TO_UINT16(folder_name->str_len, p);
462         min_len += folder_name->str_len;
463         if (pkt_len < min_len) goto browse_length_error;
464         AVRC_TRACE_DEBUG("%s AVRC_PDU_SET_BROWSED_PLAYER item: %d len: %d",
465                          __func__, i, folder_name->str_len);
466         folder_name->p_str =
467             (uint8_t*)osi_malloc((folder_name->str_len + 1) * sizeof(uint8_t));
468         BE_STREAM_TO_ARRAY(p, folder_name->p_str, folder_name->str_len);
469       }
470       break;
471     }
472 
473     default:
474       AVRC_TRACE_ERROR("%s pdu %d not handled", __func__, pdu);
475   }
476 
477   return status;
478 
479 browse_length_error:
480   android_errorWriteLog(0x534e4554, "111451066");
481   AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
482                      __func__, pkt_len, min_len);
483   return AVRC_STS_BAD_CMD;
484 }
485 
486 /*******************************************************************************
487  *
488  * Function         avrc_ctrl_pars_vendor_rsp
489  *
490  * Description      This function parses the vendor specific commands defined by
491  *                  Bluetooth SIG
492  *
493  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
494  *                  successfully.
495  *                  Otherwise, the error code defined by AVRCP 1.4
496  *
497  ******************************************************************************/
avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR * p_msg,tAVRC_RESPONSE * p_result,uint8_t * p_buf,uint16_t * buf_len)498 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
499                                            tAVRC_RESPONSE* p_result,
500                                            uint8_t* p_buf, uint16_t* buf_len) {
501   if (p_msg->vendor_len < 4) {
502     android_errorWriteLog(0x534e4554, "111450417");
503     AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 4",
504                        __func__, p_msg->vendor_len);
505     return AVRC_STS_INTERNAL_ERR;
506   }
507 
508   uint8_t* p = p_msg->p_vendor_data;
509   BE_STREAM_TO_UINT8(p_result->pdu, p);
510   p++; /* skip the reserved/packe_type byte */
511 
512   uint16_t len;
513   uint16_t min_len = 0;
514   BE_STREAM_TO_UINT16(len, p);
515   AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d  vendor_len=0x%x", __func__,
516                    p_msg->hdr.ctype, p_result->pdu, len, p_msg->vendor_len);
517   if (p_msg->vendor_len < len + 4) {
518     android_errorWriteLog(0x534e4554, "111450417");
519     AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d",
520                        __func__, p_msg->vendor_len, len + 4);
521     return AVRC_STS_INTERNAL_ERR;
522   }
523   /* Todo: Issue in handling reject, check */
524   if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
525     min_len += 1;
526     if (len < min_len) goto length_error;
527     p_result->rsp.status = *p;
528     return p_result->rsp.status;
529   }
530 
531   /* TODO: Break the big switch into functions. */
532   switch (p_result->pdu) {
533     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
534     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
535 
536     case AVRC_PDU_REGISTER_NOTIFICATION:
537       return avrc_parse_notification_rsp(p, len, &p_result->reg_notif);
538 
539     case AVRC_PDU_GET_CAPABILITIES:
540       if (len == 0) {
541         p_result->get_caps.count = 0;
542         p_result->get_caps.capability_id = 0;
543         break;
544       }
545       min_len += 2;
546       if (len < min_len) goto length_error;
547       BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
548       BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
549       AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ", __func__,
550                        p_result->get_caps.capability_id,
551                        p_result->get_caps.count);
552       if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
553         min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_COMP_ID) * 3;
554         if (len < min_len) goto length_error;
555         for (int xx = 0; ((xx < p_result->get_caps.count) &&
556                           (xx < AVRC_CAP_MAX_NUM_COMP_ID));
557              xx++) {
558           BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
559         }
560       } else if (p_result->get_caps.capability_id ==
561                  AVRC_CAP_EVENTS_SUPPORTED) {
562         min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_EVT_ID);
563         if (len < min_len) goto length_error;
564         for (int xx = 0; ((xx < p_result->get_caps.count) &&
565                           (xx < AVRC_CAP_MAX_NUM_EVT_ID));
566              xx++) {
567           BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
568         }
569       }
570       break;
571 
572     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
573       if (len == 0) {
574         p_result->list_app_attr.num_attr = 0;
575         break;
576       }
577       min_len += 1;
578       BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
579       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
580                        p_result->list_app_attr.num_attr);
581 
582       if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
583         android_errorWriteLog(0x534e4554, "63146237");
584         p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
585       }
586 
587       min_len += p_result->list_app_attr.num_attr;
588       if (len < min_len) goto length_error;
589       for (int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) {
590         BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
591       }
592       break;
593 
594     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
595       if (len == 0) {
596         p_result->list_app_values.num_val = 0;
597         break;
598       }
599       min_len += 1;
600       BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
601       if (p_result->list_app_values.num_val > AVRC_MAX_APP_ATTR_SIZE) {
602         android_errorWriteLog(0x534e4554, "78526423");
603         p_result->list_app_values.num_val = AVRC_MAX_APP_ATTR_SIZE;
604       }
605 
606       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
607                        p_result->list_app_values.num_val);
608       min_len += p_result->list_app_values.num_val;
609       if (len < min_len) goto length_error;
610       for (int xx = 0; xx < p_result->list_app_values.num_val; xx++) {
611         BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
612       }
613       break;
614 
615     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: {
616       if (len == 0) {
617         p_result->get_cur_app_val.num_val = 0;
618         break;
619       }
620       min_len += 1;
621       BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
622       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
623                        p_result->get_cur_app_val.num_val);
624 
625       if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
626         android_errorWriteLog(0x534e4554, "63146237");
627         p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
628       }
629 
630       min_len += p_result->get_cur_app_val.num_val * 2;
631       if (len < min_len) {
632         p_result->get_cur_app_val.num_val = 0;
633         goto length_error;
634       }
635       tAVRC_APP_SETTING* app_sett = (tAVRC_APP_SETTING*)osi_calloc(
636           p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING));
637       for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) {
638         BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
639         BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
640       }
641       p_result->get_cur_app_val.p_vals = app_sett;
642     } break;
643 
644     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: {
645       uint8_t num_attrs;
646 
647       if (len == 0) {
648         p_result->get_app_attr_txt.num_attr = 0;
649         break;
650       }
651       min_len += 1;
652       BE_STREAM_TO_UINT8(num_attrs, p);
653       if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
654         num_attrs = AVRC_MAX_APP_ATTR_SIZE;
655       }
656       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
657                        p_result->get_app_attr_txt.num_attr);
658       p_result->get_app_attr_txt.num_attr = num_attrs;
659 
660       p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(
661           num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
662       for (int xx = 0; xx < num_attrs; xx++) {
663         min_len += 4;
664         if (len < min_len) {
665           for (int j = 0; j < xx; j++) {
666             osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str);
667           }
668           osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs);
669           p_result->get_app_attr_txt.num_attr = 0;
670           goto length_error;
671         }
672         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
673         BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id,
674                             p);
675         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
676         min_len += p_result->get_app_attr_txt.p_attrs[xx].str_len;
677         if (len < min_len) {
678           for (int j = 0; j < xx; j++) {
679             osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str);
680           }
681           osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs);
682           p_result->get_app_attr_txt.num_attr = 0;
683           goto length_error;
684         }
685         if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0) {
686           uint8_t* p_str = (uint8_t*)osi_calloc(
687               p_result->get_app_attr_txt.p_attrs[xx].str_len);
688           BE_STREAM_TO_ARRAY(p, p_str,
689                              p_result->get_app_attr_txt.p_attrs[xx].str_len);
690           p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
691         } else {
692           p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
693         }
694       }
695     } break;
696 
697     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
698       uint8_t num_vals;
699 
700       if (len == 0) {
701         p_result->get_app_val_txt.num_attr = 0;
702         break;
703       }
704       min_len += 1;
705       BE_STREAM_TO_UINT8(num_vals, p);
706       if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
707         num_vals = AVRC_MAX_APP_ATTR_SIZE;
708       }
709       p_result->get_app_val_txt.num_attr = num_vals;
710       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
711                        p_result->get_app_val_txt.num_attr);
712 
713       p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(
714           num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
715       for (int i = 0; i < num_vals; i++) {
716         min_len += 4;
717         if (len < min_len) {
718           for (int j = 0; j < i; j++) {
719             osi_free(p_result->get_app_val_txt.p_attrs[j].p_str);
720           }
721           osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs);
722           p_result->get_app_val_txt.num_attr = 0;
723           goto length_error;
724         }
725         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
726         BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
727         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
728         min_len += p_result->get_app_val_txt.p_attrs[i].str_len;
729         if (len < min_len) {
730           for (int j = 0; j < i; j++) {
731             osi_free(p_result->get_app_val_txt.p_attrs[j].p_str);
732           }
733           osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs);
734           p_result->get_app_val_txt.num_attr = 0;
735           goto length_error;
736         }
737         if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
738           uint8_t* p_str = (uint8_t*)osi_calloc(
739               p_result->get_app_val_txt.p_attrs[i].str_len);
740           BE_STREAM_TO_ARRAY(p, p_str,
741                              p_result->get_app_val_txt.p_attrs[i].str_len);
742           p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
743         } else {
744           p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
745         }
746       }
747     } break;
748 
749     case AVRC_PDU_SET_PLAYER_APP_VALUE:
750       /* nothing comes as part of this rsp */
751       break;
752 
753     case AVRC_PDU_GET_ELEMENT_ATTR: {
754       uint8_t num_attrs;
755 
756       if (len <= 0) {
757         p_result->get_attrs.num_attrs = 0;
758         break;
759       }
760       min_len += 1;
761       BE_STREAM_TO_UINT8(num_attrs, p);
762       p_result->get_attrs.num_attrs = num_attrs;
763       if (num_attrs) {
764         tAVRC_ATTR_ENTRY* p_attrs =
765             (tAVRC_ATTR_ENTRY*)osi_calloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
766         for (int i = 0; i < num_attrs; i++) {
767           min_len += 8;
768           if (len < min_len) {
769             for (int j = 0; j < i; j++) {
770               osi_free(p_attrs[j].name.p_str);
771             }
772             osi_free(p_attrs);
773             p_result->get_attrs.num_attrs = 0;
774             goto length_error;
775           }
776           BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
777           BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
778           BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
779           min_len += p_attrs[i].name.str_len;
780           if (len < min_len) {
781             for (int j = 0; j < i; j++) {
782               osi_free(p_attrs[j].name.p_str);
783             }
784             osi_free(p_attrs);
785             p_result->get_attrs.num_attrs = 0;
786             goto length_error;
787           }
788           if (p_attrs[i].name.str_len > 0) {
789             p_attrs[i].name.p_str =
790                 (uint8_t*)osi_calloc(p_attrs[i].name.str_len);
791             BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str,
792                                p_attrs[i].name.str_len);
793           } else {
794             p_attrs[i].name.p_str = NULL;
795           }
796         }
797         p_result->get_attrs.p_attrs = p_attrs;
798       }
799     } break;
800 
801     case AVRC_PDU_GET_PLAY_STATUS:
802       if (len == 0) {
803         break;
804       }
805       min_len += 9;
806       if (len < min_len) goto length_error;
807       BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
808       BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
809       BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
810       break;
811 
812     case AVRC_PDU_SET_ADDRESSED_PLAYER:
813       if (len != 1) {
814         AVRC_TRACE_ERROR("%s pdu: %d len %d", __func__, p_result->pdu, len);
815         return AVRC_STS_BAD_CMD;
816       }
817       BE_STREAM_TO_UINT8(p_result->rsp.status, p);
818       break;
819 
820     default:
821       return AVRC_STS_BAD_CMD;
822   }
823   return AVRC_STS_NO_ERROR;
824 
825 length_error:
826   android_errorWriteLog(0x534e4554, "111450417");
827   AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
828                      __func__, len, min_len);
829   return AVRC_STS_INTERNAL_ERR;
830 }
831 
832 /*******************************************************************************
833  *
834  * Function         AVRC_Ctrl_ParsResponse
835  *
836  * Description      This function is a parse response for AVRCP Controller.
837  *
838  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
839  *                  successfully.
840  *                  Otherwise, the error code defined by AVRCP 1.4
841  *
842  ******************************************************************************/
AVRC_Ctrl_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result,uint8_t * p_buf,uint16_t * buf_len)843 tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
844                                  uint8_t* p_buf, uint16_t* buf_len) {
845   tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
846   if (p_msg && p_result) {
847     switch (p_msg->hdr.opcode) {
848       case AVRC_OP_VENDOR: /*  0x00    Vendor-dependent commands */
849         status =
850             avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf, buf_len);
851         break;
852 
853       case AVRC_OP_BROWSE: /* 0xff Browse commands */
854         status = avrc_pars_browse_rsp(&p_msg->browse, p_result);
855         break;
856 
857       default:
858         AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
859         break;
860     }
861     p_result->rsp.opcode = p_msg->hdr.opcode;
862     p_result->rsp.status = status;
863   }
864   return status;
865 }
866 
867 /*******************************************************************************
868  *
869  * Function         AVRC_ParsResponse
870  *
871  * Description      This function is a superset of AVRC_ParsMetadata to parse
872  *                  the response.
873  *
874  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
875  *                  successfully.
876  *                  Otherwise, the error code defined by AVRCP 1.4
877  *
878  ******************************************************************************/
AVRC_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result,UNUSED_ATTR uint8_t * p_buf,UNUSED_ATTR uint16_t buf_len)879 tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
880                             UNUSED_ATTR uint8_t* p_buf,
881                             UNUSED_ATTR uint16_t buf_len) {
882   tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
883   uint16_t id;
884 
885   if (p_msg && p_result) {
886     switch (p_msg->hdr.opcode) {
887       case AVRC_OP_VENDOR: /*  0x00    Vendor-dependent commands */
888         status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
889         break;
890 
891       case AVRC_OP_PASS_THRU: /*  0x7C    panel subunit opcode */
892         status = avrc_pars_pass_thru(&p_msg->pass, &id);
893         if (status == AVRC_STS_NO_ERROR) {
894           p_result->pdu = (uint8_t)id;
895         }
896         break;
897 
898       default:
899         AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
900         break;
901     }
902     p_result->rsp.opcode = p_msg->hdr.opcode;
903     p_result->rsp.status = status;
904   }
905   return status;
906 }
907