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