blob: a9b1a2adf5eb5f857dcdf511889609b5d9a68d07 [file] [log] [blame]
Ravi Nagarajan9adddf42013-03-06 05:29:48 -08001/******************************************************************************
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"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080024#include "bt_utils.h"
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080025
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*******************************************************************************/
41static 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -070052 AVRC_TRACE_ERROR("avrc_bld_get_capability_rsp bad parameter. p_rsp: %x", p_rsp);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080053 status = AVRC_STS_BAD_PARAM;
54 return status;
55 }
56
Sharvil Nanavatib44cc592014-05-04 10:03:35 -070057 AVRC_TRACE_API("avrc_bld_get_capability_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -080058 /* 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*******************************************************************************/
119static 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
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700125 AVRC_TRACE_API("avrc_bld_list_app_settings_attr_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800126 /* 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*******************************************************************************/
170static 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
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700177 AVRC_TRACE_API("avrc_bld_list_app_settings_values_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800178
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*******************************************************************************/
220static 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700229 AVRC_TRACE_ERROR("avrc_bld_get_cur_app_setting_value_rsp NULL parameter");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800230 return AVRC_STS_BAD_PARAM;
231 }
232
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700233 AVRC_TRACE_API("avrc_bld_get_cur_app_setting_value_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800234 /* 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*******************************************************************************/
278static tAVRC_STS avrc_bld_set_app_setting_value_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
279{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800280 UNUSED(p_rsp);
281 UNUSED(p_pkt);
282
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800283 /* nothing to be added. */
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700284 AVRC_TRACE_API("avrc_bld_set_app_setting_value_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800285 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*******************************************************************************/
299static 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700309 AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp NULL parameter");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800310 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700334 AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp out of room (str_len:%d, left:%d)",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800335 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700342 AVRC_TRACE_ERROR("avrc_bld_app_setting_text_rsp NULL attr text[%d]", xx);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800343 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*******************************************************************************/
370static tAVRC_STS avrc_bld_get_app_setting_attr_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
371 BT_HDR *p_pkt)
372{
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700373 AVRC_TRACE_API("avrc_bld_get_app_setting_attr_text_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800374 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*******************************************************************************/
388static tAVRC_STS avrc_bld_get_app_setting_value_text_rsp (tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp,
389 BT_HDR *p_pkt)
390{
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700391 AVRC_TRACE_API("avrc_bld_get_app_setting_value_text_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800392 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*******************************************************************************/
406static tAVRC_STS avrc_bld_inform_charset_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
407{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800408 UNUSED(p_rsp);
409 UNUSED(p_pkt);
410
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800411 /* nothing to be added. */
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700412 AVRC_TRACE_API("avrc_bld_inform_charset_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800413 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*******************************************************************************/
427static tAVRC_STS avrc_bld_inform_battery_status_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
428{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800429 UNUSED(p_rsp);
430 UNUSED(p_pkt);
431
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800432 /* nothing to be added. */
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700433 AVRC_TRACE_API("avrc_bld_inform_battery_status_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800434 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*******************************************************************************/
448static 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
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700454 AVRC_TRACE_API("avrc_bld_get_elem_attrs_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800455 if (!p_rsp->p_attrs)
456 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700457 AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp NULL parameter");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800458 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700482 AVRC_TRACE_ERROR("avrc_bld_get_elem_attrs_rsp invalid attr id[%d]: %d", xx, p_rsp->p_attrs[xx].attr_id);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800483 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*******************************************************************************/
512static 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
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700516 AVRC_TRACE_API("avrc_bld_get_play_status_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800517 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*******************************************************************************/
540static 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
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700548 AVRC_TRACE_API("avrc_bld_notify_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800549
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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700567 AVRC_TRACE_ERROR("bad play state");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800568 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700595 AVRC_TRACE_ERROR("bad battery status");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800596 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700608 AVRC_TRACE_ERROR("bad system status");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800609 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700631 AVRC_TRACE_ERROR("bad player app seeting attribute or value");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800632 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;
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700644 AVRC_TRACE_ERROR("unknown event_id");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800645 }
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*******************************************************************************/
664static tAVRC_STS avrc_bld_next_rsp (tAVRC_RSP *p_rsp, BT_HDR *p_pkt)
665{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800666 UNUSED(p_rsp);
667 UNUSED(p_pkt);
668
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800669 /* nothing to be added. */
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700670 AVRC_TRACE_API("avrc_bld_next_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800671 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*******************************************************************************/
685tAVRC_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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700691 AVRC_TRACE_ERROR("avrc_bld_group_navigation_rsp bad navigation op id: %d", navi_id);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800692 return AVRC_STS_BAD_PARAM;
693 }
694
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700695 AVRC_TRACE_API("avrc_bld_group_navigation_rsp");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800696 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*******************************************************************************/
712static tAVRC_STS avrc_bld_rejected_rsp( tAVRC_RSP *p_rsp, BT_HDR *p_pkt )
713{
714 UINT8 *p_data, *p_start;
715
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700716 AVRC_TRACE_API("avrc_bld_rejected_rsp: status=%d, pdu:x%x", p_rsp->status, p_rsp->pdu);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800717
718 p_start = (UINT8 *)(p_pkt + 1) + p_pkt->offset;
719 p_data = p_start + 2;
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700720 AVRC_TRACE_DEBUG("pdu:x%x", *p_start);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800721
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*******************************************************************************/
739static 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
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700745 AVRC_TRACE_API("avrc_bld_init_rsp_buffer: pdu=%x, opcode=%x/%x", p_rsp->pdu, opcode,
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800746 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;
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700751 AVRC_TRACE_API("opcode=%x", opcode);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800752 }
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*******************************************************************************/
811tAVRC_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;
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800816 UNUSED(handle);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800817
818 if (!p_rsp || !pp_pkt)
819 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700820 AVRC_TRACE_API("AVRC_BldResponse. Invalid parameters passed. p_rsp=%p, pp_pkt=%p",
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800821 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 {
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700829 AVRC_TRACE_API("AVRC_BldResponse: Failed to initialize response buffer");
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800830 return AVRC_STS_INTERNAL_ERR;
831 }
832 alloc = TRUE;
833 }
834 status = AVRC_STS_NO_ERROR;
835 p_pkt = *pp_pkt;
836
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700837 AVRC_TRACE_API("AVRC_BldResponse: pdu=%x status=%x", p_rsp->rsp.pdu, p_rsp->rsp.status);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800838 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 }
Sharvil Nanavatib44cc592014-05-04 10:03:35 -0700912 AVRC_TRACE_API("AVRC_BldResponse: returning %d", status);
Ravi Nagarajan9adddf42013-03-06 05:29:48 -0800913 return status;
914}
915
916#endif /* (AVRC_METADATA_INCLUDED == TRUE)*/
917