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 <assert.h>
26#include <string.h>
27
28#include "bt_types.h"
29#include "bt_target.h"
30#include "bt_utils.h"
31#include "avdt_api.h"
32#include "avdtc_api.h"
33#include "avdt_int.h"
34#include "l2c_api.h"
35#include "l2cdefs.h"
36
37
38/*******************************************************************************
39**
40** Function         avdt_ad_type_to_tcid
41**
42** Description      Derives the TCID from the channel type and SCB.
43**
44**
45** Returns          TCID value.
46**
47*******************************************************************************/
48UINT8 avdt_ad_type_to_tcid(UINT8 type, tAVDT_SCB *p_scb)
49{
50    UINT8 scb_idx;
51
52    if (type == AVDT_CHAN_SIG)
53    {
54        return 0;
55    }
56    else
57    {
58        scb_idx = avdt_scb_to_hdl(p_scb) - 1;
59        /*
60        AVDT_TRACE_DEBUG("type: %d, tcid: %d", type, ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type));
61        */
62        return ((scb_idx * (AVDT_CHAN_NUM_TYPES - 1)) + type);
63    }
64}
65
66/*******************************************************************************
67**
68** Function         avdt_ad_tcid_to_type
69**
70** Description      Derives the channel type from the TCID.
71**
72**
73** Returns          Channel type value.
74**
75*******************************************************************************/
76static UINT8 avdt_ad_tcid_to_type(UINT8 tcid)
77{
78    UINT8 type;
79
80    if (tcid == 0)
81    {
82        type = AVDT_CHAN_SIG;
83    }
84    else
85    {
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...
90        */
91        type = ((tcid + AVDT_CHAN_NUM_TYPES - 2) % (AVDT_CHAN_NUM_TYPES - 1)) + 1;
92    }
93    AVDT_TRACE_DEBUG("tcid: %d, type: %d", tcid, type);
94    return type;
95}
96
97
98/*******************************************************************************
99**
100** Function         avdt_ad_init
101**
102** Description      Initialize adaption layer.
103**
104**
105** Returns          Nothing.
106**
107*******************************************************************************/
108void avdt_ad_init(void)
109{
110    int             i;
111    tAVDT_TC_TBL    *p_tbl = avdt_cb.ad.tc_tbl;
112    memset(&avdt_cb.ad, 0, sizeof(tAVDT_AD));
113
114    /* make sure the peer_mtu is a valid value */
115    for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
116    {
117        p_tbl->peer_mtu = L2CAP_DEFAULT_MTU;
118    }
119}
120
121
122/*******************************************************************************
123**
124** Function         avdt_ad_tc_tbl_by_st
125**
126** Description      Find adaption layer transport channel table entry matching
127**                  the given state.
128**
129**
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).
133**
134*******************************************************************************/
135tAVDT_TC_TBL *avdt_ad_tc_tbl_by_st(UINT8 type, tAVDT_CCB *p_ccb, UINT8 state)
136{
137    int             i;
138    tAVDT_TC_TBL    *p_tbl = avdt_cb.ad.tc_tbl;
139    UINT8           ccb_idx;
140
141    if (p_ccb == NULL)
142    {
143        /* resending security req */
144        for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
145        {
146            /* must be AVDT_CHAN_SIG - tcid always zero */
147            if ((p_tbl->tcid == 0) &&
148                (p_tbl->state == state))
149            {
150                break;
151            }
152        }
153    }
154    else
155    {
156        ccb_idx = avdt_ccb_to_idx(p_ccb);
157
158        for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
159        {
160            if (type == AVDT_CHAN_SIG)
161            {
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))
166                {
167                    break;
168                }
169            }
170            else
171            {
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))
176                {
177                    break;
178                }
179            }
180        }
181    }
182
183    /* if nothing found return null */
184    if (i == AVDT_NUM_TC_TBL)
185    {
186        p_tbl = NULL;
187    }
188
189    return p_tbl;
190}
191
192
193/*******************************************************************************
194**
195** Function         avdt_ad_tc_tbl_by_lcid
196**
197** Description      Find adaption layer transport channel table entry by LCID.
198**
199**
200** Returns          Pointer to entry.
201**
202*******************************************************************************/
203tAVDT_TC_TBL *avdt_ad_tc_tbl_by_lcid(UINT16 lcid)
204{
205    UINT8 idx;
206
207    idx = avdt_cb.ad.lcid_tbl[lcid - L2CAP_BASE_APPL_CID];
208
209    if (idx < AVDT_NUM_TC_TBL)
210    {
211        return &avdt_cb.ad.tc_tbl[idx];
212    }
213    else
214    {
215        return NULL;
216    }
217}
218
219
220/*******************************************************************************
221**
222** Function         avdt_ad_tc_tbl_by_type
223**
224** Description      This function retrieves the transport channel table entry
225**                  for a particular channel.
226**
227**
228** Returns          Pointer to transport channel table entry.
229**
230*******************************************************************************/
231tAVDT_TC_TBL *avdt_ad_tc_tbl_by_type(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
232{
233    UINT8           tcid;
234    int             i;
235    tAVDT_TC_TBL    *p_tbl = avdt_cb.ad.tc_tbl;
236    UINT8           ccb_idx = avdt_ccb_to_idx(p_ccb);
237
238    /* get tcid from type, scb */
239    tcid = avdt_ad_type_to_tcid(type, p_scb);
240
241    for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
242    {
243        if ((p_tbl->tcid == tcid) && (p_tbl->ccb_idx == ccb_idx))
244        {
245            break;
246        }
247    }
248
249    assert(i != AVDT_NUM_TC_TBL);
250
251    return p_tbl;
252}
253
254
255/*******************************************************************************
256**
257** Function         avdt_ad_tc_tbl_alloc
258**
259** Description      Allocate an entry in the traffic channel table.
260**
261**
262** Returns          Pointer to entry.
263**
264*******************************************************************************/
265tAVDT_TC_TBL *avdt_ad_tc_tbl_alloc(tAVDT_CCB *p_ccb)
266{
267    int             i;
268    tAVDT_TC_TBL    *p_tbl = avdt_cb.ad.tc_tbl;
269
270    /* find next free entry in tc table */
271    for (i = 0; i < AVDT_NUM_TC_TBL; i++, p_tbl++)
272    {
273        if (p_tbl->state == AVDT_AD_ST_UNUSED)
274        {
275            break;
276        }
277    }
278
279    /* sanity check */
280    assert(i != AVDT_NUM_TC_TBL);
281
282
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;
288    return p_tbl;
289
290}
291
292/*******************************************************************************
293**
294** Function         avdt_ad_tc_tbl_to_idx
295**
296** Description      Convert a transport channel table entry to an index.
297**
298**
299** Returns          Index value.
300**
301*******************************************************************************/
302UINT8 avdt_ad_tc_tbl_to_idx(tAVDT_TC_TBL *p_tbl)
303{
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);
307}
308
309/*******************************************************************************
310**
311** Function         avdt_ad_tc_close_ind
312**
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.
318**
319**
320** Returns          Nothing.
321**
322*******************************************************************************/
323void avdt_ad_tc_close_ind(tAVDT_TC_TBL *p_tbl, UINT16 reason)
324{
325    tAVDT_CCB   *p_ccb;
326    tAVDT_SCB   *p_scb;
327    tAVDT_SCB_TC_CLOSE  close;
328    UNUSED(reason);
329
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;
335
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)
340    {
341        p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
342        avdt_ccb_event(p_ccb, AVDT_CCB_LL_CLOSE_EVT, NULL);
343    }
344    /* if media or other channel, notify scb that channel close */
345    else
346    {
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);
349        if (p_scb != NULL)
350        {
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);
354        }
355    }
356}
357
358/*******************************************************************************
359**
360** Function         avdt_ad_tc_open_ind
361**
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.
365**
366**
367** Returns          Nothing.
368**
369*******************************************************************************/
370void avdt_ad_tc_open_ind(tAVDT_TC_TBL *p_tbl)
371{
372    tAVDT_CCB   *p_ccb;
373    tAVDT_SCB   *p_scb;
374    tAVDT_OPEN  open;
375    tAVDT_EVT_HDR evt;
376
377    p_tbl->state = AVDT_AD_ST_OPEN;
378
379    /* if signaling channel, notify ccb that channel open */
380    if (p_tbl->tcid == 0)
381    {
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);
384
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)
390        {
391            evt.err_param = AVDT_ACP;
392        }
393        avdt_ccb_event(p_ccb, AVDT_CCB_LL_OPEN_EVT, (tAVDT_CCB_EVT *)&evt);
394    }
395    /* if media or other channel, notify scb that channel open */
396    else
397    {
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);
400
401        /* put lcid in event data */
402        if (p_scb != NULL)
403        {
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);
408        }
409    }
410}
411
412
413/*******************************************************************************
414**
415** Function         avdt_ad_tc_cong_ind
416**
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.
422**
423**
424** Returns          Nothing.
425**
426*******************************************************************************/
427void avdt_ad_tc_cong_ind(tAVDT_TC_TBL *p_tbl, BOOLEAN is_congested)
428{
429    tAVDT_CCB   *p_ccb;
430    tAVDT_SCB   *p_scb;
431
432    /* if signaling channel, notify ccb of congestion */
433    if (p_tbl->tcid == 0)
434    {
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);
437    }
438    /* if media or other channel, notify scb that channel open */
439    else
440    {
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);
443        if (p_scb != NULL)
444        {
445            avdt_scb_event(p_scb, AVDT_SCB_TC_CONG_EVT, (tAVDT_SCB_EVT *) &is_congested);
446        }
447    }
448}
449
450
451/*******************************************************************************
452**
453** Function         avdt_ad_tc_data_ind
454**
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.
458**
459**
460** Returns          Nothing.
461**
462*******************************************************************************/
463void avdt_ad_tc_data_ind(tAVDT_TC_TBL *p_tbl, BT_HDR *p_buf)
464{
465    tAVDT_CCB   *p_ccb;
466    tAVDT_SCB   *p_scb;
467
468    /* store type (media, recovery, reporting) */
469    p_buf->layer_specific = avdt_ad_tcid_to_type(p_tbl->tcid);
470
471
472    /* if signaling channel, handle control message */
473    if (p_tbl->tcid == 0)
474    {
475        p_ccb = avdt_ccb_by_idx(p_tbl->ccb_idx);
476        avdt_msg_ind(p_ccb, p_buf);
477    }
478    /* if media or other channel, send event to scb */
479    else
480    {
481        p_scb = avdt_scb_by_hdl(avdt_cb.ad.rt_tbl[p_tbl->ccb_idx][p_tbl->tcid].scb_hdl);
482        if (p_scb != NULL)
483        {
484            avdt_scb_event(p_scb, AVDT_SCB_TC_DATA_EVT, (tAVDT_SCB_EVT *) &p_buf);
485        }
486        else
487        {
488            osi_free(p_buf);
489            AVDT_TRACE_ERROR(" avdt_ad_tc_data_ind buffer freed");
490        }
491    }
492}
493
494/*******************************************************************************
495**
496** Function         avdt_ad_write_req
497**
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().
502**
503**
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
507**
508*******************************************************************************/
509UINT8 avdt_ad_write_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, BT_HDR *p_buf)
510{
511    UINT8   tcid;
512
513    /* get tcid from type, scb */
514    tcid = avdt_ad_type_to_tcid(type, p_scb);
515
516
517    return L2CA_DataWrite(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid, p_buf);
518}
519
520
521/*******************************************************************************
522**
523** Function         avdt_ad_open_req
524**
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.
532**
533**
534** Returns          Nothing.
535**
536*******************************************************************************/
537void avdt_ad_open_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb, UINT8 role)
538{
539    tAVDT_TC_TBL    *p_tbl;
540    UINT16          lcid;
541
542    if((p_tbl = avdt_ad_tc_tbl_alloc(p_ccb)) == NULL)
543    {
544        AVDT_TRACE_ERROR("avdt_ad_open_req: Cannot allocate p_tbl");
545        return;
546    }
547
548
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);
552
553    if (type == AVDT_CHAN_SIG)
554    {
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;
558    }
559    else
560    {
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;
564
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));
570    }
571
572    /* if we're acceptor, we're done; just sit back and listen */
573    if (role == AVDT_ACP)
574    {
575        p_tbl->state = AVDT_AD_ST_ACP;
576    }
577    /* else we're inititator, start the L2CAP connection */
578    else
579    {
580        p_tbl->state = AVDT_AD_ST_CONN;
581
582        /* call l2cap connect req */
583        if ((lcid = L2CA_ConnectReq(AVDT_PSM, p_ccb->peer_addr)) != 0)
584        {
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));
589
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,
593                lcid);
594        }
595        else
596        {
597            /* if connect req failed, call avdt_ad_tc_close_ind() */
598            avdt_ad_tc_close_ind(p_tbl, 0);
599        }
600    }
601}
602
603/*******************************************************************************
604**
605** Function         avdt_ad_close_req
606**
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().
610**
611**
612** Returns          Nothing.
613**
614*******************************************************************************/
615void avdt_ad_close_req(UINT8 type, tAVDT_CCB *p_ccb, tAVDT_SCB *p_scb)
616{
617    UINT8           tcid;
618    tAVDT_TC_TBL    *p_tbl;
619
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);
622
623    switch(p_tbl->state)
624    {
625    case AVDT_AD_ST_UNUSED:
626        /* probably for reporting */
627        break;
628    case AVDT_AD_ST_ACP:
629        /* if we're listening on this channel, send ourselves a close ind */
630        avdt_ad_tc_close_ind(p_tbl, 0);
631        break;
632    default:
633        /* get tcid from type, scb */
634        tcid = avdt_ad_type_to_tcid(type, p_scb);
635
636        /* call l2cap disconnect req */
637        L2CA_DisconnectReq(avdt_cb.ad.rt_tbl[avdt_ccb_to_idx(p_ccb)][tcid].lcid);
638    }
639}
640
641