blob: 21f112292d8690bca0f7da3a77c9a675dd8f632d [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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>
Chris Manton83e2c342014-09-29 21:37:44 -070027#include "bt_types.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080028#include "bt_target.h"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080029#include "bt_utils.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080030#include "avct_api.h"
31#include "avct_int.h"
Pavlin Radoslavov258c2532015-09-27 20:59:05 -070032#include "bt_common.h"
Myles Watsond7ffd642016-10-27 10:27:36 -070033#include "osi/include/osi.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080034
35/*****************************************************************************
36** state machine constants and types
37*****************************************************************************/
38
The Android Open Source Project5738f832012-12-12 16:00:35 -080039/* verbose state strings for trace */
40const 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 */
48const 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
The Android Open Source Project5738f832012-12-12 16:00:35 -080059/* lcb state machine states */
60enum {
61 AVCT_LCB_IDLE_ST,
62 AVCT_LCB_OPENING_ST,
63 AVCT_LCB_OPEN_ST,
64 AVCT_LCB_CLOSING_ST
65};
66
67/* state machine action enumeration list */
68enum {
69 AVCT_LCB_CHNL_OPEN,
70 AVCT_LCB_CHNL_DISC,
71 AVCT_LCB_SEND_MSG,
72 AVCT_LCB_OPEN_IND,
73 AVCT_LCB_OPEN_FAIL,
74 AVCT_LCB_CLOSE_IND,
75 AVCT_LCB_CLOSE_CFM,
76 AVCT_LCB_MSG_IND,
77 AVCT_LCB_CONG_IND,
78 AVCT_LCB_BIND_CONN,
79 AVCT_LCB_BIND_FAIL,
80 AVCT_LCB_UNBIND_DISC,
81 AVCT_LCB_CHK_DISC,
82 AVCT_LCB_DISCARD_MSG,
83 AVCT_LCB_DEALLOC,
84 AVCT_LCB_FREE_MSG_IND,
85 AVCT_LCB_NUM_ACTIONS
86};
87
88#define AVCT_LCB_IGNORE AVCT_LCB_NUM_ACTIONS
89
90/* type for action functions */
91typedef void (*tAVCT_LCB_ACTION)(tAVCT_LCB *p_ccb, tAVCT_LCB_EVT *p_data);
92
93/* action function list */
94const tAVCT_LCB_ACTION avct_lcb_action[] = {
95 avct_lcb_chnl_open,
96 avct_lcb_chnl_disc,
97 avct_lcb_send_msg,
98 avct_lcb_open_ind,
99 avct_lcb_open_fail,
100 avct_lcb_close_ind,
101 avct_lcb_close_cfm,
102 avct_lcb_msg_ind,
103 avct_lcb_cong_ind,
104 avct_lcb_bind_conn,
105 avct_lcb_bind_fail,
106 avct_lcb_unbind_disc,
107 avct_lcb_chk_disc,
108 avct_lcb_discard_msg,
109 avct_lcb_dealloc,
110 avct_lcb_free_msg_ind
111};
112
113/* state table information */
114#define AVCT_LCB_ACTIONS 2 /* number of actions */
115#define AVCT_LCB_NEXT_STATE 2 /* position of next state */
116#define AVCT_LCB_NUM_COLS 3 /* number of columns in state tables */
117
118/* state table for idle state */
Marie Janssend19e0782016-07-15 12:48:27 -0700119const uint8_t avct_lcb_st_idle[][AVCT_LCB_NUM_COLS] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800120/* Event Action 1 Action 2 Next state */
121/* UL_BIND_EVT */ {AVCT_LCB_CHNL_OPEN, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
122/* UL_UNBIND_EVT */ {AVCT_LCB_UNBIND_DISC, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
123/* UL_MSG_EVT */ {AVCT_LCB_DISCARD_MSG, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
124/* INT_CLOSE_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
125/* LL_OPEN_EVT */ {AVCT_LCB_OPEN_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
126/* LL_CLOSE_EVT */ {AVCT_LCB_CLOSE_IND, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
127/* LL_MSG_EVT */ {AVCT_LCB_FREE_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST},
128/* LL_CONG_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_IDLE_ST}
129};
130
131/* state table for opening state */
Marie Janssend19e0782016-07-15 12:48:27 -0700132const uint8_t avct_lcb_st_opening[][AVCT_LCB_NUM_COLS] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800133/* Event Action 1 Action 2 Next state */
134/* UL_BIND_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
135/* UL_UNBIND_EVT */ {AVCT_LCB_UNBIND_DISC, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
136/* UL_MSG_EVT */ {AVCT_LCB_DISCARD_MSG, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
137/* INT_CLOSE_EVT */ {AVCT_LCB_CHNL_DISC, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
138/* LL_OPEN_EVT */ {AVCT_LCB_OPEN_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
139/* LL_CLOSE_EVT */ {AVCT_LCB_OPEN_FAIL, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
140/* LL_MSG_EVT */ {AVCT_LCB_FREE_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST},
141/* LL_CONG_EVT */ {AVCT_LCB_CONG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPENING_ST}
142};
143
144/* state table for open state */
Marie Janssend19e0782016-07-15 12:48:27 -0700145const uint8_t avct_lcb_st_open[][AVCT_LCB_NUM_COLS] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800146/* Event Action 1 Action 2 Next state */
147/* UL_BIND_EVT */ {AVCT_LCB_BIND_CONN, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
148/* UL_UNBIND_EVT */ {AVCT_LCB_CHK_DISC, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
149/* UL_MSG_EVT */ {AVCT_LCB_SEND_MSG, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
150/* INT_CLOSE_EVT */ {AVCT_LCB_CHNL_DISC, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
151/* LL_OPEN_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
152/* LL_CLOSE_EVT */ {AVCT_LCB_CLOSE_IND, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
153/* LL_MSG_EVT */ {AVCT_LCB_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST},
154/* LL_CONG_EVT */ {AVCT_LCB_CONG_IND, AVCT_LCB_IGNORE, AVCT_LCB_OPEN_ST}
155};
156
157/* state table for closing state */
Marie Janssend19e0782016-07-15 12:48:27 -0700158const uint8_t avct_lcb_st_closing[][AVCT_LCB_NUM_COLS] = {
The Android Open Source Project5738f832012-12-12 16:00:35 -0800159/* Event Action 1 Action 2 Next state */
160/* UL_BIND_EVT */ {AVCT_LCB_BIND_FAIL, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
161/* UL_UNBIND_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
162/* UL_MSG_EVT */ {AVCT_LCB_DISCARD_MSG, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
163/* INT_CLOSE_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
164/* LL_OPEN_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
165/* LL_CLOSE_EVT */ {AVCT_LCB_CLOSE_CFM, AVCT_LCB_DEALLOC, AVCT_LCB_IDLE_ST},
166/* LL_MSG_EVT */ {AVCT_LCB_FREE_MSG_IND, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST},
167/* LL_CONG_EVT */ {AVCT_LCB_IGNORE, AVCT_LCB_IGNORE, AVCT_LCB_CLOSING_ST}
168};
169
170/* type for state table */
Marie Janssend19e0782016-07-15 12:48:27 -0700171typedef const uint8_t (*tAVCT_LCB_ST_TBL)[AVCT_LCB_NUM_COLS];
The Android Open Source Project5738f832012-12-12 16:00:35 -0800172
173/* state table */
174const tAVCT_LCB_ST_TBL avct_lcb_st_tbl[] = {
175 avct_lcb_st_idle,
176 avct_lcb_st_opening,
177 avct_lcb_st_open,
178 avct_lcb_st_closing
179};
180
181/*******************************************************************************
182**
183** Function avct_lcb_event
184**
185** Description State machine event handling function for lcb
186**
187**
188** Returns Nothing.
189**
190*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700191void avct_lcb_event(tAVCT_LCB *p_lcb, uint8_t event, tAVCT_LCB_EVT *p_data)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800192{
193 tAVCT_LCB_ST_TBL state_table;
Marie Janssend19e0782016-07-15 12:48:27 -0700194 uint8_t action;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800195 int i;
196
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700197 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]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800198
199 /* look up the state table for the current state */
200 state_table = avct_lcb_st_tbl[p_lcb->state];
201
202 /* set next state */
203 p_lcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
204
205 /* execute action functions */
206 for (i = 0; i < AVCT_LCB_ACTIONS; i++)
207 {
Marie Janssenf33b6f42016-11-22 15:01:42 -0800208 action = state_table[event][i];
209 if (action != AVCT_LCB_IGNORE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800210 {
211 (*avct_lcb_action[action])(p_lcb, p_data);
212 }
213 else
214 {
215 break;
216 }
217 }
218}
219
220/*******************************************************************************
221**
222** Function avct_bcb_event
223**
224** Description State machine event handling function for lcb
225**
226**
227** Returns Nothing.
228**
229*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700230void avct_bcb_event(tAVCT_BCB *p_bcb, uint8_t event, tAVCT_LCB_EVT *p_data)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800231{
232 tAVCT_LCB_ST_TBL state_table;
Marie Janssend19e0782016-07-15 12:48:27 -0700233 uint8_t action;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800234 int i;
235
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700236 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]);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800237
238 /* look up the state table for the current state */
239 state_table = avct_lcb_st_tbl[p_bcb->state];
240
241 /* set next state */
242 p_bcb->state = state_table[event][AVCT_LCB_NEXT_STATE];
243
244 /* execute action functions */
245 for (i = 0; i < AVCT_LCB_ACTIONS; i++)
246 {
Marie Janssenf33b6f42016-11-22 15:01:42 -0800247 action = state_table[event][i];
248 if (action != AVCT_LCB_IGNORE)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800249 {
250 (*avct_bcb_action[action])(p_bcb, p_data);
251 }
252 else
253 {
254 break;
255 }
256 }
257}
The Android Open Source Project5738f832012-12-12 16:00:35 -0800258
259/*******************************************************************************
260**
261** Function avct_lcb_by_bd
262**
263** Description This lookup function finds the lcb for a BD address.
264**
265**
266** Returns pointer to the lcb, or NULL if none found.
267**
268*******************************************************************************/
269tAVCT_LCB *avct_lcb_by_bd(BD_ADDR bd_addr)
270{
271 tAVCT_LCB *p_lcb = &avct_cb.lcb[0];
272 int i;
273
274 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
275 {
276 /* if allocated lcb has matching lcb */
277 if (p_lcb->allocated && (!memcmp(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN)))
278 {
279 break;
280 }
281 }
282
283 if (i == AVCT_NUM_LINKS)
284 {
285 /* if no lcb found */
286 p_lcb = NULL;
287
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700288 AVCT_TRACE_DEBUG("No lcb for addr %02x-%02x-%02x-%02x-%02x-%02x",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800289 bd_addr[0], bd_addr[1], bd_addr[2], bd_addr[3], bd_addr[4], bd_addr[5]);
290 }
291 return p_lcb;
292}
293
294/*******************************************************************************
295**
296** Function avct_lcb_alloc
297**
298** Description Allocate a link control block.
299**
300**
301** Returns pointer to the lcb, or NULL if none could be allocated.
302**
303*******************************************************************************/
304tAVCT_LCB *avct_lcb_alloc(BD_ADDR bd_addr)
305{
306 tAVCT_LCB *p_lcb = &avct_cb.lcb[0];
307 int i;
308
309 for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
310 {
311 if (!p_lcb->allocated)
312 {
Marie Janssend19e0782016-07-15 12:48:27 -0700313 p_lcb->allocated = (uint8_t)(i + 1);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800314 memcpy(p_lcb->peer_addr, bd_addr, BD_ADDR_LEN);
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700315 AVCT_TRACE_DEBUG("avct_lcb_alloc %d", p_lcb->allocated);
Pavlin Radoslavov1a3844f2015-09-25 11:21:15 -0700316 p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800317 break;
318 }
319 }
320
321 if (i == AVCT_NUM_LINKS)
322 {
323 /* out of lcbs */
324 p_lcb = NULL;
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700325 AVCT_TRACE_WARNING("Out of lcbs");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800326 }
327 return p_lcb;
328}
329
330/*******************************************************************************
331**
332** Function avct_lcb_dealloc
333**
334** Description Deallocate a link control block.
335**
336**
337** Returns void.
338**
339*******************************************************************************/
Myles Watsond35a6482016-10-27 08:52:16 -0700340void avct_lcb_dealloc(tAVCT_LCB *p_lcb,
341 UNUSED_ATTR tAVCT_LCB_EVT *p_data)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800342{
Andre Eisenbach072bd752016-03-18 02:09:58 -0700343 AVCT_TRACE_DEBUG("%s allocated: %d", __func__, p_lcb->allocated);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800344
Andre Eisenbach072bd752016-03-18 02:09:58 -0700345 // 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++)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800349 {
Andre Eisenbach072bd752016-03-18 02:09:58 -0700350 if (p_ccb->allocated && p_ccb->p_lcb == p_lcb)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800351 {
Andre Eisenbach072bd752016-03-18 02:09:58 -0700352 AVCT_TRACE_DEBUG("%s LCB in use; lcb index: %d", __func__, i);
353 return;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800354 }
355 }
356
Andre Eisenbach072bd752016-03-18 02:09:58 -0700357 // If not, de-allocate now...
The Android Open Source Project5738f832012-12-12 16:00:35 -0800358
Andre Eisenbach072bd752016-03-18 02:09:58 -0700359 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));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800363}
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*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700375tAVCT_LCB *avct_lcb_by_lcid(uint16_t lcid)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800376{
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 {
382 if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid)))
383 {
384 break;
385 }
386 }
387
388 if (i == AVCT_NUM_LINKS)
389 {
390 /* out of lcbs */
391 p_lcb = NULL;
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700392 AVCT_TRACE_WARNING("No lcb for lcid %x", lcid);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800393 }
394
395 return p_lcb;
396}
397
398/*******************************************************************************
399**
400** Function avct_lcb_has_pid
401**
402** Description See if any ccbs on this lcb have a particular pid.
403**
404**
405** Returns Pointer to CCB if PID found, NULL otherwise.
406**
407*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700408tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, uint16_t pid)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800409{
410 tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
411 int i;
412
413 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
414 {
415 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid))
416 {
417 return p_ccb;
418 }
419 }
420 return NULL;
421}
422
423/*******************************************************************************
424**
425** Function avct_lcb_last_ccb
426**
427** Description See if given ccb is only one on the lcb.
428**
429**
Marie Janssend19e0782016-07-15 12:48:27 -0700430** Returns true if ccb is last, false otherwise.
The Android Open Source Project5738f832012-12-12 16:00:35 -0800431**
432*******************************************************************************/
Marie Janssend19e0782016-07-15 12:48:27 -0700433bool avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
The Android Open Source Project5738f832012-12-12 16:00:35 -0800434{
435 tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
436 int i;
437
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700438 AVCT_TRACE_WARNING("avct_lcb_last_ccb");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800439 for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
440 {
Sharvil Nanavati158084e2014-05-04 09:53:44 -0700441 AVCT_TRACE_WARNING("%x: aloc:%d, lcb:0x%x/0x%x, ccb:0x%x/0x%x",
The Android Open Source Project5738f832012-12-12 16:00:35 -0800442 i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
443 if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last))
444 {
Marie Janssend19e0782016-07-15 12:48:27 -0700445 return false;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800446 }
447 }
Marie Janssend19e0782016-07-15 12:48:27 -0700448 return true;
The Android Open Source Project5738f832012-12-12 16:00:35 -0800449}
450
451
452