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