1/****************************************************************************** 2 * 3 * Copyright (C) 2002-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 module contains API of the audio/video distribution transport 22 * protocol. 23 * 24 ******************************************************************************/ 25 26#include <string.h> 27#include "bt_types.h" 28#include "bt_target.h" 29#include "avdt_api.h" 30#include "avdtc_api.h" 31#include "avdt_int.h" 32#include "l2c_api.h" 33#include "btm_api.h" 34#include "btu.h" 35 36 37/* Control block for AVDT */ 38#if AVDT_DYNAMIC_MEMORY == FALSE 39tAVDT_CB avdt_cb; 40#endif 41 42 43/******************************************************************************* 44** 45** Function avdt_process_timeout 46** 47** Description This function is called by BTU when an AVDTP timer 48** expires. The function sends a timer event to the 49** appropriate CCB or SCB state machine. 50** 51** This function is for use internal to the stack only. 52** 53** 54** Returns void 55** 56*******************************************************************************/ 57void avdt_process_timeout(TIMER_LIST_ENT *p_tle) 58{ 59 UINT8 event = 0; 60 UINT8 err_code = AVDT_ERR_TIMEOUT; 61 62 switch (p_tle->event) 63 { 64 case BTU_TTYPE_AVDT_CCB_RET: 65 event = AVDT_CCB_RET_TOUT_EVT + AVDT_CCB_MKR; 66 break; 67 68 case BTU_TTYPE_AVDT_CCB_RSP: 69 event = AVDT_CCB_RSP_TOUT_EVT + AVDT_CCB_MKR; 70 break; 71 72 case BTU_TTYPE_AVDT_CCB_IDLE: 73 event = AVDT_CCB_IDLE_TOUT_EVT + AVDT_CCB_MKR; 74 break; 75 76 case BTU_TTYPE_AVDT_SCB_TC: 77 event = AVDT_SCB_TC_TOUT_EVT; 78 break; 79 80 default: 81 break; 82 } 83 84 if (event & AVDT_CCB_MKR) 85 { 86 avdt_ccb_event((tAVDT_CCB *) p_tle->param, (UINT8) (event & ~AVDT_CCB_MKR), 87 (tAVDT_CCB_EVT *) &err_code); 88 } 89 else 90 { 91 avdt_scb_event((tAVDT_SCB *) p_tle->param, event, NULL); 92 } 93} 94 95/******************************************************************************* 96** 97** Function AVDT_Register 98** 99** Description This is the system level registration function for the 100** AVDTP protocol. This function initializes AVDTP and 101** prepares the protocol stack for its use. This function 102** must be called once by the system or platform using AVDTP 103** before the other functions of the API an be used. 104** 105** 106** Returns void 107** 108*******************************************************************************/ 109void AVDT_Register(tAVDT_REG *p_reg, tAVDT_CTRL_CBACK *p_cback) 110{ 111 /* register PSM with L2CAP */ 112 L2CA_Register(AVDT_PSM, (tL2CAP_APPL_INFO *) &avdt_l2c_appl); 113 114 /* set security level */ 115 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask, 116 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG); 117 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP, p_reg->sec_mask, 118 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_SIG); 119 120 /* do not use security on the media channel */ 121 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE, 122 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA); 123 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE, 124 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_MEDIA); 125 126#if AVDT_REPORTING == TRUE 127 /* do not use security on the reporting channel */ 128 BTM_SetSecurityLevel(TRUE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE, 129 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT); 130 BTM_SetSecurityLevel(FALSE, "", BTM_SEC_SERVICE_AVDTP_NOSEC, BTM_SEC_NONE, 131 AVDT_PSM, BTM_SEC_PROTO_AVDT, AVDT_CHAN_REPORT); 132#endif 133 134 /* initialize AVDTP data structures */ 135 avdt_scb_init(); 136 avdt_ccb_init(); 137 avdt_ad_init(); 138 139 /* copy registration struct */ 140 memcpy(&avdt_cb.rcb, p_reg, sizeof(tAVDT_REG)); 141 avdt_cb.p_conn_cback = p_cback; 142} 143 144/******************************************************************************* 145** 146** Function AVDT_Deregister 147** 148** Description This function is called to deregister use AVDTP protocol. 149** It is called when AVDTP is no longer being used by any 150** application in the system. Before this function can be 151** called, all streams must be removed with AVDT_RemoveStream(). 152** 153** 154** Returns void 155** 156*******************************************************************************/ 157void AVDT_Deregister(void) 158{ 159 /* deregister PSM with L2CAP */ 160 L2CA_Deregister(AVDT_PSM); 161} 162 163/******************************************************************************* 164** 165** Function AVDT_SINK_Activate 166** 167** Description Activate SEP of A2DP Sink. In Use parameter is adjusted. 168** In Use will be made false in case of activation. A2DP SRC 169** will receive in_use as false and can open A2DP Sink 170** connection 171** 172** Returns void. 173** 174*******************************************************************************/ 175void AVDT_SINK_Activate() 176{ 177 tAVDT_SCB *p_scb = &avdt_cb.scb[0]; 178 int i; 179 AVDT_TRACE_DEBUG("AVDT_SINK_Activate"); 180 /* for all allocated scbs */ 181 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) 182 { 183 if ((p_scb->allocated) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) 184 { 185 AVDT_TRACE_DEBUG("AVDT_SINK_Activate found scb"); 186 p_scb->sink_activated = TRUE; 187 /* update in_use */ 188 p_scb->in_use = FALSE; 189 break; 190 } 191 } 192} 193 194/******************************************************************************* 195** 196** Function AVDT_SINK_Deactivate 197** 198** Description Deactivate SEP of A2DP Sink. In Use parameter is adjusted. 199** In Use will be made TRUE in case of activation. A2DP SRC 200** will receive in_use as true and will not open A2DP Sink 201** connection 202** 203** Returns void. 204** 205*******************************************************************************/ 206void AVDT_SINK_Deactivate() 207{ 208 tAVDT_SCB *p_scb = &avdt_cb.scb[0]; 209 int i; 210 AVDT_TRACE_DEBUG("AVDT_SINK_Deactivate"); 211 /* for all allocated scbs */ 212 for (i = 0; i < AVDT_NUM_SEPS; i++, p_scb++) 213 { 214 if ((p_scb->allocated) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) 215 { 216 AVDT_TRACE_DEBUG("AVDT_SINK_Deactivate, found scb"); 217 p_scb->sink_activated = FALSE; 218 /* update in_use */ 219 p_scb->in_use = TRUE; 220 break; 221 } 222 } 223} 224 225void AVDT_AbortReq(UINT8 handle) 226{ 227 AVDT_TRACE_ERROR("%s", __func__); 228 229 tAVDT_SCB *p_scb = avdt_scb_by_hdl(handle); 230 if (p_scb != NULL) 231 { 232 avdt_scb_event(p_scb, AVDT_SCB_API_ABORT_REQ_EVT, NULL); 233 } else { 234 AVDT_TRACE_ERROR("%s Improper SCB, can not abort the stream", __func__); 235 } 236} 237 238/******************************************************************************* 239** 240** Function AVDT_CreateStream 241** 242** Description Create a stream endpoint. After a stream endpoint is 243** created an application can initiate a connection between 244** this endpoint and an endpoint on a peer device. In 245** addition, a peer device can discover, get the capabilities, 246** and connect to this endpoint. 247** 248** 249** Returns AVDT_SUCCESS if successful, otherwise error. 250** 251*******************************************************************************/ 252UINT16 AVDT_CreateStream(UINT8 *p_handle, tAVDT_CS *p_cs) 253{ 254 UINT16 result = AVDT_SUCCESS; 255 tAVDT_SCB *p_scb; 256 257 /* Verify parameters; if invalid, return failure */ 258 if (((p_cs->cfg.psc_mask & (~AVDT_PSC)) != 0) || (p_cs->p_ctrl_cback == NULL)) 259 { 260 result = AVDT_BAD_PARAMS; 261 } 262 /* Allocate scb; if no scbs, return failure */ 263 else if ((p_scb = avdt_scb_alloc(p_cs)) == NULL) 264 { 265 result = AVDT_NO_RESOURCES; 266 } 267 else 268 { 269 *p_handle = avdt_scb_to_hdl(p_scb); 270 } 271 return result; 272} 273 274/******************************************************************************* 275** 276** Function AVDT_RemoveStream 277** 278** Description Remove a stream endpoint. This function is called when 279** the application is no longer using a stream endpoint. 280** If this function is called when the endpoint is connected 281** the connection is closed and then the stream endpoint 282** is removed. 283** 284** 285** Returns AVDT_SUCCESS if successful, otherwise error. 286** 287*******************************************************************************/ 288UINT16 AVDT_RemoveStream(UINT8 handle) 289{ 290 UINT16 result = AVDT_SUCCESS; 291 tAVDT_SCB *p_scb; 292 293 /* look up scb */ 294 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 295 { 296 result = AVDT_BAD_HANDLE; 297 } 298 else 299 { 300 /* send remove event to scb */ 301 avdt_scb_event(p_scb, AVDT_SCB_API_REMOVE_EVT, NULL); 302 } 303 return result; 304} 305 306/******************************************************************************* 307** 308** Function AVDT_DiscoverReq 309** 310** Description This function initiates a connection to the AVDTP service 311** on the peer device, if not already present, and discovers 312** the stream endpoints on the peer device. (Please note 313** that AVDTP discovery is unrelated to SDP discovery). 314** This function can be called at any time regardless of whether 315** there is an AVDTP connection to the peer device. 316** 317** When discovery is complete, an AVDT_DISCOVER_CFM_EVT 318** is sent to the application via its callback function. 319** The application must not call AVDT_GetCapReq() or 320** AVDT_DiscoverReq() again to the same device until 321** discovery is complete. 322** 323** The memory addressed by sep_info is allocated by the 324** application. This memory is written to by AVDTP as part 325** of the discovery procedure. This memory must remain 326** accessible until the application receives the 327** AVDT_DISCOVER_CFM_EVT. 328** 329** Returns AVDT_SUCCESS if successful, otherwise error. 330** 331*******************************************************************************/ 332UINT16 AVDT_DiscoverReq(BD_ADDR bd_addr, tAVDT_SEP_INFO *p_sep_info, 333 UINT8 max_seps, tAVDT_CTRL_CBACK *p_cback) 334{ 335 tAVDT_CCB *p_ccb; 336 UINT16 result = AVDT_SUCCESS; 337 tAVDT_CCB_EVT evt; 338 339 /* find channel control block for this bd addr; if none, allocate one */ 340 if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL) 341 { 342 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL) 343 { 344 /* could not allocate channel control block */ 345 result = AVDT_NO_RESOURCES; 346 } 347 } 348 349 if (result == AVDT_SUCCESS) 350 { 351 /* make sure no discovery or get capabilities req already in progress */ 352 if (p_ccb->proc_busy) 353 { 354 result = AVDT_BUSY; 355 } 356 /* send event to ccb */ 357 else 358 { 359 evt.discover.p_sep_info = p_sep_info; 360 evt.discover.num_seps = max_seps; 361 evt.discover.p_cback = p_cback; 362 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCOVER_REQ_EVT, &evt); 363 } 364 } 365 return result; 366} 367 368/******************************************************************************* 369** 370** Function avdt_get_cap_req 371** 372** Description internal function to serve both AVDT_GetCapReq and 373** AVDT_GetAllCapReq 374** 375** Returns AVDT_SUCCESS if successful, otherwise error. 376** 377*******************************************************************************/ 378static UINT16 avdt_get_cap_req(BD_ADDR bd_addr, tAVDT_CCB_API_GETCAP *p_evt) 379{ 380 tAVDT_CCB *p_ccb = NULL; 381 UINT16 result = AVDT_SUCCESS; 382 383 /* verify SEID */ 384 if ((p_evt->single.seid < AVDT_SEID_MIN) || (p_evt->single.seid > AVDT_SEID_MAX)) 385 { 386 AVDT_TRACE_ERROR("seid: %d", p_evt->single.seid); 387 result = AVDT_BAD_PARAMS; 388 } 389 /* find channel control block for this bd addr; if none, allocate one */ 390 else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL) 391 { 392 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL) 393 { 394 /* could not allocate channel control block */ 395 result = AVDT_NO_RESOURCES; 396 } 397 } 398 399 if (result == AVDT_SUCCESS) 400 { 401 /* make sure no discovery or get capabilities req already in progress */ 402 if (p_ccb->proc_busy) 403 { 404 result = AVDT_BUSY; 405 } 406 /* send event to ccb */ 407 else 408 { 409 avdt_ccb_event(p_ccb, AVDT_CCB_API_GETCAP_REQ_EVT, (tAVDT_CCB_EVT *)p_evt); 410 } 411 } 412 return result; 413} 414 415/******************************************************************************* 416** 417** Function AVDT_GetCapReq 418** 419** Description This function initiates a connection to the AVDTP service 420** on the peer device, if not already present, and gets the 421** capabilities of a stream endpoint on the peer device. 422** This function can be called at any time regardless of 423** whether there is an AVDTP connection to the peer device. 424** 425** When the procedure is complete, an AVDT_GETCAP_CFM_EVT is 426** sent to the application via its callback function. The 427** application must not call AVDT_GetCapReq() or 428** AVDT_DiscoverReq() again until the procedure is complete. 429** 430** The memory pointed to by p_cfg is allocated by the 431** application. This memory is written to by AVDTP as part 432** of the get capabilities procedure. This memory must 433** remain accessible until the application receives 434** the AVDT_GETCAP_CFM_EVT. 435** 436** Returns AVDT_SUCCESS if successful, otherwise error. 437** 438*******************************************************************************/ 439UINT16 AVDT_GetCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback) 440{ 441 tAVDT_CCB_API_GETCAP getcap; 442 443 getcap.single.seid = seid; 444 getcap.single.sig_id = AVDT_SIG_GETCAP; 445 getcap.p_cfg = p_cfg; 446 getcap.p_cback = p_cback; 447 return avdt_get_cap_req (bd_addr, &getcap); 448} 449 450/******************************************************************************* 451** 452** Function AVDT_GetAllCapReq 453** 454** Description This function initiates a connection to the AVDTP service 455** on the peer device, if not already present, and gets the 456** capabilities of a stream endpoint on the peer device. 457** This function can be called at any time regardless of 458** whether there is an AVDTP connection to the peer device. 459** 460** When the procedure is complete, an AVDT_GETCAP_CFM_EVT is 461** sent to the application via its callback function. The 462** application must not call AVDT_GetCapReq() or 463** AVDT_DiscoverReq() again until the procedure is complete. 464** 465** The memory pointed to by p_cfg is allocated by the 466** application. This memory is written to by AVDTP as part 467** of the get capabilities procedure. This memory must 468** remain accessible until the application receives 469** the AVDT_GETCAP_CFM_EVT. 470** 471** Returns AVDT_SUCCESS if successful, otherwise error. 472** 473*******************************************************************************/ 474UINT16 AVDT_GetAllCapReq(BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg, tAVDT_CTRL_CBACK *p_cback) 475{ 476 tAVDT_CCB_API_GETCAP getcap; 477 478 getcap.single.seid = seid; 479 getcap.single.sig_id = AVDT_SIG_GET_ALLCAP; 480 getcap.p_cfg = p_cfg; 481 getcap.p_cback = p_cback; 482 return avdt_get_cap_req (bd_addr, &getcap); 483} 484 485/******************************************************************************* 486** 487** Function AVDT_DelayReport 488** 489** Description This functions sends a Delay Report to the peer device 490** that is associated with a particular SEID. 491** This function is called by SNK device. 492** 493** Returns AVDT_SUCCESS if successful, otherwise error. 494** 495*******************************************************************************/ 496UINT16 AVDT_DelayReport(UINT8 handle, UINT8 seid, UINT16 delay) 497{ 498 tAVDT_SCB *p_scb; 499 UINT16 result = AVDT_SUCCESS; 500 tAVDT_SCB_EVT evt; 501 502 /* map handle to scb */ 503 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 504 { 505 result = AVDT_BAD_HANDLE; 506 } 507 else 508 /* send event to scb */ 509 { 510 evt.apidelay.hdr.seid = seid; 511 evt.apidelay.delay = delay; 512 avdt_scb_event(p_scb, AVDT_SCB_API_DELAY_RPT_REQ_EVT, &evt); 513 } 514 515 return result; 516} 517 518/******************************************************************************* 519** 520** Function AVDT_OpenReq 521** 522** Description This function initiates a connection to the AVDTP service 523** on the peer device, if not already present, and connects 524** to a stream endpoint on a peer device. When the connection 525** is completed, an AVDT_OPEN_CFM_EVT is sent to the 526** application via the control callback function for this handle. 527** 528** Returns AVDT_SUCCESS if successful, otherwise error. 529** 530*******************************************************************************/ 531UINT16 AVDT_OpenReq(UINT8 handle, BD_ADDR bd_addr, UINT8 seid, tAVDT_CFG *p_cfg) 532{ 533 tAVDT_CCB *p_ccb = NULL; 534 tAVDT_SCB *p_scb = NULL; 535 UINT16 result = AVDT_SUCCESS; 536 tAVDT_SCB_EVT evt; 537 538 /* verify SEID */ 539 if ((seid < AVDT_SEID_MIN) || (seid > AVDT_SEID_MAX)) 540 { 541 result = AVDT_BAD_PARAMS; 542 } 543 /* map handle to scb */ 544 else if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 545 { 546 result = AVDT_BAD_HANDLE; 547 } 548 /* find channel control block for this bd addr; if none, allocate one */ 549 else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL) 550 { 551 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL) 552 { 553 /* could not allocate channel control block */ 554 result = AVDT_NO_RESOURCES; 555 } 556 } 557 558 /* send event to scb */ 559 if (result == AVDT_SUCCESS) 560 { 561 evt.msg.config_cmd.hdr.seid = seid; 562 evt.msg.config_cmd.hdr.ccb_idx = avdt_ccb_to_idx(p_ccb); 563 evt.msg.config_cmd.int_seid = handle; 564 evt.msg.config_cmd.p_cfg = p_cfg; 565 avdt_scb_event(p_scb, AVDT_SCB_API_SETCONFIG_REQ_EVT, &evt); 566 } 567 return result; 568} 569 570/******************************************************************************* 571** 572** Function AVDT_ConfigRsp 573** 574** Description Respond to a configure request from the peer device. This 575** function must be called if the application receives an 576** AVDT_CONFIG_IND_EVT through its control callback. 577** 578** 579** Returns AVDT_SUCCESS if successful, otherwise error. 580** 581*******************************************************************************/ 582UINT16 AVDT_ConfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, UINT8 category) 583{ 584 tAVDT_SCB *p_scb; 585 tAVDT_SCB_EVT evt; 586 UINT16 result = AVDT_SUCCESS; 587 UINT8 event_code; 588 589 /* map handle to scb */ 590 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 591 { 592 result = AVDT_BAD_HANDLE; 593 } 594 /* handle special case when this function is called but peer has not send 595 ** a configuration cmd; ignore and return error result 596 */ 597 else if (!p_scb->in_use) 598 { 599 result = AVDT_BAD_HANDLE; 600 } 601 /* send event to scb */ 602 else 603 { 604 evt.msg.hdr.err_code = error_code; 605 evt.msg.hdr.err_param = category; 606 evt.msg.hdr.label = label; 607 if (error_code == 0) 608 { 609 event_code = AVDT_SCB_API_SETCONFIG_RSP_EVT; 610 } 611 else 612 { 613 event_code = AVDT_SCB_API_SETCONFIG_REJ_EVT; 614 } 615 avdt_scb_event(p_scb, event_code, &evt); 616 } 617 618 return result; 619} 620 621/******************************************************************************* 622** 623** Function AVDT_StartReq 624** 625** Description Start one or more stream endpoints. This initiates the 626** transfer of media packets for the streams. All stream 627** endpoints must previously be opened. When the streams 628** are started, an AVDT_START_CFM_EVT is sent to the 629** application via the control callback function for each stream. 630** 631** 632** Returns AVDT_SUCCESS if successful, otherwise error. 633** 634*******************************************************************************/ 635UINT16 AVDT_StartReq(UINT8 *p_handles, UINT8 num_handles) 636{ 637 tAVDT_SCB *p_scb = NULL; 638 tAVDT_CCB_EVT evt; 639 UINT16 result = AVDT_SUCCESS; 640 int i; 641 642 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) 643 { 644 result = AVDT_BAD_PARAMS; 645 } 646 else 647 { 648 /* verify handles */ 649 for (i = 0; i < num_handles; i++) 650 { 651 if ((p_scb = avdt_scb_by_hdl(p_handles[i])) == NULL) 652 { 653 result = AVDT_BAD_HANDLE; 654 break; 655 } 656 } 657 } 658 659 if (result == AVDT_SUCCESS) 660 { 661 if (p_scb->p_ccb == NULL) 662 { 663 result = AVDT_BAD_HANDLE; 664 } 665 else 666 { 667 /* send event to ccb */ 668 memcpy(evt.msg.multi.seid_list, p_handles, num_handles); 669 evt.msg.multi.num_seps = num_handles; 670 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_START_REQ_EVT, &evt); 671 } 672 } 673 return result; 674} 675 676/******************************************************************************* 677** 678** Function AVDT_SuspendReq 679** 680** Description Suspend one or more stream endpoints. This suspends the 681** transfer of media packets for the streams. All stream 682** endpoints must previously be open and started. When the 683** streams are suspended, an AVDT_SUSPEND_CFM_EVT is sent to 684** the application via the control callback function for 685** each stream. 686** 687** 688** Returns AVDT_SUCCESS if successful, otherwise error. 689** 690*******************************************************************************/ 691UINT16 AVDT_SuspendReq(UINT8 *p_handles, UINT8 num_handles) 692{ 693 tAVDT_SCB *p_scb = NULL; 694 tAVDT_CCB_EVT evt; 695 UINT16 result = AVDT_SUCCESS; 696 int i; 697 698 if ((num_handles == 0) || (num_handles > AVDT_NUM_SEPS)) 699 { 700 result = AVDT_BAD_PARAMS; 701 } 702 else 703 { 704 /* verify handles */ 705 for (i = 0; i < num_handles; i++) 706 { 707 if ((p_scb = avdt_scb_by_hdl(p_handles[i])) == NULL) 708 { 709 result = AVDT_BAD_HANDLE; 710 break; 711 } 712 } 713 } 714 715 if (result == AVDT_SUCCESS) 716 { 717 if (p_scb->p_ccb == NULL) 718 { 719 result = AVDT_BAD_HANDLE; 720 } 721 else 722 { 723 /* send event to ccb */ 724 memcpy(evt.msg.multi.seid_list, p_handles, num_handles); 725 evt.msg.multi.num_seps = num_handles; 726 avdt_ccb_event(p_scb->p_ccb, AVDT_CCB_API_SUSPEND_REQ_EVT, &evt); 727 } 728 } 729 730 return result; 731} 732 733/******************************************************************************* 734** 735** Function AVDT_CloseReq 736** 737** Description Close a stream endpoint. This stops the transfer of media 738** packets and closes the transport channel associated with 739** this stream endpoint. When the stream is closed, an 740** AVDT_CLOSE_CFM_EVT is sent to the application via the 741** control callback function for this handle. 742** 743** 744** Returns AVDT_SUCCESS if successful, otherwise error. 745** 746*******************************************************************************/ 747UINT16 AVDT_CloseReq(UINT8 handle) 748{ 749 tAVDT_SCB *p_scb; 750 UINT16 result = AVDT_SUCCESS; 751 752 /* map handle to scb */ 753 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 754 { 755 result = AVDT_BAD_HANDLE; 756 } 757 else 758 /* send event to scb */ 759 { 760 avdt_scb_event(p_scb, AVDT_SCB_API_CLOSE_REQ_EVT, NULL); 761 } 762 763 return result; 764} 765 766/******************************************************************************* 767** 768** Function AVDT_ReconfigReq 769** 770** Description Reconfigure a stream endpoint. This allows the application 771** to change the codec or content protection capabilities of 772** a stream endpoint after it has been opened. This function 773** can only be called if the stream is opened but not started 774** or if the stream has been suspended. When the procedure 775** is completed, an AVDT_RECONFIG_CFM_EVT is sent to the 776** application via the control callback function for this handle. 777** 778** 779** Returns AVDT_SUCCESS if successful, otherwise error. 780** 781*******************************************************************************/ 782UINT16 AVDT_ReconfigReq(UINT8 handle, tAVDT_CFG *p_cfg) 783{ 784 tAVDT_SCB *p_scb; 785 UINT16 result = AVDT_SUCCESS; 786 tAVDT_SCB_EVT evt; 787 788 /* map handle to scb */ 789 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 790 { 791 result = AVDT_BAD_HANDLE; 792 } 793 /* send event to scb */ 794 else 795 { 796 /* force psc_mask to zero */ 797 p_cfg->psc_mask = 0; 798 799 evt.msg.reconfig_cmd.p_cfg = p_cfg; 800 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_REQ_EVT, &evt); 801 } 802 return result; 803} 804 805/******************************************************************************* 806** 807** Function AVDT_ReconfigRsp 808** 809** Description Respond to a reconfigure request from the peer device. 810** This function must be called if the application receives 811** an AVDT_RECONFIG_IND_EVT through its control callback. 812** 813** 814** Returns AVDT_SUCCESS if successful, otherwise error. 815** 816*******************************************************************************/ 817UINT16 AVDT_ReconfigRsp(UINT8 handle, UINT8 label, UINT8 error_code, UINT8 category) 818{ 819 tAVDT_SCB *p_scb; 820 tAVDT_SCB_EVT evt; 821 UINT16 result = AVDT_SUCCESS; 822 823 /* map handle to scb */ 824 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 825 { 826 result = AVDT_BAD_HANDLE; 827 } 828 /* send event to scb */ 829 else 830 { 831 evt.msg.hdr.err_code = error_code; 832 evt.msg.hdr.err_param = category; 833 evt.msg.hdr.label = label; 834 avdt_scb_event(p_scb, AVDT_SCB_API_RECONFIG_RSP_EVT, &evt); 835 } 836 837 return result; 838} 839 840/******************************************************************************* 841** 842** Function AVDT_SecurityReq 843** 844** Description Send a security request to the peer device. When the 845** security procedure is completed, an AVDT_SECURITY_CFM_EVT 846** is sent to the application via the control callback function 847** for this handle. (Please note that AVDTP security procedures 848** are unrelated to Bluetooth link level security.) 849** 850** 851** Returns AVDT_SUCCESS if successful, otherwise error. 852** 853*******************************************************************************/ 854UINT16 AVDT_SecurityReq(UINT8 handle, UINT8 *p_data, UINT16 len) 855{ 856 tAVDT_SCB *p_scb; 857 UINT16 result = AVDT_SUCCESS; 858 tAVDT_SCB_EVT evt; 859 860 /* map handle to scb */ 861 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 862 { 863 result = AVDT_BAD_HANDLE; 864 } 865 /* send event to scb */ 866 else 867 { 868 evt.msg.security_rsp.p_data = p_data; 869 evt.msg.security_rsp.len = len; 870 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_REQ_EVT, &evt); 871 } 872 return result; 873} 874 875/******************************************************************************* 876** 877** Function AVDT_SecurityRsp 878** 879** Description Respond to a security request from the peer device. 880** This function must be called if the application receives 881** an AVDT_SECURITY_IND_EVT through its control callback. 882** (Please note that AVDTP security procedures are unrelated 883** to Bluetooth link level security.) 884** 885** 886** Returns AVDT_SUCCESS if successful, otherwise error. 887** 888*******************************************************************************/ 889UINT16 AVDT_SecurityRsp(UINT8 handle, UINT8 label, UINT8 error_code, 890 UINT8 *p_data, UINT16 len) 891{ 892 tAVDT_SCB *p_scb; 893 UINT16 result = AVDT_SUCCESS; 894 tAVDT_SCB_EVT evt; 895 896 /* map handle to scb */ 897 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 898 { 899 result = AVDT_BAD_HANDLE; 900 } 901 /* send event to scb */ 902 else 903 { 904 evt.msg.security_rsp.hdr.err_code = error_code; 905 evt.msg.security_rsp.hdr.label = label; 906 evt.msg.security_rsp.p_data = p_data; 907 evt.msg.security_rsp.len = len; 908 avdt_scb_event(p_scb, AVDT_SCB_API_SECURITY_RSP_EVT, &evt); 909 } 910 return result; 911} 912 913/******************************************************************************* 914** 915** Function AVDT_WriteReqOpt 916** 917** Description Send a media packet to the peer device. The stream must 918** be started before this function is called. Also, this 919** function can only be called if the stream is a SRC. 920** 921** When AVDTP has sent the media packet and is ready for the 922** next packet, an AVDT_WRITE_CFM_EVT is sent to the 923** application via the control callback. The application must 924** wait for the AVDT_WRITE_CFM_EVT before it makes the next 925** call to AVDT_WriteReq(). If the applications calls 926** AVDT_WriteReq() before it receives the event the packet 927** will not be sent. The application may make its first call 928** to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT 929** or AVDT_START_IND_EVT. 930** 931** The application passes the packet using the BT_HDR structure. 932** This structure is described in section 2.1. The offset 933** field must be equal to or greater than AVDT_MEDIA_OFFSET 934** (if NO_RTP is specified, L2CAP_MIN_OFFSET can be used). 935** This allows enough space in the buffer for the L2CAP and 936** AVDTP headers. 937** 938** The memory pointed to by p_pkt must be a GKI buffer 939** allocated by the application. This buffer will be freed 940** by the protocol stack; the application must not free 941** this buffer. 942** 943** The opt parameter allows passing specific options like: 944** - NO_RTP : do not add the RTP header to buffer 945** 946** Returns AVDT_SUCCESS if successful, otherwise error. 947** 948*******************************************************************************/ 949UINT16 AVDT_WriteReqOpt(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt, tAVDT_DATA_OPT_MASK opt) 950{ 951 tAVDT_SCB *p_scb; 952 tAVDT_SCB_EVT evt; 953 UINT16 result = AVDT_SUCCESS; 954 955 /* map handle to scb */ 956 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 957 { 958 result = AVDT_BAD_HANDLE; 959 } 960 else 961 { 962 evt.apiwrite.p_buf = p_pkt; 963 evt.apiwrite.time_stamp = time_stamp; 964 evt.apiwrite.m_pt = m_pt; 965 evt.apiwrite.opt = opt; 966#if AVDT_MULTIPLEXING == TRUE 967 GKI_init_q (&evt.apiwrite.frag_q); 968#endif 969 avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt); 970 } 971 972 return result; 973} 974 975/******************************************************************************* 976** 977** Function AVDT_WriteReq 978** 979** Description Send a media packet to the peer device. The stream must 980** be started before this function is called. Also, this 981** function can only be called if the stream is a SRC. 982** 983** When AVDTP has sent the media packet and is ready for the 984** next packet, an AVDT_WRITE_CFM_EVT is sent to the 985** application via the control callback. The application must 986** wait for the AVDT_WRITE_CFM_EVT before it makes the next 987** call to AVDT_WriteReq(). If the applications calls 988** AVDT_WriteReq() before it receives the event the packet 989** will not be sent. The application may make its first call 990** to AVDT_WriteReq() after it receives an AVDT_START_CFM_EVT 991** or AVDT_START_IND_EVT. 992** 993** The application passes the packet using the BT_HDR structure. 994** This structure is described in section 2.1. The offset 995** field must be equal to or greater than AVDT_MEDIA_OFFSET. 996** This allows enough space in the buffer for the L2CAP and 997** AVDTP headers. 998** 999** The memory pointed to by p_pkt must be a GKI buffer 1000** allocated by the application. This buffer will be freed 1001** by the protocol stack; the application must not free 1002** this buffer. 1003** 1004** 1005** Returns AVDT_SUCCESS if successful, otherwise error. 1006** 1007*******************************************************************************/ 1008UINT16 AVDT_WriteReq(UINT8 handle, BT_HDR *p_pkt, UINT32 time_stamp, UINT8 m_pt) 1009{ 1010 return AVDT_WriteReqOpt(handle, p_pkt, time_stamp, m_pt, AVDT_DATA_OPT_NONE); 1011} 1012 1013/******************************************************************************* 1014** 1015** Function AVDT_ConnectReq 1016** 1017** Description This function initiates an AVDTP signaling connection 1018** to the peer device. When the connection is completed, an 1019** AVDT_CONNECT_IND_EVT is sent to the application via its 1020** control callback function. If the connection attempt fails 1021** an AVDT_DISCONNECT_IND_EVT is sent. The security mask 1022** parameter overrides the outgoing security mask set in 1023** AVDT_Register(). 1024** 1025** Returns AVDT_SUCCESS if successful, otherwise error. 1026** 1027*******************************************************************************/ 1028UINT16 AVDT_ConnectReq(BD_ADDR bd_addr, UINT8 sec_mask, tAVDT_CTRL_CBACK *p_cback) 1029{ 1030 tAVDT_CCB *p_ccb = NULL; 1031 UINT16 result = AVDT_SUCCESS; 1032 tAVDT_CCB_EVT evt; 1033 1034 /* find channel control block for this bd addr; if none, allocate one */ 1035 if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL) 1036 { 1037 if ((p_ccb = avdt_ccb_alloc(bd_addr)) == NULL) 1038 { 1039 /* could not allocate channel control block */ 1040 result = AVDT_NO_RESOURCES; 1041 } 1042 } 1043 else if (p_ccb->ll_opened == FALSE) 1044 { 1045 AVDT_TRACE_WARNING("AVDT_ConnectReq: CCB LL is in the middle of opening"); 1046 1047 /* ccb was already allocated for the incoming signalling. */ 1048 result = AVDT_BUSY; 1049 } 1050 1051 if (result == AVDT_SUCCESS) 1052 { 1053 /* send event to ccb */ 1054 evt.connect.p_cback = p_cback; 1055 evt.connect.sec_mask = sec_mask; 1056 avdt_ccb_event(p_ccb, AVDT_CCB_API_CONNECT_REQ_EVT, &evt); 1057 } 1058 return result; 1059} 1060 1061/******************************************************************************* 1062** 1063** Function AVDT_DisconnectReq 1064** 1065** Description This function disconnect an AVDTP signaling connection 1066** to the peer device. When disconnected an 1067** AVDT_DISCONNECT_IND_EVT is sent to the application via its 1068** control callback function. 1069** 1070** Returns AVDT_SUCCESS if successful, otherwise error. 1071** 1072*******************************************************************************/ 1073UINT16 AVDT_DisconnectReq(BD_ADDR bd_addr, tAVDT_CTRL_CBACK *p_cback) 1074{ 1075 tAVDT_CCB *p_ccb = NULL; 1076 UINT16 result = AVDT_SUCCESS; 1077 tAVDT_CCB_EVT evt; 1078 1079 /* find channel control block for this bd addr; if none, error */ 1080 if ((p_ccb = avdt_ccb_by_bd(bd_addr)) == NULL) 1081 { 1082 result = AVDT_BAD_PARAMS; 1083 } 1084 1085 if (result == AVDT_SUCCESS) 1086 { 1087 /* send event to ccb */ 1088 evt.disconnect.p_cback = p_cback; 1089 avdt_ccb_event(p_ccb, AVDT_CCB_API_DISCONNECT_REQ_EVT, &evt); 1090 } 1091 return result; 1092} 1093 1094/******************************************************************************* 1095** 1096** Function AVDT_GetL2CapChannel 1097** 1098** Description Get the L2CAP CID used by the handle. 1099** 1100** Returns CID if successful, otherwise 0. 1101** 1102*******************************************************************************/ 1103UINT16 AVDT_GetL2CapChannel(UINT8 handle) 1104{ 1105 tAVDT_SCB *p_scb; 1106 tAVDT_CCB *p_ccb; 1107 UINT8 tcid; 1108 UINT16 lcid = 0; 1109 1110 /* map handle to scb */ 1111 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) 1112 && ((p_ccb = p_scb->p_ccb) != NULL)) 1113 { 1114 /* get tcid from type, scb */ 1115 tcid = avdt_ad_type_to_tcid(AVDT_CHAN_MEDIA, p_scb); 1116 1117 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid; 1118 } 1119 1120 return (lcid); 1121} 1122 1123/******************************************************************************* 1124** 1125** Function AVDT_GetSignalChannel 1126** 1127** Description Get the L2CAP CID used by the signal channel of the given handle. 1128** 1129** Returns CID if successful, otherwise 0. 1130** 1131*******************************************************************************/ 1132UINT16 AVDT_GetSignalChannel(UINT8 handle, BD_ADDR bd_addr) 1133{ 1134 tAVDT_SCB *p_scb; 1135 tAVDT_CCB *p_ccb; 1136 UINT8 tcid = 0; /* tcid is always 0 for signal channel */ 1137 UINT16 lcid = 0; 1138 1139 /* map handle to scb */ 1140 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) 1141 && ((p_ccb = p_scb->p_ccb) != NULL)) 1142 { 1143 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid; 1144 } 1145 else if ((p_ccb = avdt_ccb_by_bd(bd_addr)) != NULL) 1146 { 1147 lcid = avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid; 1148 } 1149 1150 return (lcid); 1151} 1152 1153#if AVDT_MULTIPLEXING == TRUE 1154/******************************************************************************* 1155** 1156** Function AVDT_WriteDataReq 1157** 1158** Description Send a media packet to the peer device. The stream must 1159** be started before this function is called. Also, this 1160** function can only be called if the stream is a SRC. 1161** 1162** When AVDTP has sent the media packet and is ready for the 1163** next packet, an AVDT_WRITE_CFM_EVT is sent to the 1164** application via the control callback. The application must 1165** wait for the AVDT_WRITE_CFM_EVT before it makes the next 1166** call to AVDT_WriteDataReq(). If the applications calls 1167** AVDT_WriteDataReq() before it receives the event the packet 1168** will not be sent. The application may make its first call 1169** to AVDT_WriteDataReq() after it receives an 1170** AVDT_START_CFM_EVT or AVDT_START_IND_EVT. 1171** 1172** Returns AVDT_SUCCESS if successful, otherwise error. 1173** 1174*******************************************************************************/ 1175extern UINT16 AVDT_WriteDataReq(UINT8 handle, UINT8 *p_data, UINT32 data_len, 1176 UINT32 time_stamp, UINT8 m_pt, UINT8 marker) 1177{ 1178 1179 tAVDT_SCB *p_scb; 1180 tAVDT_SCB_EVT evt; 1181 UINT16 result = AVDT_SUCCESS; 1182 1183 do 1184 { 1185 /* check length of media frame */ 1186 if(data_len > AVDT_MAX_MEDIA_SIZE) 1187 { 1188 result = AVDT_BAD_PARAMS; 1189 break; 1190 } 1191 /* map handle to scb */ 1192 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 1193 { 1194 result = AVDT_BAD_HANDLE; 1195 break; 1196 } 1197 AVDT_TRACE_WARNING("mux_tsid_media:%d", p_scb->curr_cfg.mux_tsid_media); 1198 1199 if (p_scb->p_pkt != NULL 1200 || p_scb->p_ccb == NULL 1201 || !GKI_queue_is_empty(&p_scb->frag_q) 1202 || p_scb->frag_off != 0 1203 || p_scb->curr_cfg.mux_tsid_media == 0) 1204 { 1205 result = AVDT_ERR_BAD_STATE; 1206 AVDT_TRACE_WARNING("p_scb->p_pkt=%x, p_scb->p_ccb=%x, IsQueueEmpty=%x, p_scb->frag_off=%x", 1207 p_scb->p_pkt, p_scb->p_ccb, GKI_queue_is_empty(&p_scb->frag_q), p_scb->frag_off); 1208 break; 1209 } 1210 evt.apiwrite.p_buf = 0; /* it will indicate using of fragments queue frag_q */ 1211 /* create queue of media fragments */ 1212 GKI_init_q (&evt.apiwrite.frag_q); 1213 1214 /* compose fragments from media payload and put fragments into gueue */ 1215 avdt_scb_queue_frags(p_scb, &p_data, &data_len, &evt.apiwrite.frag_q); 1216 1217 if(GKI_queue_is_empty(&evt.apiwrite.frag_q)) 1218 { 1219 AVDT_TRACE_WARNING("AVDT_WriteDataReq out of GKI buffers"); 1220 result = AVDT_ERR_RESOURCE; 1221 break; 1222 } 1223 evt.apiwrite.data_len = data_len; 1224 evt.apiwrite.p_data = p_data; 1225 1226 /* process the fragments queue */ 1227 evt.apiwrite.time_stamp = time_stamp; 1228 evt.apiwrite.m_pt = m_pt | (marker<<7); 1229 avdt_scb_event(p_scb, AVDT_SCB_API_WRITE_REQ_EVT, &evt); 1230 } while (0); 1231 1232#if (BT_USE_TRACES == TRUE) 1233 if(result != AVDT_SUCCESS) 1234 { 1235 AVDT_TRACE_WARNING("*** AVDT_WriteDataReq failed result=%d",result); 1236 } 1237#endif 1238 return result; 1239} 1240#endif 1241 1242#if AVDT_MULTIPLEXING == TRUE 1243/******************************************************************************* 1244** 1245** Function AVDT_SetMediaBuf 1246** 1247** Description Assigns buffer for media packets or forbids using of assigned 1248** buffer if argument p_buf is NULL. This function can only 1249** be called if the stream is a SNK. 1250** 1251** AVDTP uses this buffer to reassemble fragmented media packets. 1252** When AVDTP receives a complete media packet, it calls the 1253** p_media_cback assigned by AVDT_CreateStream(). 1254** This function can be called during callback to assign a 1255** different buffer for next media packet or can leave the current 1256** buffer for next packet. 1257** 1258** Returns AVDT_SUCCESS if successful, otherwise error. 1259** 1260*******************************************************************************/ 1261extern UINT16 AVDT_SetMediaBuf(UINT8 handle, UINT8 *p_buf, UINT32 buf_len) 1262{ 1263 tAVDT_SCB *p_scb; 1264 UINT16 result = AVDT_SUCCESS; 1265 1266 /* map handle to scb */ 1267 if ((p_scb = avdt_scb_by_hdl(handle)) == NULL) 1268 { 1269 result = AVDT_BAD_HANDLE; 1270 } 1271 else 1272 { 1273 if(p_buf && p_scb->cs.p_media_cback == NULL) 1274 result = AVDT_NO_RESOURCES; 1275 else 1276 { 1277 p_scb->p_media_buf = p_buf; 1278 p_scb->media_buf_len = buf_len; 1279 } 1280 } 1281 1282 return result; 1283} 1284#endif 1285 1286#if AVDT_REPORTING == TRUE 1287/******************************************************************************* 1288** 1289** Function AVDT_SendReport 1290** 1291** Description 1292** 1293** 1294** 1295** Returns 1296** 1297*******************************************************************************/ 1298UINT16 AVDT_SendReport(UINT8 handle, AVDT_REPORT_TYPE type, 1299 tAVDT_REPORT_DATA *p_data) 1300{ 1301 tAVDT_SCB *p_scb; 1302 UINT16 result = AVDT_BAD_PARAMS; 1303 BT_HDR *p_pkt; 1304 tAVDT_TC_TBL *p_tbl; 1305 UINT8 *p, *plen, *pm1, *p_end; 1306#if AVDT_MULTIPLEXING == TRUE 1307 UINT8 *p_al=NULL, u; 1308#endif 1309 UINT32 ssrc; 1310 UINT16 len; 1311 1312 /* map handle to scb && verify parameters */ 1313 if (((p_scb = avdt_scb_by_hdl(handle)) != NULL) 1314 && (p_scb->p_ccb != NULL) 1315 && (((type == AVDT_RTCP_PT_SR) && (p_scb->cs.tsep == AVDT_TSEP_SRC)) || 1316 ((type == AVDT_RTCP_PT_RR) && (p_scb->cs.tsep == AVDT_TSEP_SNK)) || 1317 (type == AVDT_RTCP_PT_SDES)) ) 1318 { 1319 result = AVDT_NO_RESOURCES; 1320 1321 /* build SR - assume fit in one packet */ 1322 p_tbl = avdt_ad_tc_tbl_by_type(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb); 1323 if((p_tbl->state == AVDT_AD_ST_OPEN) && 1324 (p_pkt = (BT_HDR *)GKI_getbuf(p_tbl->peer_mtu)) != NULL) 1325 { 1326 p_pkt->offset = L2CAP_MIN_OFFSET; 1327 p = (UINT8 *)(p_pkt + 1) + p_pkt->offset; 1328#if AVDT_MULTIPLEXING == TRUE 1329 if(p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX) 1330 { 1331 /* Adaptation Layer header later */ 1332 p_al = p; 1333 p += 2; 1334 } 1335#endif 1336 pm1 = p; 1337 *p++ = AVDT_MEDIA_OCTET1 | 1; 1338 *p++ = type; 1339 /* save the location for length */ 1340 plen = p; 1341 p+= 2; 1342 ssrc = avdt_scb_gen_ssrc(p_scb); 1343 UINT32_TO_BE_STREAM(p, ssrc); 1344 1345 switch(type) 1346 { 1347 case AVDT_RTCP_PT_SR: /* Sender Report */ 1348 *pm1 = AVDT_MEDIA_OCTET1; 1349 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_sec); 1350 UINT32_TO_BE_STREAM(p, p_data->sr.ntp_frac); 1351 UINT32_TO_BE_STREAM(p, p_data->sr.rtp_time); 1352 UINT32_TO_BE_STREAM(p, p_data->sr.pkt_count); 1353 UINT32_TO_BE_STREAM(p, p_data->sr.octet_count); 1354 break; 1355 1356 case AVDT_RTCP_PT_RR: /* Receiver Report */ 1357 *p++ = p_data->rr.frag_lost; 1358 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost); 1359 p_data->rr.packet_lost &= 0xFFFFFF; 1360 AVDT_TRACE_API("packet_lost: %d", p_data->rr.packet_lost); 1361 UINT24_TO_BE_STREAM(p, p_data->rr.packet_lost); 1362 UINT32_TO_BE_STREAM(p, p_data->rr.seq_num_rcvd); 1363 UINT32_TO_BE_STREAM(p, p_data->rr.jitter); 1364 UINT32_TO_BE_STREAM(p, p_data->rr.lsr); 1365 UINT32_TO_BE_STREAM(p, p_data->rr.dlsr); 1366 break; 1367 1368 case AVDT_RTCP_PT_SDES: /* Source Description */ 1369 *p++ = AVDT_RTCP_SDES_CNAME; 1370 len = strlen((char *)p_data->cname); 1371 if(len > AVDT_MAX_CNAME_SIZE) 1372 len = AVDT_MAX_CNAME_SIZE; 1373 *p++ = (UINT8)len; 1374 BCM_STRNCPY_S((char *)p, len+1, (char *)p_data->cname, len+1); 1375 p += len; 1376 break; 1377 } 1378 p_end = p; 1379 len = p - pm1 - 1; 1380 UINT16_TO_BE_STREAM(plen, len); 1381 1382#if AVDT_MULTIPLEXING == TRUE 1383 if(p_scb->curr_cfg.psc_mask & AVDT_PSC_MUX) 1384 { 1385 /* Adaptation Layer header */ 1386 p = p_al; 1387 len++; 1388 UINT16_TO_BE_STREAM(p_al, len ); 1389 /* TSID, no-fragment bit and coding of length(9-bit length field) */ 1390 u = *p; 1391 *p = (p_scb->curr_cfg.mux_tsid_report<<3) | AVDT_ALH_LCODE_9BITM0; 1392 if(u) 1393 *p |= AVDT_ALH_LCODE_9BITM1; 1394 } 1395#endif 1396 1397 /* set the actual payload length */ 1398 p_pkt->len = p_end - p; 1399 /* send the packet */ 1400 if(L2CAP_DW_FAILED != avdt_ad_write_req(AVDT_CHAN_REPORT, p_scb->p_ccb, p_scb, p_pkt)) 1401 result = AVDT_SUCCESS; 1402 } 1403 } 1404 1405 return result; 1406} 1407#endif 1408 1409/****************************************************************************** 1410** 1411** Function AVDT_SetTraceLevel 1412** 1413** Description Sets the trace level for AVDT. If 0xff is passed, the 1414** current trace level is returned. 1415** 1416** Input Parameters: 1417** new_level: The level to set the AVDT tracing to: 1418** 0xff-returns the current setting. 1419** 0-turns off tracing. 1420** >= 1-Errors. 1421** >= 2-Warnings. 1422** >= 3-APIs. 1423** >= 4-Events. 1424** >= 5-Debug. 1425** 1426** Returns The new trace level or current trace level if 1427** the input parameter is 0xff. 1428** 1429******************************************************************************/ 1430UINT8 AVDT_SetTraceLevel (UINT8 new_level) 1431{ 1432 if (new_level != 0xFF) 1433 avdt_cb.trace_level = new_level; 1434 1435 return (avdt_cb.trace_level); 1436} 1437