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