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