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*******************************************************************************/
46UINT8 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*******************************************************************************/
74static 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*******************************************************************************/
106void 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*******************************************************************************/
133tAVDT_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*******************************************************************************/
201tAVDT_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*******************************************************************************/
229tAVDT_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*******************************************************************************/
263tAVDT_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*******************************************************************************/
299UINT8 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*******************************************************************************/
320void 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*******************************************************************************/
366void 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*******************************************************************************/
423void 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*******************************************************************************/
459void 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*******************************************************************************/
502UINT8 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*******************************************************************************/
530void 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*******************************************************************************/
603void 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