1 /******************************************************************************
2  *
3  *  Copyright 2003-2016 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 
19 #define LOG_TAG "avrcp"
20 
21 #include <bluetooth/log.h>
22 #include <string.h>
23 
24 #include <cstdint>
25 
26 #include "avct_api.h"
27 #include "avrc_api.h"
28 #include "avrc_defs.h"
29 #include "avrc_int.h"
30 #include "internal_include/bt_target.h"
31 #include "osi/include/allocator.h"
32 #include "stack/avct/avct_defs.h"
33 #include "stack/include/bt_hdr.h"
34 #include "stack/include/bt_types.h"
35 
36 using namespace bluetooth;
37 
38 /*****************************************************************************
39  *  Global data
40  ****************************************************************************/
41 #define AVRC_ITEM_PLAYER_IS_VALID(_p_player)                                           \
42   ((_p_player)->name.p_str && ((_p_player)->major_type & AVRC_MJ_TYPE_INVALID) == 0 && \
43    ((_p_player)->sub_type & AVRC_SUB_TYPE_INVALID) == 0 &&                             \
44    (((_p_player)->play_status <= AVRC_PLAYSTATE_REV_SEEK) ||                           \
45     ((_p_player)->play_status == AVRC_PLAYSTATE_ERROR)))
46 
47 /* 17 = item_type(1) + item len(2) + min item (14) */
48 #define AVRC_MIN_LEN_GET_FOLDER_ITEMS_RSP 17
49 
50 /*******************************************************************************
51  *
52  * Function         avrc_bld_get_capability_rsp
53  *
54  * Description      This function builds the Get Capability response.
55  *
56  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
57  *                  Otherwise, the error code.
58  *
59  ******************************************************************************/
avrc_bld_get_capability_rsp(tAVRC_GET_CAPS_RSP * p_rsp,BT_HDR * p_pkt)60 static tAVRC_STS avrc_bld_get_capability_rsp(tAVRC_GET_CAPS_RSP* p_rsp, BT_HDR* p_pkt) {
61   uint8_t *p_data, *p_start, *p_len, *p_count;
62   uint16_t len = 0;
63   uint8_t xx;
64   uint32_t* p_company_id;
65   uint8_t* p_event_id;
66   tAVRC_STS status = AVRC_STS_NO_ERROR;
67 
68   if (!(AVRC_IS_VALID_CAP_ID(p_rsp->capability_id))) {
69     log::error("bad parameter. p_rsp: {}", std::format_ptr(p_rsp));
70     status = AVRC_STS_BAD_PARAM;
71     return status;
72   }
73 
74   log::verbose("");
75   /* get the existing length, if any, and also the num attributes */
76   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
77   p_data = p_len = p_start + 2; /* pdu + rsvd */
78 
79   BE_STREAM_TO_UINT16(len, p_data);
80   UINT8_TO_BE_STREAM(p_data, p_rsp->capability_id);
81   p_count = p_data;
82 
83   if (len == 0) {
84     *p_count = p_rsp->count;
85     p_data++;
86     len = 2; /* move past the capability_id and count */
87   } else {
88     p_data = p_start + p_pkt->len;
89     *p_count += p_rsp->count;
90   }
91 
92   if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
93     p_company_id = p_rsp->param.company_id;
94     for (xx = 0; xx < p_rsp->count; xx++) {
95       UINT24_TO_BE_STREAM(p_data, p_company_id[xx]);
96     }
97     len += p_rsp->count * 3;
98   } else {
99     p_event_id = p_rsp->param.event_id;
100     *p_count = 0;
101     for (xx = 0; xx < p_rsp->count; xx++) {
102       if (AVRC_IS_VALID_EVENT_ID(p_event_id[xx])) {
103         (*p_count)++;
104         UINT8_TO_BE_STREAM(p_data, p_event_id[xx]);
105       }
106     }
107     len += (*p_count);
108   }
109   UINT16_TO_BE_STREAM(p_len, len);
110   p_pkt->len = (p_data - p_start);
111   status = AVRC_STS_NO_ERROR;
112 
113   return status;
114 }
115 
116 /*******************************************************************************
117  *
118  * Function         avrc_bld_list_app_settings_attr_rsp
119  *
120  * Description      This function builds the List Application Settings Attribute
121  *                  response.
122  *
123  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
124  *                  Otherwise, the error code.
125  *
126  ******************************************************************************/
avrc_bld_list_app_settings_attr_rsp(tAVRC_LIST_APP_ATTR_RSP * p_rsp,BT_HDR * p_pkt)127 static tAVRC_STS avrc_bld_list_app_settings_attr_rsp(tAVRC_LIST_APP_ATTR_RSP* p_rsp,
128                                                      BT_HDR* p_pkt) {
129   uint8_t *p_data, *p_start, *p_len, *p_num;
130   uint16_t len = 0;
131   uint8_t xx;
132 
133   log::verbose("");
134   /* get the existing length, if any, and also the num attributes */
135   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
136   p_data = p_len = p_start + 2; /* pdu + rsvd */
137 
138   BE_STREAM_TO_UINT16(len, p_data);
139   p_num = p_data;
140   if (len == 0) {
141     /* first time initialize the attribute count */
142     *p_num = 0;
143     p_data++;
144   } else {
145     p_data = p_start + p_pkt->len;
146   }
147 
148   for (xx = 0; xx < p_rsp->num_attr; xx++) {
149     if (AVRC_IsValidPlayerAttr(p_rsp->attrs[xx])) {
150       (*p_num)++;
151       UINT8_TO_BE_STREAM(p_data, p_rsp->attrs[xx]);
152     }
153   }
154 
155   len = *p_num + 1;
156   UINT16_TO_BE_STREAM(p_len, len);
157   p_pkt->len = (p_data - p_start);
158 
159   return AVRC_STS_NO_ERROR;
160 }
161 
162 /*******************************************************************************
163  *
164  * Function         avrc_bld_list_app_settings_values_rsp
165  *
166  * Description      This function builds the List Application Setting Values
167  *                  response.
168  *
169  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
170  *                  Otherwise, the error code.
171  *
172  ******************************************************************************/
avrc_bld_list_app_settings_values_rsp(tAVRC_LIST_APP_VALUES_RSP * p_rsp,BT_HDR * p_pkt)173 static tAVRC_STS avrc_bld_list_app_settings_values_rsp(tAVRC_LIST_APP_VALUES_RSP* p_rsp,
174                                                        BT_HDR* p_pkt) {
175   uint8_t *p_data, *p_start, *p_len, *p_num;
176   uint8_t xx;
177   uint16_t len;
178 
179   log::verbose("");
180 
181   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
182   p_data = p_len = p_start + 2; /* pdu + rsvd */
183 
184   /* get the existing length, if any, and also the num attributes */
185   BE_STREAM_TO_UINT16(len, p_data);
186   p_num = p_data;
187   /* first time initialize the attribute count */
188   if (len == 0) {
189     *p_num = p_rsp->num_val;
190     p_data++;
191   } else {
192     p_data = p_start + p_pkt->len;
193     *p_num += p_rsp->num_val;
194   }
195 
196   for (xx = 0; xx < p_rsp->num_val; xx++) {
197     UINT8_TO_BE_STREAM(p_data, p_rsp->vals[xx]);
198   }
199 
200   len = *p_num + 1;
201   UINT16_TO_BE_STREAM(p_len, len);
202   p_pkt->len = (p_data - p_start);
203   return AVRC_STS_NO_ERROR;
204 }
205 
206 /*******************************************************************************
207  *
208  * Function         avrc_bld_get_cur_app_setting_value_rsp
209  *
210  * Description      This function builds the Get Current Application Setting
211  *                  Value response.
212  *
213  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
214  *                  Otherwise, the error code.
215  *
216  ******************************************************************************/
avrc_bld_get_cur_app_setting_value_rsp(tAVRC_GET_CUR_APP_VALUE_RSP * p_rsp,BT_HDR * p_pkt)217 static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp(tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp,
218                                                         BT_HDR* p_pkt) {
219   uint8_t *p_data, *p_start, *p_len, *p_count;
220   uint16_t len;
221   uint8_t xx;
222 
223   if (!p_rsp->p_vals) {
224     log::error("NULL parameter");
225     return AVRC_STS_BAD_PARAM;
226   }
227 
228   log::verbose("");
229   /* get the existing length, if any, and also the num attributes */
230   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
231   p_data = p_len = p_start + 2; /* pdu + rsvd */
232 
233   BE_STREAM_TO_UINT16(len, p_data);
234   p_count = p_data;
235   if (len == 0) {
236     /* first time initialize the attribute count */
237     *p_count = 0;
238     p_data++;
239   } else {
240     p_data = p_start + p_pkt->len;
241   }
242 
243   for (xx = 0; xx < p_rsp->num_val; xx++) {
244     if (avrc_is_valid_player_attrib_value(p_rsp->p_vals[xx].attr_id, p_rsp->p_vals[xx].attr_val)) {
245       (*p_count)++;
246       UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_id);
247       UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_val);
248     }
249   }
250   len = ((*p_count) << 1) + 1;
251   UINT16_TO_BE_STREAM(p_len, len);
252   p_pkt->len = (p_data - p_start);
253 
254   return AVRC_STS_NO_ERROR;
255 }
256 
257 /*******************************************************************************
258  *
259  * Function         avrc_bld_set_app_setting_value_rsp
260  *
261  * Description      This function builds the Set Application Setting Value
262  *                  response.
263  *
264  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
265  *                  Otherwise, the error code.
266  *
267  ******************************************************************************/
avrc_bld_set_app_setting_value_rsp(tAVRC_RSP *,BT_HDR *)268 static tAVRC_STS avrc_bld_set_app_setting_value_rsp(tAVRC_RSP* /* p_rsp */, BT_HDR* /* p_pkt */) {
269   /* nothing to be added. */
270   log::verbose("");
271   return AVRC_STS_NO_ERROR;
272 }
273 
274 /*******************************************************************************
275  *
276  * Function         avrc_bld_app_setting_text_rsp
277  *
278  * Description      This function builds the Get Application Settings Attribute
279  *                  Text or Get Application Settings Value Text response.
280  *
281  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
282  *                  Otherwise, the error code.
283  *
284  ******************************************************************************/
avrc_bld_app_setting_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)285 static tAVRC_STS avrc_bld_app_setting_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp, BT_HDR* p_pkt) {
286   uint8_t *p_data, *p_start, *p_len, *p_count;
287   uint16_t len, len_left;
288   uint8_t xx;
289   tAVRC_STS sts = AVRC_STS_NO_ERROR;
290   uint8_t num_added = 0;
291 
292   if (!p_rsp->p_attrs) {
293     log::error("NULL parameter");
294     return AVRC_STS_BAD_PARAM;
295   }
296   /* get the existing length, if any, and also the num attributes */
297   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
298   p_data = p_len = p_start + 2; /* pdu + rsvd */
299 
300   /*
301    * NOTE: The buffer is allocated within avrc_bld_init_rsp_buffer(), and is
302    * always of size BT_DEFAULT_BUFFER_SIZE.
303    */
304   len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
305 
306   BE_STREAM_TO_UINT16(len, p_data);
307   p_count = p_data;
308 
309   if (len == 0) {
310     *p_count = 0;
311     p_data++;
312   } else {
313     p_data = p_start + p_pkt->len;
314   }
315 
316   for (xx = 0; xx < p_rsp->num_attr; xx++) {
317     if (len_left < (p_rsp->p_attrs[xx].str_len + 4)) {
318       log::error("out of room (str_len:{}, left:{})", p_rsp->p_attrs[xx].str_len, len_left);
319       p_rsp->num_attr = num_added;
320       sts = AVRC_STS_INTERNAL_ERR;
321       break;
322     }
323     if (!p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str) {
324       log::error("NULL attr text[{}]", xx);
325       continue;
326     }
327     UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
328     UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
329     UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
330     ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str, p_rsp->p_attrs[xx].str_len);
331     (*p_count)++;
332     num_added++;
333   }
334   len = p_data - p_count;
335   UINT16_TO_BE_STREAM(p_len, len);
336   p_pkt->len = (p_data - p_start);
337 
338   return sts;
339 }
340 
341 /*******************************************************************************
342  *
343  * Function         avrc_bld_get_app_setting_attr_text_rsp
344  *
345  * Description      This function builds the Get Application Setting Attribute
346  *                  Text response.
347  *
348  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
349  *                  Otherwise, the error code.
350  *
351  ******************************************************************************/
avrc_bld_get_app_setting_attr_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)352 static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp,
353                                                         BT_HDR* p_pkt) {
354   log::verbose("");
355   return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
356 }
357 
358 /*******************************************************************************
359  *
360  * Function         avrc_bld_get_app_setting_value_text_rsp
361  *
362  * Description      This function builds the Get Application Setting Value Text
363  *                  response.
364  *
365  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
366  *                  Otherwise, the error code.
367  *
368  ******************************************************************************/
avrc_bld_get_app_setting_value_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)369 static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp,
370                                                          BT_HDR* p_pkt) {
371   log::verbose("");
372   return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
373 }
374 
375 /*******************************************************************************
376  *
377  * Function         avrc_bld_inform_charset_rsp
378  *
379  * Description      This function builds the Inform Displayable Character Set
380  *                  response.
381  *
382  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
383  *                  Otherwise, the error code.
384  *
385  ******************************************************************************/
avrc_bld_inform_charset_rsp(tAVRC_RSP *,BT_HDR *)386 static tAVRC_STS avrc_bld_inform_charset_rsp(tAVRC_RSP* /* p_rsp */, BT_HDR* /* p_pkt */) {
387   /* nothing to be added. */
388   log::verbose("");
389   return AVRC_STS_NO_ERROR;
390 }
391 
392 /*******************************************************************************
393  *
394  * Function         avrc_bld_inform_battery_status_rsp
395  *
396  * Description      This function builds the Inform Battery Status
397  *                  response.
398  *
399  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
400  *                  Otherwise, the error code.
401  *
402  ******************************************************************************/
avrc_bld_inform_battery_status_rsp(tAVRC_RSP *,BT_HDR *)403 static tAVRC_STS avrc_bld_inform_battery_status_rsp(tAVRC_RSP* /* p_rsp */, BT_HDR* /* p_pkt */) {
404   /* nothing to be added. */
405   log::verbose("");
406   return AVRC_STS_NO_ERROR;
407 }
408 
avrc_build_attribute_entries(int num_attrs,tAVRC_ATTR_ENTRY * p_attrs,int remaining_buffer_capacity,uint8_t ** pp_data,uint8_t * p_attribute_count)409 static void avrc_build_attribute_entries(int num_attrs, tAVRC_ATTR_ENTRY* p_attrs,
410                                          int remaining_buffer_capacity, uint8_t** pp_data,
411                                          uint8_t* p_attribute_count) {
412   log::verbose("num_attrs: {}, remaining_buffer_capacity: {}", num_attrs,
413                remaining_buffer_capacity);
414   uint8_t* p_data = *pp_data;
415   /* Fill in the Attribute ID, Character Set, Length and Values */
416   for (int index = 0; index < num_attrs; index++) {
417     log::verbose("attr id[{}]: {}", index, p_attrs[index].attr_id);
418     log::assert_that(AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_attrs[index].attr_id),
419                      "assert failed: AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_attrs[index].attr_id)");
420     if (!p_attrs[index].name.p_str) {
421       p_attrs[index].name.str_len = 0;
422     }
423     /* 8 is the size of attr_id, char set and str_len */
424     remaining_buffer_capacity -= 8;
425     if (remaining_buffer_capacity < 0) {
426       log::warn("not enough buffer space for attr_id[{}]: {}, skipping {} attributes", index,
427                 p_attrs[index].attr_id, num_attrs - index);
428       break;
429     }
430     if (remaining_buffer_capacity < p_attrs[index].name.str_len) {
431       log::warn("not enough buffer space for attr_id[{}]: {}, truncating attribute", index,
432                 p_attrs[index].attr_id);
433       p_attrs[index].name.str_len = remaining_buffer_capacity;
434       remaining_buffer_capacity = 0;
435     }
436     remaining_buffer_capacity -= p_attrs[index].name.str_len;
437     UINT32_TO_BE_STREAM(p_data, p_attrs[index].attr_id);
438     UINT16_TO_BE_STREAM(p_data, p_attrs[index].name.charset_id);
439     UINT16_TO_BE_STREAM(p_data, p_attrs[index].name.str_len);
440     ARRAY_TO_BE_STREAM(p_data, p_attrs[index].name.p_str, p_attrs[index].name.str_len);
441     (*p_attribute_count)++;
442   }
443   *pp_data = p_data;
444   log::verbose("filled attributes, remaining_buffer_capacity: {}", remaining_buffer_capacity);
445 }
446 
447 /*******************************************************************************
448  *
449  * Function         avrc_bld_get_elem_attrs_rsp
450  *
451  * Description      This function builds the Get Element Attributes
452  *                  response.
453  *
454  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
455  *                  Otherwise, the error code.
456  *
457  ******************************************************************************/
avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ATTRS_RSP * p_rsp,BT_HDR * p_pkt)458 static tAVRC_STS avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp, BT_HDR* p_pkt) {
459   log::verbose("");
460   if (!p_rsp->p_attrs) {
461     log::error("NULL p_attrs");
462     return AVRC_STS_BAD_PARAM;
463   }
464   /* Figure out how much we have left in current buffer */
465   int remaining_buffer_capacity = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset;
466   if (remaining_buffer_capacity < 5) {
467     log::error("{} not enough buffer for packet header", remaining_buffer_capacity);
468     return AVRC_STS_INTERNAL_ERR;
469   }
470   /* Get to the beginning of PDU */
471   uint8_t* p_pdu_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
472   /* Skip PDU ID and Reserved byte to get pointer to Parameter Length */
473   uint8_t *p_data, *p_parameter_len;
474   p_data = p_parameter_len = p_pdu_start + 2;
475   /* Parse parameter length */
476   uint16_t parameter_len;
477   BE_STREAM_TO_UINT16(parameter_len, p_data);
478   /* Get pointer to Attribute Count */
479   uint8_t* p_attribute_count = p_data;
480   /* Initialize field values when Parameter Length is 0 */
481   if (parameter_len == 0) {
482     *p_attribute_count = 0;
483     p_data++;
484   } else {
485     // TODO: Why do we need this case?
486     p_data = p_pdu_start + p_pkt->len;
487   }
488   remaining_buffer_capacity -= p_data - p_pdu_start;
489   ;
490   if (remaining_buffer_capacity < 0) {
491     log::error("not enough buffer capacity for response");
492     return AVRC_STS_BAD_PARAM;
493   }
494   /* Fill in the Attribute ID, Character Set, Length and Values */
495   avrc_build_attribute_entries(p_rsp->num_attrs, p_rsp->p_attrs, remaining_buffer_capacity, &p_data,
496                                p_attribute_count);
497   parameter_len = p_data - p_attribute_count;
498   UINT16_TO_BE_STREAM(p_parameter_len, parameter_len);
499   p_pkt->len = (p_data - p_pdu_start);
500   return AVRC_STS_NO_ERROR;
501 }
502 
503 /*******************************************************************************
504  *
505  * Function         avrc_bld_get_play_status_rsp
506  *
507  * Description      This function builds the Get Play Status
508  *                  response.
509  *
510  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
511  *                  Otherwise, the error code.
512  *
513  ******************************************************************************/
avrc_bld_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP * p_rsp,BT_HDR * p_pkt)514 static tAVRC_STS avrc_bld_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP* p_rsp, BT_HDR* p_pkt) {
515   uint8_t *p_data, *p_start;
516 
517   log::verbose("");
518   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
519   p_data = p_start + 2;
520 
521   /* add fixed length - song len(4) + song position(4) + status(1) */
522   UINT16_TO_BE_STREAM(p_data, 9);
523   UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
524   UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
525   UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
526   p_pkt->len = (p_data - p_start);
527 
528   return AVRC_STS_NO_ERROR;
529 }
530 
531 /*******************************************************************************
532  *
533  * Function         avrc_bld_notify_rsp
534  *
535  * Description      This function builds the Notification response.
536  *
537  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
538  *                  Otherwise, the error code.
539  *
540  ******************************************************************************/
avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP * p_rsp,BT_HDR * p_pkt)541 static tAVRC_STS avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP* p_rsp, BT_HDR* p_pkt) {
542   uint8_t *p_data, *p_start;
543   uint8_t* p_len;
544   uint16_t len = 0;
545   uint8_t xx;
546   tAVRC_STS status = AVRC_STS_NO_ERROR;
547 
548   log::verbose("event_id {}", p_rsp->event_id);
549 
550   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
551   p_data = p_len = p_start + 2; /* pdu + rsvd */
552   p_data += 2;
553 
554   UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
555   switch (p_rsp->event_id) {
556     case AVRC_EVT_PLAY_STATUS_CHANGE: /* 0x01 */
557       /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always true */
558       if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
559           (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR)) {
560         UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
561         len = 2;
562       } else {
563         log::error("bad play state");
564         status = AVRC_STS_BAD_PARAM;
565       }
566       break;
567 
568     case AVRC_EVT_TRACK_CHANGE: /* 0x02 */
569       ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
570       len = (uint8_t)(AVRC_UID_SIZE + 1);
571       break;
572 
573     case AVRC_EVT_TRACK_REACHED_END:   /* 0x03 */
574     case AVRC_EVT_TRACK_REACHED_START: /* 0x04 */
575     case AVRC_EVT_NOW_PLAYING_CHANGE:  /* 0x09 */
576     case AVRC_EVT_AVAL_PLAYERS_CHANGE: /* 0x0a */
577       len = 1;
578       break;
579 
580     case AVRC_EVT_PLAY_POS_CHANGED: /* 0x05 */
581       UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
582       len = 5;
583       break;
584 
585     case AVRC_EVT_BATTERY_STATUS_CHANGE: /* 0x06 */
586       if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status)) {
587         UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
588         len = 2;
589       } else {
590         log::error("bad battery status");
591         status = AVRC_STS_BAD_PARAM;
592       }
593       break;
594 
595     case AVRC_EVT_SYSTEM_STATUS_CHANGE: /* 0x07 */
596       if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status)) {
597         UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
598         len = 2;
599       } else {
600         log::error("bad system status");
601         status = AVRC_STS_BAD_PARAM;
602       }
603       break;
604 
605     case AVRC_EVT_APP_SETTING_CHANGE: /* 0x08 */
606       if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS) {
607         p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
608       }
609 
610       if (p_rsp->param.player_setting.num_attr > 0) {
611         UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
612         len = 2;
613         for (xx = 0; xx < p_rsp->param.player_setting.num_attr; xx++) {
614           if (avrc_is_valid_player_attrib_value(p_rsp->param.player_setting.attr_id[xx],
615                                                 p_rsp->param.player_setting.attr_value[xx])) {
616             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
617             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
618           } else {
619             log::error("bad player app seeting attribute or value");
620             status = AVRC_STS_BAD_PARAM;
621             break;
622           }
623           len += 2;
624         }
625       } else {
626         status = AVRC_STS_BAD_PARAM;
627       }
628       break;
629 
630     case AVRC_EVT_VOLUME_CHANGE: /* 0x0d */
631       len = 2;
632       UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume));
633       break;
634 
635     case AVRC_EVT_ADDR_PLAYER_CHANGE: /* 0x0b */
636       UINT16_TO_BE_STREAM(p_data, p_rsp->param.addr_player.player_id);
637       UINT16_TO_BE_STREAM(p_data, p_rsp->param.addr_player.uid_counter);
638       len = 5;
639       break;
640 
641     case AVRC_EVT_UIDS_CHANGE:                               /* 0x0c */
642       UINT16_TO_BE_STREAM(p_data, p_rsp->param.uid_counter); /* uid counter */
643       len = 3;
644       break;
645 
646     default:
647       status = AVRC_STS_BAD_PARAM;
648       log::error("unknown event_id");
649   }
650 
651   UINT16_TO_BE_STREAM(p_len, len);
652   p_pkt->len = (p_data - p_start);
653 
654   return status;
655 }
656 
657 /*******************************************************************************
658  *
659  * Function         avrc_bld_next_rsp
660  *
661  * Description      This function builds the Request Continue or Abort
662  *                  response.
663  *
664  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
665  *                  Otherwise, the error code.
666  *
667  ******************************************************************************/
avrc_bld_next_rsp(tAVRC_NEXT_RSP * p_rsp,BT_HDR * p_pkt)668 static tAVRC_STS avrc_bld_next_rsp(tAVRC_NEXT_RSP* p_rsp, BT_HDR* p_pkt) {
669   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
670   uint8_t* p_data = (p_start + 2); /* Skip the pdu and reserved bits */
671 
672   UINT16_TO_BE_STREAM(p_data, 0x0001); /* only one attribute to be sent */
673   UINT8_TO_BE_STREAM(p_data, p_rsp->target_pdu);
674 
675   log::verbose("target_pdu: 0x{:02x}", p_rsp->target_pdu);
676   return AVRC_STS_NO_ERROR;
677 }
678 
679 /*****************************************************************************
680  *
681  * Function      avrc_bld_set_absolute_volume_rsp
682  *
683  * Description   This function builds the set absolute volume response
684  *
685  * Returns       AVRC_STS_NO_ERROR, if the response is build successfully
686  *
687  *****************************************************************************/
avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol,BT_HDR * p_pkt)688 static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, BT_HDR* p_pkt) {
689   log::verbose("");
690   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
691   /* To calculate length */
692   uint8_t* p_data = p_start + 2;
693   /* add fixed length status(1) */
694   UINT16_TO_BE_STREAM(p_data, 1);
695   UINT8_TO_BE_STREAM(p_data, abs_vol);
696   p_pkt->len = (p_data - p_start);
697   return AVRC_STS_NO_ERROR;
698 }
699 
700 /*******************************************************************************
701  *
702  * Function         avrc_bld_group_navigation_rsp
703  *
704  * Description      This function builds the Group Navigation
705  *                  response.
706  *
707  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
708  *                  Otherwise, the error code.
709  *
710  ******************************************************************************/
avrc_bld_group_navigation_rsp(uint16_t navi_id,BT_HDR * p_pkt)711 static tAVRC_STS avrc_bld_group_navigation_rsp(uint16_t navi_id, BT_HDR* p_pkt) {
712   if (!AVRC_IS_VALID_GROUP(navi_id)) {
713     log::error("bad navigation op id: {}", navi_id);
714     return AVRC_STS_BAD_PARAM;
715   }
716   log::verbose("");
717   uint8_t* p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
718   UINT16_TO_BE_STREAM(p_data, navi_id);
719   p_pkt->len = 2;
720   return AVRC_STS_NO_ERROR;
721 }
722 
723 /*******************************************************************************
724  *
725  * Function         avrc_bld_rejected_rsp
726  *
727  * Description      This function builds the General Response response.
728  *
729  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
730  *
731  ******************************************************************************/
avrc_bld_rejected_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)732 static tAVRC_STS avrc_bld_rejected_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
733   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
734   uint8_t* p_data;
735   uint8_t opcode = p_rsp->opcode;
736 
737   log::verbose("status={}, pdu:x{:x}, opcode={:x}", p_rsp->status, p_rsp->pdu, opcode);
738 
739   if (opcode == AVRC_OP_BROWSE) {
740     p_data = p_start + 1;
741     if ((AVRC_PDU_INVALID == *p_start) || (avrc_opcode_from_pdu(*p_start) != AVRC_OP_BROWSE)) {
742       /* if invalid or the given opcode is not recognized as a browsing command
743        * opcode, */
744       /* use general reject command */
745       *p_start = AVRC_PDU_GENERAL_REJECT;
746     }
747   } else {
748     p_data = p_start + 2;
749   }
750   log::verbose("pdu:x{:x}, Opcode:{:x}", *p_start, opcode);
751   UINT16_TO_BE_STREAM(p_data, 1);
752   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
753   p_pkt->len = p_data - p_start;
754   return AVRC_STS_NO_ERROR;
755 }
756 
757 /*****************************************************************************
758  *  the following commands are introduced in AVRCP 1.4
759  ****************************************************************************/
760 
761 /*******************************************************************************
762  *
763  * Function         avrc_bld_ctrl_status_rsp
764  *
765  * Description      This function builds the responses with a uint8_t parameter.
766  *
767  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
768  *                  Otherwise, the error code.
769  *
770  ******************************************************************************/
avrc_bld_ctrl_status_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)771 static tAVRC_STS avrc_bld_ctrl_status_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
772   uint8_t* p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
773   log::verbose("pdu:x{:x}", *p_start);
774 
775   /* To calculate length */
776   uint8_t* p_data = p_start + 2; /* pdu + rsvd */
777 
778   /* add fixed length - status(1) */
779   UINT16_TO_BE_STREAM(p_data, 1);
780   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
781   p_pkt->len = (p_data - p_start);
782   return AVRC_STS_NO_ERROR;
783 }
784 
785 /*******************************************************************************
786  *
787  * Function         avrc_bld_set_addr_player_rsp
788  *
789  * Description      This function builds the Set Addresses Player response.
790  *
791  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
792  *                  Otherwise, the error code.
793  *
794  ******************************************************************************/
avrc_bld_set_addr_player_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)795 static tAVRC_STS avrc_bld_set_addr_player_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
796   log::verbose("");
797   return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt);
798 }
799 
800 /*******************************************************************************
801  *
802  * Function         avrc_bld_set_browsed_player_rsp
803  *
804  * Description      This function builds the Set Browsed Player response.
805  *
806  *                  This message goes through the Browsing channel
807  *
808  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
809  *                  Otherwise, the error code.
810  *
811  ******************************************************************************/
avrc_bld_set_browsed_player_rsp(tAVRC_SET_BR_PLAYER_RSP * p_rsp,BT_HDR * p_pkt)812 static tAVRC_STS avrc_bld_set_browsed_player_rsp(tAVRC_SET_BR_PLAYER_RSP* p_rsp, BT_HDR* p_pkt) {
813   uint8_t *p_data, *p_start;
814   uint8_t* p_len;
815   uint16_t len;
816   tAVRC_NAME* p_folders = p_rsp->p_folders;
817   uint16_t len_left;
818   uint8_t* p_folder_depth;
819   uint16_t mtu;
820 
821   /* make sure the given buffer can accomodate this response */
822   len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE;
823   p_data = (uint8_t*)(p_pkt + 1);
824   BE_STREAM_TO_UINT16(mtu, p_data);
825   if (len_left > mtu) {
826     len_left = mtu;
827   }
828   len_left = len_left - p_pkt->offset - p_pkt->len;
829   log::verbose("len_left:{}, mtu:{}", len_left, mtu);
830 
831   /* get the existing length, if any, and also the num attributes */
832   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
833   p_data = p_len = p_start + 1; /* pdu */
834 
835   /* the existing len */
836   BE_STREAM_TO_UINT16(len, p_data);
837   /* find the position to add the folder depth.
838    * 9 is sizeof (status + uid_counter + num_items + charset_id) */
839   p_folder_depth = p_data + 9;
840   if (len == 0) {
841     /* first time initialize the attribute count */
842     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
843     UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
844     UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
845     UINT16_TO_BE_STREAM(p_data, p_rsp->charset_id);
846     *p_folder_depth = 0;
847     p_data++;
848     len = 10;
849     /* assuming that we would never use a buffer that is too small for headers
850      */
851     len_left -= 12;
852   } else {
853     p_data = p_start + p_pkt->len;
854   }
855 
856   for (uint8_t xx = 0; (xx < p_rsp->folder_depth) && (len_left > (p_folders[xx].str_len + 2));
857        xx++) {
858     (*p_folder_depth)++;
859     UINT16_TO_BE_STREAM(p_data, p_folders[xx].str_len);
860     ARRAY_TO_BE_STREAM(p_data, p_folders[xx].p_str, p_folders[xx].str_len);
861     len += (p_folders[xx].str_len + 2);
862   }
863   UINT16_TO_BE_STREAM(p_len, len);
864   p_pkt->len = (p_data - p_start);
865   return AVRC_STS_NO_ERROR;
866 }
867 
868 /*******************************************************************************
869  *
870  * Function         avrc_bld_get_folder_items_rsp
871  *
872  * Description      This function builds the Get Folder Items response.
873  *                  The error code is returned in *p_status.
874  *                  AVRC_STS_INTERNAL_ERR means no buffers.
875  *                  Try again later or with smaller item_count
876  *
877  *                  This message goes through the Browsing channel
878  *
879  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
880  *                  AVRC_STS_INTERNAL_ERR, if the given buffer does not have
881  *                  enough room
882  *                  Otherwise, the error code.
883  *
884  ******************************************************************************/
avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP * p_rsp,BT_HDR * p_pkt)885 static tAVRC_STS avrc_bld_get_folder_items_rsp(tAVRC_GET_ITEMS_RSP* p_rsp, BT_HDR* p_pkt) {
886   uint8_t *p_data, *p_start;
887   uint8_t *p_len, xx;
888   uint16_t len;
889   size_t item_len;
890   uint8_t *p_item_len, yy;
891   tAVRC_ITEM_PLAYER* p_player;
892   tAVRC_ITEM_FOLDER* p_folder;
893   tAVRC_ITEM_MEDIA* p_media;
894   tAVRC_ATTR_ENTRY* p_attr;
895   tAVRC_ITEM* p_item_list = p_rsp->p_item_list;
896   tAVRC_STS status = AVRC_STS_NO_ERROR;
897   uint16_t len_left;
898   uint8_t *p_num, *p;
899   uint8_t *p_item_start, *p_attr_count;
900   uint16_t item_count;
901   uint16_t mtu;
902   bool multi_items_add_fail = false;
903   log::verbose("");
904 
905   /* make sure the given buffer can accomodate this response */
906   len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE;
907   p = (uint8_t*)(p_pkt + 1);
908   BE_STREAM_TO_UINT16(mtu, p);
909   if (len_left > mtu) {
910     len_left = mtu;
911   }
912 
913   // according to spec
914   // Version 5.3 | Vol 3, Part A, Chapter 5
915   // MTU may be controlled by the peer
916   if (len_left < p_pkt->offset + p_pkt->len) {
917     log::error("memory not enough (len_left={})", len_left);
918     return AVRC_STS_INTERNAL_ERR;
919   }
920 
921   len_left = len_left - p_pkt->offset - p_pkt->len;
922 
923   /* get the existing length, if any, and also the num attributes */
924   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
925   p_data = p_len = p_start + 1; /* pdu */
926 
927   /* the existing len */
928   BE_STREAM_TO_UINT16(len, p_data);
929   p_num = p_data + 3;
930   if (len == 0) {
931     /* first time initialize the attribute count */
932     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
933     UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
934     item_count = 0;
935     p_data += 2;
936     len = 5;
937 
938     if (len_left < 5) {
939       log::error("memory not enough (len_left={})", len_left);
940       return AVRC_STS_INTERNAL_ERR;
941     }
942 
943     len_left -= 5;
944   } else {
945     p_data = p_start + p_pkt->len;
946     p = p_num;
947     BE_STREAM_TO_UINT16(item_count, p);
948   }
949   log::verbose("len:{}, len_left:{}, num:{}", len, len_left, item_count);
950 
951   /* min len required = item_type(1) + item len(2) + min item (14) = 17 */
952   for (xx = 0; xx < p_rsp->item_count && len_left > AVRC_MIN_LEN_GET_FOLDER_ITEMS_RSP &&
953                !multi_items_add_fail;
954        xx++) {
955     p_item_start = p_data;
956     UINT8_TO_BE_STREAM(p_data, p_item_list[xx].item_type);
957     /* variable item length - save the location to add length */
958     p_item_len = p_data;
959     p_data += 2;
960     item_len = 0;
961     const uint16_t item_header_len = 3; /* item_type(1) + item len(2) */
962     uint16_t item_len_left = len_left - item_header_len;
963     switch (p_item_list[xx].item_type) {
964       case AVRC_ITEM_PLAYER:
965         /* min len required: 2 + 1 + 4 + 1 + 16 + 2 + 2 = 30 + str_len */
966         p_player = &p_item_list[xx].u.player;
967         item_len = AVRC_FEATURE_MASK_SIZE + p_player->name.str_len + 12;
968 
969         if ((item_len_left < item_len) || !AVRC_ITEM_PLAYER_IS_VALID(p_player)) {
970           if (item_len_left < item_len && item_count > 0) {
971             multi_items_add_fail = true;
972           }
973           p_data = p_item_start;
974           break;
975         }
976         UINT16_TO_BE_STREAM(p_data, p_player->player_id);
977         UINT8_TO_BE_STREAM(p_data, p_player->major_type);
978         UINT32_TO_BE_STREAM(p_data, p_player->sub_type);
979         UINT8_TO_BE_STREAM(p_data, p_player->play_status);
980         ARRAY_TO_BE_STREAM(p_data, p_player->features, AVRC_FEATURE_MASK_SIZE);
981         UINT16_TO_BE_STREAM(p_data, p_player->name.charset_id);
982         UINT16_TO_BE_STREAM(p_data, p_player->name.str_len);
983         ARRAY_TO_BE_STREAM(p_data, p_player->name.p_str, p_player->name.str_len);
984         break;
985 
986       case AVRC_ITEM_FOLDER:
987         /* min len required: 8 + 1 + 1 + 2 + 2 = 14 + str_len */
988         p_folder = &p_item_list[xx].u.folder;
989         item_len = AVRC_UID_SIZE + p_folder->name.str_len + 6;
990 
991         if ((item_len_left < item_len) || !p_folder->name.p_str ||
992             p_folder->type > AVRC_FOLDER_TYPE_YEARS) {
993           if (item_len_left < item_len && item_count > 0) {
994             multi_items_add_fail = true;
995           }
996           p_data = p_item_start;
997           break;
998         }
999         ARRAY_TO_BE_STREAM(p_data, p_folder->uid, AVRC_UID_SIZE);
1000         UINT8_TO_BE_STREAM(p_data, p_folder->type);
1001         UINT8_TO_BE_STREAM(p_data, p_folder->playable);
1002         UINT16_TO_BE_STREAM(p_data, p_folder->name.charset_id);
1003         UINT16_TO_BE_STREAM(p_data, p_folder->name.str_len);
1004         ARRAY_TO_BE_STREAM(p_data, p_folder->name.p_str, p_folder->name.str_len);
1005         break;
1006 
1007       case AVRC_ITEM_MEDIA:
1008         /* min len required: 8 + 1 + 2 + 2 + 1 = 14 + str_len */
1009         p_media = &p_item_list[xx].u.media;
1010         item_len = AVRC_UID_SIZE + p_media->name.str_len + 6;
1011 
1012         if ((item_len_left < item_len) || !p_media->name.p_str ||
1013             p_media->type > AVRC_MEDIA_TYPE_VIDEO) {
1014           if (item_len_left < item_len && item_count > 0) {
1015             multi_items_add_fail = true;
1016           }
1017           p_data = p_item_start;
1018           break;
1019         }
1020         ARRAY_TO_BE_STREAM(p_data, p_media->uid, AVRC_UID_SIZE);
1021         UINT8_TO_BE_STREAM(p_data, p_media->type);
1022         UINT16_TO_BE_STREAM(p_data, p_media->name.charset_id);
1023         UINT16_TO_BE_STREAM(p_data, p_media->name.str_len);
1024         ARRAY_TO_BE_STREAM(p_data, p_media->name.p_str, p_media->name.str_len);
1025         p_attr_count = p_data++;
1026         *p_attr_count = 0;
1027         uint16_t attribute_len_left = item_len_left - item_len;
1028         p_attr = p_media->p_attr_list;
1029         for (yy = 0; yy < p_media->attr_count; yy++) {
1030           /* len required: 4 + 2 + 2 + str_len */
1031           const size_t attribute_len = p_attr[yy].name.str_len + 8;
1032           if (attribute_len_left < attribute_len || !p_attr[yy].name.p_str ||
1033               AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_attr[yy].attr_id)) {
1034             if (attribute_len_left < attribute_len && item_count > 0) {
1035               multi_items_add_fail = true;
1036               p_data = p_item_start;
1037               break;
1038             }
1039             continue;
1040           }
1041           (*p_attr_count)++;
1042           UINT32_TO_BE_STREAM(p_data, p_attr[yy].attr_id);
1043           UINT16_TO_BE_STREAM(p_data, p_attr[yy].name.charset_id);
1044           UINT16_TO_BE_STREAM(p_data, p_attr[yy].name.str_len);
1045           ARRAY_TO_BE_STREAM(p_data, p_attr[yy].name.p_str, p_attr[yy].name.str_len);
1046           item_len += attribute_len;
1047           attribute_len_left -= attribute_len;
1048         }
1049         break;
1050     } /* switch item_type */
1051 
1052     if (p_item_start != p_data) {
1053       /* successfully added the item */
1054       item_count++;
1055       /* fill in variable item length */
1056       UINT16_TO_BE_STREAM(p_item_len, item_len);
1057       len_left -= item_len + item_header_len;
1058       len += item_len + item_header_len;
1059     } else if (!multi_items_add_fail) {
1060       /* some item is not added properly - set an error status */
1061       if (item_len_left < item_len) {
1062         status = AVRC_STS_INTERNAL_ERR;
1063       } else {
1064         status = AVRC_STS_BAD_PARAM;
1065       }
1066       break;
1067     }
1068     log::verbose("len:{}, len_left:{}, num:{}, item_len:{}", len, len_left, item_count, item_len);
1069   } /* for item_count */
1070 
1071   UINT16_TO_BE_STREAM(p_num, item_count);
1072   UINT16_TO_BE_STREAM(p_len, len);
1073   p_pkt->len = (p_data - p_start);
1074 
1075   return status;
1076 }
1077 
1078 /*******************************************************************************
1079  *
1080  * Function         avrc_bld_change_path_rsp
1081  *
1082  * Description      This function builds the Change Path response.
1083  *
1084  *                  This message goes through the Browsing channel
1085  *
1086  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1087  *                  Otherwise, the error code.
1088  *
1089  ******************************************************************************/
avrc_bld_change_path_rsp(tAVRC_CHG_PATH_RSP * p_rsp,BT_HDR * p_pkt)1090 static tAVRC_STS avrc_bld_change_path_rsp(tAVRC_CHG_PATH_RSP* p_rsp, BT_HDR* p_pkt) {
1091   uint8_t *p_data, *p_start;
1092 
1093   /* get the existing length, if any, and also the num attributes */
1094   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1095   p_data = p_start + 1; /* pdu */
1096   /* add fixed length - status(1) + num_items(4) */
1097   UINT16_TO_BE_STREAM(p_data, 5);
1098   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
1099   UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
1100   p_pkt->len = (p_data - p_start);
1101   return AVRC_STS_NO_ERROR;
1102 }
1103 
1104 /*******************************************************************************
1105  *
1106  * Function         avrc_bld_get_attrs_rsp
1107  *
1108  * Description      This function builds the GetItemAttributes response,
1109  *
1110  *                  The Get Item Attributes message goes through the
1111  *                  Browsing channel (already specified in the |p_pkt|)
1112  *
1113  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1114  *                  AVRC_STS_INTERNAL_ERR, if the given buffer does not have
1115  *                  enough room
1116  *                  Otherwise, the error code.
1117  *
1118  ******************************************************************************/
avrc_bld_get_item_attrs_rsp(tAVRC_GET_ATTRS_RSP * p_rsp,BT_HDR * p_pkt)1119 static tAVRC_STS avrc_bld_get_item_attrs_rsp(tAVRC_GET_ATTRS_RSP* p_rsp, BT_HDR* p_pkt) {
1120   log::verbose("");
1121   if (!p_rsp->p_attrs) {
1122     log::error("NULL p_attrs");
1123     return AVRC_STS_BAD_PARAM;
1124   }
1125   /* Figure out how much we have left in current buffer */
1126   int remaining_buffer_capacity = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset;
1127   /* Get to the beginning of data section in buffer */
1128   uint8_t* p_data = (uint8_t*)(p_pkt + 1);
1129   /* Get the MTU size that is filled in earlier */
1130   uint16_t mtu;
1131   BE_STREAM_TO_UINT16(mtu, p_data);
1132   if (remaining_buffer_capacity > mtu) {
1133     remaining_buffer_capacity = mtu;
1134   }
1135   log::verbose("remaining_buffer_capacity:{}, mtu:{}", remaining_buffer_capacity, mtu);
1136   if (remaining_buffer_capacity < 5) {
1137     log::error("not enough space for packet header, remaining:{} < 5", remaining_buffer_capacity);
1138     return AVRC_STS_INTERNAL_ERR;
1139   }
1140   /* Get to the beginning of PDU */
1141   uint8_t* p_pdu_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1142   /* Skip PDU ID to get pointer to Parameter length */
1143   uint8_t* p_parameter_len;
1144   p_data = p_parameter_len = p_pdu_start + 1;
1145   /* Parse existing parameter length */
1146   uint16_t parameter_len;
1147   BE_STREAM_TO_UINT16(parameter_len, p_data);
1148   /* Skip one byte to Number of Attributes */
1149   uint8_t* p_status = p_data++;
1150   uint8_t* p_attribute_count = p_data++;
1151   if (parameter_len == 0) {
1152     /* First time, initialize the status byte */
1153     *p_status = p_rsp->status;
1154     if (p_rsp->status != AVRC_STS_NO_ERROR) {
1155       // TODO(siyuanh): This is a hack
1156       parameter_len = 1;
1157       UINT16_TO_BE_STREAM(p_parameter_len, parameter_len);
1158       p_pkt->len = p_status - p_pdu_start;
1159       return AVRC_STS_NO_ERROR;
1160     }
1161     *p_attribute_count = 0;
1162   } else {
1163     // TODO(siyuanh): Why do wee need this case?
1164     p_data = p_pdu_start + p_pkt->len;
1165   }
1166   remaining_buffer_capacity -= p_data - p_pdu_start;
1167   /* Fill in the Attribute ID, Character Set, Length and Values */
1168   avrc_build_attribute_entries(p_rsp->num_attrs, p_rsp->p_attrs, remaining_buffer_capacity, &p_data,
1169                                p_attribute_count);
1170   parameter_len = p_data - p_status;
1171   UINT16_TO_BE_STREAM(p_parameter_len, parameter_len);
1172   p_pkt->len = p_data - p_pdu_start;
1173   return AVRC_STS_NO_ERROR;
1174 }
1175 
1176 /*******************************************************************************
1177  *
1178  * Function         avrc_bld_get_num_of_item_rsp
1179  *
1180  * Description      This function builds the Get Total Number of Items response.
1181  *
1182  *                  This message goes through the Browsing channel
1183  *
1184  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1185  *                  AVRC_STS_INTERNAL_ERR, if the given buffer does not have
1186  *                  enough room
1187  *                  Otherwise, the error code.
1188  *
1189  ******************************************************************************/
avrc_bld_get_num_of_item_rsp(tAVRC_GET_NUM_OF_ITEMS_RSP * p_rsp,BT_HDR * p_pkt)1190 static tAVRC_STS avrc_bld_get_num_of_item_rsp(tAVRC_GET_NUM_OF_ITEMS_RSP* p_rsp, BT_HDR* p_pkt) {
1191   uint8_t *p_data, *p_start, *p_len;
1192 
1193   log::verbose("");
1194   /* get the existing length, if any, and also the num attributes */
1195   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1196   p_data = p_len = p_start + 1; /* pdu */
1197 
1198   if (p_rsp->status == AVRC_STS_NO_ERROR) {
1199     /* add fixed length - status(1) + uid_counter(2) + num_items(4) */
1200     UINT16_TO_BE_STREAM(p_data, 7);
1201     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
1202     UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
1203     UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
1204     p_pkt->len = (p_data - p_start);
1205     return AVRC_STS_NO_ERROR;
1206   } else {
1207     /* add fixed length - status(1) */
1208     UINT16_TO_BE_STREAM(p_data, 7);
1209     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
1210     p_pkt->len = (p_data - p_start);
1211     return p_rsp->status;
1212   }
1213 }
1214 
1215 /*******************************************************************************
1216  *
1217  * Function         avrc_bld_search_rsp
1218  *
1219  * Description      This function builds the Search response.
1220  *
1221  *                  This message goes through the Browsing channel
1222  *
1223  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1224  *                  Otherwise, the error code.
1225  *
1226  ******************************************************************************/
avrc_bld_search_rsp(tAVRC_SEARCH_RSP * p_rsp,BT_HDR * p_pkt)1227 static tAVRC_STS avrc_bld_search_rsp(tAVRC_SEARCH_RSP* p_rsp, BT_HDR* p_pkt) {
1228   uint8_t *p_data, *p_start, *p_len;
1229 
1230   log::verbose("");
1231   /* get the existing length, if any, and also the num attributes */
1232   p_start = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1233   p_data = p_len = p_start + 1; /* pdu */
1234 
1235   /* add fixed length - status(1) + uid_counter(2) + num_items(4) */
1236   UINT16_TO_BE_STREAM(p_data, 7);
1237   UINT8_TO_BE_STREAM(p_data, p_rsp->status);
1238   UINT16_TO_BE_STREAM(p_data, p_rsp->uid_counter);
1239   UINT32_TO_BE_STREAM(p_data, p_rsp->num_items);
1240   p_pkt->len = (p_data - p_start);
1241   return AVRC_STS_NO_ERROR;
1242 }
1243 
1244 /*******************************************************************************
1245  *
1246  * Function         avrc_bld_play_item_rsp
1247  *
1248  * Description      This function builds the Play Item response.
1249  *
1250  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1251  *                  Otherwise, the error code.
1252  *
1253  ******************************************************************************/
avrc_bld_play_item_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)1254 static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
1255   log::verbose("");
1256   return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt);
1257 }
1258 
1259 /*******************************************************************************
1260  *
1261  * Function         avrc_bld_add_to_now_playing_rsp
1262  *
1263  * Description      This function builds the Add to Now Playing response.
1264  *
1265  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1266  *                  Otherwise, the error code.
1267  *
1268  ******************************************************************************/
avrc_bld_add_to_now_playing_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)1269 static tAVRC_STS avrc_bld_add_to_now_playing_rsp(tAVRC_RSP* p_rsp, BT_HDR* p_pkt) {
1270   log::verbose("");
1271   return avrc_bld_ctrl_status_rsp(p_rsp, p_pkt);
1272 }
1273 
1274 /*******************************************************************************
1275  *
1276  * Function         avrc_bld_init_rsp_buffer
1277  *
1278  * Description      This function initializes the response buffer based on PDU
1279  *
1280  * Returns          NULL, if no buffer or failure to build the message.
1281  *                  Otherwise, the buffer that contains the initialized message.
1282  *
1283  ******************************************************************************/
avrc_bld_init_rsp_buffer(tAVRC_RESPONSE * p_rsp)1284 static BT_HDR* avrc_bld_init_rsp_buffer(tAVRC_RESPONSE* p_rsp) {
1285   uint16_t offset = 0;
1286   uint16_t chnl = AVCT_DATA_CTRL;
1287   uint8_t opcode = avrc_opcode_from_pdu(p_rsp->pdu);
1288 
1289   log::verbose("pdu={:x}, opcode={:x}/{:x}", p_rsp->pdu, opcode, p_rsp->rsp.opcode);
1290   if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
1291       avrc_is_valid_opcode(p_rsp->rsp.opcode)) {
1292     opcode = p_rsp->rsp.opcode;
1293     log::verbose("opcode={:x}", opcode);
1294   }
1295 
1296   switch (opcode) {
1297     case AVRC_OP_BROWSE:
1298       chnl = AVCT_DATA_BROWSE;
1299       offset = AVCT_BROWSE_OFFSET;
1300       break;
1301 
1302     case AVRC_OP_PASS_THRU:
1303       offset = AVRC_MSG_PASS_THRU_OFFSET;
1304       break;
1305 
1306     case AVRC_OP_VENDOR:
1307       offset = AVRC_MSG_VENDOR_OFFSET;
1308       break;
1309   }
1310 
1311   /* allocate and initialize the buffer */
1312   BT_HDR* p_pkt = (BT_HDR*)osi_calloc(BT_DEFAULT_BUFFER_SIZE);
1313   uint8_t *p_data, *p_start;
1314 
1315   p_pkt->layer_specific = chnl;
1316   p_pkt->event = opcode;
1317   p_pkt->offset = offset;
1318   p_data = (uint8_t*)(p_pkt + 1) + p_pkt->offset;
1319   p_start = p_data;
1320 
1321   /* pass thru - group navigation - has a two byte op_id, so dont do it here */
1322   if (opcode != AVRC_OP_PASS_THRU) {
1323     *p_data++ = p_rsp->pdu;
1324   }
1325 
1326   switch (opcode) {
1327     case AVRC_OP_VENDOR:
1328       /* reserved 0, packet_type 0 */
1329       UINT8_TO_BE_STREAM(p_data, 0);
1330       [[fallthrough]];
1331     case AVRC_OP_BROWSE:
1332       /* add fixed length - 0 */
1333       UINT16_TO_BE_STREAM(p_data, 0);
1334       break;
1335   }
1336 
1337   p_pkt->len = (p_data - p_start);
1338   p_rsp->rsp.opcode = opcode;
1339 
1340   return p_pkt;
1341 }
1342 
1343 /*******************************************************************************
1344  *
1345  * Function         AVRC_BldResponse
1346  *
1347  * Description      This function builds the given AVRCP response to the given
1348  *                  buffer
1349  *
1350  * Returns          AVRC_STS_NO_ERROR, if the response is built successfully
1351  *                  Otherwise, the error code.
1352  *
1353  ******************************************************************************/
AVRC_BldResponse(uint8_t handle,tAVRC_RESPONSE * p_rsp,BT_HDR ** pp_pkt)1354 tAVRC_STS AVRC_BldResponse(uint8_t handle, tAVRC_RESPONSE* p_rsp, BT_HDR** pp_pkt) {
1355   tAVRC_STS status = AVRC_STS_BAD_PARAM;
1356   BT_HDR* p_pkt;
1357   bool alloc = false;
1358   uint8_t* p;
1359   uint16_t peer_mtu;
1360 
1361   if (!p_rsp || !pp_pkt) {
1362     log::verbose("Invalid parameters passed. p_rsp={}, pp_pkt={}", std::format_ptr(p_rsp),
1363                  std::format_ptr(pp_pkt));
1364     return AVRC_STS_BAD_PARAM;
1365   }
1366 
1367   if (*pp_pkt == NULL) {
1368     *pp_pkt = avrc_bld_init_rsp_buffer(p_rsp);
1369     if (*pp_pkt == NULL) {
1370       log::verbose("Failed to initialize response buffer");
1371       return AVRC_STS_INTERNAL_ERR;
1372     }
1373 
1374     if ((*pp_pkt)->layer_specific == AVCT_DATA_BROWSE) {
1375       p = (uint8_t*)((*pp_pkt) + 1);
1376       peer_mtu = AVCT_GetBrowseMtu(handle) - AVCT_HDR_LEN_SINGLE;
1377       UINT16_TO_BE_STREAM(p, peer_mtu);
1378     }
1379 
1380     alloc = true;
1381   }
1382   status = AVRC_STS_NO_ERROR;
1383   p_pkt = *pp_pkt;
1384 
1385   log::verbose("pdu={:x} status={:x}", p_rsp->rsp.pdu, p_rsp->rsp.status);
1386   if (p_rsp->rsp.status != AVRC_STS_NO_ERROR) {
1387     return avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt);
1388   }
1389 
1390   switch (p_rsp->pdu) {
1391     case AVRC_PDU_NEXT_GROUP:
1392     case AVRC_PDU_PREV_GROUP:
1393       status = avrc_bld_group_navigation_rsp(p_rsp->pdu, p_pkt);
1394       break;
1395 
1396     case AVRC_PDU_GET_CAPABILITIES:
1397       status = avrc_bld_get_capability_rsp(&p_rsp->get_caps, p_pkt);
1398       break;
1399 
1400     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1401       status = avrc_bld_list_app_settings_attr_rsp(&p_rsp->list_app_attr, p_pkt);
1402       break;
1403 
1404     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1405       status = avrc_bld_list_app_settings_values_rsp(&p_rsp->list_app_values, p_pkt);
1406       break;
1407 
1408     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1409       status = avrc_bld_get_cur_app_setting_value_rsp(&p_rsp->get_cur_app_val, p_pkt);
1410       break;
1411 
1412     case AVRC_PDU_SET_PLAYER_APP_VALUE:
1413       status = avrc_bld_set_app_setting_value_rsp(&p_rsp->set_app_val, p_pkt);
1414       break;
1415 
1416     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1417       status = avrc_bld_get_app_setting_attr_text_rsp(&p_rsp->get_app_attr_txt, p_pkt);
1418       break;
1419 
1420     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1421       status = avrc_bld_get_app_setting_value_text_rsp(&p_rsp->get_app_val_txt, p_pkt);
1422       break;
1423 
1424     case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1425       status = avrc_bld_inform_charset_rsp(&p_rsp->inform_charset, p_pkt);
1426       break;
1427 
1428     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
1429       status = avrc_bld_inform_battery_status_rsp(&p_rsp->inform_battery_status, p_pkt);
1430       break;
1431 
1432     case AVRC_PDU_GET_ELEMENT_ATTR:
1433       status = avrc_bld_get_elem_attrs_rsp(&p_rsp->get_attrs, p_pkt);
1434       break;
1435 
1436     case AVRC_PDU_GET_PLAY_STATUS:
1437       status = avrc_bld_get_play_status_rsp(&p_rsp->get_play_status, p_pkt);
1438       break;
1439 
1440     case AVRC_PDU_REGISTER_NOTIFICATION:
1441       status = avrc_bld_notify_rsp(&p_rsp->reg_notif, p_pkt);
1442       break;
1443 
1444     case AVRC_PDU_REQUEST_CONTINUATION_RSP:
1445       status = avrc_bld_next_rsp(&p_rsp->continu, p_pkt);
1446       break;
1447 
1448     case AVRC_PDU_ABORT_CONTINUATION_RSP:
1449       status = avrc_bld_next_rsp(&p_rsp->abort, p_pkt);
1450       break;
1451 
1452     case AVRC_PDU_SET_ADDRESSED_PLAYER:
1453       status = avrc_bld_set_addr_player_rsp(&p_rsp->addr_player, p_pkt);
1454       break;
1455 
1456     case AVRC_PDU_PLAY_ITEM:
1457       status = avrc_bld_play_item_rsp(&p_rsp->play_item, p_pkt);
1458       break;
1459 
1460     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1461       status = avrc_bld_set_absolute_volume_rsp(p_rsp->volume.volume, p_pkt);
1462       break;
1463 
1464     case AVRC_PDU_ADD_TO_NOW_PLAYING:
1465       status = avrc_bld_add_to_now_playing_rsp(&p_rsp->add_to_play, p_pkt);
1466       break;
1467 
1468     case AVRC_PDU_SET_BROWSED_PLAYER:
1469       status = avrc_bld_set_browsed_player_rsp(&p_rsp->br_player, p_pkt);
1470       break;
1471 
1472     case AVRC_PDU_GET_FOLDER_ITEMS:
1473       status = avrc_bld_get_folder_items_rsp(&p_rsp->get_items, p_pkt);
1474       break;
1475 
1476     case AVRC_PDU_CHANGE_PATH:
1477       status = avrc_bld_change_path_rsp(&p_rsp->chg_path, p_pkt);
1478       break;
1479 
1480     case AVRC_PDU_GET_ITEM_ATTRIBUTES:
1481       status = avrc_bld_get_item_attrs_rsp(&p_rsp->get_attrs, p_pkt);
1482       break;
1483 
1484     case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS:
1485       status = avrc_bld_get_num_of_item_rsp(&p_rsp->get_num_of_items, p_pkt);
1486       break;
1487 
1488     case AVRC_PDU_SEARCH:
1489       status = avrc_bld_search_rsp(&p_rsp->search, p_pkt);
1490       break;
1491   }
1492 
1493   if (alloc && (status != AVRC_STS_NO_ERROR)) {
1494     osi_free(p_pkt);
1495     *pp_pkt = NULL;
1496   }
1497   log::verbose("returning {}", status);
1498   return status;
1499 }
1500