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 "stack/bt_types.h"
28 #include "common/bt_target.h"
29 #include "common/bt_defs.h"
30 #include "stack/avct_api.h"
31 #include "avct_int.h"
32 #include "osi/allocator.h"
33 
34 #if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE)
35 
36 /*****************************************************************************
37 ** state machine constants and types
38 *****************************************************************************/
39 
40 #if BT_TRACE_VERBOSE == TRUE
41 
42 /* verbose state strings for trace */
43 const char *const avct_lcb_st_str[] = {
44     "LCB_IDLE_ST",
45     "LCB_OPENING_ST",
46     "LCB_OPEN_ST",
47     "LCB_CLOSING_ST"
48 };
49 
50 /* verbose event strings for trace */
51 const char *const avct_lcb_evt_str[] = {
52     "UL_BIND_EVT",
53     "UL_UNBIND_EVT",
54     "UL_MSG_EVT",
55     "INT_CLOSE_EVT",
56     "LL_OPEN_EVT",
57     "LL_CLOSE_EVT",
58     "LL_MSG_EVT",
59     "LL_CONG_EVT"
60 };
61 
62 #endif
63 
64 /* lcb state machine states */
65 enum {
66     AVCT_LCB_IDLE_ST,
67     AVCT_LCB_OPENING_ST,
68     AVCT_LCB_OPEN_ST,
69     AVCT_LCB_CLOSING_ST
70 };
71 
72 /* state machine action enumeration list */
73 enum {
74     AVCT_LCB_CHNL_OPEN,
75     AVCT_LCB_CHNL_DISC,
76     AVCT_LCB_SEND_MSG,
77     AVCT_LCB_OPEN_IND,
78     AVCT_LCB_OPEN_FAIL,
79     AVCT_LCB_CLOSE_IND,
80     AVCT_LCB_CLOSE_CFM,
81     AVCT_LCB_MSG_IND,
82     AVCT_LCB_CONG_IND,
83     AVCT_LCB_BIND_CONN,
84     AVCT_LCB_BIND_FAIL,
85     AVCT_LCB_UNBIND_DISC,
86     AVCT_LCB_CHK_DISC,
87     AVCT_LCB_DISCARD_MSG,
88     AVCT_LCB_DEALLOC,
89     AVCT_LCB_FREE_MSG_IND,
90     AVCT_LCB_NUM_ACTIONS
91 };
92 
93 #define AVCT_LCB_IGNORE     AVCT_LCB_NUM_ACTIONS
94 
95 /* type for action functions */
96 typedef void (*tAVCT_LCB_ACTION)(tAVCT_LCB *p_ccb, tAVCT_LCB_EVT *p_data);
97 
98 /* action function list */
99 const tAVCT_LCB_ACTION avct_lcb_action[] = {
100     avct_lcb_chnl_open,
101     avct_lcb_chnl_disc,
102     avct_lcb_send_msg,
103     avct_lcb_open_ind,
104     avct_lcb_open_fail,
105     avct_lcb_close_ind,
106     avct_lcb_close_cfm,
107     avct_lcb_msg_ind,
108     avct_lcb_cong_ind,
109     avct_lcb_bind_conn,
110     avct_lcb_bind_fail,
111     avct_lcb_unbind_disc,
112     avct_lcb_chk_disc,
113     avct_lcb_discard_msg,
114     avct_lcb_dealloc,
115     avct_lcb_free_msg_ind
116 };
117 
118 /* state table information */
119 #define AVCT_LCB_ACTIONS            2       /* number of actions */
120 #define AVCT_LCB_NEXT_STATE         2       /* position of next state */
121 #define AVCT_LCB_NUM_COLS           3       /* number of columns in state tables */
122 
123 /* state table for idle state */
124 const UINT8 avct_lcb_st_idle[][AVCT_LCB_NUM_COLS] = {
125     /* Event                Action 1                    Action 2                    Next state */
126     /* UL_BIND_EVT */       {AVCT_LCB_CHNL_OPEN,        AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
127     /* UL_UNBIND_EVT */     {AVCT_LCB_UNBIND_DISC,      AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
128     /* UL_MSG_EVT */        {AVCT_LCB_DISCARD_MSG,      AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
129     /* INT_CLOSE_EVT */     {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
130     /* LL_OPEN_EVT */       {AVCT_LCB_OPEN_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
131     /* LL_CLOSE_EVT */      {AVCT_LCB_CLOSE_IND,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
132     /* LL_MSG_EVT */        {AVCT_LCB_FREE_MSG_IND,     AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST},
133     /* LL_CONG_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_IDLE_ST}
134 };
135 
136 /* state table for opening state */
137 const UINT8 avct_lcb_st_opening[][AVCT_LCB_NUM_COLS] = {
138     /* Event                Action 1                    Action 2                    Next state */
139     /* UL_BIND_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
140     /* UL_UNBIND_EVT */     {AVCT_LCB_UNBIND_DISC,      AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
141     /* UL_MSG_EVT */        {AVCT_LCB_DISCARD_MSG,      AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
142     /* INT_CLOSE_EVT */     {AVCT_LCB_CHNL_DISC,        AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
143     /* LL_OPEN_EVT */       {AVCT_LCB_OPEN_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
144     /* LL_CLOSE_EVT */      {AVCT_LCB_OPEN_FAIL,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
145     /* LL_MSG_EVT */        {AVCT_LCB_FREE_MSG_IND,     AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST},
146     /* LL_CONG_EVT */       {AVCT_LCB_CONG_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPENING_ST}
147 };
148 
149 /* state table for open state */
150 const UINT8 avct_lcb_st_open[][AVCT_LCB_NUM_COLS] = {
151     /* Event                Action 1                    Action 2                    Next state */
152     /* UL_BIND_EVT */       {AVCT_LCB_BIND_CONN,        AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
153     /* UL_UNBIND_EVT */     {AVCT_LCB_CHK_DISC,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
154     /* UL_MSG_EVT */        {AVCT_LCB_SEND_MSG,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
155     /* INT_CLOSE_EVT */     {AVCT_LCB_CHNL_DISC,        AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
156     /* LL_OPEN_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
157     /* LL_CLOSE_EVT */      {AVCT_LCB_CLOSE_IND,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
158     /* LL_MSG_EVT */        {AVCT_LCB_MSG_IND,          AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST},
159     /* LL_CONG_EVT */       {AVCT_LCB_CONG_IND,         AVCT_LCB_IGNORE,            AVCT_LCB_OPEN_ST}
160 };
161 
162 /* state table for closing state */
163 const UINT8 avct_lcb_st_closing[][AVCT_LCB_NUM_COLS] = {
164     /* Event                Action 1                    Action 2                    Next state */
165     /* UL_BIND_EVT */       {AVCT_LCB_BIND_FAIL,        AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
166     /* UL_UNBIND_EVT */     {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
167     /* UL_MSG_EVT */        {AVCT_LCB_DISCARD_MSG,      AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
168     /* INT_CLOSE_EVT */     {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
169     /* LL_OPEN_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
170     /* LL_CLOSE_EVT */      {AVCT_LCB_CLOSE_CFM,        AVCT_LCB_DEALLOC,           AVCT_LCB_IDLE_ST},
171     /* LL_MSG_EVT */        {AVCT_LCB_FREE_MSG_IND,     AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST},
172     /* LL_CONG_EVT */       {AVCT_LCB_IGNORE,           AVCT_LCB_IGNORE,            AVCT_LCB_CLOSING_ST}
173 };
174 
175 /* type for state table */
176 typedef const UINT8 (*tAVCT_LCB_ST_TBL)[AVCT_LCB_NUM_COLS];
177 
178 /* state table */
179 const tAVCT_LCB_ST_TBL avct_lcb_st_tbl[] = {
180     avct_lcb_st_idle,
181     avct_lcb_st_opening,
182     avct_lcb_st_open,
183     avct_lcb_st_closing
184 };
185 
186 /*******************************************************************************
187 **
188 ** Function         avct_lcb_event
189 **
190 ** Description      State machine event handling function for lcb
191 **
192 **
193 ** Returns          Nothing.
194 **
195 *******************************************************************************/
avct_lcb_event(tAVCT_LCB * p_lcb,UINT8 event,tAVCT_LCB_EVT * p_data)196 void avct_lcb_event(tAVCT_LCB *p_lcb, UINT8 event, tAVCT_LCB_EVT *p_data)
197 {
198     tAVCT_LCB_ST_TBL    state_table;
199     UINT8               action;
200     int                 i;
201 
202 #if BT_TRACE_VERBOSE == TRUE
203     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]);
204 #else
205     AVCT_TRACE_EVENT("LCB lcb=%d event=%d state=%d", p_lcb->allocated, event, p_lcb->state);
206 #endif
207 
208     /* look up the state table for the current state */
209     state_table = avct_lcb_st_tbl[p_lcb->state];
210 
211     /* set next state */
212     p_lcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
213 
214     /* execute action functions */
215     for (i = 0; i < AVCT_LCB_ACTIONS; i++) {
216         if ((action = state_table[event][i]) != AVCT_LCB_IGNORE) {
217             (*avct_lcb_action[action])(p_lcb, p_data);
218         } else {
219             break;
220         }
221     }
222 }
223 
224 /*******************************************************************************
225 **
226 ** Function         avct_bcb_event
227 **
228 ** Description      State machine event handling function for lcb
229 **
230 **
231 ** Returns          Nothing.
232 **
233 *******************************************************************************/
234 #if (AVCT_BROWSE_INCLUDED == TRUE)
avct_bcb_event(tAVCT_BCB * p_bcb,UINT8 event,tAVCT_LCB_EVT * p_data)235 void avct_bcb_event(tAVCT_BCB *p_bcb, UINT8 event, tAVCT_LCB_EVT *p_data)
236 {
237     tAVCT_LCB_ST_TBL    state_table;
238     UINT8               action;
239     int                 i;
240 
241 #if BT_TRACE_VERBOSE == TRUE
242     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]);
243 #else
244     AVCT_TRACE_EVENT("BCB lcb=%d event=%d state=%d", p_bcb->allocated, event, p_bcb->state);
245 #endif
246 
247     /* look up the state table for the current state */
248     state_table = avct_lcb_st_tbl[p_bcb->state];
249 
250     /* set next state */
251     p_bcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
252 
253     /* execute action functions */
254     for (i = 0; i < AVCT_LCB_ACTIONS; i++) {
255         if ((action = state_table[event][i]) != AVCT_LCB_IGNORE) {
256             (*avct_bcb_action[action])(p_bcb, p_data);
257         } else {
258             break;
259         }
260     }
261 }
262 #endif
263 
264 /*******************************************************************************
265 **
266 ** Function         avct_lcb_by_bd
267 **
268 ** Description      This lookup function finds the lcb for a BD address.
269 **
270 **
271 ** Returns          pointer to the lcb, or NULL if none found.
272 **
273 *******************************************************************************/
avct_lcb_by_bd(BD_ADDR bd_addr)274 tAVCT_LCB *avct_lcb_by_bd(BD_ADDR bd_addr)
275 {
276     tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
277     int         i;
278 
279     for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
280         /* if allocated lcb has matching lcb */
281         if (p_lcb->allocated && (!memcmp(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN))) {
282             break;
283         }
284     }
285 
286     if (i == AVCT_NUM_LINKS) {
287         /* if no lcb found */
288         p_lcb = NULL;
289 
290         AVCT_TRACE_DEBUG("No lcb for addr %02x-%02x-%02x-%02x-%02x-%02x",
291                          bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
292     }
293     return p_lcb;
294 }
295 
296 /*******************************************************************************
297 **
298 ** Function         avct_lcb_alloc
299 **
300 ** Description      Allocate a link control block.
301 **
302 **
303 ** Returns          pointer to the lcb, or NULL if none could be allocated.
304 **
305 *******************************************************************************/
avct_lcb_alloc(BD_ADDR bd_addr)306 tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr)
307 {
308     tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
309     int         i;
310 
311     for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
312         if (!p_lcb->allocated) {
313             p_lcb->allocated = (UINT8)(i + 1);
314             memcpy(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN);
315             AVCT_TRACE_DEBUG("avct_lcb_alloc %d", p_lcb->allocated);
316             p_lcb->tx_q = fixed_queue_new(QUEUE_SIZE_MAX);
317             break;
318         }
319     }
320 
321     if (i == AVCT_NUM_LINKS) {
322         /* out of lcbs */
323         p_lcb = NULL;
324         AVCT_TRACE_WARNING("Out of lcbs");
325     }
326     return p_lcb;
327 }
328 
329 /*******************************************************************************
330 **
331 ** Function         avct_lcb_dealloc
332 **
333 ** Description      Deallocate a link control block.
334 **
335 **
336 ** Returns          void.
337 **
338 *******************************************************************************/
avct_lcb_dealloc(tAVCT_LCB * p_lcb,tAVCT_LCB_EVT * p_data)339 void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
340 {
341     UNUSED(p_data);
342 
343     AVCT_TRACE_DEBUG("%s allocated: %d", __func__, p_lcb->allocated);
344 
345     // Check if the LCB is still referenced
346 
347     tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
348     for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
349     {
350         if (p_ccb->allocated && p_ccb->p_lcb == p_lcb)
351         {
352             AVCT_TRACE_DEBUG("%s LCB in use; lcb index: %d", __func__, i);
353             return;
354         }
355     }
356 
357     // If not, de-allocate now...
358 
359     AVCT_TRACE_DEBUG("%s Freeing LCB", __func__);
360     osi_free(p_lcb->p_rx_msg);
361     fixed_queue_free(p_lcb->tx_q, NULL);
362     memset(p_lcb, 0, sizeof(tAVCT_LCB));
363 }
364 
365 /*******************************************************************************
366 **
367 ** Function         avct_lcb_by_lcid
368 **
369 ** Description      Find the LCB associated with the L2CAP LCID
370 **
371 **
372 ** Returns          pointer to the lcb, or NULL if none found.
373 **
374 *******************************************************************************/
avct_lcb_by_lcid(UINT16 lcid)375 tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid)
376 {
377     tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
378     int         i;
379 
380     for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++) {
381         if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid))) {
382             break;
383         }
384     }
385 
386     if (i == AVCT_NUM_LINKS) {
387         /* out of lcbs */
388         p_lcb = NULL;
389         AVCT_TRACE_WARNING("No lcb for lcid %x", lcid);
390     }
391 
392     return p_lcb;
393 }
394 
395 /*******************************************************************************
396 **
397 ** Function         avct_lcb_has_pid
398 **
399 ** Description      See if any ccbs on this lcb have a particular pid.
400 **
401 **
402 ** Returns          Pointer to CCB if PID found, NULL otherwise.
403 **
404 *******************************************************************************/
avct_lcb_has_pid(tAVCT_LCB * p_lcb,UINT16 pid)405 tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid)
406 {
407     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
408     int         i;
409 
410     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
411         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid)) {
412             return p_ccb;
413         }
414     }
415     return NULL;
416 }
417 
418 /*******************************************************************************
419 **
420 ** Function         avct_lcb_last_ccb
421 **
422 ** Description      See if given ccb is only one on the lcb.
423 **
424 **
425 ** Returns          TRUE if ccb is last, FALSE otherwise.
426 **
427 *******************************************************************************/
avct_lcb_last_ccb(tAVCT_LCB * p_lcb,tAVCT_CCB * p_ccb_last)428 BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
429 {
430     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
431     int         i;
432 
433     AVCT_TRACE_DEBUG("avct_lcb_last_ccb");
434     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++) {
435         AVCT_TRACE_DEBUG("%x: aloc:%d, lcb:%p/%p, ccb:%p/%p",
436                          i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
437         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last)) {
438             return FALSE;
439         }
440     }
441     return TRUE;
442 }
443 
444 
445 #endif /* #if (defined(AVCT_INCLUDED) && AVCT_INCLUDED == TRUE) */
446