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