1 /******************************************************************************
2  *
3  *  Copyright (C) 2003-2013 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 #include <string.h>
19 
20 #include "bt_common.h"
21 #include "avrc_api.h"
22 #include "avrc_defs.h"
23 #include "avrc_int.h"
24 #include "bt_utils.h"
25 
26 /*****************************************************************************
27 **  Global data
28 *****************************************************************************/
29 #if (AVRC_METADATA_INCLUDED == TRUE)
30 
31 /*******************************************************************************
32 **
33 ** Function         avrc_bld_get_capability_rsp
34 **
35 ** Description      This function builds the Get Capability response.
36 **
37 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
38 **                  Otherwise, the error code.
39 **
40 *******************************************************************************/
avrc_bld_get_capability_rsp(tAVRC_GET_CAPS_RSP * p_rsp,BT_HDR * p_pkt)41 static tAVRC_STS avrc_bld_get_capability_rsp (tAVRC_GET_CAPS_RSP *p_rsp, BT_HDR *p_pkt)
42 {
43     UINT8   *p_data, *p_start, *p_len, *p_count;
44     UINT16  len = 0;
45     UINT8   xx;
46     UINT32  *p_company_id;
47     UINT8   *p_event_id;
48     tAVRC_STS status = AVRC_STS_NO_ERROR;
49 
50     if (!(AVRC_IS_VALID_CAP_ID(p_rsp->capability_id)))
51     {
52         AVRC_TRACE_ERROR("%s bad parameter. p_rsp: %x", __func__, p_rsp);
53         status = AVRC_STS_BAD_PARAM;
54         return status;
55     }
56 
57     AVRC_TRACE_API("%s", __func__);
58     /* get the existing length, if any, and also the num attributes */
59     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
60     p_data = p_len = p_start + 2; /* pdu + rsvd */
61 
62     BE_STREAM_TO_UINT16(len, p_data);
63     UINT8_TO_BE_STREAM(p_data, p_rsp->capability_id);
64     p_count = p_data;
65 
66     if (len == 0)
67     {
68         *p_count = p_rsp->count;
69         p_data++;
70         len = 2; /* move past the capability_id and count */
71     }
72     else
73     {
74         p_data = p_start + p_pkt->len;
75         *p_count += p_rsp->count;
76     }
77 
78     if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID)
79     {
80         p_company_id = p_rsp->param.company_id;
81         for (xx=0; xx< p_rsp->count; xx++)
82         {
83             UINT24_TO_BE_STREAM(p_data, p_company_id[xx]);
84         }
85         len += p_rsp->count * 3;
86     }
87     else
88     {
89         p_event_id = p_rsp->param.event_id;
90         *p_count = 0;
91         for (xx=0; xx< p_rsp->count; xx++)
92         {
93             if (AVRC_IS_VALID_EVENT_ID(p_event_id[xx]))
94             {
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 (tAVRC_LIST_APP_ATTR_RSP *p_rsp, BT_HDR *p_pkt)
120 {
121     UINT8   *p_data, *p_start, *p_len, *p_num;
122     UINT16  len = 0;
123     UINT8   xx;
124 
125     AVRC_TRACE_API("%s", __func__);
126     /* get the existing length, if any, and also the num attributes */
127     p_start = (UINT8 *)(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     {
134         /* first time initialize the attribute count */
135         *p_num = 0;
136         p_data++;
137     }
138     else
139     {
140         p_data = p_start + p_pkt->len;
141     }
142 
143     for (xx=0; xx<p_rsp->num_attr; xx++)
144     {
145         if(AVRC_IsValidPlayerAttr(p_rsp->attrs[xx]))
146         {
147             (*p_num)++;
148             UINT8_TO_BE_STREAM(p_data, p_rsp->attrs[xx]);
149         }
150     }
151 
152     len = *p_num + 1;
153     UINT16_TO_BE_STREAM(p_len, len);
154     p_pkt->len = (p_data - p_start);
155 
156     return AVRC_STS_NO_ERROR;
157 }
158 
159 /*******************************************************************************
160 **
161 ** Function         avrc_bld_list_app_settings_values_rsp
162 **
163 ** Description      This function builds the List Application Setting Values
164 **                  response.
165 **
166 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
167 **                  Otherwise, the error code.
168 **
169 *******************************************************************************/
avrc_bld_list_app_settings_values_rsp(tAVRC_LIST_APP_VALUES_RSP * p_rsp,BT_HDR * p_pkt)170 static tAVRC_STS avrc_bld_list_app_settings_values_rsp (tAVRC_LIST_APP_VALUES_RSP *p_rsp,
171     BT_HDR *p_pkt)
172 {
173     UINT8   *p_data, *p_start, *p_len, *p_num;
174     UINT8   xx;
175     UINT16  len;
176 
177     AVRC_TRACE_API("%s", __func__);
178 
179     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
180     p_data = p_len = p_start + 2; /* pdu + rsvd */
181 
182     /* get the existing length, if any, and also the num attributes */
183     BE_STREAM_TO_UINT16(len, p_data);
184     p_num = p_data;
185     /* first time initialize the attribute count */
186     if (len == 0)
187     {
188         *p_num = p_rsp->num_val;
189         p_data++;
190     }
191     else
192     {
193         p_data = p_start + p_pkt->len;
194         *p_num += p_rsp->num_val;
195     }
196 
197 
198     for (xx=0; xx<p_rsp->num_val; xx++)
199     {
200         UINT8_TO_BE_STREAM(p_data, p_rsp->vals[xx]);
201     }
202 
203     len = *p_num + 1;
204     UINT16_TO_BE_STREAM(p_len, len);
205     p_pkt->len = (p_data - p_start);
206     return AVRC_STS_NO_ERROR;
207 }
208 
209 /*******************************************************************************
210 **
211 ** Function         avrc_bld_get_cur_app_setting_value_rsp
212 **
213 ** Description      This function builds the Get Current Application Setting Value
214 **                  response.
215 **
216 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
217 **                  Otherwise, the error code.
218 **
219 *******************************************************************************/
avrc_bld_get_cur_app_setting_value_rsp(tAVRC_GET_CUR_APP_VALUE_RSP * p_rsp,BT_HDR * p_pkt)220 static tAVRC_STS avrc_bld_get_cur_app_setting_value_rsp (tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp,
221     BT_HDR *p_pkt)
222 {
223     UINT8   *p_data, *p_start, *p_len, *p_count;
224     UINT16  len;
225     UINT8   xx;
226 
227     if (!p_rsp->p_vals)
228     {
229         AVRC_TRACE_ERROR("%s NULL parameter", __func__);
230         return AVRC_STS_BAD_PARAM;
231     }
232 
233     AVRC_TRACE_API("%s", __func__);
234     /* get the existing length, if any, and also the num attributes */
235     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
236     p_data = p_len = p_start + 2; /* pdu + rsvd */
237 
238     BE_STREAM_TO_UINT16(len, p_data);
239     p_count = p_data;
240     if (len == 0)
241     {
242         /* first time initialize the attribute count */
243         *p_count = 0;
244         p_data++;
245     }
246     else
247     {
248         p_data = p_start + p_pkt->len;
249     }
250 
251     for (xx=0; xx<p_rsp->num_val; xx++)
252     {
253         if (avrc_is_valid_player_attrib_value(p_rsp->p_vals[xx].attr_id, p_rsp->p_vals[xx].attr_val))
254         {
255             (*p_count)++;
256             UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_id);
257             UINT8_TO_BE_STREAM(p_data, p_rsp->p_vals[xx].attr_val);
258         }
259     }
260     len = ((*p_count) << 1) + 1;
261     UINT16_TO_BE_STREAM(p_len, len);
262     p_pkt->len = (p_data - p_start);
263 
264     return AVRC_STS_NO_ERROR;
265 }
266 
267 /*******************************************************************************
268 **
269 ** Function         avrc_bld_set_app_setting_value_rsp
270 **
271 ** Description      This function builds the Set Application Setting Value
272 **                  response.
273 **
274 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
275 **                  Otherwise, the error code.
276 **
277 *******************************************************************************/
avrc_bld_set_app_setting_value_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)278 static tAVRC_STS avrc_bld_set_app_setting_value_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
279 {
280     UNUSED(p_rsp);
281     UNUSED(p_pkt);
282 
283     /* nothing to be added. */
284     AVRC_TRACE_API("%s", __func__);
285     return AVRC_STS_NO_ERROR;
286 }
287 
288 /*******************************************************************************
289 **
290 ** Function         avrc_bld_app_setting_text_rsp
291 **
292 ** Description      This function builds the Get Application Settings Attribute Text
293 **                  or Get Application Settings Value Text response.
294 **
295 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
296 **                  Otherwise, the error code.
297 **
298 *******************************************************************************/
avrc_bld_app_setting_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)299 static tAVRC_STS avrc_bld_app_setting_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp, BT_HDR *p_pkt)
300 {
301     UINT8   *p_data, *p_start, *p_len, *p_count;
302     UINT16  len, len_left;
303     UINT8   xx;
304     tAVRC_STS   sts = AVRC_STS_NO_ERROR;
305     UINT8       num_added = 0;
306 
307     if (!p_rsp->p_attrs)
308     {
309         AVRC_TRACE_ERROR("%s NULL parameter", __func__);
310         return AVRC_STS_BAD_PARAM;
311     }
312     /* get the existing length, if any, and also the num attributes */
313     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
314     p_data = p_len = p_start + 2; /* pdu + rsvd */
315 
316     /*
317      * NOTE: The buffer is allocated within avrc_bld_init_rsp_buffer(), and is
318      * always of size BT_DEFAULT_BUFFER_SIZE.
319      */
320     len_left = BT_DEFAULT_BUFFER_SIZE - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
321 
322     BE_STREAM_TO_UINT16(len, p_data);
323     p_count = p_data;
324 
325     if (len == 0)
326     {
327         *p_count = 0;
328         p_data++;
329     }
330     else
331     {
332         p_data = p_start + p_pkt->len;
333     }
334 
335     for (xx=0; xx<p_rsp->num_attr; xx++)
336     {
337         if  (len_left < (p_rsp->p_attrs[xx].str_len + 4))
338         {
339             AVRC_TRACE_ERROR("%s out of room (str_len:%d, left:%d)",
340                              __func__, xx, p_rsp->p_attrs[xx].str_len, len_left);
341             p_rsp->num_attr = num_added;
342             sts = AVRC_STS_INTERNAL_ERR;
343             break;
344         }
345         if ( !p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str )
346         {
347             AVRC_TRACE_ERROR("%s NULL attr text[%d]", __func__, xx);
348             continue;
349         }
350         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
351         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
352         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
353         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str, p_rsp->p_attrs[xx].str_len);
354         (*p_count)++;
355         num_added++;
356     }
357     len = p_data - p_count;
358     UINT16_TO_BE_STREAM(p_len, len);
359     p_pkt->len = (p_data - p_start);
360 
361     return sts;
362 }
363 
364 /*******************************************************************************
365 **
366 ** Function         avrc_bld_get_app_setting_attr_text_rsp
367 **
368 ** Description      This function builds the Get Application Setting Attribute Text
369 **                  response.
370 **
371 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
372 **                  Otherwise, the error code.
373 **
374 *******************************************************************************/
avrc_bld_get_app_setting_attr_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)375 static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
376     BT_HDR *p_pkt)
377 {
378     AVRC_TRACE_API("%s", __func__);
379     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
380 }
381 
382 /*******************************************************************************
383 **
384 ** Function         avrc_bld_get_app_setting_value_text_rsp
385 **
386 ** Description      This function builds the Get Application Setting Value Text
387 **                  response.
388 **
389 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
390 **                  Otherwise, the error code.
391 **
392 *******************************************************************************/
avrc_bld_get_app_setting_value_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)393 static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
394     BT_HDR *p_pkt)
395 {
396     AVRC_TRACE_API("%s", __func__);
397     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
398 }
399 
400 /*******************************************************************************
401 **
402 ** Function         avrc_bld_inform_charset_rsp
403 **
404 ** Description      This function builds the Inform Displayable Character Set
405 **                  response.
406 **
407 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
408 **                  Otherwise, the error code.
409 **
410 *******************************************************************************/
avrc_bld_inform_charset_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)411 static tAVRC_STS avrc_bld_inform_charset_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
412 {
413     UNUSED(p_rsp);
414     UNUSED(p_pkt);
415 
416     /* nothing to be added. */
417     AVRC_TRACE_API("%s", __func__);
418     return AVRC_STS_NO_ERROR;
419 }
420 
421 /*******************************************************************************
422 **
423 ** Function         avrc_bld_inform_battery_status_rsp
424 **
425 ** Description      This function builds the Inform Battery Status
426 **                  response.
427 **
428 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
429 **                  Otherwise, the error code.
430 **
431 *******************************************************************************/
avrc_bld_inform_battery_status_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)432 static tAVRC_STS avrc_bld_inform_battery_status_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
433 {
434     UNUSED(p_rsp);
435     UNUSED(p_pkt);
436 
437     /* nothing to be added. */
438     AVRC_TRACE_API("%s", __func__);
439     return AVRC_STS_NO_ERROR;
440 }
441 
442 /*******************************************************************************
443 **
444 ** Function         avrc_bld_get_elem_attrs_rsp
445 **
446 ** Description      This function builds the Get Element Attributes
447 **                  response.
448 **
449 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
450 **                  Otherwise, the error code.
451 **
452 *******************************************************************************/
avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ELEM_ATTRS_RSP * p_rsp,BT_HDR * p_pkt)453 static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, BT_HDR *p_pkt)
454 {
455     UINT8   *p_data, *p_start, *p_len, *p_count;
456     UINT16  len;
457     UINT8   xx;
458 
459     AVRC_TRACE_API("%s", __func__);
460     if (!p_rsp->p_attrs)
461     {
462         AVRC_TRACE_ERROR("%s NULL parameter", __func__);
463         return AVRC_STS_BAD_PARAM;
464     }
465 
466     /* get the existing length, if any, and also the num attributes */
467     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
468     p_data = p_len = p_start + 2; /* pdu + rsvd */
469 
470     BE_STREAM_TO_UINT16(len, p_data);
471     p_count = p_data;
472 
473     if (len == 0)
474     {
475         *p_count = 0;
476         p_data++;
477     }
478     else
479     {
480         p_data = p_start + p_pkt->len;
481     }
482 
483     for (xx=0; xx<p_rsp->num_attr; xx++)
484     {
485         if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_rsp->p_attrs[xx].attr_id))
486         {
487             AVRC_TRACE_ERROR("%s invalid attr id[%d]: %d",
488                              __func__, xx, p_rsp->p_attrs[xx].attr_id);
489             continue;
490         }
491         if ( !p_rsp->p_attrs[xx].name.p_str )
492         {
493             p_rsp->p_attrs[xx].name.str_len = 0;
494         }
495         UINT32_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
496         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.charset_id);
497         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.str_len);
498         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, p_rsp->p_attrs[xx].name.str_len);
499         (*p_count)++;
500     }
501     len = p_data - p_count;
502     UINT16_TO_BE_STREAM(p_len, len);
503     p_pkt->len = (p_data - p_start);
504     return AVRC_STS_NO_ERROR;
505 }
506 
507 /*******************************************************************************
508 **
509 ** Function         avrc_bld_get_play_status_rsp
510 **
511 ** Description      This function builds the Get Play Status
512 **                  response.
513 **
514 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
515 **                  Otherwise, the error code.
516 **
517 *******************************************************************************/
avrc_bld_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP * p_rsp,BT_HDR * p_pkt)518 static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp, BT_HDR *p_pkt)
519 {
520     UINT8   *p_data, *p_start;
521 
522     AVRC_TRACE_API("avrc_bld_get_play_status_rsp");
523     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
524     p_data = p_start + 2;
525 
526     /* add fixed lenth - song len(4) + song position(4) + status(1) */
527     UINT16_TO_BE_STREAM(p_data, 9);
528     UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
529     UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
530     UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
531     p_pkt->len = (p_data - p_start);
532 
533     return AVRC_STS_NO_ERROR;
534 }
535 
536 /*******************************************************************************
537 **
538 ** Function         avrc_bld_notify_rsp
539 **
540 ** Description      This function builds the Notification response.
541 **
542 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
543 **                  Otherwise, the error code.
544 **
545 *******************************************************************************/
avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP * p_rsp,BT_HDR * p_pkt)546 static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
547 {
548     UINT8   *p_data, *p_start;
549     UINT8   *p_len;
550     UINT16  len = 0;
551     UINT8   xx;
552     tAVRC_STS status = AVRC_STS_NO_ERROR;
553 
554     AVRC_TRACE_API("%s event_id %d", __func__, p_rsp->event_id);
555 
556     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
557     p_data = p_len = p_start + 2; /* pdu + rsvd */
558     p_data += 2;
559 
560     UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
561     switch (p_rsp->event_id)
562     {
563     case AVRC_EVT_PLAY_STATUS_CHANGE:       /* 0x01 */
564         /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always TRUE */
565         if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
566             (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR) )
567         {
568             UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
569             len = 2;
570         }
571         else
572         {
573             AVRC_TRACE_ERROR("%s bad play state", __func__);
574             status = AVRC_STS_BAD_PARAM;
575         }
576         break;
577 
578     case AVRC_EVT_TRACK_CHANGE:             /* 0x02 */
579         ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
580         len = (UINT8)(AVRC_UID_SIZE + 1);
581         break;
582 
583     case AVRC_EVT_TRACK_REACHED_END:        /* 0x03 */
584     case AVRC_EVT_TRACK_REACHED_START:      /* 0x04 */
585         len = 1;
586         break;
587 
588     case AVRC_EVT_PLAY_POS_CHANGED:         /* 0x05 */
589         UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
590         len = 5;
591         break;
592 
593     case AVRC_EVT_BATTERY_STATUS_CHANGE:    /* 0x06 */
594         if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status))
595         {
596             UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
597             len = 2;
598         }
599         else
600         {
601             AVRC_TRACE_ERROR("%s bad battery status", __func__);
602             status = AVRC_STS_BAD_PARAM;
603         }
604         break;
605 
606     case AVRC_EVT_SYSTEM_STATUS_CHANGE:     /* 0x07 */
607         if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status))
608         {
609             UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
610             len = 2;
611         }
612         else
613         {
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         {
625             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
626             len = 2;
627             for (xx=0; xx<p_rsp->param.player_setting.num_attr; xx++)
628             {
629                 if (avrc_is_valid_player_attrib_value(p_rsp->param.player_setting.attr_id[xx],
630                     p_rsp->param.player_setting.attr_value[xx]))
631                 {
632                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
633                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
634                 }
635                 else
636                 {
637                     AVRC_TRACE_ERROR("%s bad player app seeting attribute or value", __func__);
638                     status = AVRC_STS_BAD_PARAM;
639                     break;
640                 }
641                 len += 2;
642             }
643         }
644         else
645             status = AVRC_STS_BAD_PARAM;
646         break;
647 
648     case AVRC_EVT_VOLUME_CHANGE:
649         len = 2;
650         UINT8_TO_BE_STREAM(p_data, (AVRC_MAX_VOLUME & p_rsp->param.volume));
651         break;
652 
653     default:
654         status = AVRC_STS_BAD_PARAM;
655         AVRC_TRACE_ERROR("%s unknown event_id", __func__);
656     }
657 
658     UINT16_TO_BE_STREAM(p_len, len);
659     p_pkt->len = (p_data - p_start);
660 
661     return status;
662 }
663 
664 /*******************************************************************************
665 **
666 ** Function         avrc_bld_next_rsp
667 **
668 ** Description      This function builds the Request Continue or Abort
669 **                  response.
670 **
671 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
672 **                  Otherwise, the error code.
673 **
674 *******************************************************************************/
avrc_bld_next_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)675 static tAVRC_STS avrc_bld_next_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
676 {
677     UNUSED(p_rsp);
678     UNUSED(p_pkt);
679 
680     /* nothing to be added. */
681     AVRC_TRACE_API("%s", __func__);
682     return AVRC_STS_NO_ERROR;
683 }
684 
685 /*****************************************************************************
686 **
687 ** Function      avrc_bld_set_address_player_rsp
688 **
689 ** Description   This function builds the set address player response
690 **
691 ** Returns       AVRC_STS_NO_ERROR
692 **
693 ******************************************************************************/
avrc_bld_set_address_player_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)694 static tAVRC_STS avrc_bld_set_address_player_rsp(tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
695 {
696     AVRC_TRACE_API("%s", __func__);
697     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
698     /* To calculate length */
699     UINT8 *p_data = p_start + 2;
700     /* add fixed lenth status(1) */
701     UINT16_TO_BE_STREAM(p_data, 1);
702     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
703     p_pkt->len = (p_data - p_start);
704     return AVRC_STS_NO_ERROR;
705 }
706 
707 /*****************************************************************************
708 **
709 ** Function      avrc_bld_play_item_rsp
710 **
711 ** Description   This function builds the play item response
712 **
713 ** Returns       AVRC_STS_NO_ERROR, if the response is build successfully
714 **
715 ******************************************************************************/
avrc_bld_play_item_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)716 static tAVRC_STS avrc_bld_play_item_rsp(tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
717 {
718     AVRC_TRACE_API("%s", __func__);
719     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
720     /* To calculate length */
721     UINT8 *p_data = p_start + 2;
722     /* add fixed lenth status(1) */
723     UINT16_TO_BE_STREAM(p_data, 1);
724     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
725     p_pkt->len = (p_data - p_start);
726     return AVRC_STS_NO_ERROR;
727 }
728 
729 /*****************************************************************************
730 **
731 ** Function      avrc_bld_set_absolute_volume_rsp
732 **
733 ** Description   This function builds the set absolute volume response
734 **
735 ** Returns       AVRC_STS_NO_ERROR, if the response is build successfully
736 **
737 ******************************************************************************/
avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol,BT_HDR * p_pkt)738 static tAVRC_STS avrc_bld_set_absolute_volume_rsp(uint8_t abs_vol, BT_HDR *p_pkt)
739 {
740     AVRC_TRACE_API("%s", __func__);
741     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
742     /* To calculate length */
743     UINT8 *p_data = p_start + 2;
744     /* add fixed lenth status(1) */
745     UINT16_TO_BE_STREAM(p_data, 1);
746     UINT8_TO_BE_STREAM(p_data, abs_vol);
747     p_pkt->len = (p_data - p_start);
748     return AVRC_STS_NO_ERROR;
749 }
750 
751 /*******************************************************************************
752 **
753 ** Function         avrc_bld_group_navigation_rsp
754 **
755 ** Description      This function builds the Group Navigation
756 **                  response.
757 **
758 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
759 **                  Otherwise, the error code.
760 **
761 *******************************************************************************/
avrc_bld_group_navigation_rsp(UINT16 navi_id,BT_HDR * p_pkt)762 tAVRC_STS avrc_bld_group_navigation_rsp (UINT16 navi_id, BT_HDR *p_pkt)
763 {
764     if (!AVRC_IS_VALID_GROUP(navi_id))
765     {
766         AVRC_TRACE_ERROR("%s bad navigation op id: %d", __func__, navi_id);
767         return AVRC_STS_BAD_PARAM;
768     }
769     AVRC_TRACE_API("%s", __func__);
770     UINT8 *p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
771     UINT16_TO_BE_STREAM(p_data, navi_id);
772     p_pkt->len = 2;
773     return AVRC_STS_NO_ERROR;
774 }
775 
776 /*******************************************************************************
777 **
778 ** Function         avrc_bld_rejected_rsp
779 **
780 ** Description      This function builds the General Response response.
781 **
782 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
783 **
784 *******************************************************************************/
avrc_bld_rejected_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)785 static tAVRC_STS avrc_bld_rejected_rsp( tAVRC_RSP *p_rsp, BT_HDR *p_pkt )
786 {
787     AVRC_TRACE_API("%s: status=%d, pdu:x%x", __func__, p_rsp->status, p_rsp->pdu);
788 
789     UINT8 *p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
790     UINT8 *p_data = p_start + 2;
791     AVRC_TRACE_DEBUG("%s pdu:x%x", __func__, *p_start);
792 
793     UINT16_TO_BE_STREAM(p_data, 1);
794     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
795     p_pkt->len = p_data - p_start;
796 
797     return AVRC_STS_NO_ERROR;
798 }
799 
800 /*******************************************************************************
801 **
802 ** Function         avrc_bld_init_rsp_buffer
803 **
804 ** Description      This function initializes the response buffer based on PDU
805 **
806 ** Returns          NULL, if no GKI buffer or failure to build the message.
807 **                  Otherwise, the GKI buffer that contains the initialized message.
808 **
809 *******************************************************************************/
avrc_bld_init_rsp_buffer(tAVRC_RESPONSE * p_rsp)810 static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
811 {
812     UINT16 offset = AVRC_MSG_PASS_THRU_OFFSET;
813     UINT16 chnl = AVCT_DATA_CTRL;
814     UINT8  opcode = avrc_opcode_from_pdu(p_rsp->pdu);
815 
816     AVRC_TRACE_API("%s: pdu=%x, opcode=%x/%x", __func__, p_rsp->pdu, opcode, p_rsp->rsp.opcode);
817     if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
818         avrc_is_valid_opcode(p_rsp->rsp.opcode))
819     {
820         opcode = p_rsp->rsp.opcode;
821         AVRC_TRACE_API("%s opcode=%x", __func__, opcode);
822     }
823 
824     switch (opcode)
825     {
826     case AVRC_OP_PASS_THRU:
827         offset = AVRC_MSG_PASS_THRU_OFFSET;
828         break;
829 
830     case AVRC_OP_VENDOR:
831         offset = AVRC_MSG_VENDOR_OFFSET;
832         break;
833     }
834 
835     /* allocate and initialize the buffer */
836     BT_HDR *p_pkt = (BT_HDR *)osi_malloc(BT_DEFAULT_BUFFER_SIZE);
837     UINT8 *p_data, *p_start;
838 
839     p_pkt->layer_specific = chnl;
840     p_pkt->event    = opcode;
841     p_pkt->offset   = offset;
842     p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
843     p_start = p_data;
844 
845     /* pass thru - group navigation - has a two byte op_id, so dont do it here */
846     if (opcode != AVRC_OP_PASS_THRU)
847         *p_data++ = p_rsp->pdu;
848 
849     switch (opcode) {
850     case AVRC_OP_VENDOR:
851         /* reserved 0, packet_type 0 */
852         UINT8_TO_BE_STREAM(p_data, 0);
853         /* continue to the next "case to add length */
854         /* add fixed lenth - 0 */
855         UINT16_TO_BE_STREAM(p_data, 0);
856         break;
857     }
858 
859     p_pkt->len = (p_data - p_start);
860     p_rsp->rsp.opcode = opcode;
861 
862     return p_pkt;
863 }
864 
865 /*******************************************************************************
866 **
867 ** Function         AVRC_BldResponse
868 **
869 ** Description      This function builds the given AVRCP response to the given
870 **                  GKI buffer
871 **
872 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
873 **                  Otherwise, the error code.
874 **
875 *******************************************************************************/
AVRC_BldResponse(UINT8 handle,tAVRC_RESPONSE * p_rsp,BT_HDR ** pp_pkt)876 tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt)
877 {
878     tAVRC_STS status = AVRC_STS_BAD_PARAM;
879     BT_HDR *p_pkt;
880     BOOLEAN alloc = FALSE;
881     UNUSED(handle);
882 
883     if (!p_rsp || !pp_pkt)
884     {
885         AVRC_TRACE_API("%s Invalid parameters passed. p_rsp=%p, pp_pkt=%p",
886                        __func__, p_rsp, pp_pkt);
887         return AVRC_STS_BAD_PARAM;
888     }
889 
890     if (*pp_pkt == NULL)
891     {
892         if ((*pp_pkt = avrc_bld_init_rsp_buffer(p_rsp)) == NULL)
893         {
894             AVRC_TRACE_API("%s Failed to initialize response buffer", __func__);
895             return AVRC_STS_INTERNAL_ERR;
896         }
897         alloc = TRUE;
898     }
899     status = AVRC_STS_NO_ERROR;
900     p_pkt = *pp_pkt;
901 
902     AVRC_TRACE_API("%s pdu=%x status=%x", __func__, p_rsp->rsp.pdu, p_rsp->rsp.status);
903     if (p_rsp->rsp.status != AVRC_STS_NO_ERROR)
904     {
905         return( avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt) );
906     }
907 
908     switch (p_rsp->pdu)
909     {
910     case AVRC_PDU_NEXT_GROUP:
911     case AVRC_PDU_PREV_GROUP:
912         status = avrc_bld_group_navigation_rsp(p_rsp->pdu, p_pkt);
913         break;
914 
915     case AVRC_PDU_GET_CAPABILITIES:
916         status = avrc_bld_get_capability_rsp(&p_rsp->get_caps, p_pkt);
917         break;
918 
919     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
920         status = avrc_bld_list_app_settings_attr_rsp(&p_rsp->list_app_attr, p_pkt);
921         break;
922 
923     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
924         status = avrc_bld_list_app_settings_values_rsp(&p_rsp->list_app_values, p_pkt);
925         break;
926 
927     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
928         status = avrc_bld_get_cur_app_setting_value_rsp(&p_rsp->get_cur_app_val, p_pkt);
929         break;
930 
931     case AVRC_PDU_SET_PLAYER_APP_VALUE:
932         status = avrc_bld_set_app_setting_value_rsp(&p_rsp->set_app_val, p_pkt);
933         break;
934 
935     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
936         status = avrc_bld_get_app_setting_attr_text_rsp(&p_rsp->get_app_attr_txt, p_pkt);
937         break;
938 
939     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
940         status = avrc_bld_get_app_setting_value_text_rsp(&p_rsp->get_app_val_txt, p_pkt);
941         break;
942 
943     case AVRC_PDU_INFORM_DISPLAY_CHARSET:
944         status = avrc_bld_inform_charset_rsp(&p_rsp->inform_charset, p_pkt);
945         break;
946 
947     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
948         status = avrc_bld_inform_battery_status_rsp(&p_rsp->inform_battery_status, p_pkt);
949         break;
950 
951     case AVRC_PDU_GET_ELEMENT_ATTR:
952         status = avrc_bld_get_elem_attrs_rsp(&p_rsp->get_elem_attrs, p_pkt);
953         break;
954 
955     case AVRC_PDU_GET_PLAY_STATUS:
956         status = avrc_bld_get_play_status_rsp(&p_rsp->get_play_status, p_pkt);
957         break;
958 
959     case AVRC_PDU_REGISTER_NOTIFICATION:
960         status = avrc_bld_notify_rsp(&p_rsp->reg_notif, p_pkt);
961         break;
962 
963     case AVRC_PDU_REQUEST_CONTINUATION_RSP:     /*        0x40 */
964         status = avrc_bld_next_rsp(&p_rsp->continu, p_pkt);
965         break;
966 
967     case AVRC_PDU_ABORT_CONTINUATION_RSP:       /*          0x41 */
968         status = avrc_bld_next_rsp(&p_rsp->abort, p_pkt);
969         break;
970 
971     case AVRC_PDU_SET_ADDRESSED_PLAYER: /*PDU 0x60*/
972         status = avrc_bld_set_address_player_rsp(&p_rsp->addr_player, p_pkt);
973         break;
974 
975     case AVRC_PDU_PLAY_ITEM:
976         status = avrc_bld_play_item_rsp(&p_rsp->play_item, p_pkt);
977         break;
978 
979     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
980         status = avrc_bld_set_absolute_volume_rsp(p_rsp->volume.volume, p_pkt);
981         break;
982     }
983 
984     if (alloc && (status != AVRC_STS_NO_ERROR) )
985     {
986         osi_free(p_pkt);
987         *pp_pkt = NULL;
988     }
989     AVRC_TRACE_API("%s returning %d", __func__, status);
990     return status;
991 }
992 
993 #endif /* (AVRC_METADATA_INCLUDED == TRUE)*/
994 
995