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