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