• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gki.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("avrc_bld_get_capability_rsp bad parameter. p_rsp: %x", p_rsp);
53         status = AVRC_STS_BAD_PARAM;
54         return status;
55     }
56 
57     AVRC_TRACE_API("avrc_bld_get_capability_rsp");
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("avrc_bld_list_app_settings_attr_rsp");
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("avrc_bld_list_app_settings_values_rsp");
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("avrc_bld_get_cur_app_setting_value_rsp NULL parameter");
230         return AVRC_STS_BAD_PARAM;
231     }
232 
233     AVRC_TRACE_API("avrc_bld_get_cur_app_setting_value_rsp");
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("avrc_bld_set_app_setting_value_rsp");
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("avrc_bld_app_setting_text_rsp NULL parameter");
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     len_left = GKI_get_buf_size(p_pkt) - BT_HDR_SIZE - p_pkt->offset - p_pkt->len;
316 
317     BE_STREAM_TO_UINT16(len, p_data);
318     p_count = p_data;
319 
320     if (len == 0)
321     {
322         *p_count = 0;
323         p_data++;
324     }
325     else
326     {
327         p_data = p_start + p_pkt->len;
328     }
329 
330     for (xx=0; xx<p_rsp->num_attr; xx++)
331     {
332         if  (len_left < (p_rsp->p_attrs[xx].str_len + 4))
333         {
334             AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp out of room (str_len:%d, left:%d)",
335                 xx, p_rsp->p_attrs[xx].str_len, len_left);
336             p_rsp->num_attr = num_added;
337             sts = AVRC_STS_INTERNAL_ERR;
338             break;
339         }
340         if ( !p_rsp->p_attrs[xx].str_len || !p_rsp->p_attrs[xx].p_str )
341         {
342             AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp NULL attr text[%d]", xx);
343             continue;
344         }
345         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
346         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].charset_id);
347         UINT8_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].str_len);
348         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].p_str, p_rsp->p_attrs[xx].str_len);
349         (*p_count)++;
350         num_added++;
351     }
352     len = p_data - p_count;
353     UINT16_TO_BE_STREAM(p_len, len);
354     p_pkt->len = (p_data - p_start);
355 
356     return sts;
357 }
358 
359 /*******************************************************************************
360 **
361 ** Function         avrc_bld_get_app_setting_attr_text_rsp
362 **
363 ** Description      This function builds the Get Application Setting Attribute Text
364 **                  response.
365 **
366 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
367 **                  Otherwise, the error code.
368 **
369 *******************************************************************************/
avrc_bld_get_app_setting_attr_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)370 static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
371     BT_HDR *p_pkt)
372 {
373     AVRC_TRACE_API("avrc_bld_get_app_setting_attr_text_rsp");
374     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
375 }
376 
377 /*******************************************************************************
378 **
379 ** Function         avrc_bld_get_app_setting_value_text_rsp
380 **
381 ** Description      This function builds the Get Application Setting Value Text
382 **                  response.
383 **
384 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
385 **                  Otherwise, the error code.
386 **
387 *******************************************************************************/
avrc_bld_get_app_setting_value_text_rsp(tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp,BT_HDR * p_pkt)388 static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
389     BT_HDR *p_pkt)
390 {
391     AVRC_TRACE_API("avrc_bld_get_app_setting_value_text_rsp");
392     return avrc_bld_app_setting_text_rsp(p_rsp, p_pkt);
393 }
394 
395 /*******************************************************************************
396 **
397 ** Function         avrc_bld_inform_charset_rsp
398 **
399 ** Description      This function builds the Inform Displayable Character Set
400 **                  response.
401 **
402 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
403 **                  Otherwise, the error code.
404 **
405 *******************************************************************************/
avrc_bld_inform_charset_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)406 static tAVRC_STS avrc_bld_inform_charset_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
407 {
408     UNUSED(p_rsp);
409     UNUSED(p_pkt);
410 
411     /* nothing to be added. */
412     AVRC_TRACE_API("avrc_bld_inform_charset_rsp");
413     return AVRC_STS_NO_ERROR;
414 }
415 
416 /*******************************************************************************
417 **
418 ** Function         avrc_bld_inform_battery_status_rsp
419 **
420 ** Description      This function builds the Inform Battery Status
421 **                  response.
422 **
423 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
424 **                  Otherwise, the error code.
425 **
426 *******************************************************************************/
avrc_bld_inform_battery_status_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)427 static tAVRC_STS avrc_bld_inform_battery_status_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
428 {
429     UNUSED(p_rsp);
430     UNUSED(p_pkt);
431 
432     /* nothing to be added. */
433     AVRC_TRACE_API("avrc_bld_inform_battery_status_rsp");
434     return AVRC_STS_NO_ERROR;
435 }
436 
437 /*******************************************************************************
438 **
439 ** Function         avrc_bld_get_elem_attrs_rsp
440 **
441 ** Description      This function builds the Get Element Attributes
442 **                  response.
443 **
444 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
445 **                  Otherwise, the error code.
446 **
447 *******************************************************************************/
avrc_bld_get_elem_attrs_rsp(tAVRC_GET_ELEM_ATTRS_RSP * p_rsp,BT_HDR * p_pkt)448 static tAVRC_STS avrc_bld_get_elem_attrs_rsp (tAVRC_GET_ELEM_ATTRS_RSP *p_rsp, BT_HDR *p_pkt)
449 {
450     UINT8   *p_data, *p_start, *p_len, *p_count;
451     UINT16  len;
452     UINT8   xx;
453 
454     AVRC_TRACE_API("avrc_bld_get_elem_attrs_rsp");
455     if (!p_rsp->p_attrs)
456     {
457         AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp NULL parameter");
458         return AVRC_STS_BAD_PARAM;
459     }
460 
461     /* get the existing length, if any, and also the num attributes */
462     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
463     p_data = p_len = p_start + 2; /* pdu + rsvd */
464 
465     BE_STREAM_TO_UINT16(len, p_data);
466     p_count = p_data;
467 
468     if (len == 0)
469     {
470         *p_count = 0;
471         p_data++;
472     }
473     else
474     {
475         p_data = p_start + p_pkt->len;
476     }
477 
478     for (xx=0; xx<p_rsp->num_attr; xx++)
479     {
480         if (!AVRC_IS_VALID_MEDIA_ATTRIBUTE(p_rsp->p_attrs[xx].attr_id))
481         {
482             AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp invalid attr id[%d]: %d", xx, p_rsp->p_attrs[xx].attr_id);
483             continue;
484         }
485         if ( !p_rsp->p_attrs[xx].name.p_str )
486         {
487             p_rsp->p_attrs[xx].name.str_len = 0;
488         }
489         UINT32_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].attr_id);
490         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.charset_id);
491         UINT16_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.str_len);
492         ARRAY_TO_BE_STREAM(p_data, p_rsp->p_attrs[xx].name.p_str, p_rsp->p_attrs[xx].name.str_len);
493         (*p_count)++;
494     }
495     len = p_data - p_count;
496     UINT16_TO_BE_STREAM(p_len, len);
497     p_pkt->len = (p_data - p_start);
498     return AVRC_STS_NO_ERROR;
499 }
500 
501 /*******************************************************************************
502 **
503 ** Function         avrc_bld_get_play_status_rsp
504 **
505 ** Description      This function builds the Get Play Status
506 **                  response.
507 **
508 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
509 **                  Otherwise, the error code.
510 **
511 *******************************************************************************/
avrc_bld_get_play_status_rsp(tAVRC_GET_PLAY_STATUS_RSP * p_rsp,BT_HDR * p_pkt)512 static tAVRC_STS avrc_bld_get_play_status_rsp (tAVRC_GET_PLAY_STATUS_RSP *p_rsp, BT_HDR *p_pkt)
513 {
514     UINT8   *p_data, *p_start;
515 
516     AVRC_TRACE_API("avrc_bld_get_play_status_rsp");
517     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
518     p_data = p_start + 2;
519 
520     /* add fixed lenth - song len(4) + song position(4) + status(1) */
521     UINT16_TO_BE_STREAM(p_data, 9);
522     UINT32_TO_BE_STREAM(p_data, p_rsp->song_len);
523     UINT32_TO_BE_STREAM(p_data, p_rsp->song_pos);
524     UINT8_TO_BE_STREAM(p_data, p_rsp->play_status);
525     p_pkt->len = (p_data - p_start);
526 
527     return AVRC_STS_NO_ERROR;
528 }
529 
530 /*******************************************************************************
531 **
532 ** Function         avrc_bld_notify_rsp
533 **
534 ** Description      This function builds the Notification response.
535 **
536 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
537 **                  Otherwise, the error code.
538 **
539 *******************************************************************************/
avrc_bld_notify_rsp(tAVRC_REG_NOTIF_RSP * p_rsp,BT_HDR * p_pkt)540 static tAVRC_STS avrc_bld_notify_rsp (tAVRC_REG_NOTIF_RSP *p_rsp, BT_HDR *p_pkt)
541 {
542     UINT8   *p_data, *p_start;
543     UINT8   *p_len;
544     UINT16  len = 0;
545     UINT8   xx;
546     tAVRC_STS status = AVRC_STS_NO_ERROR;
547 
548     AVRC_TRACE_API("avrc_bld_notify_rsp");
549 
550     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
551     p_data = p_len = p_start + 2; /* pdu + rsvd */
552     p_data += 2;
553 
554     UINT8_TO_BE_STREAM(p_data, p_rsp->event_id);
555     switch (p_rsp->event_id)
556     {
557     case AVRC_EVT_PLAY_STATUS_CHANGE:       /* 0x01 */
558         /* p_rsp->param.play_status >= AVRC_PLAYSTATE_STOPPED is always TRUE */
559         if ((p_rsp->param.play_status <= AVRC_PLAYSTATE_REV_SEEK) ||
560             (p_rsp->param.play_status == AVRC_PLAYSTATE_ERROR) )
561         {
562             UINT8_TO_BE_STREAM(p_data, p_rsp->param.play_status);
563             len = 2;
564         }
565         else
566         {
567             AVRC_TRACE_ERROR("bad play state");
568             status = AVRC_STS_BAD_PARAM;
569         }
570         break;
571 
572     case AVRC_EVT_TRACK_CHANGE:             /* 0x02 */
573         ARRAY_TO_BE_STREAM(p_data, p_rsp->param.track, AVRC_UID_SIZE);
574         len = (UINT8)(AVRC_UID_SIZE + 1);
575         break;
576 
577     case AVRC_EVT_TRACK_REACHED_END:        /* 0x03 */
578     case AVRC_EVT_TRACK_REACHED_START:      /* 0x04 */
579         len = 1;
580         break;
581 
582     case AVRC_EVT_PLAY_POS_CHANGED:         /* 0x05 */
583         UINT32_TO_BE_STREAM(p_data, p_rsp->param.play_pos);
584         len = 5;
585         break;
586 
587     case AVRC_EVT_BATTERY_STATUS_CHANGE:    /* 0x06 */
588         if (AVRC_IS_VALID_BATTERY_STATUS(p_rsp->param.battery_status))
589         {
590             UINT8_TO_BE_STREAM(p_data, p_rsp->param.battery_status);
591             len = 2;
592         }
593         else
594         {
595             AVRC_TRACE_ERROR("bad battery status");
596             status = AVRC_STS_BAD_PARAM;
597         }
598         break;
599 
600     case AVRC_EVT_SYSTEM_STATUS_CHANGE:     /* 0x07 */
601         if (AVRC_IS_VALID_SYSTEM_STATUS(p_rsp->param.system_status))
602         {
603             UINT8_TO_BE_STREAM(p_data, p_rsp->param.system_status);
604             len = 2;
605         }
606         else
607         {
608             AVRC_TRACE_ERROR("bad system status");
609             status = AVRC_STS_BAD_PARAM;
610         }
611         break;
612 
613     case AVRC_EVT_APP_SETTING_CHANGE:       /* 0x08 */
614         if (p_rsp->param.player_setting.num_attr > AVRC_MAX_APP_SETTINGS)
615             p_rsp->param.player_setting.num_attr = AVRC_MAX_APP_SETTINGS;
616 
617         if (p_rsp->param.player_setting.num_attr > 0)
618         {
619             UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.num_attr);
620             len = 2;
621             for (xx=0; xx<p_rsp->param.player_setting.num_attr; xx++)
622             {
623                 if (avrc_is_valid_player_attrib_value(p_rsp->param.player_setting.attr_id[xx],
624                     p_rsp->param.player_setting.attr_value[xx]))
625                 {
626                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_id[xx]);
627                     UINT8_TO_BE_STREAM(p_data, p_rsp->param.player_setting.attr_value[xx]);
628                 }
629                 else
630                 {
631                     AVRC_TRACE_ERROR("bad player app seeting attribute or value");
632                     status = AVRC_STS_BAD_PARAM;
633                     break;
634                 }
635                 len += 2;
636             }
637         }
638         else
639             status = AVRC_STS_BAD_PARAM;
640         break;
641 
642     default:
643         status = AVRC_STS_BAD_PARAM;
644         AVRC_TRACE_ERROR("unknown event_id");
645     }
646 
647     UINT16_TO_BE_STREAM(p_len, len);
648     p_pkt->len = (p_data - p_start);
649 
650     return status;
651 }
652 
653 /*******************************************************************************
654 **
655 ** Function         avrc_bld_next_rsp
656 **
657 ** Description      This function builds the Request Continue or Abort
658 **                  response.
659 **
660 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
661 **                  Otherwise, the error code.
662 **
663 *******************************************************************************/
avrc_bld_next_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)664 static tAVRC_STS avrc_bld_next_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
665 {
666     UNUSED(p_rsp);
667     UNUSED(p_pkt);
668 
669     /* nothing to be added. */
670     AVRC_TRACE_API("avrc_bld_next_rsp");
671     return AVRC_STS_NO_ERROR;
672 }
673 
674 /*******************************************************************************
675 **
676 ** Function         avrc_bld_group_navigation_rsp
677 **
678 ** Description      This function builds the Group Navigation
679 **                  response.
680 **
681 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
682 **                  Otherwise, the error code.
683 **
684 *******************************************************************************/
avrc_bld_group_navigation_rsp(UINT16 navi_id,BT_HDR * p_pkt)685 tAVRC_STS avrc_bld_group_navigation_rsp (UINT16 navi_id, BT_HDR *p_pkt)
686 {
687     UINT8   *p_data;
688 
689     if (!AVRC_IS_VALID_GROUP(navi_id))
690     {
691         AVRC_TRACE_ERROR("avrc_bld_group_navigation_rsp bad navigation op id: %d", navi_id);
692         return AVRC_STS_BAD_PARAM;
693     }
694 
695     AVRC_TRACE_API("avrc_bld_group_navigation_rsp");
696     p_data = (UINT8 *)(p_pkt+1) + p_pkt->offset;
697     UINT16_TO_BE_STREAM(p_data, navi_id);
698     p_pkt->len = 2;
699     return AVRC_STS_NO_ERROR;
700 }
701 
702 /*******************************************************************************
703 **
704 ** Function         avrc_bld_rejected_rsp
705 **
706 ** Description      This function builds the General Response response.
707 **
708 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
709 **                  Otherwise, the error code.
710 **
711 *******************************************************************************/
avrc_bld_rejected_rsp(tAVRC_RSP * p_rsp,BT_HDR * p_pkt)712 static tAVRC_STS avrc_bld_rejected_rsp( tAVRC_RSP *p_rsp, BT_HDR *p_pkt )
713 {
714     UINT8 *p_data, *p_start;
715 
716     AVRC_TRACE_API("avrc_bld_rejected_rsp: status=%d, pdu:x%x", p_rsp->status, p_rsp->pdu);
717 
718     p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
719     p_data = p_start + 2;
720     AVRC_TRACE_DEBUG("pdu:x%x", *p_start);
721 
722     UINT16_TO_BE_STREAM(p_data, 1);
723     UINT8_TO_BE_STREAM(p_data, p_rsp->status);
724     p_pkt->len = p_data - p_start;
725 
726     return AVRC_STS_NO_ERROR;
727 }
728 
729 /*******************************************************************************
730 **
731 ** Function         avrc_bld_init_rsp_buffer
732 **
733 ** Description      This function initializes the response buffer based on PDU
734 **
735 ** Returns          NULL, if no GKI buffer or failure to build the message.
736 **                  Otherwise, the GKI buffer that contains the initialized message.
737 **
738 *******************************************************************************/
avrc_bld_init_rsp_buffer(tAVRC_RESPONSE * p_rsp)739 static BT_HDR *avrc_bld_init_rsp_buffer(tAVRC_RESPONSE *p_rsp)
740 {
741     UINT16 offset = AVRC_MSG_PASS_THRU_OFFSET, chnl = AVCT_DATA_CTRL, len=AVRC_META_CMD_POOL_SIZE;
742     BT_HDR *p_pkt=NULL;
743     UINT8  opcode = avrc_opcode_from_pdu(p_rsp->pdu);
744 
745     AVRC_TRACE_API("avrc_bld_init_rsp_buffer: pdu=%x, opcode=%x/%x", p_rsp->pdu, opcode,
746         p_rsp->rsp.opcode);
747     if (opcode != p_rsp->rsp.opcode && p_rsp->rsp.status != AVRC_STS_NO_ERROR &&
748         avrc_is_valid_opcode(p_rsp->rsp.opcode))
749     {
750         opcode = p_rsp->rsp.opcode;
751         AVRC_TRACE_API("opcode=%x", opcode);
752     }
753 
754     switch (opcode)
755     {
756     case AVRC_OP_PASS_THRU:
757         offset  = AVRC_MSG_PASS_THRU_OFFSET;
758         break;
759 
760     case AVRC_OP_VENDOR:
761         offset  = AVRC_MSG_VENDOR_OFFSET;
762         if (p_rsp->pdu == AVRC_PDU_GET_ELEMENT_ATTR)
763             len     = AVRC_BROWSE_POOL_SIZE;
764         break;
765     }
766 
767     /* allocate and initialize the buffer */
768     p_pkt = (BT_HDR *)GKI_getbuf(len);
769     if (p_pkt)
770     {
771         UINT8 *p_data, *p_start;
772 
773         p_pkt->layer_specific = chnl;
774         p_pkt->event    = opcode;
775         p_pkt->offset   = offset;
776         p_data = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
777         p_start = p_data;
778 
779         /* pass thru - group navigation - has a two byte op_id, so dont do it here */
780         if (opcode != AVRC_OP_PASS_THRU)
781             *p_data++ = p_rsp->pdu;
782 
783         switch (opcode)
784         {
785         case AVRC_OP_VENDOR:
786             /* reserved 0, packet_type 0 */
787             UINT8_TO_BE_STREAM(p_data, 0);
788             /* continue to the next "case to add length */
789             /* add fixed lenth - 0 */
790             UINT16_TO_BE_STREAM(p_data, 0);
791             break;
792         }
793 
794         p_pkt->len = (p_data - p_start);
795     }
796     p_rsp->rsp.opcode = opcode;
797     return p_pkt;
798 }
799 
800 /*******************************************************************************
801 **
802 ** Function         AVRC_BldResponse
803 **
804 ** Description      This function builds the given AVRCP response to the given
805 **                  GKI buffer
806 **
807 ** Returns          AVRC_STS_NO_ERROR, if the response is built successfully
808 **                  Otherwise, the error code.
809 **
810 *******************************************************************************/
AVRC_BldResponse(UINT8 handle,tAVRC_RESPONSE * p_rsp,BT_HDR ** pp_pkt)811 tAVRC_STS AVRC_BldResponse( UINT8 handle, tAVRC_RESPONSE *p_rsp, BT_HDR **pp_pkt)
812 {
813     tAVRC_STS status = AVRC_STS_BAD_PARAM;
814     BT_HDR *p_pkt;
815     BOOLEAN alloc = FALSE;
816     UNUSED(handle);
817 
818     if (!p_rsp || !pp_pkt)
819     {
820         AVRC_TRACE_API("AVRC_BldResponse. Invalid parameters passed. p_rsp=%p, pp_pkt=%p",
821             p_rsp, pp_pkt);
822         return AVRC_STS_BAD_PARAM;
823     }
824 
825     if (*pp_pkt == NULL)
826     {
827         if ((*pp_pkt = avrc_bld_init_rsp_buffer(p_rsp)) == NULL)
828         {
829             AVRC_TRACE_API("AVRC_BldResponse: Failed to initialize response buffer");
830             return AVRC_STS_INTERNAL_ERR;
831         }
832         alloc = TRUE;
833     }
834     status = AVRC_STS_NO_ERROR;
835     p_pkt = *pp_pkt;
836 
837     AVRC_TRACE_API("AVRC_BldResponse: pdu=%x status=%x", p_rsp->rsp.pdu, p_rsp->rsp.status);
838     if (p_rsp->rsp.status != AVRC_STS_NO_ERROR)
839     {
840         return( avrc_bld_rejected_rsp(&p_rsp->rsp, p_pkt) );
841     }
842 
843     switch (p_rsp->pdu)
844     {
845     case AVRC_PDU_NEXT_GROUP:
846     case AVRC_PDU_PREV_GROUP:
847         status = avrc_bld_group_navigation_rsp(p_rsp->pdu, p_pkt);
848         break;
849 
850     case AVRC_PDU_GET_CAPABILITIES:
851         status = avrc_bld_get_capability_rsp(&p_rsp->get_caps, p_pkt);
852         break;
853 
854     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
855         status = avrc_bld_list_app_settings_attr_rsp(&p_rsp->list_app_attr, p_pkt);
856         break;
857 
858     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
859         status = avrc_bld_list_app_settings_values_rsp(&p_rsp->list_app_values, p_pkt);
860         break;
861 
862     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
863         status = avrc_bld_get_cur_app_setting_value_rsp(&p_rsp->get_cur_app_val, p_pkt);
864         break;
865 
866     case AVRC_PDU_SET_PLAYER_APP_VALUE:
867         status = avrc_bld_set_app_setting_value_rsp(&p_rsp->set_app_val, p_pkt);
868         break;
869 
870     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
871         status = avrc_bld_get_app_setting_attr_text_rsp(&p_rsp->get_app_attr_txt, p_pkt);
872         break;
873 
874     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
875         status = avrc_bld_get_app_setting_value_text_rsp(&p_rsp->get_app_val_txt, p_pkt);
876         break;
877 
878     case AVRC_PDU_INFORM_DISPLAY_CHARSET:
879         status = avrc_bld_inform_charset_rsp(&p_rsp->inform_charset, p_pkt);
880         break;
881 
882     case AVRC_PDU_INFORM_BATTERY_STAT_OF_CT:
883         status = avrc_bld_inform_battery_status_rsp(&p_rsp->inform_battery_status, p_pkt);
884         break;
885 
886     case AVRC_PDU_GET_ELEMENT_ATTR:
887         status = avrc_bld_get_elem_attrs_rsp(&p_rsp->get_elem_attrs, p_pkt);
888         break;
889 
890     case AVRC_PDU_GET_PLAY_STATUS:
891         status = avrc_bld_get_play_status_rsp(&p_rsp->get_play_status, p_pkt);
892         break;
893 
894     case AVRC_PDU_REGISTER_NOTIFICATION:
895         status = avrc_bld_notify_rsp(&p_rsp->reg_notif, p_pkt);
896         break;
897 
898     case AVRC_PDU_REQUEST_CONTINUATION_RSP:     /*        0x40 */
899         status = avrc_bld_next_rsp(&p_rsp->continu, p_pkt);
900         break;
901 
902     case AVRC_PDU_ABORT_CONTINUATION_RSP:       /*          0x41 */
903         status = avrc_bld_next_rsp(&p_rsp->abort, p_pkt);
904         break;
905     }
906 
907     if (alloc && (status != AVRC_STS_NO_ERROR) )
908     {
909         GKI_freebuf(p_pkt);
910         *pp_pkt = NULL;
911     }
912     AVRC_TRACE_API("AVRC_BldResponse: returning %d", status);
913     return status;
914 }
915 
916 #endif /* (AVRC_METADATA_INCLUDED == TRUE)*/
917 
918