• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 */
40 const 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 */
48 const 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 */
62 enum {
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 */
70 enum {
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 */
93 typedef void (*tAVCT_LCB_ACTION)(tAVCT_LCB *p_ccb, tAVCT_LCB_EVT *p_data);
94 
95 /* action function list */
96 const 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 */
121 const 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 */
134 const 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 */
147 const 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 */
160 const 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 */
173 typedef const UINT8 (*tAVCT_LCB_ST_TBL)[AVCT_LCB_NUM_COLS];
174 
175 /* state table */
176 const 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 *******************************************************************************/
avct_lcb_event(tAVCT_LCB * p_lcb,UINT8 event,tAVCT_LCB_EVT * p_data)193 void 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)
avct_bcb_event(tAVCT_BCB * p_bcb,UINT8 event,tAVCT_LCB_EVT * p_data)236 void 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 *******************************************************************************/
avct_lcb_by_bd(BD_ADDR bd_addr)279 tAVCT_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 *******************************************************************************/
avct_lcb_alloc(BD_ADDR bd_addr)314 tAVCT_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 *******************************************************************************/
avct_lcb_dealloc(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)349 void 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 *******************************************************************************/
avct_lcb_by_lcid(UINT16 lcid)394 tAVCT_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 *******************************************************************************/
avct_lcb_has_pid(tAVCT_LCB * p_lcb,UINT16 pid)427 tAVCT_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 *******************************************************************************/
avct_lcb_last_ccb(tAVCT_LCB * p_lcb,tAVCT_CCB * p_ccb_last)452 BOOLEAN 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