OSDN Git Service

Reduce persistence on aquiring master role am: 59d9673187
[android-x86/system-bt.git] / stack / avct / avct_lcb.c
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 *******************************************************************************/
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)
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 *******************************************************************************/
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 *******************************************************************************/
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 *******************************************************************************/
351 void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
352 {
353     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
354     BOOLEAN     found = FALSE;
355     int         i;
356     UNUSED(p_data);
357
358     AVCT_TRACE_DEBUG("avct_lcb_dealloc %d", p_lcb->allocated);
359
360     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
361     {
362         /* if ccb allocated and */
363         if (p_ccb->allocated)
364         {
365             if (p_ccb->p_lcb == p_lcb)
366             {
367                 AVCT_TRACE_DEBUG("avct_lcb_dealloc used by ccb: %d", i);
368                 found = TRUE;
369                 break;
370             }
371         }
372     }
373
374     if (!found)
375     {
376         AVCT_TRACE_DEBUG("avct_lcb_dealloc now");
377
378         /* clear reassembled msg buffer if in use */
379         if (p_lcb->p_rx_msg != NULL)
380         {
381             osi_freebuf(p_lcb->p_rx_msg);
382         }
383         fixed_queue_free(p_lcb->tx_q, NULL);
384         memset(p_lcb, 0, sizeof(tAVCT_LCB));
385     }
386 }
387
388 /*******************************************************************************
389 **
390 ** Function         avct_lcb_by_lcid
391 **
392 ** Description      Find the LCB associated with the L2CAP LCID
393 **
394 **
395 ** Returns          pointer to the lcb, or NULL if none found.
396 **
397 *******************************************************************************/
398 tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid)
399 {
400     tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
401     int         i;
402
403     for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
404     {
405         if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid)))
406         {
407             break;
408         }
409     }
410
411     if (i == AVCT_NUM_LINKS)
412     {
413         /* out of lcbs */
414         p_lcb = NULL;
415         AVCT_TRACE_WARNING("No lcb for lcid %x", lcid);
416     }
417
418     return p_lcb;
419 }
420
421 /*******************************************************************************
422 **
423 ** Function         avct_lcb_has_pid
424 **
425 ** Description      See if any ccbs on this lcb have a particular pid.
426 **
427 **
428 ** Returns          Pointer to CCB if PID found, NULL otherwise.
429 **
430 *******************************************************************************/
431 tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid)
432 {
433     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
434     int         i;
435
436     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
437     {
438         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid))
439         {
440             return p_ccb;
441         }
442     }
443     return NULL;
444 }
445
446 /*******************************************************************************
447 **
448 ** Function         avct_lcb_last_ccb
449 **
450 ** Description      See if given ccb is only one on the lcb.
451 **
452 **
453 ** Returns          TRUE if ccb is last, FALSE otherwise.
454 **
455 *******************************************************************************/
456 BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
457 {
458     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
459     int         i;
460
461     AVCT_TRACE_WARNING("avct_lcb_last_ccb");
462     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
463     {
464         AVCT_TRACE_WARNING("%x: aloc:%d, lcb:0x%x/0x%x, ccb:0x%x/0x%x",
465             i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
466         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last))
467         {
468             return FALSE;
469         }
470     }
471     return TRUE;
472 }
473
474
475