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