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 "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