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