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