Home | History | Annotate | Download | only in pan
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2004-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 file contains the PAN main functions and state machine.
     22  *
     23  ******************************************************************************/
     24 
     25 #include "bt_target.h"
     26 
     27 #if defined(BTA_PAN_INCLUDED) && (BTA_PAN_INCLUDED == TRUE)
     28 
     29 #include <string.h>
     30 #include "bta_api.h"
     31 #include "bta_sys.h"
     32 #include "gki.h"
     33 #include "pan_api.h"
     34 #include "bta_pan_api.h"
     35 #include "bta_pan_int.h"
     36 #include "bd.h"
     37 #include "utl.h"
     38 
     39 /*****************************************************************************
     40 ** Constants and types
     41 *****************************************************************************/
     42 
     43 
     44 
     45 /* state machine action enumeration list */
     46 enum
     47 {
     48     BTA_PAN_API_CLOSE,
     49     BTA_PAN_TX_PATH,
     50     BTA_PAN_RX_PATH,
     51     BTA_PAN_TX_FLOW,
     52     BTA_PAN_WRITE_BUF,
     53     BTA_PAN_CONN_OPEN,
     54     BTA_PAN_CONN_CLOSE,
     55     BTA_PAN_FREE_BUF,
     56     BTA_PAN_IGNORE
     57 };
     58 
     59 
     60 
     61 /* type for action functions */
     62 typedef void (*tBTA_PAN_ACTION)(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data);
     63 
     64 
     65 
     66 
     67 /* action function list */
     68 const tBTA_PAN_ACTION bta_pan_action[] =
     69 {
     70     bta_pan_api_close,
     71     bta_pan_tx_path,
     72     bta_pan_rx_path,
     73     bta_pan_tx_flow,
     74     bta_pan_write_buf,
     75     bta_pan_conn_open,
     76     bta_pan_conn_close,
     77     bta_pan_free_buf,
     78 
     79 };
     80 
     81 /* state table information */
     82 #define BTA_PAN_ACTIONS              1       /* number of actions */
     83 #define BTA_PAN_NEXT_STATE           1       /* position of next state */
     84 #define BTA_PAN_NUM_COLS             2       /* number of columns in state tables */
     85 
     86 
     87 
     88 /* state table for listen state */
     89 const UINT8 bta_pan_st_idle[][BTA_PAN_NUM_COLS] =
     90 {
     91    /* API_CLOSE */          {BTA_PAN_API_CLOSE,              BTA_PAN_IDLE_ST},
     92    /* CI_TX_READY */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
     93    /* CI_RX_READY */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
     94    /* CI_TX_FLOW */         {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
     95    /* CI_RX_WRITE */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
     96    /* CI_RX_WRITEBUF */     {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
     97    /* PAN_CONN_OPEN */      {BTA_PAN_CONN_OPEN,              BTA_PAN_OPEN_ST},
     98    /* PAN_CONN_CLOSE */     {BTA_PAN_CONN_OPEN,              BTA_PAN_IDLE_ST},
     99    /* FLOW_ENABLE */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
    100    /* BNEP_DATA */          {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST}
    101 
    102 };
    103 
    104 
    105 
    106 /* state table for open state */
    107 const UINT8 bta_pan_st_open[][BTA_PAN_NUM_COLS] =
    108 {
    109    /* API_CLOSE */          {BTA_PAN_API_CLOSE,               BTA_PAN_OPEN_ST},
    110    /* CI_TX_READY */        {BTA_PAN_TX_PATH,                 BTA_PAN_OPEN_ST},
    111    /* CI_RX_READY */        {BTA_PAN_RX_PATH,                 BTA_PAN_OPEN_ST},
    112    /* CI_TX_FLOW */         {BTA_PAN_TX_FLOW,                 BTA_PAN_OPEN_ST},
    113    /* CI_RX_WRITE */        {BTA_PAN_IGNORE,                  BTA_PAN_OPEN_ST},
    114    /* CI_RX_WRITEBUF */     {BTA_PAN_WRITE_BUF,               BTA_PAN_OPEN_ST},
    115    /* PAN_CONN_OPEN */      {BTA_PAN_IGNORE,                  BTA_PAN_OPEN_ST},
    116    /* PAN_CONN_CLOSE */     {BTA_PAN_CONN_CLOSE,              BTA_PAN_IDLE_ST},
    117    /* FLOW_ENABLE */        {BTA_PAN_RX_PATH,                 BTA_PAN_OPEN_ST},
    118    /* BNEP_DATA */          {BTA_PAN_TX_PATH,                 BTA_PAN_OPEN_ST}
    119 };
    120 
    121 /* state table for closing state */
    122 const UINT8 bta_pan_st_closing[][BTA_PAN_NUM_COLS] =
    123 {
    124    /* API_CLOSE */          {BTA_PAN_IGNORE,                   BTA_PAN_CLOSING_ST},
    125    /* CI_TX_READY */        {BTA_PAN_TX_PATH,                  BTA_PAN_CLOSING_ST},
    126    /* CI_RX_READY */        {BTA_PAN_RX_PATH,                  BTA_PAN_CLOSING_ST},
    127    /* CI_TX_FLOW */         {BTA_PAN_TX_FLOW,                  BTA_PAN_CLOSING_ST},
    128    /* CI_RX_WRITE */        {BTA_PAN_IGNORE,                   BTA_PAN_CLOSING_ST},
    129    /* CI_RX_WRITEBUF */     {BTA_PAN_FREE_BUF,                 BTA_PAN_CLOSING_ST},
    130    /* PAN_CONN_OPEN */      {BTA_PAN_IGNORE,                   BTA_PAN_CLOSING_ST},
    131    /* PAN_CONN_CLOSE */     {BTA_PAN_CONN_CLOSE,               BTA_PAN_IDLE_ST},
    132    /* FLOW_ENABLE */        {BTA_PAN_RX_PATH,                  BTA_PAN_CLOSING_ST},
    133    /* BNEP_DATA */          {BTA_PAN_TX_PATH,                  BTA_PAN_CLOSING_ST}
    134 };
    135 
    136 /* type for state table */
    137 typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
    138 
    139 /* state table */
    140 const tBTA_PAN_ST_TBL bta_pan_st_tbl[] = {
    141     bta_pan_st_idle,
    142     bta_pan_st_open,
    143     bta_pan_st_closing
    144 };
    145 
    146 /*****************************************************************************
    147 ** Global data
    148 *****************************************************************************/
    149 
    150 /* PAN control block */
    151 #if BTA_DYNAMIC_MEMORY == FALSE
    152 tBTA_PAN_CB  bta_pan_cb;
    153 #endif
    154 
    155 /*******************************************************************************
    156 **
    157 ** Function         bta_pan_scb_alloc
    158 **
    159 ** Description      Allocate a PAN server control block.
    160 **
    161 **
    162 ** Returns          pointer to the scb, or NULL if none could be allocated.
    163 **
    164 *******************************************************************************/
    165 tBTA_PAN_SCB *bta_pan_scb_alloc(void)
    166 {
    167     tBTA_PAN_SCB     *p_scb = &bta_pan_cb.scb[0];
    168     int             i;
    169 
    170     for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
    171     {
    172         if (!p_scb->in_use)
    173         {
    174             p_scb->in_use = TRUE;
    175             APPL_TRACE_DEBUG("bta_pan_scb_alloc %d", i);
    176             break;
    177         }
    178     }
    179 
    180     if (i == BTA_PAN_NUM_CONN)
    181     {
    182         /* out of scbs */
    183         p_scb = NULL;
    184         APPL_TRACE_WARNING("Out of scbs");
    185     }
    186     return p_scb;
    187 }
    188 
    189 /*******************************************************************************
    190 **
    191 ** Function         bta_pan_sm_execute
    192 **
    193 ** Description      State machine event handling function for PAN
    194 **
    195 **
    196 ** Returns          void
    197 **
    198 *******************************************************************************/
    199 static void bta_pan_sm_execute(tBTA_PAN_SCB *p_scb, UINT16 event, tBTA_PAN_DATA *p_data)
    200 {
    201     tBTA_PAN_ST_TBL      state_table;
    202     UINT8               action;
    203     int                 i;
    204 
    205     APPL_TRACE_EVENT("PAN scb=%d event=0x%x state=%d", bta_pan_scb_to_idx(p_scb), event, p_scb->state);
    206 
    207     /* look up the state table for the current state */
    208     state_table = bta_pan_st_tbl[p_scb->state];
    209 
    210     event &= 0x00FF;
    211 
    212     /* set next state */
    213     p_scb->state = state_table[event][BTA_PAN_NEXT_STATE];
    214 
    215     /* execute action functions */
    216     for (i = 0; i < BTA_PAN_ACTIONS; i++)
    217     {
    218         if ((action = state_table[event][i]) != BTA_PAN_IGNORE)
    219         {
    220             (*bta_pan_action[action])(p_scb, p_data);
    221         }
    222         else
    223         {
    224             break;
    225         }
    226     }
    227 }
    228 
    229 /*******************************************************************************
    230 **
    231 ** Function         bta_pan_api_enable
    232 **
    233 ** Description      Handle an API enable event.
    234 **
    235 **
    236 ** Returns          void
    237 **
    238 *******************************************************************************/
    239 static void bta_pan_api_enable(tBTA_PAN_DATA *p_data)
    240 {
    241     /* initialize control block */
    242     memset(&bta_pan_cb, 0, sizeof(bta_pan_cb));
    243 
    244     /* store callback function */
    245     bta_pan_cb.p_cback = p_data->api_enable.p_cback;
    246     bta_pan_enable(p_data);
    247 }
    248 
    249 /*******************************************************************************
    250 **
    251 ** Function         bta_pan_api_disable
    252 **
    253 ** Description      Handle an API disable event.
    254 **
    255 **
    256 ** Returns          void
    257 **
    258 *******************************************************************************/
    259 static void bta_pan_api_disable(tBTA_PAN_DATA *p_data)
    260 {
    261     UNUSED(p_data);
    262 
    263     bta_pan_disable();
    264 }
    265 
    266 
    267 /*******************************************************************************
    268 **
    269 ** Function         bta_pan_api_open
    270 **
    271 ** Description      Handle an API listen event.
    272 **
    273 **
    274 ** Returns          void
    275 **
    276 *******************************************************************************/
    277 static void bta_pan_api_open(tBTA_PAN_DATA *p_data)
    278 {
    279     tBTA_PAN_SCB     *p_scb;
    280     tBTA_PAN_OPEN data;
    281 
    282     /* allocate an scb */
    283     if ((p_scb = bta_pan_scb_alloc()) != NULL)
    284     {
    285         bta_pan_open(p_scb, p_data);
    286     }
    287     else
    288     {
    289         bdcpy(data.bd_addr, p_data->api_open.bd_addr);
    290         data.status = BTA_PAN_FAIL;
    291         bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
    292 
    293     }
    294 }
    295 /*******************************************************************************
    296 **
    297 ** Function         bta_pan_scb_dealloc
    298 **
    299 ** Description      Deallocate a link control block.
    300 **
    301 **
    302 ** Returns          void
    303 **
    304 *******************************************************************************/
    305 void bta_pan_scb_dealloc(tBTA_PAN_SCB *p_scb)
    306 {
    307     APPL_TRACE_DEBUG("bta_pan_scb_dealloc %d", bta_pan_scb_to_idx(p_scb));
    308     memset(p_scb, 0, sizeof(tBTA_PAN_SCB));
    309 }
    310 
    311 /*******************************************************************************
    312 **
    313 ** Function         bta_pan_scb_to_idx
    314 **
    315 ** Description      Given a pointer to an scb, return its index.
    316 **
    317 **
    318 ** Returns          Index of scb.
    319 **
    320 *******************************************************************************/
    321 UINT8 bta_pan_scb_to_idx(tBTA_PAN_SCB *p_scb)
    322 {
    323 
    324     return ((UINT8) (p_scb - bta_pan_cb.scb)) + 1;
    325 }
    326 
    327 
    328 
    329 /*******************************************************************************
    330 **
    331 ** Function         bta_pan_scb_by_handle
    332 **
    333 ** Description      Find scb associated with handle.
    334 **
    335 **
    336 ** Returns          Pointer to scb or NULL if not found.
    337 **
    338 *******************************************************************************/
    339 tBTA_PAN_SCB *bta_pan_scb_by_handle(UINT16 handle)
    340 {
    341     tBTA_PAN_SCB     *p_scb = &bta_pan_cb.scb[0];
    342     UINT8 i;
    343 
    344     for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
    345     {
    346         if (p_scb->handle == handle)
    347         {
    348             return p_scb;;
    349         }
    350     }
    351 
    352 
    353     APPL_TRACE_WARNING("No scb for handle %d", handle);
    354 
    355     return NULL;
    356 }
    357 
    358 /*******************************************************************************
    359 **
    360 ** Function         bta_pan_hdl_event
    361 **
    362 ** Description      Data gateway main event handling function.
    363 **
    364 **
    365 ** Returns          void
    366 **
    367 *******************************************************************************/
    368 BOOLEAN bta_pan_hdl_event(BT_HDR *p_msg)
    369 {
    370     tBTA_PAN_SCB *p_scb;
    371     BOOLEAN     freebuf = TRUE;
    372 
    373     switch (p_msg->event)
    374     {
    375         /* handle enable event */
    376         case BTA_PAN_API_ENABLE_EVT:
    377             bta_pan_api_enable((tBTA_PAN_DATA *) p_msg);
    378             break;
    379 
    380         /* handle disable event */
    381         case BTA_PAN_API_DISABLE_EVT:
    382             bta_pan_api_disable((tBTA_PAN_DATA *) p_msg);
    383             break;
    384 
    385         /* handle set role event */
    386         case BTA_PAN_API_SET_ROLE_EVT:
    387             bta_pan_set_role((tBTA_PAN_DATA *) p_msg);
    388             break;
    389 
    390         /* handle open event */
    391         case BTA_PAN_API_OPEN_EVT:
    392             bta_pan_api_open((tBTA_PAN_DATA *) p_msg);
    393             break;
    394 
    395 
    396         /* events that require buffer not be released */
    397         case BTA_PAN_CI_RX_WRITEBUF_EVT:
    398             freebuf = FALSE;
    399             if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
    400             {
    401                 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
    402             }
    403             break;
    404 
    405         /* all other events */
    406         default:
    407             if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
    408             {
    409                 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
    410             }
    411             break;
    412 
    413     }
    414     return freebuf;
    415 }
    416 #endif /* BTA_PAN_INCLUDED */
    417