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