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