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 the AVDTP adaption layer. 22 * 23 ******************************************************************************/ 24 25 #include <string.h> 26 #include "data_types.h" 27 #include "bt_target.h" 28 #include "bt_utils.h" 29 #include "avdt_api.h" 30 #include "avdtc_api.h" 31 #include "avdt_int.h" 32 #include "l2c_api.h" 33 #include "l2cdefs.h" 34 #include "wcassert.h" 35 36 37 /******************************************************************************* 38 ** 39 ** Function avdt_ad_type_to_tcid 40 ** 41 ** Description Derives the TCID from the channel type and SCB. 42 ** 43 ** 44 ** Returns TCID value. 45 ** 46 *******************************************************************************/ 47 UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb) 48 { 49 UINT8 scb_idx; 50 51 if (type == AVDT_CHAN_SIG) 52 { 53 return 0; 54 } 55 else 56 { 57 scb_idx = avdt_scb_to_hdl(p_scb) - 1; 58 /* 59 AVDT_TRACE_DEBUG("type: %d, tcid: %d", type, ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type)); 60 */ 61 return ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type); 62 } 63 } 64 65 /******************************************************************************* 66 ** 67 ** Function avdt_ad_tcid_to_type 68 ** 69 ** Description Derives the channel type from the TCID. 70 ** 71 ** 72 ** Returns Channel type value. 73 ** 74 *******************************************************************************/ 75 static UINT8 avdt_ad_tcid_to_type(UINT8 tcid) 76 { 77 UINT8 type; 78 79 if (tcid == 0) 80 { 81 type = AVDT_CHAN_SIG; 82 } 83 else 84 { 85 /* tcid translates to type based on number of channels, as follows: 86 ** only media channel : tcid=1,2,3,4,5,6... type=1,1,1,1,1,1... 87 ** media and report : tcid=1,2,3,4,5,6... type=1,2,1,2,1,2... 88 ** media, report, recov : tcid=1,2,3,4,5,6... type=1,2,3,1,2,3... 89 */ 90 type = ((tcid + AVDT_CHAN_NUM_TYPES - 2) % (AVDT_CHAN_NUM_TYPES - 1)) + 1; 91 } 92 AVDT_TRACE_DEBUG("tcid: %d, type: %d", tcid, type); 93 return type; 94 } 95 96 97 /******************************************************************************* 98 ** 99 ** Function avdt_ad_init 100 ** 101 ** Description Initialize adaption layer. 102 ** 103 ** 104 ** Returns Nothing. 105 ** 106 *******************************************************************************/ 107 void avdt_ad_init(void) 108 { 109 int i; 110 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl; 111 memset(&avdt_cb.ad, 0, sizeof(tAVDT_AD)); 112 113 /* make sure the peer_mtu is a valid value */ 114 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) 115 { 116 p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; 117 } 118 } 119 120 121 /******************************************************************************* 122 ** 123 ** Function avdt_ad_tc_tbl_by_st 124 ** 125 ** Description Find adaption layer transport channel table entry matching 126 ** the given state. 127 ** 128 ** 129 ** Returns Pointer to matching entry. For control channel it returns 130 ** the matching entry. For media or other it returns the 131 ** first matching entry (there could be more than one). 132 ** 133 *******************************************************************************/ 134 tAVDT_TC_TBL *avdt_ad_tc_tbl_by_st(UINT8 type, tAVDT_CCB *p_ccb, UINT8 state) 135 { 136 int i; 137 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl; 138 UINT8 ccb_idx; 139 140 if (p_ccb == NULL) 141 { 142 /* resending security req */ 143 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) 144 { 145 /* must be AVDT_CHAN_SIG - tcid always zero */ 146 if ((p_tbl->tcid == 0) && 147 (p_tbl->state == state)) 148 { 149 break; 150 } 151 } 152 } 153 else 154 { 155 ccb_idx = avdt_ccb_to_idx(p_ccb); 156 157 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) 158 { 159 if (type == AVDT_CHAN_SIG) 160 { 161 /* if control channel, tcid always zero */ 162 if ((p_tbl->tcid == 0) && 163 (p_tbl->ccb_idx == ccb_idx) && 164 (p_tbl->state == state)) 165 { 166 break; 167 } 168 } 169 else 170 { 171 /* if other channel, tcid is always > zero */ 172 if ((p_tbl->tcid > 0) && 173 (p_tbl->ccb_idx == ccb_idx) && 174 (p_tbl->state == state)) 175 { 176 break; 177 } 178 } 179 } 180 } 181 182 /* if nothing found return null */ 183 if (i == AVDT_NUM_TC_TBL) 184 { 185 p_tbl = NULL; 186 } 187 188 return p_tbl; 189 } 190 191 192 /******************************************************************************* 193 ** 194 ** Function avdt_ad_tc_tbl_by_lcid 195 ** 196 ** Description Find adaption layer transport channel table entry by LCID. 197 ** 198 ** 199 ** Returns Pointer to entry. 200 ** 201 *******************************************************************************/ 202 tAVDT_TC_TBL *avdt_ad_tc_tbl_by_lcid(UINT16 lcid) 203 { 204 UINT8 idx; 205 206 idx = avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID]; 207 208 if (idx < AVDT_NUM_TC_TBL) 209 { 210 return &avdt_cb.ad.tc_tbl[idx]; 211 } 212 else 213 { 214 return NULL; 215 } 216 } 217 218 219 /******************************************************************************* 220 ** 221 ** Function avdt_ad_tc_tbl_by_type 222 ** 223 ** Description This function retrieves the transport channel table entry 224 ** for a particular channel. 225 ** 226 ** 227 ** Returns Pointer to transport channel table entry. 228 ** 229 *******************************************************************************/ 230 tAVDT_TC_TBL *avdt_ad_tc_tbl_by_type(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb) 231 { 232 UINT8 tcid; 233 int i; 234 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl; 235 UINT8 ccb_idx = avdt_ccb_to_idx(p_ccb); 236 237 /* get tcid from type, scb */ 238 tcid = avdt_ad_type_to_tcid(type, p_scb); 239 240 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) 241 { 242 if ((p_tbl->tcid == tcid) && (p_tbl->ccb_idx == ccb_idx)) 243 { 244 break; 245 } 246 } 247 248 WC_ASSERT(i != AVDT_NUM_TC_TBL); 249 250 return p_tbl; 251 } 252 253 254 /******************************************************************************* 255 ** 256 ** Function avdt_ad_tc_tbl_alloc 257 ** 258 ** Description Allocate an entry in the traffic channel table. 259 ** 260 ** 261 ** Returns Pointer to entry. 262 ** 263 *******************************************************************************/ 264 tAVDT_TC_TBL *avdt_ad_tc_tbl_alloc(tAVDT_CCB *p_ccb) 265 { 266 int i; 267 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl; 268 269 /* find next free entry in tc table */ 270 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++) 271 { 272 if (p_tbl->state == AVDT_AD_ST_UNUSED) 273 { 274 break; 275 } 276 } 277 278 /* sanity check */ 279 WC_ASSERT(i != AVDT_NUM_TC_TBL); 280 281 /* initialize entry */ 282 p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; 283 p_tbl->cfg_flags = 0; 284 p_tbl->ccb_idx = avdt_ccb_to_idx(p_ccb); 285 p_tbl->state = AVDT_AD_ST_IDLE; 286 287 return p_tbl; 288 } 289 290 /******************************************************************************* 291 ** 292 ** Function avdt_ad_tc_tbl_to_idx 293 ** 294 ** Description Convert a transport channel table entry to an index. 295 ** 296 ** 297 ** Returns Index value. 298 ** 299 *******************************************************************************/ 300 UINT8 avdt_ad_tc_tbl_to_idx(tAVDT_TC_TBL *p_tbl) 301 { 302 AVDT_TRACE_DEBUG("avdt_ad_tc_tbl_to_idx: %d", (p_tbl - avdt_cb.ad.tc_tbl)); 303 /* use array arithmetic to determine index */ 304 return (UINT8) (p_tbl - avdt_cb.ad.tc_tbl); 305 } 306 307 /******************************************************************************* 308 ** 309 ** Function avdt_ad_tc_close_ind 310 ** 311 ** Description This function is called by the L2CAP interface when the 312 ** L2CAP channel is closed. It looks up the CCB or SCB for 313 ** the channel and sends it a close event. The reason 314 ** parameter is the same value passed by the L2CAP 315 ** callback function. 316 ** 317 ** 318 ** Returns Nothing. 319 ** 320 *******************************************************************************/ 321 void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason) 322 { 323 tAVDT_CCB *p_ccb; 324 tAVDT_SCB *p_scb; 325 tAVDT_SCB_TC_CLOSE close; 326 UNUSED(reason); 327 328 close.old_tc_state = p_tbl->state; 329 /* clear avdt_ad_tc_tbl entry */ 330 p_tbl->state = AVDT_AD_ST_UNUSED; 331 p_tbl->cfg_flags = 0; 332 p_tbl->peer_mtu = L2CAP_DEFAULT_MTU; 333 334 AVDT_TRACE_DEBUG("avdt_ad_tc_close_ind tcid: %d, old: %d", 335 p_tbl->tcid, close.old_tc_state); 336 /* if signaling channel, notify ccb that channel open */ 337 if (p_tbl->tcid == 0) 338 { 339 p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx); 340 avdt_ccb_event(p_ccb, AVDT_CCB_LL_CLOSE_EVT, NULL); 341 } 342 /* if media or other channel, notify scb that channel close */ 343 else 344 { 345 /* look up scb in stream routing table by ccb, tcid */ 346 p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl); 347 if (p_scb != NULL) 348 { 349 close.tcid = p_tbl->tcid; 350 close.type = avdt_ad_tcid_to_type(p_tbl->tcid); 351 avdt_scb_event(p_scb, AVDT_SCB_TC_CLOSE_EVT, (tAVDT_SCB_EVT *)&close); 352 } 353 } 354 } 355 356 /******************************************************************************* 357 ** 358 ** Function avdt_ad_tc_open_ind 359 ** 360 ** Description This function is called by the L2CAP interface when 361 ** the L2CAP channel is opened. It looks up the CCB or SCB 362 ** for the channel and sends it an open event. 363 ** 364 ** 365 ** Returns Nothing. 366 ** 367 *******************************************************************************/ 368 void avdt_ad_tc_open_ind(tAVDT_TC_TBL *p_tbl) 369 { 370 tAVDT_CCB *p_ccb; 371 tAVDT_SCB *p_scb; 372 tAVDT_OPEN open; 373 tAVDT_EVT_HDR evt; 374 375 p_tbl->state = AVDT_AD_ST_OPEN; 376 377 /* if signaling channel, notify ccb that channel open */ 378 if (p_tbl->tcid == 0) 379 { 380 /* set the signal channel to use high priority within the ACL link */ 381 L2CA_SetTxPriority(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][AVDT_CHAN_SIG].lcid, L2CAP_CHNL_PRIORITY_HIGH); 382 383 p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx); 384 /* use err_param to indicate the role of connection. 385 * AVDT_ACP, if ACP */ 386 evt.err_param = AVDT_INT; 387 if(p_tbl->cfg_flags & AVDT_L2C_CFG_CONN_ACP) 388 { 389 evt.err_param = AVDT_ACP; 390 } 391 avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, (tAVDT_CCB_EVT *)&evt); 392 } 393 /* if media or other channel, notify scb that channel open */ 394 else 395 { 396 /* look up scb in stream routing table by ccb, tcid */ 397 p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl); 398 399 /* put lcid in event data */ 400 if (p_scb != NULL) 401 { 402 open.peer_mtu = p_tbl->peer_mtu; 403 open.lcid = avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].lcid; 404 open.hdr.err_code = avdt_ad_tcid_to_type(p_tbl->tcid); 405 avdt_scb_event(p_scb, AVDT_SCB_TC_OPEN_EVT, (tAVDT_SCB_EVT *) &open); 406 } 407 } 408 } 409 410 411 /******************************************************************************* 412 ** 413 ** Function avdt_ad_tc_cong_ind 414 ** 415 ** Description This function is called by the L2CAP interface layer when 416 ** L2CAP calls the congestion callback. It looks up the CCB 417 ** or SCB for the channel and sends it a congestion event. 418 ** The is_congested parameter is the same value passed by 419 ** the L2CAP callback function. 420 ** 421 ** 422 ** Returns Nothing. 423 ** 424 *******************************************************************************/ 425 void avdt_ad_tc_cong_ind(tAVDT_TC_TBL *p_tbl, BOOLEAN is_congested) 426 { 427 tAVDT_CCB *p_ccb; 428 tAVDT_SCB *p_scb; 429 430 /* if signaling channel, notify ccb of congestion */ 431 if (p_tbl->tcid == 0) 432 { 433 p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx); 434 avdt_ccb_event(p_ccb, AVDT_CCB_LL_CONG_EVT, (tAVDT_CCB_EVT *) &is_congested); 435 } 436 /* if media or other channel, notify scb that channel open */ 437 else 438 { 439 /* look up scb in stream routing table by ccb, tcid */ 440 p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl); 441 if (p_scb != NULL) 442 { 443 avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT, (tAVDT_SCB_EVT *) &is_congested); 444 } 445 } 446 } 447 448 449 /******************************************************************************* 450 ** 451 ** Function avdt_ad_tc_data_ind 452 ** 453 ** Description This function is called by the L2CAP interface layer when 454 ** incoming data is received from L2CAP. It looks up the CCB 455 ** or SCB for the channel and routes the data accordingly. 456 ** 457 ** 458 ** Returns Nothing. 459 ** 460 *******************************************************************************/ 461 void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf) 462 { 463 tAVDT_CCB *p_ccb; 464 tAVDT_SCB *p_scb; 465 466 /* store type (media, recovery, reporting) */ 467 p_buf->layer_specific = avdt_ad_tcid_to_type(p_tbl->tcid); 468 469 470 /* if signaling channel, handle control message */ 471 if (p_tbl->tcid == 0) 472 { 473 p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx); 474 avdt_msg_ind(p_ccb, p_buf); 475 } 476 /* if media or other channel, send event to scb */ 477 else 478 { 479 p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl); 480 if (p_scb != NULL) 481 { 482 avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT *) &p_buf); 483 } 484 else 485 { 486 GKI_freebuf(p_buf); 487 AVDT_TRACE_ERROR(" avdt_ad_tc_data_ind buffer freed"); 488 } 489 } 490 } 491 492 /******************************************************************************* 493 ** 494 ** Function avdt_ad_write_req 495 ** 496 ** Description This function is called by a CCB or SCB to send data to a 497 ** transport channel. It looks up the LCID of the channel 498 ** based on the type, CCB, and SCB (if present). Then it 499 ** passes the data to L2CA_DataWrite(). 500 ** 501 ** 502 ** Returns AVDT_AD_SUCCESS, if data accepted, else FALSE 503 ** AVDT_AD_CONGESTED, if data accepted and the channel is congested 504 ** AVDT_AD_FAILED, if error 505 ** 506 *******************************************************************************/ 507 UINT8 avdt_ad_write_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, BT_HDR *p_buf) 508 { 509 UINT8 tcid; 510 511 /* get tcid from type, scb */ 512 tcid = avdt_ad_type_to_tcid(type, p_scb); 513 514 515 return L2CA_DataWrite(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid, p_buf); 516 } 517 518 519 /******************************************************************************* 520 ** 521 ** Function avdt_ad_open_req 522 ** 523 ** Description This function is called by a CCB or SCB to open a transport 524 ** channel. This function allocates and initializes a 525 ** transport channel table entry. The channel can be opened 526 ** in two roles: as an initiator or acceptor. When opened 527 ** as an initiator the function will start an L2CAP connection. 528 ** When opened as an acceptor the function simply configures 529 ** the table entry to listen for an incoming channel. 530 ** 531 ** 532 ** Returns Nothing. 533 ** 534 *******************************************************************************/ 535 void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role) 536 { 537 tAVDT_TC_TBL *p_tbl; 538 UINT16 lcid; 539 540 p_tbl = avdt_ad_tc_tbl_alloc(p_ccb); 541 542 p_tbl->tcid = avdt_ad_type_to_tcid(type, p_scb); 543 AVDT_TRACE_DEBUG("avdt_ad_open_req: type: %d, role: %d, tcid:%d", 544 type, role, p_tbl->tcid); 545 546 if (type == AVDT_CHAN_SIG) 547 { 548 /* if signaling, get mtu from registration control block */ 549 p_tbl->my_mtu = avdt_cb.rcb.ctrl_mtu; 550 p_tbl->my_flush_to = L2CAP_DEFAULT_FLUSH_TO; 551 } 552 else 553 { 554 /* otherwise get mtu from scb */ 555 p_tbl->my_mtu = p_scb->cs.mtu; 556 p_tbl->my_flush_to = p_scb->cs.flush_to; 557 558 /* also set scb_hdl in rt_tbl */ 559 avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].scb_hdl = avdt_scb_to_hdl(p_scb); 560 AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].scb_hdl = %d", 561 avdt_ccb_to_idx(p_ccb), p_tbl->tcid, 562 avdt_scb_to_hdl(p_scb)); 563 } 564 565 /* if we're acceptor, we're done; just sit back and listen */ 566 if (role == AVDT_ACP) 567 { 568 p_tbl->state = AVDT_AD_ST_ACP; 569 } 570 /* else we're inititator, start the L2CAP connection */ 571 else 572 { 573 p_tbl->state = AVDT_AD_ST_CONN; 574 575 /* call l2cap connect req */ 576 if ((lcid = L2CA_ConnectReq(AVDT_PSM, p_ccb->peer_addr)) != 0) 577 { 578 /* if connect req ok, store tcid in lcid table */ 579 avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID] = avdt_ad_tc_tbl_to_idx(p_tbl); 580 AVDT_TRACE_DEBUG("avdt_cb.ad.lcid_tbl[%d] = %d", 581 (lcid - L2CAP_BASE_APPL_CID), avdt_ad_tc_tbl_to_idx(p_tbl)); 582 583 avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][p_tbl->tcid].lcid = lcid; 584 AVDT_TRACE_DEBUG("avdt_cb.ad.rt_tbl[%d][%d].lcid = 0x%x", 585 avdt_ccb_to_idx(p_ccb), p_tbl->tcid, 586 lcid); 587 } 588 else 589 { 590 /* if connect req failed, call avdt_ad_tc_close_ind() */ 591 avdt_ad_tc_close_ind(p_tbl, 0); 592 } 593 } 594 } 595 596 /******************************************************************************* 597 ** 598 ** Function avdt_ad_close_req 599 ** 600 ** Description This function is called by a CCB or SCB to close a 601 ** transport channel. The function looks up the LCID for the 602 ** channel and calls L2CA_DisconnectReq(). 603 ** 604 ** 605 ** Returns Nothing. 606 ** 607 *******************************************************************************/ 608 void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb) 609 { 610 UINT8 tcid; 611 tAVDT_TC_TBL *p_tbl; 612 613 p_tbl = avdt_ad_tc_tbl_by_type(type, p_ccb, p_scb); 614 AVDT_TRACE_DEBUG("avdt_ad_close_req state: %d", p_tbl->state); 615 616 switch(p_tbl->state) 617 { 618 case AVDT_AD_ST_UNUSED: 619 /* probably for reporting */ 620 break; 621 case AVDT_AD_ST_ACP: 622 /* if we're listening on this channel, send ourselves a close ind */ 623 avdt_ad_tc_close_ind(p_tbl, 0); 624 break; 625 default: 626 /* get tcid from type, scb */ 627 tcid = avdt_ad_type_to_tcid(type, p_scb); 628 629 /* call l2cap disconnect req */ 630 L2CA_DisconnectReq(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid); 631 } 632 } 633 634