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 "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