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