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