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