• 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       break;
188 
189     case AVRC_EVT_UIDS_CHANGE:
190       break;
191 
192     case AVRC_EVT_TRACK_REACHED_END:
193     case AVRC_EVT_TRACK_REACHED_START:
194     case AVRC_EVT_PLAY_POS_CHANGED:
195     case AVRC_EVT_BATTERY_STATUS_CHANGE:
196     case AVRC_EVT_SYSTEM_STATUS_CHANGE:
197     default:
198       break;
199   }
200 
201   return AVRC_STS_NO_ERROR;
202 
203 length_error:
204   android_errorWriteLog(0x534e4554, "111450417");
205   AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
206                      __func__, len, min_len);
207   return AVRC_STS_INTERNAL_ERR;
208 }
209 
avrc_pars_browse_rsp(tAVRC_MSG_BROWSE * p_msg,tAVRC_RESPONSE * p_rsp)210 static tAVRC_STS avrc_pars_browse_rsp(tAVRC_MSG_BROWSE* p_msg,
211                                       tAVRC_RESPONSE* p_rsp) {
212   tAVRC_STS status = AVRC_STS_NO_ERROR;
213   uint8_t pdu;
214 
215   if (p_msg->browse_len == 0) {
216     AVRC_TRACE_ERROR("%s length ", p_msg->browse_len);
217     return AVRC_STS_BAD_PARAM;
218   }
219 
220   uint8_t* p = p_msg->p_browse_data;
221 
222   /* read the pdu */
223   if (p_msg->browse_len < 3) {
224     android_errorWriteLog(0x534e4554, "111451066");
225     AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 3",
226                        __func__, p_msg->browse_len);
227     return AVRC_STS_BAD_PARAM;
228   }
229   BE_STREAM_TO_UINT8(pdu, p);
230   uint16_t pkt_len;
231   int min_len = 0;
232   /* read the entire packet len */
233   BE_STREAM_TO_UINT16(pkt_len, p);
234 
235   AVRC_TRACE_DEBUG("%s pdu:%d, pkt_len:%d", __func__, pdu, pkt_len);
236 
237   if (p_msg->browse_len < (pkt_len + 3)) {
238     android_errorWriteLog(0x534e4554, "111451066");
239     AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d",
240                        __func__, p_msg->browse_len, pkt_len + 3);
241     return AVRC_STS_INTERNAL_ERR;
242   }
243 
244   switch (pdu) {
245     case AVRC_PDU_GET_FOLDER_ITEMS: {
246       tAVRC_GET_ITEMS_RSP* get_item_rsp = &(p_rsp->get_items);
247       /* Copy back the PDU */
248       get_item_rsp->pdu = pdu;
249 
250       min_len += 1;
251       if (pkt_len < min_len) goto browse_length_error;
252       /* read the status */
253       BE_STREAM_TO_UINT8(get_item_rsp->status, p);
254       if (get_item_rsp->status != AVRC_STS_NO_ERROR) {
255         AVRC_TRACE_WARNING("%s returning error %d", __func__,
256                            get_item_rsp->status);
257         return get_item_rsp->status;
258       }
259 
260       min_len += 4;
261       if (pkt_len < min_len) goto browse_length_error;
262       /* read the UID counter */
263       BE_STREAM_TO_UINT16(get_item_rsp->uid_counter, p);
264       /* read the number of items */
265       BE_STREAM_TO_UINT16(get_item_rsp->item_count, p);
266 
267       AVRC_TRACE_DEBUG(
268           "%s pdu %d status %d pkt_len %d uid counter %d item count %d",
269           __func__, get_item_rsp->pdu, get_item_rsp->status, pkt_len,
270           get_item_rsp->uid_counter, get_item_rsp->item_count);
271 
272       /* get each of the items */
273       get_item_rsp->p_item_list = (tAVRC_ITEM*)osi_malloc(
274           get_item_rsp->item_count * (sizeof(tAVRC_ITEM)));
275       tAVRC_ITEM* curr_item = get_item_rsp->p_item_list;
276       for (int i = 0; i < get_item_rsp->item_count; i++) {
277         min_len += 1;
278         if (pkt_len < min_len) goto browse_length_error;
279         BE_STREAM_TO_UINT8(curr_item->item_type, p);
280         AVRC_TRACE_DEBUG("%s item type %d", __func__, curr_item->item_type);
281         switch (curr_item->item_type) {
282           case AVRC_ITEM_PLAYER: {
283             /* Handle player */
284             tAVRC_ITEM_PLAYER* player = &(curr_item->u.player);
285             uint8_t player_len;
286             min_len += 10 + AVRC_FEATURE_MASK_SIZE;
287             if (pkt_len < min_len) goto browse_length_error;
288             BE_STREAM_TO_UINT16(player_len, p);
289             BE_STREAM_TO_UINT16(player->player_id, p);
290             BE_STREAM_TO_UINT8(player->major_type, p);
291             BE_STREAM_TO_UINT32(player->sub_type, p);
292             BE_STREAM_TO_UINT8(player->play_status, p);
293             BE_STREAM_TO_ARRAY(p, player->features, AVRC_FEATURE_MASK_SIZE);
294 
295             /* read str */
296             min_len += 4;
297             if (pkt_len < min_len) goto browse_length_error;
298             BE_STREAM_TO_UINT16(player->name.charset_id, p);
299             BE_STREAM_TO_UINT16(player->name.str_len, p);
300             min_len += player->name.str_len;
301             if (pkt_len < min_len) goto browse_length_error;
302             player->name.p_str = (uint8_t*)osi_malloc(
303                 (player->name.str_len + 1) * sizeof(uint8_t));
304             BE_STREAM_TO_ARRAY(p, player->name.p_str, player->name.str_len);
305             AVRC_TRACE_DEBUG(
306                 "%s type %d id %d mtype %d stype %d ps %d cs %d name len %d",
307                 __func__, curr_item->item_type, player->player_id,
308                 player->major_type, player->sub_type, player->play_status,
309                 player->name.charset_id, player->name.str_len);
310           } break;
311 
312           case AVRC_ITEM_FOLDER: {
313             tAVRC_ITEM_FOLDER* folder = &(curr_item->u.folder);
314             uint16_t folder_len;
315             min_len += 4 + AVRC_UID_SIZE;
316             if (pkt_len < min_len) goto browse_length_error;
317             BE_STREAM_TO_UINT16(folder_len, p);
318 
319             BE_STREAM_TO_ARRAY(p, folder->uid, AVRC_UID_SIZE);
320             BE_STREAM_TO_UINT8(folder->type, p);
321             BE_STREAM_TO_UINT8(folder->playable, p);
322 
323             /* read str, encoding to be handled by upper layers */
324             min_len += 4;
325             if (pkt_len < min_len) goto browse_length_error;
326             BE_STREAM_TO_UINT16(folder->name.charset_id, p);
327             BE_STREAM_TO_UINT16(folder->name.str_len, p);
328             min_len += folder->name.str_len;
329             if (pkt_len < min_len) goto browse_length_error;
330             folder->name.p_str = (uint8_t*)osi_malloc(
331                 (folder->name.str_len + 1) * sizeof(uint8_t));
332             BE_STREAM_TO_ARRAY(p, folder->name.p_str, folder->name.str_len);
333             AVRC_TRACE_DEBUG("%s type %d playable %d cs %d name len %d",
334                              __func__, folder->type, folder->playable,
335                              folder->name.charset_id, folder->name.str_len);
336           } break;
337 
338           case AVRC_ITEM_MEDIA: {
339             tAVRC_ITEM_MEDIA* media = &(curr_item->u.media);
340             uint8_t media_len;
341             min_len += 3 + AVRC_UID_SIZE;
342             if (pkt_len < min_len) goto browse_length_error;
343             BE_STREAM_TO_UINT16(media_len, p);
344             BE_STREAM_TO_ARRAY(p, media->uid, AVRC_UID_SIZE);
345             BE_STREAM_TO_UINT8(media->type, p);
346 
347             /* read str, encoding to be handled by upper layers */
348             min_len += 4;
349             if (pkt_len < min_len) goto browse_length_error;
350             BE_STREAM_TO_UINT16(media->name.charset_id, p);
351             BE_STREAM_TO_UINT16(media->name.str_len, p);
352             min_len += 1 + media->name.str_len;
353             if (pkt_len < min_len) goto browse_length_error;
354             media->name.p_str =
355                 (uint8_t*)osi_malloc((media->name.str_len) * sizeof(uint8_t));
356             BE_STREAM_TO_ARRAY(p, media->name.p_str, media->name.str_len);
357 
358             BE_STREAM_TO_UINT8(media->attr_count, p);
359             AVRC_TRACE_DEBUG("%s media type %d charset id %d len %d attr ct %d",
360                              __func__, media->type, media->name.charset_id,
361                              media->name.str_len, media->attr_count);
362 
363             media->p_attr_list = (tAVRC_ATTR_ENTRY*)osi_malloc(
364                 media->attr_count * sizeof(tAVRC_ATTR_ENTRY));
365             for (int jk = 0; jk < media->attr_count; jk++) {
366               tAVRC_ATTR_ENTRY* attr_entry = &(media->p_attr_list[jk]);
367               min_len += 8;
368               if (pkt_len < min_len) goto browse_length_error;
369               BE_STREAM_TO_UINT32(attr_entry->attr_id, p);
370 
371               /* Parse the name now */
372               BE_STREAM_TO_UINT16(attr_entry->name.charset_id, p);
373               BE_STREAM_TO_UINT16(attr_entry->name.str_len, p);
374               min_len += attr_entry->name.str_len;
375               if (pkt_len < min_len) goto browse_length_error;
376               attr_entry->name.p_str = (uint8_t*)osi_malloc(
377                   attr_entry->name.str_len * sizeof(uint8_t));
378               BE_STREAM_TO_ARRAY(p, attr_entry->name.p_str,
379                                  attr_entry->name.str_len);
380               AVRC_TRACE_DEBUG("%s media attr id %d cs %d name len %d",
381                                __func__, attr_entry->attr_id,
382                                attr_entry->name.charset_id,
383                                attr_entry->name.str_len);
384             }
385           } break;
386 
387           default:
388             AVRC_TRACE_ERROR("%s item type not handled %d", __func__,
389                              curr_item->item_type);
390             return AVRC_STS_INTERNAL_ERR;
391         }
392 
393         AVRC_TRACE_DEBUG("%s pkt_len %d min_len %d", __func__, pkt_len,
394                          min_len);
395 
396         /* advance to populate the next item */
397         curr_item++;
398       }
399       break;
400     }
401 
402     case AVRC_PDU_CHANGE_PATH: {
403       tAVRC_CHG_PATH_RSP* change_path_rsp = &(p_rsp->chg_path);
404       min_len += 5;
405       if (pkt_len < min_len) goto browse_length_error;
406       /* Copyback the PDU */
407       change_path_rsp->pdu = pdu;
408       /* Read the status */
409       BE_STREAM_TO_UINT8(change_path_rsp->status, p);
410       /* Read the number of items in folder */
411       BE_STREAM_TO_UINT32(change_path_rsp->num_items, p);
412 
413       AVRC_TRACE_DEBUG("%s pdu %d status %d item count %d", __func__,
414                        change_path_rsp->pdu, change_path_rsp->status,
415                        change_path_rsp->num_items);
416       break;
417     }
418 
419     case AVRC_PDU_SET_BROWSED_PLAYER: {
420       tAVRC_SET_BR_PLAYER_RSP* set_br_pl_rsp = &(p_rsp->br_player);
421       /* Copyback the PDU */
422       set_br_pl_rsp->pdu = pdu;
423 
424       /* Read the status */
425       min_len += 10;
426       if (pkt_len < min_len) goto browse_length_error;
427       BE_STREAM_TO_UINT8(set_br_pl_rsp->status, p);
428 
429       if (set_br_pl_rsp->status != AVRC_STS_NO_ERROR) {
430         AVRC_TRACE_ERROR(
431             "%s Stopping further parsing because player not browsable sts %d",
432             __func__, set_br_pl_rsp->status);
433         break;
434       }
435       BE_STREAM_TO_UINT16(set_br_pl_rsp->uid_counter, p);
436       BE_STREAM_TO_UINT32(set_br_pl_rsp->num_items, p);
437       BE_STREAM_TO_UINT16(set_br_pl_rsp->charset_id, p);
438       BE_STREAM_TO_UINT8(set_br_pl_rsp->folder_depth, p);
439       AVRC_TRACE_DEBUG(
440           "%s AVRC_PDU_SET_BROWSED_PLAYER status %d items %d cs %d depth %d",
441           __func__, set_br_pl_rsp->status, set_br_pl_rsp->num_items,
442           set_br_pl_rsp->charset_id, set_br_pl_rsp->folder_depth);
443 
444       set_br_pl_rsp->p_folders = (tAVRC_NAME*)osi_malloc(
445           set_br_pl_rsp->num_items * sizeof(tAVRC_NAME));
446 
447       /* Read each of the folder in the depth */
448       for (uint32_t i = 0; i < set_br_pl_rsp->folder_depth; i++) {
449         tAVRC_NAME* folder_name = &(set_br_pl_rsp->p_folders[i]);
450         min_len += 2;
451         if (pkt_len < min_len) goto browse_length_error;
452         BE_STREAM_TO_UINT16(folder_name->str_len, p);
453         min_len += folder_name->str_len;
454         if (pkt_len < min_len) goto browse_length_error;
455         AVRC_TRACE_DEBUG("%s AVRC_PDU_SET_BROWSED_PLAYER item: %d len: %d",
456                          __func__, i, folder_name->str_len);
457         folder_name->p_str =
458             (uint8_t*)osi_malloc((folder_name->str_len + 1) * sizeof(uint8_t));
459         BE_STREAM_TO_ARRAY(p, folder_name->p_str, folder_name->str_len);
460       }
461       break;
462     }
463 
464     default:
465       AVRC_TRACE_ERROR("%s pdu %d not handled", __func__, pdu);
466   }
467 
468   return status;
469 
470 browse_length_error:
471   android_errorWriteLog(0x534e4554, "111451066");
472   AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
473                      __func__, pkt_len, min_len);
474   return AVRC_STS_BAD_CMD;
475 }
476 
477 /*******************************************************************************
478  *
479  * Function         avrc_ctrl_pars_vendor_rsp
480  *
481  * Description      This function parses the vendor specific commands defined by
482  *                  Bluetooth SIG
483  *
484  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
485  *                  successfully.
486  *                  Otherwise, the error code defined by AVRCP 1.4
487  *
488  ******************************************************************************/
avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR * p_msg,tAVRC_RESPONSE * p_result,uint8_t * p_buf,uint16_t * buf_len)489 static tAVRC_STS avrc_ctrl_pars_vendor_rsp(tAVRC_MSG_VENDOR* p_msg,
490                                            tAVRC_RESPONSE* p_result,
491                                            uint8_t* p_buf, uint16_t* buf_len) {
492   if (p_msg->vendor_len < 4) {
493     android_errorWriteLog(0x534e4554, "111450417");
494     AVRC_TRACE_WARNING("%s: message length %d too short: must be at least 4",
495                        __func__, p_msg->vendor_len);
496     return AVRC_STS_INTERNAL_ERR;
497   }
498 
499   uint8_t* p = p_msg->p_vendor_data;
500   BE_STREAM_TO_UINT8(p_result->pdu, p);
501   p++; /* skip the reserved/packe_type byte */
502 
503   uint16_t len;
504   uint16_t min_len = 0;
505   BE_STREAM_TO_UINT16(len, p);
506   AVRC_TRACE_DEBUG("%s ctype:0x%x pdu:0x%x, len:%d  vendor_len=0x%x", __func__,
507                    p_msg->hdr.ctype, p_result->pdu, len, p_msg->vendor_len);
508   if (p_msg->vendor_len < len + 4) {
509     android_errorWriteLog(0x534e4554, "111450417");
510     AVRC_TRACE_WARNING("%s: message length %d too short: must be at least %d",
511                        __func__, p_msg->vendor_len, len + 4);
512     return AVRC_STS_INTERNAL_ERR;
513   }
514   /* Todo: Issue in handling reject, check */
515   if (p_msg->hdr.ctype == AVRC_RSP_REJ) {
516     min_len += 1;
517     if (len < min_len) goto length_error;
518     p_result->rsp.status = *p;
519     return p_result->rsp.status;
520   }
521 
522   /* TODO: Break the big switch into functions. */
523   switch (p_result->pdu) {
524     /* case AVRC_PDU_REQUEST_CONTINUATION_RSP: 0x40 */
525     /* case AVRC_PDU_ABORT_CONTINUATION_RSP:   0x41 */
526 
527     case AVRC_PDU_REGISTER_NOTIFICATION:
528       return avrc_parse_notification_rsp(p, len, &p_result->reg_notif);
529 
530     case AVRC_PDU_GET_CAPABILITIES:
531       if (len == 0) {
532         p_result->get_caps.count = 0;
533         p_result->get_caps.capability_id = 0;
534         break;
535       }
536       min_len += 2;
537       if (len < min_len) goto length_error;
538       BE_STREAM_TO_UINT8(p_result->get_caps.capability_id, p);
539       BE_STREAM_TO_UINT8(p_result->get_caps.count, p);
540       AVRC_TRACE_DEBUG("%s cap id = %d, cap_count = %d ", __func__,
541                        p_result->get_caps.capability_id,
542                        p_result->get_caps.count);
543       if (p_result->get_caps.capability_id == AVRC_CAP_COMPANY_ID) {
544         min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_COMP_ID) * 3;
545         if (len < min_len) goto length_error;
546         for (int xx = 0; ((xx < p_result->get_caps.count) &&
547                           (xx < AVRC_CAP_MAX_NUM_COMP_ID));
548              xx++) {
549           BE_STREAM_TO_UINT24(p_result->get_caps.param.company_id[xx], p);
550         }
551       } else if (p_result->get_caps.capability_id ==
552                  AVRC_CAP_EVENTS_SUPPORTED) {
553         min_len += MIN(p_result->get_caps.count, AVRC_CAP_MAX_NUM_EVT_ID);
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_EVT_ID));
557              xx++) {
558           BE_STREAM_TO_UINT8(p_result->get_caps.param.event_id[xx], p);
559         }
560       }
561       break;
562 
563     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
564       if (len == 0) {
565         p_result->list_app_attr.num_attr = 0;
566         break;
567       }
568       min_len += 1;
569       BE_STREAM_TO_UINT8(p_result->list_app_attr.num_attr, p);
570       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
571                        p_result->list_app_attr.num_attr);
572 
573       if (p_result->list_app_attr.num_attr > AVRC_MAX_APP_ATTR_SIZE) {
574         android_errorWriteLog(0x534e4554, "63146237");
575         p_result->list_app_attr.num_attr = AVRC_MAX_APP_ATTR_SIZE;
576       }
577 
578       min_len += p_result->list_app_attr.num_attr;
579       if (len < min_len) goto length_error;
580       for (int xx = 0; xx < p_result->list_app_attr.num_attr; xx++) {
581         BE_STREAM_TO_UINT8(p_result->list_app_attr.attrs[xx], p);
582       }
583       break;
584 
585     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
586       if (len == 0) {
587         p_result->list_app_values.num_val = 0;
588         break;
589       }
590       min_len += 1;
591       BE_STREAM_TO_UINT8(p_result->list_app_values.num_val, p);
592       if (p_result->list_app_values.num_val > AVRC_MAX_APP_ATTR_SIZE) {
593         android_errorWriteLog(0x534e4554, "78526423");
594         p_result->list_app_values.num_val = AVRC_MAX_APP_ATTR_SIZE;
595       }
596 
597       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
598                        p_result->list_app_values.num_val);
599       min_len += p_result->list_app_values.num_val;
600       if (len < min_len) goto length_error;
601       for (int xx = 0; xx < p_result->list_app_values.num_val; xx++) {
602         BE_STREAM_TO_UINT8(p_result->list_app_values.vals[xx], p);
603       }
604       break;
605 
606     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE: {
607       if (len == 0) {
608         p_result->get_cur_app_val.num_val = 0;
609         break;
610       }
611       min_len += 1;
612       BE_STREAM_TO_UINT8(p_result->get_cur_app_val.num_val, p);
613       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
614                        p_result->get_cur_app_val.num_val);
615 
616       if (p_result->get_cur_app_val.num_val > AVRC_MAX_APP_ATTR_SIZE) {
617         android_errorWriteLog(0x534e4554, "63146237");
618         p_result->get_cur_app_val.num_val = AVRC_MAX_APP_ATTR_SIZE;
619       }
620 
621       min_len += p_result->get_cur_app_val.num_val * 2;
622       if (len < min_len) {
623         p_result->get_cur_app_val.num_val = 0;
624         goto length_error;
625       }
626       tAVRC_APP_SETTING* app_sett = (tAVRC_APP_SETTING*)osi_calloc(
627           p_result->get_cur_app_val.num_val * sizeof(tAVRC_APP_SETTING));
628       for (int xx = 0; xx < p_result->get_cur_app_val.num_val; xx++) {
629         BE_STREAM_TO_UINT8(app_sett[xx].attr_id, p);
630         BE_STREAM_TO_UINT8(app_sett[xx].attr_val, p);
631       }
632       p_result->get_cur_app_val.p_vals = app_sett;
633     } break;
634 
635     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT: {
636       uint8_t num_attrs;
637 
638       if (len == 0) {
639         p_result->get_app_attr_txt.num_attr = 0;
640         break;
641       }
642       min_len += 1;
643       BE_STREAM_TO_UINT8(num_attrs, p);
644       if (num_attrs > AVRC_MAX_APP_ATTR_SIZE) {
645         num_attrs = AVRC_MAX_APP_ATTR_SIZE;
646       }
647       AVRC_TRACE_DEBUG("%s attr count = %d ", __func__,
648                        p_result->get_app_attr_txt.num_attr);
649       p_result->get_app_attr_txt.num_attr = num_attrs;
650 
651       p_result->get_app_attr_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(
652           num_attrs * sizeof(tAVRC_APP_SETTING_TEXT));
653       for (int xx = 0; xx < num_attrs; xx++) {
654         min_len += 4;
655         if (len < min_len) {
656           for (int j = 0; j < xx; j++) {
657             osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str);
658           }
659           osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs);
660           p_result->get_app_attr_txt.num_attr = 0;
661           goto length_error;
662         }
663         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].attr_id, p);
664         BE_STREAM_TO_UINT16(p_result->get_app_attr_txt.p_attrs[xx].charset_id,
665                             p);
666         BE_STREAM_TO_UINT8(p_result->get_app_attr_txt.p_attrs[xx].str_len, p);
667         min_len += p_result->get_app_attr_txt.p_attrs[xx].str_len;
668         if (len < min_len) {
669           for (int j = 0; j < xx; j++) {
670             osi_free(p_result->get_app_attr_txt.p_attrs[j].p_str);
671           }
672           osi_free_and_reset((void**)&p_result->get_app_attr_txt.p_attrs);
673           p_result->get_app_attr_txt.num_attr = 0;
674           goto length_error;
675         }
676         if (p_result->get_app_attr_txt.p_attrs[xx].str_len != 0) {
677           uint8_t* p_str = (uint8_t*)osi_calloc(
678               p_result->get_app_attr_txt.p_attrs[xx].str_len);
679           BE_STREAM_TO_ARRAY(p, p_str,
680                              p_result->get_app_attr_txt.p_attrs[xx].str_len);
681           p_result->get_app_attr_txt.p_attrs[xx].p_str = p_str;
682         } else {
683           p_result->get_app_attr_txt.p_attrs[xx].p_str = NULL;
684         }
685       }
686     } break;
687 
688     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
689       uint8_t num_vals;
690 
691       if (len == 0) {
692         p_result->get_app_val_txt.num_attr = 0;
693         break;
694       }
695       min_len += 1;
696       BE_STREAM_TO_UINT8(num_vals, p);
697       if (num_vals > AVRC_MAX_APP_ATTR_SIZE) {
698         num_vals = AVRC_MAX_APP_ATTR_SIZE;
699       }
700       p_result->get_app_val_txt.num_attr = num_vals;
701       AVRC_TRACE_DEBUG("%s value count = %d ", __func__,
702                        p_result->get_app_val_txt.num_attr);
703 
704       p_result->get_app_val_txt.p_attrs = (tAVRC_APP_SETTING_TEXT*)osi_calloc(
705           num_vals * sizeof(tAVRC_APP_SETTING_TEXT));
706       for (int i = 0; i < num_vals; i++) {
707         min_len += 4;
708         if (len < min_len) {
709           for (int j = 0; j < i; j++) {
710             osi_free(p_result->get_app_val_txt.p_attrs[j].p_str);
711           }
712           osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs);
713           p_result->get_app_val_txt.num_attr = 0;
714           goto length_error;
715         }
716         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].attr_id, p);
717         BE_STREAM_TO_UINT16(p_result->get_app_val_txt.p_attrs[i].charset_id, p);
718         BE_STREAM_TO_UINT8(p_result->get_app_val_txt.p_attrs[i].str_len, p);
719         min_len += p_result->get_app_val_txt.p_attrs[i].str_len;
720         if (len < min_len) {
721           for (int j = 0; j < i; j++) {
722             osi_free(p_result->get_app_val_txt.p_attrs[j].p_str);
723           }
724           osi_free_and_reset((void**)&p_result->get_app_val_txt.p_attrs);
725           p_result->get_app_val_txt.num_attr = 0;
726           goto length_error;
727         }
728         if (p_result->get_app_val_txt.p_attrs[i].str_len != 0) {
729           uint8_t* p_str = (uint8_t*)osi_calloc(
730               p_result->get_app_val_txt.p_attrs[i].str_len);
731           BE_STREAM_TO_ARRAY(p, p_str,
732                              p_result->get_app_val_txt.p_attrs[i].str_len);
733           p_result->get_app_val_txt.p_attrs[i].p_str = p_str;
734         } else {
735           p_result->get_app_val_txt.p_attrs[i].p_str = NULL;
736         }
737       }
738     } break;
739 
740     case AVRC_PDU_SET_PLAYER_APP_VALUE:
741       /* nothing comes as part of this rsp */
742       break;
743 
744     case AVRC_PDU_GET_ELEMENT_ATTR: {
745       uint8_t num_attrs;
746 
747       if (len <= 0) {
748         p_result->get_attrs.num_attrs = 0;
749         break;
750       }
751       min_len += 1;
752       BE_STREAM_TO_UINT8(num_attrs, p);
753       p_result->get_attrs.num_attrs = num_attrs;
754       if (num_attrs) {
755         tAVRC_ATTR_ENTRY* p_attrs =
756             (tAVRC_ATTR_ENTRY*)osi_calloc(num_attrs * sizeof(tAVRC_ATTR_ENTRY));
757         for (int i = 0; i < num_attrs; i++) {
758           min_len += 8;
759           if (len < min_len) {
760             for (int j = 0; j < i; j++) {
761               osi_free(p_attrs[j].name.p_str);
762             }
763             osi_free(p_attrs);
764             p_result->get_attrs.num_attrs = 0;
765             goto length_error;
766           }
767           BE_STREAM_TO_UINT32(p_attrs[i].attr_id, p);
768           BE_STREAM_TO_UINT16(p_attrs[i].name.charset_id, p);
769           BE_STREAM_TO_UINT16(p_attrs[i].name.str_len, p);
770           min_len += p_attrs[i].name.str_len;
771           if (len < min_len) {
772             for (int j = 0; j < i; j++) {
773               osi_free(p_attrs[j].name.p_str);
774             }
775             osi_free(p_attrs);
776             p_result->get_attrs.num_attrs = 0;
777             goto length_error;
778           }
779           if (p_attrs[i].name.str_len > 0) {
780             p_attrs[i].name.p_str =
781                 (uint8_t*)osi_calloc(p_attrs[i].name.str_len);
782             BE_STREAM_TO_ARRAY(p, p_attrs[i].name.p_str,
783                                p_attrs[i].name.str_len);
784           } else {
785             p_attrs[i].name.p_str = NULL;
786           }
787         }
788         p_result->get_attrs.p_attrs = p_attrs;
789       }
790     } break;
791 
792     case AVRC_PDU_GET_PLAY_STATUS:
793       if (len == 0) {
794         break;
795       }
796       min_len += 9;
797       if (len < min_len) goto length_error;
798       BE_STREAM_TO_UINT32(p_result->get_play_status.song_len, p);
799       BE_STREAM_TO_UINT32(p_result->get_play_status.song_pos, p);
800       BE_STREAM_TO_UINT8(p_result->get_play_status.status, p);
801       break;
802 
803     case AVRC_PDU_SET_ADDRESSED_PLAYER:
804       if (len != 1) {
805         AVRC_TRACE_ERROR("%s pdu: %d len %d", __func__, p_result->pdu, len);
806         return AVRC_STS_BAD_CMD;
807       }
808       BE_STREAM_TO_UINT8(p_result->rsp.status, p);
809       break;
810 
811     default:
812       return AVRC_STS_BAD_CMD;
813   }
814   return AVRC_STS_NO_ERROR;
815 
816 length_error:
817   android_errorWriteLog(0x534e4554, "111450417");
818   AVRC_TRACE_WARNING("%s: invalid parameter length %d: must be at least %d",
819                      __func__, len, min_len);
820   return AVRC_STS_INTERNAL_ERR;
821 }
822 
823 /*******************************************************************************
824  *
825  * Function         AVRC_Ctrl_ParsResponse
826  *
827  * Description      This function is a parse response for AVRCP Controller.
828  *
829  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
830  *                  successfully.
831  *                  Otherwise, the error code defined by AVRCP 1.4
832  *
833  ******************************************************************************/
AVRC_Ctrl_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result,uint8_t * p_buf,uint16_t * buf_len)834 tAVRC_STS AVRC_Ctrl_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
835                                  uint8_t* p_buf, uint16_t* buf_len) {
836   tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
837   if (p_msg && p_result) {
838     switch (p_msg->hdr.opcode) {
839       case AVRC_OP_VENDOR: /*  0x00    Vendor-dependent commands */
840         status =
841             avrc_ctrl_pars_vendor_rsp(&p_msg->vendor, p_result, p_buf, buf_len);
842         break;
843 
844       case AVRC_OP_BROWSE: /* 0xff Browse commands */
845         status = avrc_pars_browse_rsp(&p_msg->browse, p_result);
846         break;
847 
848       default:
849         AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
850         break;
851     }
852     p_result->rsp.opcode = p_msg->hdr.opcode;
853     p_result->rsp.status = status;
854   }
855   return status;
856 }
857 
858 /*******************************************************************************
859  *
860  * Function         AVRC_ParsResponse
861  *
862  * Description      This function is a superset of AVRC_ParsMetadata to parse
863  *                  the response.
864  *
865  * Returns          AVRC_STS_NO_ERROR, if the message in p_data is parsed
866  *                  successfully.
867  *                  Otherwise, the error code defined by AVRCP 1.4
868  *
869  ******************************************************************************/
AVRC_ParsResponse(tAVRC_MSG * p_msg,tAVRC_RESPONSE * p_result,UNUSED_ATTR uint8_t * p_buf,UNUSED_ATTR uint16_t buf_len)870 tAVRC_STS AVRC_ParsResponse(tAVRC_MSG* p_msg, tAVRC_RESPONSE* p_result,
871                             UNUSED_ATTR uint8_t* p_buf,
872                             UNUSED_ATTR uint16_t buf_len) {
873   tAVRC_STS status = AVRC_STS_INTERNAL_ERR;
874   uint16_t id;
875 
876   if (p_msg && p_result) {
877     switch (p_msg->hdr.opcode) {
878       case AVRC_OP_VENDOR: /*  0x00    Vendor-dependent commands */
879         status = avrc_pars_vendor_rsp(&p_msg->vendor, p_result);
880         break;
881 
882       case AVRC_OP_PASS_THRU: /*  0x7C    panel subunit opcode */
883         status = avrc_pars_pass_thru(&p_msg->pass, &id);
884         if (status == AVRC_STS_NO_ERROR) {
885           p_result->pdu = (uint8_t)id;
886         }
887         break;
888 
889       default:
890         AVRC_TRACE_ERROR("%s unknown opcode:0x%x", __func__, p_msg->hdr.opcode);
891         break;
892     }
893     p_result->rsp.opcode = p_msg->hdr.opcode;
894     p_result->rsp.status = status;
895   }
896   return status;
897 }
898