• 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 "bt_types.h"
28 #include "bt_target.h"
29 #include "bt_utils.h"
30 #include "avct_api.h"
31 #include "avct_int.h"
32 #include "bt_common.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             p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
328             break;
329         }
330     }
331 
332     if (i == AVCT_NUM_LINKS)
333     {
334         /* out of lcbs */
335         p_lcb = NULL;
336         AVCT_TRACE_WARNING("Out of lcbs");
337     }
338     return p_lcb;
339 }
340 
341 /*******************************************************************************
342 **
343 ** Function         avct_lcb_dealloc
344 **
345 ** Description      Deallocate a link control block.
346 **
347 **
348 ** Returns          void.
349 **
350 *******************************************************************************/
avct_lcb_dealloc(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)351 void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
352 {
353     UNUSED(p_data);
354 
355     AVCT_TRACE_DEBUG("%s allocated: %d", __func__, p_lcb->allocated);
356 
357     // Check if the LCB is still referenced
358 
359     tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
360     for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
361     {
362         if (p_ccb->allocated && p_ccb->p_lcb == p_lcb)
363         {
364             AVCT_TRACE_DEBUG("%s LCB in use; lcb index: %d", __func__, i);
365             return;
366         }
367     }
368 
369     // If not, de-allocate now...
370 
371     AVCT_TRACE_DEBUG("%s Freeing LCB", __func__);
372     osi_free(p_lcb->p_rx_msg);
373     fixed_queue_free(p_lcb->tx_q, NULL);
374     memset(p_lcb, 0, sizeof(tAVCT_LCB));
375 }
376 
377 /*******************************************************************************
378 **
379 ** Function         avct_lcb_by_lcid
380 **
381 ** Description      Find the LCB associated with the L2CAP LCID
382 **
383 **
384 ** Returns          pointer to the lcb, or NULL if none found.
385 **
386 *******************************************************************************/
avct_lcb_by_lcid(UINT16 lcid)387 tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid)
388 {
389     tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
390     int         i;
391 
392     for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
393     {
394         if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid)))
395         {
396             break;
397         }
398     }
399 
400     if (i == AVCT_NUM_LINKS)
401     {
402         /* out of lcbs */
403         p_lcb = NULL;
404         AVCT_TRACE_WARNING("No lcb for lcid %x", lcid);
405     }
406 
407     return p_lcb;
408 }
409 
410 /*******************************************************************************
411 **
412 ** Function         avct_lcb_has_pid
413 **
414 ** Description      See if any ccbs on this lcb have a particular pid.
415 **
416 **
417 ** Returns          Pointer to CCB if PID found, NULL otherwise.
418 **
419 *******************************************************************************/
avct_lcb_has_pid(tAVCT_LCB * p_lcb,UINT16 pid)420 tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid)
421 {
422     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
423     int         i;
424 
425     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
426     {
427         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid))
428         {
429             return p_ccb;
430         }
431     }
432     return NULL;
433 }
434 
435 /*******************************************************************************
436 **
437 ** Function         avct_lcb_last_ccb
438 **
439 ** Description      See if given ccb is only one on the lcb.
440 **
441 **
442 ** Returns          TRUE if ccb is last, FALSE otherwise.
443 **
444 *******************************************************************************/
avct_lcb_last_ccb(tAVCT_LCB * p_lcb,tAVCT_CCB * p_ccb_last)445 BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
446 {
447     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
448     int         i;
449 
450     AVCT_TRACE_WARNING("avct_lcb_last_ccb");
451     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
452     {
453         AVCT_TRACE_WARNING("%x: aloc:%d, lcb:0x%x/0x%x, ccb:0x%x/0x%x",
454             i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
455         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last))
456         {
457             return FALSE;
458         }
459     }
460     return TRUE;
461 }
462 
463 
464 
465