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