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