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