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 *******************************************************************************/ 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) 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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 *******************************************************************************/ 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