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