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