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