1/******************************************************************************
2 *
3 *  Copyright (C) 2003-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 link control state machine and functions which
22 *  operate on the link control block.
23 *
24 ******************************************************************************/
25
26#include <string.h>
27#include "data_types.h"
28#include "bt_target.h"
29#include "avct_api.h"
30#include "avct_int.h"
31#include "gki.h"
32
33/*****************************************************************************
34** state machine constants and types
35*****************************************************************************/
36
37#if BT_TRACE_VERBOSE == TRUE
38
39/* verbose state strings for trace */
40const char * const avct_lcb_st_str[] = {
41    "LCB_IDLE_ST",
42    "LCB_OPENING_ST",
43    "LCB_OPEN_ST",
44    "LCB_CLOSING_ST"
45};
46
47/* verbose event strings for trace */
48const char * const avct_lcb_evt_str[] = {
49    "UL_BIND_EVT",
50    "UL_UNBIND_EVT",
51    "UL_MSG_EVT",
52    "INT_CLOSE_EVT",
53    "LL_OPEN_EVT",
54    "LL_CLOSE_EVT",
55    "LL_MSG_EVT",
56    "LL_CONG_EVT"
57};
58
59#endif
60
61/* lcb state machine states */
62enum {
63    AVCT_LCB_IDLE_ST,
64    AVCT_LCB_OPENING_ST,
65    AVCT_LCB_OPEN_ST,
66    AVCT_LCB_CLOSING_ST
67};
68
69/* state machine action enumeration list */
70enum {
71    AVCT_LCB_CHNL_OPEN,
72    AVCT_LCB_CHNL_DISC,
73    AVCT_LCB_SEND_MSG,
74    AVCT_LCB_OPEN_IND,
75    AVCT_LCB_OPEN_FAIL,
76    AVCT_LCB_CLOSE_IND,
77    AVCT_LCB_CLOSE_CFM,
78    AVCT_LCB_MSG_IND,
79    AVCT_LCB_CONG_IND,
80    AVCT_LCB_BIND_CONN,
81    AVCT_LCB_BIND_FAIL,
82    AVCT_LCB_UNBIND_DISC,
83    AVCT_LCB_CHK_DISC,
84    AVCT_LCB_DISCARD_MSG,
85    AVCT_LCB_DEALLOC,
86    AVCT_LCB_FREE_MSG_IND,
87    AVCT_LCB_NUM_ACTIONS
88};
89
90#define AVCT_LCB_IGNORE     AVCT_LCB_NUM_ACTIONS
91
92/* type for action functions */
93typedef void (*tAVCT_LCB_ACTION)(tAVCT_LCB *p_ccb, tAVCT_LCB_EVT *p_data);
94
95/* action function list */
96const tAVCT_LCB_ACTION avct_lcb_action[] = {
97    avct_lcb_chnl_open,
98    avct_lcb_chnl_disc,
99    avct_lcb_send_msg,
100    avct_lcb_open_ind,
101    avct_lcb_open_fail,
102    avct_lcb_close_ind,
103    avct_lcb_close_cfm,
104    avct_lcb_msg_ind,
105    avct_lcb_cong_ind,
106    avct_lcb_bind_conn,
107    avct_lcb_bind_fail,
108    avct_lcb_unbind_disc,
109    avct_lcb_chk_disc,
110    avct_lcb_discard_msg,
111    avct_lcb_dealloc,
112    avct_lcb_free_msg_ind
113};
114
115/* state table information */
116#define AVCT_LCB_ACTIONS            2       /* number of actions */
117#define AVCT_LCB_NEXT_STATE         2       /* position of next state */
118#define AVCT_LCB_NUM_COLS           3       /* number of columns in state tables */
119
120/* state table for idle state */
121const UINT8 avct_lcb_st_idle[][AVCT_LCB_NUM_COLS] = {
122/* Event                Action 1                    Action 2                    Next state */
123/* UL_BIND_EVT */       {AVCT_LCB_CHNL_OPEN,        AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
124/* UL_UNBIND_EVT */     {AVCT_LCB_UNBIND_DISC,      AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
125/* UL_MSG_EVT */        {AVCT_LCB_DISCARD_MSG,      AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
126/* INT_CLOSE_EVT */     {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
127/* LL_OPEN_EVT */       {AVCT_LCB_OPEN_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
128/* LL_CLOSE_EVT */      {AVCT_LCB_CLOSE_IND,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
129/* LL_MSG_EVT */        {AVCT_LCB_FREE_MSG_IND,     AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
130/* LL_CONG_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST}
131};
132
133/* state table for opening state */
134const UINT8 avct_lcb_st_opening[][AVCT_LCB_NUM_COLS] = {
135/* Event                Action 1                    Action 2                    Next state */
136/* UL_BIND_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
137/* UL_UNBIND_EVT */     {AVCT_LCB_UNBIND_DISC,      AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
138/* UL_MSG_EVT */        {AVCT_LCB_DISCARD_MSG,      AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
139/* INT_CLOSE_EVT */     {AVCT_LCB_CHNL_DISC,        AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
140/* LL_OPEN_EVT */       {AVCT_LCB_OPEN_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
141/* LL_CLOSE_EVT */      {AVCT_LCB_OPEN_FAIL,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
142/* LL_MSG_EVT */        {AVCT_LCB_FREE_MSG_IND,     AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
143/* LL_CONG_EVT */       {AVCT_LCB_CONG_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST}
144};
145
146/* state table for open state */
147const UINT8 avct_lcb_st_open[][AVCT_LCB_NUM_COLS] = {
148/* Event                Action 1                    Action 2                    Next state */
149/* UL_BIND_EVT */       {AVCT_LCB_BIND_CONN,        AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
150/* UL_UNBIND_EVT */     {AVCT_LCB_CHK_DISC,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
151/* UL_MSG_EVT */        {AVCT_LCB_SEND_MSG,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
152/* INT_CLOSE_EVT */     {AVCT_LCB_CHNL_DISC,        AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
153/* LL_OPEN_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
154/* LL_CLOSE_EVT */      {AVCT_LCB_CLOSE_IND,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
155/* LL_MSG_EVT */        {AVCT_LCB_MSG_IND,          AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
156/* LL_CONG_EVT */       {AVCT_LCB_CONG_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST}
157};
158
159/* state table for closing state */
160const UINT8 avct_lcb_st_closing[][AVCT_LCB_NUM_COLS] = {
161/* Event                Action 1                    Action 2                    Next state */
162/* UL_BIND_EVT */       {AVCT_LCB_BIND_FAIL,        AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
163/* UL_UNBIND_EVT */     {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
164/* UL_MSG_EVT */        {AVCT_LCB_DISCARD_MSG,      AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
165/* INT_CLOSE_EVT */     {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
166/* LL_OPEN_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
167/* LL_CLOSE_EVT */      {AVCT_LCB_CLOSE_CFM,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
168/* LL_MSG_EVT */        {AVCT_LCB_FREE_MSG_IND,     AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
169/* LL_CONG_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST}
170};
171
172/* type for state table */
173typedef const UINT8 (*tAVCT_LCB_ST_TBL)[AVCT_LCB_NUM_COLS];
174
175/* state table */
176const tAVCT_LCB_ST_TBL avct_lcb_st_tbl[] = {
177    avct_lcb_st_idle,
178    avct_lcb_st_opening,
179    avct_lcb_st_open,
180    avct_lcb_st_closing
181};
182
183/*******************************************************************************
184**
185** Function         avct_lcb_event
186**
187** Description      State machine event handling function for lcb
188**
189**
190** Returns          Nothing.
191**
192*******************************************************************************/
193void avct_lcb_event(tAVCT_LCB *p_lcb, UINT8 event, tAVCT_LCB_EVT *p_data)
194{
195    tAVCT_LCB_ST_TBL    state_table;
196    UINT8               action;
197    int                 i;
198
199#if BT_TRACE_VERBOSE == TRUE
200    AVCT_TRACE_EVENT3("LCB lcb=%d event=%s state=%s", p_lcb->allocated, avct_lcb_evt_str[event], avct_lcb_st_str[p_lcb->state]);
201#else
202    AVCT_TRACE_EVENT3("LCB lcb=%d event=%d state=%d", p_lcb->allocated, event, p_lcb->state);
203#endif
204
205    /* look up the state table for the current state */
206    state_table = avct_lcb_st_tbl[p_lcb->state];
207
208    /* set next state */
209    p_lcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
210
211    /* execute action functions */
212    for (i = 0; i < AVCT_LCB_ACTIONS; i++)
213    {
214        if ((action = state_table[event][i]) != AVCT_LCB_IGNORE)
215        {
216            (*avct_lcb_action[action])(p_lcb, p_data);
217        }
218        else
219        {
220            break;
221        }
222    }
223}
224
225/*******************************************************************************
226**
227** Function         avct_bcb_event
228**
229** Description      State machine event handling function for lcb
230**
231**
232** Returns          Nothing.
233**
234*******************************************************************************/
235#if (AVCT_BROWSE_INCLUDED == TRUE)
236void avct_bcb_event(tAVCT_BCB *p_bcb, UINT8 event, tAVCT_LCB_EVT *p_data)
237{
238    tAVCT_LCB_ST_TBL    state_table;
239    UINT8               action;
240    int                 i;
241
242#if BT_TRACE_VERBOSE == TRUE
243    AVCT_TRACE_EVENT3("BCB lcb=%d event=%s state=%s", p_bcb->allocated, avct_lcb_evt_str[event], avct_lcb_st_str[p_bcb->state]);
244#else
245    AVCT_TRACE_EVENT3("BCB lcb=%d event=%d state=%d", p_bcb->allocated, event, p_bcb->state);
246#endif
247
248    /* look up the state table for the current state */
249    state_table = avct_lcb_st_tbl[p_bcb->state];
250
251    /* set next state */
252    p_bcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
253
254    /* execute action functions */
255    for (i = 0; i < AVCT_LCB_ACTIONS; i++)
256    {
257        if ((action = state_table[event][i]) != AVCT_LCB_IGNORE)
258        {
259            (*avct_bcb_action[action])(p_bcb, p_data);
260        }
261        else
262        {
263            break;
264        }
265    }
266}
267#endif
268
269/*******************************************************************************
270**
271** Function         avct_lcb_by_bd
272**
273** Description      This lookup function finds the lcb for a BD address.
274**
275**
276** Returns          pointer to the lcb, or NULL if none found.
277**
278*******************************************************************************/
279tAVCT_LCB *avct_lcb_by_bd(BD_ADDR bd_addr)
280{
281    tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
282    int         i;
283
284    for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
285    {
286        /* if allocated lcb has matching lcb */
287        if (p_lcb->allocated && (!memcmp(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN)))
288        {
289            break;
290        }
291    }
292
293    if (i == AVCT_NUM_LINKS)
294    {
295        /* if no lcb found */
296        p_lcb = NULL;
297
298        AVCT_TRACE_DEBUG6("No lcb for addr %02x-%02x-%02x-%02x-%02x-%02x",
299                          bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
300    }
301    return p_lcb;
302}
303
304/*******************************************************************************
305**
306** Function         avct_lcb_alloc
307**
308** Description      Allocate a link control block.
309**
310**
311** Returns          pointer to the lcb, or NULL if none could be allocated.
312**
313*******************************************************************************/
314tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr)
315{
316    tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
317    int         i;
318
319    for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
320    {
321        if (!p_lcb->allocated)
322        {
323            p_lcb->allocated = (UINT8)(i + 1);
324            memcpy(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN);
325            AVCT_TRACE_DEBUG1("avct_lcb_alloc %d", p_lcb->allocated);
326            break;
327        }
328    }
329
330    if (i == AVCT_NUM_LINKS)
331    {
332        /* out of lcbs */
333        p_lcb = NULL;
334        AVCT_TRACE_WARNING0("Out of lcbs");
335    }
336    return p_lcb;
337}
338
339/*******************************************************************************
340**
341** Function         avct_lcb_dealloc
342**
343** Description      Deallocate a link control block.
344**
345**
346** Returns          void.
347**
348*******************************************************************************/
349void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
350{
351    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
352    BOOLEAN     found = FALSE;
353    int         i;
354
355    AVCT_TRACE_DEBUG1("avct_lcb_dealloc %d", p_lcb->allocated);
356
357    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
358    {
359        /* if ccb allocated and */
360        if (p_ccb->allocated)
361        {
362            if (p_ccb->p_lcb == p_lcb)
363            {
364                AVCT_TRACE_DEBUG1("avct_lcb_dealloc used by ccb: %d", i);
365                found = TRUE;
366                break;
367            }
368        }
369    }
370
371    if (!found)
372    {
373        AVCT_TRACE_DEBUG0("avct_lcb_dealloc now");
374
375        /* clear reassembled msg buffer if in use */
376        if (p_lcb->p_rx_msg != NULL)
377        {
378            GKI_freebuf(p_lcb->p_rx_msg);
379        }
380        memset(p_lcb, 0, sizeof(tAVCT_LCB));
381    }
382}
383
384/*******************************************************************************
385**
386** Function         avct_lcb_by_lcid
387**
388** Description      Find the LCB associated with the L2CAP LCID
389**
390**
391** Returns          pointer to the lcb, or NULL if none found.
392**
393*******************************************************************************/
394tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid)
395{
396    tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
397    int         i;
398
399    for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
400    {
401        if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid)))
402        {
403            break;
404        }
405    }
406
407    if (i == AVCT_NUM_LINKS)
408    {
409        /* out of lcbs */
410        p_lcb = NULL;
411        AVCT_TRACE_WARNING1("No lcb for lcid %x", lcid);
412    }
413
414    return p_lcb;
415}
416
417/*******************************************************************************
418**
419** Function         avct_lcb_has_pid
420**
421** Description      See if any ccbs on this lcb have a particular pid.
422**
423**
424** Returns          Pointer to CCB if PID found, NULL otherwise.
425**
426*******************************************************************************/
427tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid)
428{
429    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
430    int         i;
431
432    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
433    {
434        if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid))
435        {
436            return p_ccb;
437        }
438    }
439    return NULL;
440}
441
442/*******************************************************************************
443**
444** Function         avct_lcb_last_ccb
445**
446** Description      See if given ccb is only one on the lcb.
447**
448**
449** Returns          TRUE if ccb is last, FALSE otherwise.
450**
451*******************************************************************************/
452BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
453{
454    tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
455    int         i;
456
457    AVCT_TRACE_WARNING0("avct_lcb_last_ccb");
458    for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
459    {
460        AVCT_TRACE_WARNING6("%x: aloc:%d, lcb:0x%x/0x%x, ccb:0x%x/0x%x",
461            i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
462        if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last))
463        {
464            return FALSE;
465        }
466    }
467    return TRUE;
468}
469
470
471
472