1 /******************************************************************************
3 * Copyright (C) 2002-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This module contains the AVDTP adaption layer.
23 ******************************************************************************/
29 #include "bt_target.h"
32 #include "avdtc_api.h"
38 /*******************************************************************************
40 ** Function avdt_ad_type_to_tcid
42 ** Description Derives the TCID from the channel type and SCB.
45 ** Returns TCID value.
47 *******************************************************************************/
48 UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb)
52 if (type == AVDT_CHAN_SIG)
58 scb_idx = avdt_scb_to_hdl(p_scb) - 1;
60 AVDT_TRACE_DEBUG("type: %d, tcid: %d", type, ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type));
62 return ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type);
66 /*******************************************************************************
68 ** Function avdt_ad_tcid_to_type
70 ** Description Derives the channel type from the TCID.
73 ** Returns Channel type value.
75 *******************************************************************************/
76 static UINT8 avdt_ad_tcid_to_type(UINT8 tcid)
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...
91 type = ((tcid + AVDT_CHAN_NUM_TYPES - 2) % (AVDT_CHAN_NUM_TYPES - 1)) + 1;
93 AVDT_TRACE_DEBUG("tcid: %d, type: %d", tcid, type);
98 /*******************************************************************************
100 ** Function avdt_ad_init
102 ** Description Initialize adaption layer.
107 *******************************************************************************/
108 void avdt_ad_init(void)
111 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
112 memset(&avdt_cb.ad, 0, sizeof(tAVDT_AD));
114 /* make sure the peer_mtu is a valid value */
115 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
117 p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
122 /*******************************************************************************
124 ** Function avdt_ad_tc_tbl_by_st
126 ** Description Find adaption layer transport channel table entry matching
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).
134 *******************************************************************************/
135 tAVDT_TC_TBL *avdt_ad_tc_tbl_by_st(UINT8 type, tAVDT_CCB *p_ccb, UINT8 state)
138 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
143 /* resending security req */
144 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
146 /* must be AVDT_CHAN_SIG - tcid always zero */
147 if ((p_tbl->tcid == 0) &&
148 (p_tbl->state == state))
156 ccb_idx = avdt_ccb_to_idx(p_ccb);
158 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
160 if (type == AVDT_CHAN_SIG)
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))
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))
183 /* if nothing found return null */
184 if (i == AVDT_NUM_TC_TBL)
193 /*******************************************************************************
195 ** Function avdt_ad_tc_tbl_by_lcid
197 ** Description Find adaption layer transport channel table entry by LCID.
200 ** Returns Pointer to entry.
202 *******************************************************************************/
203 tAVDT_TC_TBL *avdt_ad_tc_tbl_by_lcid(UINT16 lcid)
207 idx = avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID];
209 if (idx < AVDT_NUM_TC_TBL)
211 return &avdt_cb.ad.tc_tbl[idx];
220 /*******************************************************************************
222 ** Function avdt_ad_tc_tbl_by_type
224 ** Description This function retrieves the transport channel table entry
225 ** for a particular channel.
228 ** Returns Pointer to transport channel table entry.
230 *******************************************************************************/
231 tAVDT_TC_TBL *avdt_ad_tc_tbl_by_type(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
235 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
236 UINT8 ccb_idx = avdt_ccb_to_idx(p_ccb);
238 /* get tcid from type, scb */
239 tcid = avdt_ad_type_to_tcid(type, p_scb);
241 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
243 if ((p_tbl->tcid == tcid) && (p_tbl->ccb_idx == ccb_idx))
249 assert(i != AVDT_NUM_TC_TBL);
255 /*******************************************************************************
257 ** Function avdt_ad_tc_tbl_alloc
259 ** Description Allocate an entry in the traffic channel table.
262 ** Returns Pointer to entry.
264 *******************************************************************************/
265 tAVDT_TC_TBL *avdt_ad_tc_tbl_alloc(tAVDT_CCB *p_ccb)
268 tAVDT_TC_TBL *p_tbl = avdt_cb.ad.tc_tbl;
270 /* find next free entry in tc table */
271 for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
273 if (p_tbl->state == AVDT_AD_ST_UNUSED)
280 assert(i != AVDT_NUM_TC_TBL);
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;
292 /*******************************************************************************
294 ** Function avdt_ad_tc_tbl_to_idx
296 ** Description Convert a transport channel table entry to an index.
299 ** Returns Index value.
301 *******************************************************************************/
302 UINT8 avdt_ad_tc_tbl_to_idx(tAVDT_TC_TBL *p_tbl)
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);
309 /*******************************************************************************
311 ** Function avdt_ad_tc_close_ind
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.
322 *******************************************************************************/
323 void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason)
327 tAVDT_SCB_TC_CLOSE close;
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;
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)
341 p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
342 avdt_ccb_event(p_ccb, AVDT_CCB_LL_CLOSE_EVT, NULL);
344 /* if media or other channel, notify scb that channel close */
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);
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);
358 /*******************************************************************************
360 ** Function avdt_ad_tc_open_ind
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.
369 *******************************************************************************/
370 void avdt_ad_tc_open_ind(tAVDT_TC_TBL *p_tbl)
377 p_tbl->state = AVDT_AD_ST_OPEN;
379 /* if signaling channel, notify ccb that channel open */
380 if (p_tbl->tcid == 0)
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);
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)
391 evt.err_param = AVDT_ACP;
393 avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, (tAVDT_CCB_EVT *)&evt);
395 /* if media or other channel, notify scb that channel open */
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);
401 /* put lcid in event data */
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);
413 /*******************************************************************************
415 ** Function avdt_ad_tc_cong_ind
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.
426 *******************************************************************************/
427 void avdt_ad_tc_cong_ind(tAVDT_TC_TBL *p_tbl, BOOLEAN is_congested)
432 /* if signaling channel, notify ccb of congestion */
433 if (p_tbl->tcid == 0)
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);
438 /* if media or other channel, notify scb that channel open */
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);
445 avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT, (tAVDT_SCB_EVT *) &is_congested);
451 /*******************************************************************************
453 ** Function avdt_ad_tc_data_ind
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.
462 *******************************************************************************/
463 void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf)
468 /* store type (media, recovery, reporting) */
469 p_buf->layer_specific = avdt_ad_tcid_to_type(p_tbl->tcid);
472 /* if signaling channel, handle control message */
473 if (p_tbl->tcid == 0)
475 p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
476 avdt_msg_ind(p_ccb, p_buf);
478 /* if media or other channel, send event to scb */
481 p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
484 avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT *) &p_buf);
489 AVDT_TRACE_ERROR(" avdt_ad_tc_data_ind buffer freed");
494 /*******************************************************************************
496 ** Function avdt_ad_write_req
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().
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
508 *******************************************************************************/
509 UINT8 avdt_ad_write_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, BT_HDR *p_buf)
513 /* get tcid from type, scb */
514 tcid = avdt_ad_type_to_tcid(type, p_scb);
517 return L2CA_DataWrite(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid, p_buf);
521 /*******************************************************************************
523 ** Function avdt_ad_open_req
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.
536 *******************************************************************************/
537 void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role)
542 if((p_tbl = avdt_ad_tc_tbl_alloc(p_ccb)) == NULL)
544 AVDT_TRACE_ERROR("avdt_ad_open_req: Cannot allocate p_tbl");
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);
553 if (type == AVDT_CHAN_SIG)
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;
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;
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));
572 /* if we're acceptor, we're done; just sit back and listen */
573 if (role == AVDT_ACP)
575 p_tbl->state = AVDT_AD_ST_ACP;
577 /* else we're inititator, start the L2CAP connection */
580 p_tbl->state = AVDT_AD_ST_CONN;
582 /* call l2cap connect req */
583 if ((lcid = L2CA_ConnectReq(AVDT_PSM, p_ccb->peer_addr)) != 0)
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));
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,
597 /* if connect req failed, call avdt_ad_tc_close_ind() */
598 avdt_ad_tc_close_ind(p_tbl, 0);
603 /*******************************************************************************
605 ** Function avdt_ad_close_req
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().
614 *******************************************************************************/
615 void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
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);
625 case AVDT_AD_ST_UNUSED:
626 /* probably for reporting */
629 /* if we're listening on this channel, send ourselves a close ind */
630 avdt_ad_tc_close_ind(p_tbl, 0);
633 /* get tcid from type, scb */
634 tcid = avdt_ad_type_to_tcid(type, p_scb);
636 /* call l2cap disconnect req */
637 L2CA_DisconnectReq(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid);