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 *******************************************************************************/ 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("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 *******************************************************************************/ 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("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 *******************************************************************************/ 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("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 *******************************************************************************/ 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("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 *******************************************************************************/ 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("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 *******************************************************************************/ 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("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 *******************************************************************************/ 370 static 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 *******************************************************************************/ 388 static 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 *******************************************************************************/ 406 static 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 *******************************************************************************/ 427 static 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 *******************************************************************************/ 448 static 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 *******************************************************************************/ 512 static 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 *******************************************************************************/ 540 static 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 *******************************************************************************/ 664 static 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 *******************************************************************************/ 685 tAVRC_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 *******************************************************************************/ 712 static 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 *******************************************************************************/ 739 static 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 *******************************************************************************/ 811 tAVRC_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