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