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