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*******************************************************************************/ 47UINT8 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*******************************************************************************/ 75static 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*******************************************************************************/ 107void 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*******************************************************************************/ 134tAVDT_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*******************************************************************************/ 202tAVDT_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*******************************************************************************/ 230tAVDT_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*******************************************************************************/ 264tAVDT_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*******************************************************************************/ 300UINT8 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*******************************************************************************/ 321void 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*******************************************************************************/ 368void 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*******************************************************************************/ 425void 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*******************************************************************************/ 461void 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*******************************************************************************/ 507UINT8 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*******************************************************************************/ 535void 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*******************************************************************************/ 608void 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