Home | History | Annotate | Download | only in avct
      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 "bt_types.h"
     28 #include "bt_target.h"
     29 #include "bt_utils.h"
     30 #include "avct_api.h"
     31 #include "avct_int.h"
     32 #include "bt_common.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             p_lcb->tx_q = fixed_queue_new(SIZE_MAX);
    328             break;
    329         }
    330     }
    331 
    332     if (i == AVCT_NUM_LINKS)
    333     {
    334         /* out of lcbs */
    335         p_lcb = NULL;
    336         AVCT_TRACE_WARNING("Out of lcbs");
    337     }
    338     return p_lcb;
    339 }
    340 
    341 /*******************************************************************************
    342 **
    343 ** Function         avct_lcb_dealloc
    344 **
    345 ** Description      Deallocate a link control block.
    346 **
    347 **
    348 ** Returns          void.
    349 **
    350 *******************************************************************************/
    351 void avct_lcb_dealloc(tAVCT_LCB *p_lcb, tAVCT_LCB_EVT *p_data)
    352 {
    353     UNUSED(p_data);
    354 
    355     AVCT_TRACE_DEBUG("%s allocated: %d", __func__, p_lcb->allocated);
    356 
    357     // Check if the LCB is still referenced
    358 
    359     tAVCT_CCB *p_ccb = &avct_cb.ccb[0];
    360     for (size_t i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
    361     {
    362         if (p_ccb->allocated && p_ccb->p_lcb == p_lcb)
    363         {
    364             AVCT_TRACE_DEBUG("%s LCB in use; lcb index: %d", __func__, i);
    365             return;
    366         }
    367     }
    368 
    369     // If not, de-allocate now...
    370 
    371     AVCT_TRACE_DEBUG("%s Freeing LCB", __func__);
    372     osi_free(p_lcb->p_rx_msg);
    373     fixed_queue_free(p_lcb->tx_q, NULL);
    374     memset(p_lcb, 0, sizeof(tAVCT_LCB));
    375 }
    376 
    377 /*******************************************************************************
    378 **
    379 ** Function         avct_lcb_by_lcid
    380 **
    381 ** Description      Find the LCB associated with the L2CAP LCID
    382 **
    383 **
    384 ** Returns          pointer to the lcb, or NULL if none found.
    385 **
    386 *******************************************************************************/
    387 tAVCT_LCB *avct_lcb_by_lcid(UINT16 lcid)
    388 {
    389     tAVCT_LCB   *p_lcb = &avct_cb.lcb[0];
    390     int         i;
    391 
    392     for (i = 0; i < AVCT_NUM_LINKS; i++, p_lcb++)
    393     {
    394         if (p_lcb->allocated && ((p_lcb->ch_lcid == lcid) || (p_lcb->conflict_lcid == lcid)))
    395         {
    396             break;
    397         }
    398     }
    399 
    400     if (i == AVCT_NUM_LINKS)
    401     {
    402         /* out of lcbs */
    403         p_lcb = NULL;
    404         AVCT_TRACE_WARNING("No lcb for lcid %x", lcid);
    405     }
    406 
    407     return p_lcb;
    408 }
    409 
    410 /*******************************************************************************
    411 **
    412 ** Function         avct_lcb_has_pid
    413 **
    414 ** Description      See if any ccbs on this lcb have a particular pid.
    415 **
    416 **
    417 ** Returns          Pointer to CCB if PID found, NULL otherwise.
    418 **
    419 *******************************************************************************/
    420 tAVCT_CCB *avct_lcb_has_pid(tAVCT_LCB *p_lcb, UINT16 pid)
    421 {
    422     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
    423     int         i;
    424 
    425     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
    426     {
    427         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb->cc.pid == pid))
    428         {
    429             return p_ccb;
    430         }
    431     }
    432     return NULL;
    433 }
    434 
    435 /*******************************************************************************
    436 **
    437 ** Function         avct_lcb_last_ccb
    438 **
    439 ** Description      See if given ccb is only one on the lcb.
    440 **
    441 **
    442 ** Returns          TRUE if ccb is last, FALSE otherwise.
    443 **
    444 *******************************************************************************/
    445 BOOLEAN avct_lcb_last_ccb(tAVCT_LCB *p_lcb, tAVCT_CCB *p_ccb_last)
    446 {
    447     tAVCT_CCB   *p_ccb = &avct_cb.ccb[0];
    448     int         i;
    449 
    450     AVCT_TRACE_WARNING("avct_lcb_last_ccb");
    451     for (i = 0; i < AVCT_NUM_CONN; i++, p_ccb++)
    452     {
    453         AVCT_TRACE_WARNING("%x: aloc:%d, lcb:0x%x/0x%x, ccb:0x%x/0x%x",
    454             i, p_ccb->allocated, p_ccb->p_lcb, p_lcb, p_ccb, p_ccb_last);
    455         if (p_ccb->allocated && (p_ccb->p_lcb == p_lcb) && (p_ccb != p_ccb_last))
    456         {
    457             return FALSE;
    458         }
    459     }
    460     return TRUE;
    461 }
    462 
    463 
    464 
    465