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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 ******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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