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