bta_av_api.c revision 6b84f291c4edce7e4102efd8d4052a63bcb4b9dc
1/****************************************************************************** 2 * 3 * Copyright (C) 2011-2012 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 19/****************************************************************************** 20 * 21 * This is the implementation of the API for the advanced audio/video (AV) 22 * subsystem of BTA, Broadcom's Bluetooth application layer for mobile 23 * phones. 24 * 25 ******************************************************************************/ 26 27#include <assert.h> 28 29#include "bt_target.h" 30#if defined(BTA_AV_INCLUDED) && (BTA_AV_INCLUDED == TRUE) 31 32#include "bta_api.h" 33#include "bta_sys.h" 34#include "bta_av_api.h" 35#include "bta_av_int.h" 36#include "bt_common.h" 37#include <string.h> 38 39#include "osi/include/allocator.h" 40 41/***************************************************************************** 42** Constants 43*****************************************************************************/ 44 45static const tBTA_SYS_REG bta_av_reg = 46{ 47 bta_av_hdl_event, 48 BTA_AvDisable 49}; 50 51/******************************************************************************* 52** 53** Function BTA_AvEnable 54** 55** Description Enable the advanced audio/video service. When the enable 56** operation is complete the callback function will be 57** called with a BTA_AV_ENABLE_EVT. This function must 58** be called before other function in the AV API are 59** called. 60** 61** Returns void 62** 63*******************************************************************************/ 64void BTA_AvEnable(tBTA_SEC sec_mask, tBTA_AV_FEAT features, tBTA_AV_CBACK *p_cback) 65{ 66 tBTA_AV_API_ENABLE *p_buf; 67 68 /* register with BTA system manager */ 69 bta_sys_register(BTA_ID_AV, &bta_av_reg); 70 71 if ((p_buf = (tBTA_AV_API_ENABLE *) osi_getbuf(sizeof(tBTA_AV_API_ENABLE))) != NULL) 72 { 73 p_buf->hdr.event = BTA_AV_API_ENABLE_EVT; 74 p_buf->p_cback = p_cback; 75 p_buf->features = features; 76 p_buf->sec_mask = sec_mask; 77 bta_sys_sendmsg(p_buf); 78 } 79} 80 81/******************************************************************************* 82** 83** Function BTA_AvDisable 84** 85** Description Disable the advanced audio/video service. 86** 87** Returns void 88** 89*******************************************************************************/ 90void BTA_AvDisable(void) 91{ 92 BT_HDR *p_buf; 93 94 bta_sys_deregister(BTA_ID_AV); 95 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL) 96 { 97 p_buf->event = BTA_AV_API_DISABLE_EVT; 98 bta_sys_sendmsg(p_buf); 99 } 100} 101 102/******************************************************************************* 103** 104** Function BTA_AvRegister 105** 106** Description Register the audio or video service to stack. When the 107** operation is complete the callback function will be 108** called with a BTA_AV_REGISTER_EVT. This function must 109** be called before AVDT stream is open. 110** 111** 112** Returns void 113** 114*******************************************************************************/ 115void BTA_AvRegister(tBTA_AV_CHNL chnl, const char *p_service_name, UINT8 app_id, 116 tBTA_AV_DATA_CBACK *p_data_cback, UINT16 service_uuid) 117{ 118 tBTA_AV_API_REG *p_buf; 119 120 121 if ((p_buf = (tBTA_AV_API_REG *) osi_getbuf(sizeof(tBTA_AV_API_REG))) != NULL) 122 { 123 p_buf->hdr.layer_specific = chnl; 124 p_buf->hdr.event = BTA_AV_API_REGISTER_EVT; 125 if(p_service_name) 126 { 127 BCM_STRNCPY_S( 128 p_buf->p_service_name, sizeof(p_buf->p_service_name), p_service_name, 129 BTA_SERVICE_NAME_LEN); 130 p_buf->p_service_name[BTA_SERVICE_NAME_LEN-1] = 0; 131 } 132 else 133 { 134 p_buf->p_service_name[0] = 0; 135 } 136 p_buf->app_id = app_id; 137 p_buf->p_app_data_cback = p_data_cback; 138 p_buf->service_uuid = service_uuid; 139 bta_sys_sendmsg(p_buf); 140 } 141} 142 143/******************************************************************************* 144** 145** Function BTA_AvDeregister 146** 147** Description Deregister the audio or video service 148** 149** Returns void 150** 151*******************************************************************************/ 152void BTA_AvDeregister(tBTA_AV_HNDL hndl) 153{ 154 BT_HDR *p_buf; 155 156 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL) 157 { 158 p_buf->layer_specific = hndl; 159 p_buf->event = BTA_AV_API_DEREGISTER_EVT; 160 bta_sys_sendmsg(p_buf); 161 } 162} 163 164/******************************************************************************* 165** 166** Function BTA_AvOpen 167** 168** Description Opens an advanced audio/video connection to a peer device. 169** When connection is open callback function is called 170** with a BTA_AV_OPEN_EVT. 171** 172** Returns void 173** 174*******************************************************************************/ 175void BTA_AvOpen(BD_ADDR bd_addr, tBTA_AV_HNDL handle, BOOLEAN use_rc, tBTA_SEC sec_mask, 176 UINT16 uuid) 177{ 178 tBTA_AV_API_OPEN *p_buf; 179 180 if ((p_buf = (tBTA_AV_API_OPEN *) osi_getbuf(sizeof(tBTA_AV_API_OPEN))) != NULL) 181 { 182 p_buf->hdr.event = BTA_AV_API_OPEN_EVT; 183 p_buf->hdr.layer_specific = handle; 184 bdcpy(p_buf->bd_addr, bd_addr); 185 p_buf->use_rc = use_rc; 186 p_buf->sec_mask = sec_mask; 187 p_buf->switch_res = BTA_AV_RS_NONE; 188 p_buf->uuid = uuid; 189 bta_sys_sendmsg(p_buf); 190 } 191} 192 193/******************************************************************************* 194** 195** Function BTA_AvClose 196** 197** Description Close the current streams. 198** 199** Returns void 200** 201*******************************************************************************/ 202void BTA_AvClose(tBTA_AV_HNDL handle) 203{ 204 BT_HDR *p_buf; 205 206 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL) 207 { 208 p_buf->event = BTA_AV_API_CLOSE_EVT; 209 p_buf->layer_specific = handle; 210 bta_sys_sendmsg(p_buf); 211 } 212} 213 214/******************************************************************************* 215** 216** Function BTA_AvDisconnect 217** 218** Description Close the connection to the address. 219** 220** Returns void 221** 222*******************************************************************************/ 223void BTA_AvDisconnect(BD_ADDR bd_addr) 224{ 225 tBTA_AV_API_DISCNT *p_buf; 226 227 if ((p_buf = (tBTA_AV_API_DISCNT *) osi_getbuf(sizeof(tBTA_AV_API_DISCNT))) != NULL) 228 { 229 p_buf->hdr.event = BTA_AV_API_DISCONNECT_EVT; 230 bdcpy(p_buf->bd_addr, bd_addr); 231 bta_sys_sendmsg(p_buf); 232 } 233} 234 235/******************************************************************************* 236** 237** Function BTA_AvStart 238** 239** Description Start audio/video stream data transfer. 240** 241** Returns void 242** 243*******************************************************************************/ 244void BTA_AvStart(void) 245{ 246 BT_HDR *p_buf; 247 248 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL) 249 { 250 p_buf->event = BTA_AV_API_START_EVT; 251 bta_sys_sendmsg(p_buf); 252 } 253} 254 255/******************************************************************************* 256** 257** Function BTA_AvOffloadStart 258** 259** Description Start a2dp audio offloading. 260** 261** Returns void 262** 263*******************************************************************************/ 264void BTA_AvOffloadStart(tBTA_AV_HNDL hndl) 265{ 266 BT_HDR *p_buf; 267 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL) 268 { 269 p_buf->event = BTA_AV_API_OFFLOAD_START_EVT; 270 p_buf->layer_specific = hndl; 271 bta_sys_sendmsg(p_buf); 272 } 273} 274 275/******************************************************************************* 276** 277** Function BTA_AvOffloadStartRsp 278** 279** Description Response from vendor lib for A2DP Offload Start request. 280** 281** Returns void 282** 283*******************************************************************************/ 284void BTA_AvOffloadStartRsp(tBTA_AV_HNDL hndl, tBTA_AV_STATUS status) 285{ 286 tBTA_AV_API_STATUS_RSP *p_buf; 287 if ((p_buf = (tBTA_AV_API_STATUS_RSP *) osi_getbuf(sizeof(tBTA_AV_API_STATUS_RSP))) != NULL) 288 { 289 p_buf->hdr.event = BTA_AV_API_OFFLOAD_START_RSP_EVT; 290 p_buf->hdr.layer_specific = hndl; 291 p_buf->status = status; 292 bta_sys_sendmsg(p_buf); 293 } 294} 295 296/******************************************************************************* 297** 298** Function BTA_AvEnable_Sink 299** 300** Description Enable/Disable A2DP Sink.. 301** 302** Returns void 303** 304*******************************************************************************/ 305void BTA_AvEnable_Sink(int enable) 306{ 307#if (BTA_AV_SINK_INCLUDED == TRUE) 308 BT_HDR *p_buf; 309 if ((p_buf = (BT_HDR *) osi_getbuf(sizeof(BT_HDR))) != NULL) 310 { 311 p_buf->event = BTA_AV_API_SINK_ENABLE_EVT; 312 p_buf->layer_specific = enable; 313 bta_sys_sendmsg(p_buf); 314 } 315#else 316 return; 317#endif 318} 319 320/******************************************************************************* 321** 322** Function BTA_AvStop 323** 324** Description Stop audio/video stream data transfer. 325** If suspend is TRUE, this function sends AVDT suspend signal 326** to the connected peer(s). 327** 328** Returns void 329** 330*******************************************************************************/ 331void BTA_AvStop(BOOLEAN suspend) 332{ 333 tBTA_AV_API_STOP *p_buf; 334 335 if ((p_buf = (tBTA_AV_API_STOP *) osi_getbuf(sizeof(tBTA_AV_API_STOP))) != NULL) 336 { 337 p_buf->hdr.event = BTA_AV_API_STOP_EVT; 338 p_buf->flush = TRUE; 339 p_buf->suspend = suspend; 340 bta_sys_sendmsg(p_buf); 341 } 342} 343 344/******************************************************************************* 345** 346** Function BTA_AvReconfig 347** 348** Description Reconfigure the audio/video stream. 349** If suspend is TRUE, this function tries the suspend/reconfigure 350** procedure first. 351** If suspend is FALSE or when suspend/reconfigure fails, 352** this function closes and re-opens the AVDT connection. 353** 354** Returns void 355** 356*******************************************************************************/ 357void BTA_AvReconfig(tBTA_AV_HNDL hndl, BOOLEAN suspend, UINT8 sep_info_idx, 358 UINT8 *p_codec_info, UINT8 num_protect, UINT8 *p_protect_info) 359{ 360 tBTA_AV_API_RCFG *p_buf; 361 362 if ((p_buf = (tBTA_AV_API_RCFG *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_RCFG) + num_protect))) != NULL) 363 { 364 p_buf->hdr.layer_specific = hndl; 365 p_buf->hdr.event = BTA_AV_API_RECONFIG_EVT; 366 p_buf->num_protect = num_protect; 367 p_buf->suspend = suspend; 368 p_buf->sep_info_idx = sep_info_idx; 369 p_buf->p_protect_info = (UINT8 *)(p_buf + 1); 370 memcpy(p_buf->codec_info, p_codec_info, AVDT_CODEC_SIZE); 371 memcpy(p_buf->p_protect_info, p_protect_info, num_protect); 372 bta_sys_sendmsg(p_buf); 373 } 374} 375 376/******************************************************************************* 377** 378** Function BTA_AvProtectReq 379** 380** Description Send a content protection request. This function can only 381** be used if AV is enabled with feature BTA_AV_FEAT_PROTECT. 382** 383** Returns void 384** 385*******************************************************************************/ 386void BTA_AvProtectReq(tBTA_AV_HNDL hndl, UINT8 *p_data, UINT16 len) 387{ 388 tBTA_AV_API_PROTECT_REQ *p_buf; 389 390 if ((p_buf = (tBTA_AV_API_PROTECT_REQ *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_REQ) + len))) != NULL) 391 { 392 p_buf->hdr.layer_specific = hndl; 393 p_buf->hdr.event = BTA_AV_API_PROTECT_REQ_EVT; 394 p_buf->len = len; 395 if (p_data == NULL) 396 { 397 p_buf->p_data = NULL; 398 } 399 else 400 { 401 p_buf->p_data = (UINT8 *) (p_buf + 1); 402 memcpy(p_buf->p_data, p_data, len); 403 } 404 bta_sys_sendmsg(p_buf); 405 } 406} 407 408/******************************************************************************* 409** 410** Function BTA_AvProtectRsp 411** 412** Description Send a content protection response. This function must 413** be called if a BTA_AV_PROTECT_REQ_EVT is received. 414** This function can only be used if AV is enabled with 415** feature BTA_AV_FEAT_PROTECT. 416** 417** Returns void 418** 419*******************************************************************************/ 420void BTA_AvProtectRsp(tBTA_AV_HNDL hndl, UINT8 error_code, UINT8 *p_data, UINT16 len) 421{ 422 tBTA_AV_API_PROTECT_RSP *p_buf; 423 424 if ((p_buf = (tBTA_AV_API_PROTECT_RSP *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_PROTECT_RSP) + len))) != NULL) 425 { 426 p_buf->hdr.layer_specific = hndl; 427 p_buf->hdr.event = BTA_AV_API_PROTECT_RSP_EVT; 428 p_buf->len = len; 429 p_buf->error_code = error_code; 430 if (p_data == NULL) 431 { 432 p_buf->p_data = NULL; 433 } 434 else 435 { 436 p_buf->p_data = (UINT8 *) (p_buf + 1); 437 memcpy(p_buf->p_data, p_data, len); 438 } 439 bta_sys_sendmsg(p_buf); 440 } 441} 442 443/******************************************************************************* 444** 445** Function BTA_AvRemoteCmd 446** 447** Description Send a remote control command. This function can only 448** be used if AV is enabled with feature BTA_AV_FEAT_RCCT. 449** 450** Returns void 451** 452*******************************************************************************/ 453void BTA_AvRemoteCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_RC rc_id, tBTA_AV_STATE key_state) 454{ 455 tBTA_AV_API_REMOTE_CMD *p_buf; 456 457 if ((p_buf = (tBTA_AV_API_REMOTE_CMD *) osi_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD))) != NULL) 458 { 459 p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT; 460 p_buf->hdr.layer_specific = rc_handle; 461 p_buf->msg.op_id = rc_id; 462 p_buf->msg.state = key_state; 463 p_buf->msg.p_pass_data = NULL; 464 p_buf->msg.pass_len = 0; 465 p_buf->label = label; 466 bta_sys_sendmsg(p_buf); 467 } 468} 469 470/******************************************************************************* 471** 472** Function BTA_AvRemoteVendorUniqueCmd 473** 474** Description Send a remote control command with Vendor Unique rc_id. This function can only 475** be used if AV is enabled with feature BTA_AV_FEAT_RCCT. 476** 477** Returns void 478** 479*******************************************************************************/ 480void BTA_AvRemoteVendorUniqueCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_STATE key_state, 481 UINT8* p_msg, UINT8 buf_len) 482{ 483 tBTA_AV_API_REMOTE_CMD *p_buf = 484 (tBTA_AV_API_REMOTE_CMD *) osi_getbuf(sizeof(tBTA_AV_API_REMOTE_CMD)); 485 assert(p_buf); 486 p_buf->hdr.event = BTA_AV_API_REMOTE_CMD_EVT; 487 p_buf->hdr.layer_specific = rc_handle; 488 p_buf->msg.op_id = AVRC_ID_VENDOR; 489 p_buf->msg.state = key_state; 490 p_buf->msg.p_pass_data = p_msg; 491 p_buf->msg.pass_len = buf_len; 492 p_buf->label = label; 493 bta_sys_sendmsg(p_buf); 494} 495 496/******************************************************************************* 497** 498** Function BTA_AvVendorCmd 499** 500** Description Send a vendor dependent remote control command. This 501** function can only be used if AV is enabled with feature 502** BTA_AV_FEAT_VENDOR. 503** 504** Returns void 505** 506*******************************************************************************/ 507void BTA_AvVendorCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE cmd_code, UINT8 *p_data, UINT16 len) 508{ 509 tBTA_AV_API_VENDOR *p_buf; 510 511 if ((p_buf = (tBTA_AV_API_VENDOR *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL) 512 { 513 p_buf->hdr.event = BTA_AV_API_VENDOR_CMD_EVT; 514 p_buf->hdr.layer_specific = rc_handle; 515 p_buf->msg.hdr.ctype = cmd_code; 516 p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL; 517 p_buf->msg.hdr.subunit_id = 0; 518 p_buf->msg.company_id = p_bta_av_cfg->company_id; 519 p_buf->label = label; 520 p_buf->msg.vendor_len = len; 521 if (p_data == NULL) 522 { 523 p_buf->msg.p_vendor_data = NULL; 524 } 525 else 526 { 527 p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1); 528 memcpy(p_buf->msg.p_vendor_data, p_data, len); 529 } 530 bta_sys_sendmsg(p_buf); 531 } 532} 533 534/******************************************************************************* 535** 536** Function BTA_AvVendorRsp 537** 538** Description Send a vendor dependent remote control response. 539** This function must be called if a BTA_AV_VENDOR_CMD_EVT 540** is received. This function can only be used if AV is 541** enabled with feature BTA_AV_FEAT_VENDOR. 542** 543** Returns void 544** 545*******************************************************************************/ 546void BTA_AvVendorRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, UINT8 *p_data, UINT16 len, UINT32 company_id) 547{ 548 tBTA_AV_API_VENDOR *p_buf; 549 550 if ((p_buf = (tBTA_AV_API_VENDOR *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_VENDOR) + len))) != NULL) 551 { 552 p_buf->hdr.event = BTA_AV_API_VENDOR_RSP_EVT; 553 p_buf->hdr.layer_specific = rc_handle; 554 p_buf->msg.hdr.ctype = rsp_code; 555 p_buf->msg.hdr.subunit_type = AVRC_SUB_PANEL; 556 p_buf->msg.hdr.subunit_id = 0; 557 if(company_id) 558 p_buf->msg.company_id = company_id; 559 else 560 p_buf->msg.company_id = p_bta_av_cfg->company_id; 561 p_buf->label = label; 562 p_buf->msg.vendor_len = len; 563 if (p_data == NULL) 564 { 565 p_buf->msg.p_vendor_data = NULL; 566 } 567 else 568 { 569 p_buf->msg.p_vendor_data = (UINT8 *) (p_buf + 1); 570 memcpy(p_buf->msg.p_vendor_data, p_data, len); 571 } 572 bta_sys_sendmsg(p_buf); 573 } 574} 575 576/******************************************************************************* 577** 578** Function BTA_AvOpenRc 579** 580** Description Open an AVRCP connection toward the device with the 581** specified handle 582** 583** Returns void 584** 585*******************************************************************************/ 586void BTA_AvOpenRc(tBTA_AV_HNDL handle) 587{ 588 tBTA_AV_API_OPEN_RC *p_buf; 589 590 if ((p_buf = (tBTA_AV_API_OPEN_RC *) osi_getbuf(sizeof(tBTA_AV_API_OPEN_RC))) != NULL) 591 { 592 p_buf->hdr.event = BTA_AV_API_RC_OPEN_EVT; 593 p_buf->hdr.layer_specific = handle; 594 bta_sys_sendmsg(p_buf); 595 } 596} 597 598/******************************************************************************* 599** 600** Function BTA_AvCloseRc 601** 602** Description Close an AVRCP connection 603** 604** Returns void 605** 606*******************************************************************************/ 607void BTA_AvCloseRc(UINT8 rc_handle) 608{ 609 tBTA_AV_API_CLOSE_RC *p_buf; 610 611 if ((p_buf = (tBTA_AV_API_CLOSE_RC *) osi_getbuf(sizeof(tBTA_AV_API_CLOSE_RC))) != NULL) 612 { 613 p_buf->hdr.event = BTA_AV_API_RC_CLOSE_EVT; 614 p_buf->hdr.layer_specific = rc_handle; 615 bta_sys_sendmsg(p_buf); 616 } 617} 618 619/******************************************************************************* 620** 621** Function BTA_AvMetaRsp 622** 623** Description Send a Metadata/Advanced Control response. The message contained 624** in p_pkt can be composed with AVRC utility functions. 625** This function can only be used if AV is enabled with feature 626** BTA_AV_FEAT_METADATA. 627** 628** Returns void 629** 630*******************************************************************************/ 631void BTA_AvMetaRsp(UINT8 rc_handle, UINT8 label, tBTA_AV_CODE rsp_code, 632 BT_HDR *p_pkt) 633{ 634 tBTA_AV_API_META_RSP *p_buf; 635 636 if ((p_buf = (tBTA_AV_API_META_RSP *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL) 637 { 638 p_buf->hdr.event = BTA_AV_API_META_RSP_EVT; 639 p_buf->hdr.layer_specific = rc_handle; 640 p_buf->rsp_code = rsp_code; 641 p_buf->p_pkt = p_pkt; 642 p_buf->is_rsp = TRUE; 643 p_buf->label = label; 644 645 bta_sys_sendmsg(p_buf); 646 } else if (p_pkt) { 647 osi_freebuf(p_pkt); 648 } 649} 650 651/******************************************************************************* 652** 653** Function BTA_AvMetaCmd 654** 655** Description Send a Metadata/Advanced Control command. The message contained 656** in p_pkt can be composed with AVRC utility functions. 657** This function can only be used if AV is enabled with feature 658** BTA_AV_FEAT_METADATA. 659** This message is sent only when the peer supports the TG role. 660*8 The only command makes sense right now is the absolute volume command. 661** 662** Returns void 663** 664*******************************************************************************/ 665void BTA_AvMetaCmd(UINT8 rc_handle, UINT8 label, tBTA_AV_CMD cmd_code, BT_HDR *p_pkt) 666{ 667 tBTA_AV_API_META_RSP *p_buf; 668 669 if ((p_buf = (tBTA_AV_API_META_RSP *) osi_getbuf((UINT16) (sizeof(tBTA_AV_API_META_RSP)))) != NULL) 670 { 671 p_buf->hdr.event = BTA_AV_API_META_RSP_EVT; 672 p_buf->hdr.layer_specific = rc_handle; 673 p_buf->p_pkt = p_pkt; 674 p_buf->rsp_code = cmd_code; 675 p_buf->is_rsp = FALSE; 676 p_buf->label = label; 677 678 bta_sys_sendmsg(p_buf); 679 } 680} 681 682#endif /* BTA_AV_INCLUDED */ 683