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