1 /******************************************************************************
3 * Copyright (C) 2003-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This module contains the link control state machine and functions which
22 * operate on the link control block.
24 ******************************************************************************/
28 #include "bt_target.h"
32 #include "bt_common.h"
34 /*****************************************************************************
35 ** state machine constants and types
36 *****************************************************************************/
38 #if BT_TRACE_VERBOSE == TRUE
40 /* verbose state strings for trace */
41 const char * const avct_lcb_st_str[] = {
48 /* verbose event strings for trace */
49 const char * const avct_lcb_evt_str[] = {
62 /* lcb state machine states */
70 /* state machine action enumeration list */
87 AVCT_LCB_FREE_MSG_IND,
91 #define AVCT_LCB_IGNORE AVCT_LCB_NUM_ACTIONS
93 /* type for action functions */
94 typedef void (*tAVCT_LCB_ACTION)(tAVCT_LCB *p_ccb, tAVCT_LCB_EVT *p_data);
96 /* action function list */
97 const tAVCT_LCB_ACTION avct_lcb_action[] = {
109 avct_lcb_unbind_disc,
111 avct_lcb_discard_msg,
113 avct_lcb_free_msg_ind
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 */
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}
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}
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}
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}
173 /* type for state table */
174 typedef const UINT8 (*tAVCT_LCB_ST_TBL)[AVCT_LCB_NUM_COLS];
177 const tAVCT_LCB_ST_TBL avct_lcb_st_tbl[] = {
184 /*******************************************************************************
186 ** Function avct_lcb_event
188 ** Description State machine event handling function for lcb
193 *******************************************************************************/
194 void avct_lcb_event(tAVCT_LCB *p_lcb, UINT8 event, tAVCT_LCB_EVT *p_data)
196 tAVCT_LCB_ST_TBL state_table;
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]);
203 AVCT_TRACE_EVENT("LCB lcb=%d event=%d state=%d", p_lcb->allocated, event, p_lcb->state);
206 /* look up the state table for the current state */
207 state_table = avct_lcb_st_tbl[p_lcb->state];
210 p_lcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
212 /* execute action functions */
213 for (i = 0; i < AVCT_LCB_ACTIONS; i++)
215 if ((action = state_table[event][i]) != AVCT_LCB_IGNORE)
217 (*avct_lcb_action[action])(p_lcb, p_data);
226 /*******************************************************************************
228 ** Function avct_bcb_event
230 ** Description State machine event handling function for lcb
235 *******************************************************************************/
236 #if (AVCT_BROWSE_INCLUDED == TRUE)
237 void avct_bcb_event(tAVCT_BCB *p_bcb, UINT8 event, tAVCT_LCB_EVT *p_data)
239 tAVCT_LCB_ST_TBL state_table;
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]);
246 AVCT_TRACE_EVENT("BCB lcb=%d event=%d state=%d", p_bcb->allocated, event, p_bcb->state);
249 /* look up the state table for the current state */
250 state_table = avct_lcb_st_tbl[p_bcb->state];
253 p_bcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
255 /* execute action functions */
256 for (i = 0; i < AVCT_LCB_ACTIONS; i++)
258 if ((action = state_table[event][i]) != AVCT_LCB_IGNORE)
260 (*avct_bcb_action[action])(p_bcb, p_data);
270 /*******************************************************************************
272 ** Function avct_lcb_by_bd
274 ** Description This lookup function finds the lcb for a BD address.
277 ** Returns pointer to the lcb, or NULL if none found.
279 *******************************************************************************/
280 tAVCT_LCB *avct_lcb_by_bd(BD_ADDR bd_addr)
282 tAVCT_LCB *p_lcb = &avct_cb.lcb[0];
285 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
287 /* if allocated lcb has matching lcb */
288 if (p_lcb->allocated && (!memcmp(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN)))
294 if (i == AVCT_NUM_LINKS)
296 /* if no lcb found */
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]);
305 /*******************************************************************************
307 ** Function avct_lcb_alloc
309 ** Description Allocate a link control block.
312 ** Returns pointer to the lcb, or NULL if none could be allocated.
314 *******************************************************************************/
315 tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr)
317 tAVCT_LCB *p_lcb = &avct_cb.lcb[0];
320 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
322 if (!p_lcb->allocated)
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);
332 if (i == AVCT_NUM_LINKS)
336 AVCT_TRACE_WARNING("Out of lcbs");
341 /*******************************************************************************
343 ** Function avct_lcb_dealloc
345 ** Description Deallocate a link control block.
350 *******************************************************************************/
351 void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
353 tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
354 BOOLEAN found = FALSE;
358 AVCT_TRACE_DEBUG("avct_lcb_dealloc %d", p_lcb->allocated);
360 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
362 /* if ccb allocated and */
363 if (p_ccb->allocated)
365 if (p_ccb->p_lcb == p_lcb)
367 AVCT_TRACE_DEBUG("avct_lcb_dealloc used by ccb: %d", i);
376 AVCT_TRACE_DEBUG("avct_lcb_dealloc now");
378 /* clear reassembled msg buffer if in use */
379 if (p_lcb->p_rx_msg != NULL)
381 osi_freebuf(p_lcb->p_rx_msg);
383 fixed_queue_free(p_lcb->tx_q, NULL);
384 memset(p_lcb, 0, sizeof(tAVCT_LCB));
388 /*******************************************************************************
390 ** Function avct_lcb_by_lcid
392 ** Description Find the LCB associated with the L2CAP LCID
395 ** Returns pointer to the lcb, or NULL if none found.
397 *******************************************************************************/
398 tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid)
400 tAVCT_LCB *p_lcb = &avct_cb.lcb[0];
403 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
405 if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid)))
411 if (i == AVCT_NUM_LINKS)
415 AVCT_TRACE_WARNING("No lcb for lcid %x", lcid);
421 /*******************************************************************************
423 ** Function avct_lcb_has_pid
425 ** Description See if any ccbs on this lcb have a particular pid.
428 ** Returns Pointer to CCB if PID found, NULL otherwise.
430 *******************************************************************************/
431 tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid)
433 tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
436 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
438 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid))
446 /*******************************************************************************
448 ** Function avct_lcb_last_ccb
450 ** Description See if given ccb is only one on the lcb.
453 ** Returns TRUE if ccb is last, FALSE otherwise.
455 *******************************************************************************/
456 BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
458 tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
461 AVCT_TRACE_WARNING("avct_lcb_last_ccb");
462 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
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))