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