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 action functions for the state machine.
     22  *
     23  ******************************************************************************/
     24 
     25 #include "bt_target.h"
     26 
     27 #if defined(PAN_INCLUDED) && (PAN_INCLUDED == TRUE)
     28 
     29 #include "bta_api.h"
     30 #include "bta_sys.h"
     31 #include "bd.h"
     32 #include "gki.h"
     33 #include "pan_api.h"
     34 #include "bta_pan_api.h"
     35 #include "bta_pan_int.h"
     36 #include "bta_pan_co.h"
     37 #include <string.h>
     38 
     39 
     40 /* RX and TX data flow mask */
     41 #define BTA_PAN_RX_MASK              0x0F
     42 #define BTA_PAN_TX_MASK              0xF0
     43 
     44 /*******************************************************************************
     45 **
     46 ** Function         bta_pan_conn_state_cback
     47 **
     48 ** Description      Connection state callback from Pan profile
     49 **
     50 **
     51 ** Returns          void
     52 **
     53 *******************************************************************************/
     54 static void bta_pan_conn_state_cback(UINT16 handle, BD_ADDR bd_addr, tPAN_RESULT state,
     55                                      BOOLEAN is_role_change, UINT8 src_role, UINT8 dst_role)
     56 {
     57 
     58     tBTA_PAN_CONN * p_buf;
     59     tBTA_PAN_SCB     *p_scb;
     60 
     61 
     62     if ((p_buf = (tBTA_PAN_CONN *) GKI_getbuf(sizeof(tBTA_PAN_CONN))) != NULL)
     63     {
     64         if((state == PAN_SUCCESS) && !is_role_change)
     65         {
     66             p_buf->hdr.event = BTA_PAN_CONN_OPEN_EVT;
     67             if((p_scb = bta_pan_scb_by_handle(handle)) == NULL)
     68             {
     69                 /* allocate an scb */
     70                 p_scb = bta_pan_scb_alloc();
     71 
     72             }
     73             /* we have exceeded maximum number of connections */
     74             if(!p_scb)
     75             {
     76                 PAN_Disconnect (handle);
     77                 return;
     78             }
     79 
     80             p_scb->handle = handle;
     81             p_scb->local_role = src_role;
     82             p_scb->peer_role = dst_role;
     83             p_scb->pan_flow_enable = TRUE;
     84             bdcpy(p_scb->bd_addr, bd_addr);
     85             GKI_init_q(&p_scb->data_queue);
     86 
     87             if(src_role == PAN_ROLE_CLIENT)
     88                 p_scb->app_id = bta_pan_cb.app_id[0];
     89             else if (src_role == PAN_ROLE_GN_SERVER)
     90                 p_scb->app_id = bta_pan_cb.app_id[1];
     91             else if (src_role == PAN_ROLE_NAP_SERVER)
     92                 p_scb->app_id = bta_pan_cb.app_id[2];
     93 
     94         }
     95         else if((state != PAN_SUCCESS) && !is_role_change)
     96         {
     97             p_buf->hdr.event = BTA_PAN_CONN_CLOSE_EVT;
     98 
     99         }
    100         else
    101         {
    102             return;
    103         }
    104 
    105         p_buf->result = state;
    106         p_buf->hdr.layer_specific = handle;
    107         bta_sys_sendmsg(p_buf);
    108 
    109     }
    110 
    111 
    112 
    113 }
    114 
    115 /*******************************************************************************
    116 **
    117 ** Function         bta_pan_data_flow_cb
    118 **
    119 ** Description      Data flow status callback from PAN
    120 **
    121 **
    122 ** Returns          void
    123 **
    124 *******************************************************************************/
    125 static void bta_pan_data_flow_cb(UINT16 handle, tPAN_RESULT result)
    126 {
    127     BT_HDR  *p_buf;
    128     tBTA_PAN_SCB *p_scb;
    129 
    130     if((p_scb = bta_pan_scb_by_handle(handle)) == NULL)
    131         return;
    132 
    133     if(result == PAN_TX_FLOW_ON)
    134     {
    135         if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    136         {
    137             p_buf->layer_specific = handle;
    138             p_buf->event = BTA_PAN_BNEP_FLOW_ENABLE_EVT;
    139             bta_sys_sendmsg(p_buf);
    140         }
    141         bta_pan_co_rx_flow(handle, p_scb->app_id, TRUE);
    142 
    143     }
    144     else if(result == PAN_TX_FLOW_OFF)
    145     {
    146 
    147         p_scb->pan_flow_enable = FALSE;
    148         bta_pan_co_rx_flow(handle, p_scb->app_id, FALSE);
    149 
    150     }
    151 
    152 
    153 }
    154 
    155 
    156 /*******************************************************************************
    157 **
    158 ** Function         bta_pan_data_buf_ind_cback
    159 **
    160 ** Description      data indication callback from pan profile
    161 **
    162 **
    163 ** Returns          void
    164 **
    165 *******************************************************************************/
    166 static void bta_pan_data_buf_ind_cback(UINT16 handle, BD_ADDR src, BD_ADDR dst, UINT16 protocol, BT_HDR *p_buf,
    167                                    BOOLEAN ext, BOOLEAN forward)
    168 {
    169     tBTA_PAN_SCB *p_scb;
    170     BT_HDR * p_event;
    171     BT_HDR *p_new_buf;
    172 
    173     if ( sizeof(tBTA_PAN_DATA_PARAMS) > p_buf->offset )
    174     {
    175         /* offset smaller than data structure in front of actual data */
    176         p_new_buf = (BT_HDR *)GKI_getpoolbuf( PAN_POOL_ID );
    177         if(!p_new_buf)
    178         {
    179             APPL_TRACE_WARNING0("Cannot get a PAN GKI buffer");
    180             GKI_freebuf( p_buf );
    181             return;
    182         }
    183         else
    184         {
    185             memcpy( (UINT8 *)(p_new_buf+1)+sizeof(tBTA_PAN_DATA_PARAMS), (UINT8 *)(p_buf+1)+p_buf->offset, p_buf->len );
    186             p_new_buf->len    = p_buf->len;
    187             p_new_buf->offset = sizeof(tBTA_PAN_DATA_PARAMS);
    188             GKI_freebuf( p_buf );
    189         }
    190     }
    191     else
    192     {
    193         p_new_buf = p_buf;
    194     }
    195     /* copy params into the space before the data */
    196     bdcpy(((tBTA_PAN_DATA_PARAMS *)p_new_buf)->src, src);
    197     bdcpy(((tBTA_PAN_DATA_PARAMS *)p_new_buf)->dst, dst);
    198     ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->protocol = protocol;
    199     ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->ext = ext;
    200     ((tBTA_PAN_DATA_PARAMS *)p_new_buf)->forward = forward;
    201 
    202 
    203     if((p_scb = bta_pan_scb_by_handle(handle)) == NULL)
    204     {
    205 
    206         GKI_freebuf( p_new_buf );
    207         return;
    208     }
    209 
    210     GKI_enqueue(&p_scb->data_queue, p_new_buf);
    211     if ((p_event = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    212     {
    213         p_event->layer_specific = handle;
    214         p_event->event = BTA_PAN_RX_FROM_BNEP_READY_EVT;
    215         bta_sys_sendmsg(p_event);
    216     }
    217 
    218 }
    219 
    220 
    221 /*******************************************************************************
    222 **
    223 ** Function         bta_pan_pfilt_ind_cback
    224 **
    225 ** Description
    226 **
    227 **
    228 ** Returns          void
    229 **
    230 *******************************************************************************/
    231 static void bta_pan_pfilt_ind_cback(UINT16 handle, BOOLEAN indication,tBNEP_RESULT result,
    232                                     UINT16 num_filters, UINT8 *p_filters)
    233 {
    234 
    235     bta_pan_co_pfilt_ind(handle, indication, (tBTA_PAN_STATUS)((result == BNEP_SUCCESS) ? BTA_PAN_SUCCESS : BTA_PAN_FAIL),
    236                                     num_filters, p_filters);
    237 
    238 
    239 }
    240 
    241 
    242 /*******************************************************************************
    243 **
    244 ** Function         bta_pan_mfilt_ind_cback
    245 **
    246 ** Description
    247 **
    248 **
    249 ** Returns          void
    250 **
    251 *******************************************************************************/
    252 static void bta_pan_mfilt_ind_cback(UINT16 handle, BOOLEAN indication,tBNEP_RESULT result,
    253                                     UINT16 num_mfilters, UINT8 *p_mfilters)
    254 {
    255 
    256     bta_pan_co_mfilt_ind(handle, indication, (tBTA_PAN_STATUS)((result == BNEP_SUCCESS) ? BTA_PAN_SUCCESS : BTA_PAN_FAIL),
    257                                     num_mfilters, p_mfilters);
    258 }
    259 
    260 
    261 
    262 /*******************************************************************************
    263 **
    264 ** Function         bta_pan_enable
    265 **
    266 ** Description
    267 **
    268 **
    269 **
    270 ** Returns          void
    271 **
    272 *******************************************************************************/
    273 void bta_pan_enable(tBTA_PAN_DATA *p_data)
    274 {
    275     tPAN_REGISTER reg_data;
    276     UINT16  initial_discoverability;
    277     UINT16  initial_connectability;
    278     UINT16  d_window;
    279     UINT16  d_interval;
    280     UINT16  c_window;
    281     UINT16  c_interval;
    282 
    283     bta_pan_cb.p_cback = p_data->api_enable.p_cback;
    284 
    285     reg_data.pan_conn_state_cb  = bta_pan_conn_state_cback;
    286     reg_data.pan_bridge_req_cb  = NULL;
    287     reg_data.pan_data_buf_ind_cb = bta_pan_data_buf_ind_cback;
    288     reg_data.pan_data_ind_cb = NULL;
    289     reg_data.pan_pfilt_ind_cb = bta_pan_pfilt_ind_cback;
    290     reg_data.pan_mfilt_ind_cb = bta_pan_mfilt_ind_cback;
    291     reg_data.pan_tx_data_flow_cb = bta_pan_data_flow_cb;
    292 
    293     /* read connectability and discoverability settings.
    294     Pan profile changes the settings. We have to change it back to
    295     be consistent with other bta subsystems */
    296     initial_connectability = BTM_ReadConnectability(&c_window, &c_interval);
    297     initial_discoverability = BTM_ReadDiscoverability(&d_window, &d_interval);
    298 
    299 
    300     PAN_Register (&reg_data);
    301 
    302 
    303     /* set it back to original value */
    304     BTM_SetDiscoverability(initial_discoverability, d_window, d_interval);
    305     BTM_SetConnectability(initial_connectability, c_window, c_interval);
    306 
    307     bta_pan_cb.flow_mask = bta_pan_co_init(&bta_pan_cb.q_level);
    308     bta_pan_cb.p_cback(BTA_PAN_ENABLE_EVT, NULL);
    309 
    310 }
    311 
    312 /*******************************************************************************
    313 **
    314 ** Function         bta_pan_set_role
    315 **
    316 ** Description
    317 **
    318 ** Returns          void
    319 **
    320 *******************************************************************************/
    321 void bta_pan_set_role(tBTA_PAN_DATA *p_data)
    322 {
    323     tPAN_RESULT status;
    324     tBTA_PAN_SET_ROLE set_role;
    325     UINT8  sec[3];
    326 
    327 
    328     bta_pan_cb.app_id[0] = p_data->api_set_role.user_app_id;
    329     bta_pan_cb.app_id[1] = p_data->api_set_role.gn_app_id;
    330     bta_pan_cb.app_id[2] = p_data->api_set_role.nap_app_id;
    331 
    332     sec[0] = p_data->api_set_role.user_sec_mask;
    333     sec[1] = p_data->api_set_role.gn_sec_mask;
    334     sec[2] = p_data->api_set_role.nap_sec_mask;
    335 
    336     /* set security correctly in api and here */
    337     status = PAN_SetRole(p_data->api_set_role.role, sec,
    338                                      p_data->api_set_role.user_name,
    339                                      p_data->api_set_role.gn_name,
    340                                      p_data->api_set_role.nap_name);
    341 
    342     set_role.role = p_data->api_set_role.role;
    343     if(status == PAN_SUCCESS)
    344     {
    345         if(p_data->api_set_role.role & PAN_ROLE_NAP_SERVER )
    346             bta_sys_add_uuid(UUID_SERVCLASS_NAP);
    347         else
    348             bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
    349 
    350         if(p_data->api_set_role.role & PAN_ROLE_GN_SERVER )
    351             bta_sys_add_uuid(UUID_SERVCLASS_GN);
    352         else
    353             bta_sys_remove_uuid(UUID_SERVCLASS_GN);
    354 
    355         if(p_data->api_set_role.role & PAN_ROLE_CLIENT )
    356             bta_sys_add_uuid(UUID_SERVCLASS_PANU);
    357         else
    358             bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
    359 
    360         set_role.status = BTA_PAN_SUCCESS;
    361     }
    362     /* if status is not success clear everything */
    363     else
    364     {
    365         PAN_SetRole(0, 0, NULL, NULL, NULL);
    366         bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
    367         bta_sys_remove_uuid(UUID_SERVCLASS_GN);
    368         bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
    369         set_role.status = BTA_PAN_FAIL;
    370     }
    371     bta_pan_cb.p_cback(BTA_PAN_SET_ROLE_EVT, (tBTA_PAN *)&set_role);
    372 }
    373 
    374 
    375 
    376 /*******************************************************************************
    377 **
    378 ** Function         bta_pan_disable
    379 **
    380 ** Description
    381 **
    382 **
    383 **
    384 ** Returns          void
    385 **
    386 *******************************************************************************/
    387 void bta_pan_disable(void)
    388 {
    389 
    390     BT_HDR *p_buf;
    391     tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
    392     UINT8 i;
    393 
    394 
    395     /* close all connections */
    396     PAN_SetRole (0, NULL, NULL, NULL, NULL);
    397 
    398 #if ( BTM_EIR_SERVER_INCLUDED == TRUE )&&(BTA_EIR_CANNED_UUID_LIST != TRUE)
    399     bta_sys_remove_uuid(UUID_SERVCLASS_NAP);
    400     bta_sys_remove_uuid(UUID_SERVCLASS_GN);
    401     bta_sys_remove_uuid(UUID_SERVCLASS_PANU);
    402 #endif
    403     /* free all queued up data buffers */
    404     for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
    405     {
    406         if (p_scb->in_use)
    407         {
    408             while((p_buf = (BT_HDR *)GKI_dequeue(&p_scb->data_queue)) != NULL)
    409                 GKI_freebuf(p_buf);
    410 
    411             bta_pan_co_close(p_scb->handle, p_scb->app_id);
    412 
    413         }
    414     }
    415 
    416 
    417 
    418     PAN_Deregister();
    419 
    420 }
    421 
    422 /*******************************************************************************
    423 **
    424 ** Function         bta_pan_open
    425 **
    426 ** Description
    427 **
    428 ** Returns          void
    429 **
    430 *******************************************************************************/
    431 void bta_pan_open(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    432 {
    433     tPAN_RESULT status;
    434     tBTA_PAN_OPEN data;
    435     tBTA_PAN_OPENING    opening;
    436 
    437 
    438     status = PAN_Connect (p_data->api_open.bd_addr, p_data->api_open.local_role, p_data->api_open.peer_role,
    439                         &p_scb->handle);
    440 
    441 
    442     if(status == PAN_SUCCESS)
    443     {
    444 
    445         bdcpy(p_scb->bd_addr, p_data->api_open.bd_addr);
    446         p_scb->local_role = p_data->api_open.local_role;
    447         p_scb->peer_role = p_data->api_open.peer_role;
    448         bdcpy(opening.bd_addr, p_data->api_open.bd_addr);
    449         opening.handle = p_scb->handle;
    450         bta_pan_cb.p_cback(BTA_PAN_OPENING_EVT, (tBTA_PAN *)&opening);
    451 
    452 
    453     }
    454     else
    455     {
    456         bta_pan_scb_dealloc(p_scb);
    457         bdcpy(data.bd_addr, p_data->api_open.bd_addr);
    458         data.status = BTA_PAN_FAIL;
    459         bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
    460     }
    461 
    462 }
    463 
    464 
    465 /*******************************************************************************
    466 **
    467 ** Function         bta_pan_close
    468 **
    469 ** Description
    470 **
    471 **
    472 **
    473 ** Returns          void
    474 **
    475 *******************************************************************************/
    476 void bta_pan_api_close (tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    477 {
    478     tBTA_PAN_CONN * p_buf;
    479 
    480     PAN_Disconnect (p_scb->handle);
    481 
    482 
    483     /* send an event to BTA so that application will get the connection
    484        close event */
    485     if ((p_buf = (tBTA_PAN_CONN *) GKI_getbuf(sizeof(tBTA_PAN_CONN))) != NULL)
    486     {
    487         p_buf->hdr.event = BTA_PAN_CONN_CLOSE_EVT;
    488 
    489         p_buf->hdr.layer_specific = p_scb->handle;
    490         bta_sys_sendmsg(p_buf);
    491 
    492     }
    493 }
    494 
    495 
    496 /*******************************************************************************
    497 **
    498 ** Function         bta_pan_conn_open
    499 **
    500 ** Description      process connection open event
    501 **
    502 ** Returns          void
    503 **
    504 *******************************************************************************/
    505 void bta_pan_conn_open(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    506 {
    507 
    508     tBTA_PAN_OPEN data;
    509 
    510     bdcpy(data.bd_addr, p_scb->bd_addr);
    511     data.handle = p_scb->handle;
    512     data.local_role = p_scb->local_role;
    513     data.peer_role = p_scb->peer_role;
    514 
    515     if(p_data->conn.result == PAN_SUCCESS)
    516     {
    517         data.status = BTA_PAN_SUCCESS;
    518         bta_pan_co_open(p_scb->handle, p_scb->app_id, p_scb->local_role, p_scb->peer_role, p_scb->bd_addr);
    519 
    520     }
    521     else
    522     {
    523         bta_pan_scb_dealloc(p_scb);
    524         data.status = BTA_PAN_FAIL;
    525     }
    526 
    527     p_scb->pan_flow_enable = TRUE;
    528     p_scb->app_flow_enable = TRUE;
    529 
    530     bta_sys_conn_open( BTA_ID_PAN ,p_scb->app_id, p_scb->bd_addr);
    531 
    532     bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
    533 
    534 
    535 }
    536 
    537 /*******************************************************************************
    538 **
    539 ** Function         bta_pan_conn_close
    540 **
    541 ** Description      process connection close event
    542 **
    543 **
    544 **
    545 ** Returns          void
    546 **
    547 *******************************************************************************/
    548 void bta_pan_conn_close(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    549 {
    550 
    551     tBTA_PAN_CLOSE data;
    552     BT_HDR *p_buf;
    553 
    554     data.handle = p_data->hdr.layer_specific;
    555 
    556 
    557     bta_sys_conn_close( BTA_ID_PAN ,p_scb->app_id, p_scb->bd_addr);
    558 
    559     /* free all queued up data buffers */
    560     while((p_buf = (BT_HDR *)GKI_dequeue(&p_scb->data_queue)) != NULL)
    561         GKI_freebuf(p_buf);
    562 
    563     GKI_init_q(&p_scb->data_queue);
    564 
    565     bta_pan_co_close(p_scb->handle, p_scb->app_id);
    566 
    567     bta_pan_scb_dealloc(p_scb);
    568 
    569     bta_pan_cb.p_cback(BTA_PAN_CLOSE_EVT, (tBTA_PAN *)&data);
    570 
    571 }
    572 
    573 
    574 
    575 
    576 /*******************************************************************************
    577 **
    578 ** Function         bta_pan_rx_path
    579 **
    580 ** Description      Handle data on the RX path (data sent from the phone to
    581 **                  BTA).
    582 **
    583 **
    584 ** Returns          void
    585 **
    586 *******************************************************************************/
    587 void bta_pan_rx_path(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    588 {
    589     /* if data path configured for rx pull */
    590     if ((bta_pan_cb.flow_mask & BTA_PAN_RX_MASK) == BTA_PAN_RX_PULL)
    591     {
    592         /* if we can accept data */
    593         if (p_scb->pan_flow_enable == TRUE)
    594         {
    595             /* call application callout function for rx path */
    596             bta_pan_co_rx_path(p_scb->handle, p_scb->app_id);
    597         }
    598     }
    599     /* else data path configured for rx push */
    600     else
    601     {
    602 
    603     }
    604 }
    605 
    606 /*******************************************************************************
    607 **
    608 ** Function         bta_pan_tx_path
    609 **
    610 ** Description      Handle the TX data path (data sent from BTA to the phone).
    611 **
    612 **
    613 ** Returns          void
    614 **
    615 *******************************************************************************/
    616 void bta_pan_tx_path(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    617 {
    618 
    619     BT_HDR * p_buf;
    620     /* if data path configured for tx pull */
    621     if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PULL)
    622     {
    623         /* call application callout function for tx path */
    624         bta_pan_co_tx_path(p_scb->handle, p_scb->app_id);
    625 
    626         /* free data that exceeds queue level */
    627         while(p_scb->data_queue.count > bta_pan_cb.q_level)
    628             GKI_freebuf(GKI_dequeue(&p_scb->data_queue));
    629     }
    630     /* if configured for zero copy push */
    631     else if ((bta_pan_cb.flow_mask & BTA_PAN_TX_MASK) == BTA_PAN_TX_PUSH_BUF)
    632     {
    633         /* if app can accept data */
    634         if (p_scb->app_flow_enable == TRUE)
    635         {
    636             /* read data from the queue */
    637             if ((p_buf = (BT_HDR *)GKI_dequeue(&p_scb->data_queue)) != NULL)
    638             {
    639                 /* send data to application */
    640                 bta_pan_co_tx_writebuf(p_scb->handle,
    641                                         p_scb->app_id,
    642                                         ((tBTA_PAN_DATA_PARAMS *)p_buf)->src,
    643                                         ((tBTA_PAN_DATA_PARAMS *)p_buf)->dst,
    644                                         ((tBTA_PAN_DATA_PARAMS *)p_buf)->protocol,
    645                                         p_buf,
    646                                         ((tBTA_PAN_DATA_PARAMS *)p_buf)->ext,
    647                                         ((tBTA_PAN_DATA_PARAMS *)p_buf)->forward);
    648 
    649             }
    650             /* free data that exceeds queue level  */
    651             while(p_scb->data_queue.count > bta_pan_cb.q_level)
    652                 GKI_freebuf(GKI_dequeue(&p_scb->data_queue));
    653 
    654             /* if there is more data to be passed to
    655             upper layer */
    656             if(p_scb->data_queue.count)
    657             {
    658                 if ((p_buf = (BT_HDR *) GKI_getbuf(sizeof(BT_HDR))) != NULL)
    659                 {
    660                     p_buf->layer_specific = p_scb->handle;
    661                     p_buf->event = BTA_PAN_RX_FROM_BNEP_READY_EVT;
    662                     bta_sys_sendmsg(p_buf);
    663                 }
    664 
    665             }
    666 
    667         }
    668     }
    669 }
    670 
    671 /*******************************************************************************
    672 **
    673 ** Function         bta_pan_tx_flow
    674 **
    675 ** Description      Set the application flow control state.
    676 **
    677 **
    678 ** Returns          void
    679 **
    680 *******************************************************************************/
    681 void bta_pan_tx_flow(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    682 {
    683     p_scb->app_flow_enable = p_data->ci_tx_flow.enable;
    684 }
    685 
    686 /*******************************************************************************
    687 **
    688 ** Function         bta_pan_write_buf
    689 **
    690 ** Description      Handle a bta_pan_ci_rx_writebuf() and send data to PAN.
    691 **
    692 **
    693 ** Returns          void
    694 **
    695 *******************************************************************************/
    696 void bta_pan_write_buf(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    697 {
    698     if ((bta_pan_cb.flow_mask & BTA_PAN_RX_MASK) == BTA_PAN_RX_PUSH_BUF)
    699     {
    700 
    701         PAN_WriteBuf (p_scb->handle,
    702                       ((tBTA_PAN_DATA_PARAMS *)p_data)->dst,
    703                       ((tBTA_PAN_DATA_PARAMS *)p_data)->src,
    704                       ((tBTA_PAN_DATA_PARAMS *)p_data)->protocol,
    705                       (BT_HDR *)p_data,
    706                       ((tBTA_PAN_DATA_PARAMS *)p_data)->ext);
    707 
    708     }
    709 }
    710 
    711 /*******************************************************************************
    712 **
    713 ** Function         bta_pan_free_buf
    714 **
    715 ** Description      Frees the data buffer during closing state
    716 **
    717 **
    718 ** Returns          void
    719 **
    720 *******************************************************************************/
    721 void bta_pan_free_buf(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data)
    722 {
    723 
    724     GKI_freebuf(p_data);
    725 
    726 }
    727 
    728 #endif /* PAN_INCLUDED */
    729