Home | History | Annotate | Download | only in llcp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2013 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  *
     22  *  This file contains the LLCP Data Link Connection Management
     23  *
     24  ******************************************************************************/
     25 
     26 #include <string.h>
     27 #include "gki.h"
     28 #include "nfc_target.h"
     29 #include "bt_types.h"
     30 #include "llcp_int.h"
     31 #include "llcp_defs.h"
     32 #include "nfc_int.h"
     33 
     34 static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
     35 static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
     36 static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
     37 static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
     38 static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
     39 
     40 #if (BT_TRACE_VERBOSE == TRUE)
     41 static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state);
     42 static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event);
     43 #endif
     44 
     45 /*******************************************************************************
     46 **
     47 ** Function         llcp_dlsm_execute
     48 **
     49 ** Description      This function executes the state machine for data link connection.
     50 **
     51 ** Returns          tLLCP_STATUS
     52 **
     53 *******************************************************************************/
     54 tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
     55 {
     56     tLLCP_STATUS status;
     57 
     58 #if (BT_TRACE_VERBOSE == TRUE)
     59     LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %s, evt: %s",
     60                         p_dlcb->local_sap,
     61                         llcp_dlsm_get_state_name (p_dlcb->state),
     62                         llcp_dlsm_get_event_name (event));
     63 #else
     64     LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %d, evt: %d", p_dlcb->local_sap, p_dlcb->state, event);
     65 #endif
     66 
     67     switch (p_dlcb->state)
     68     {
     69     case LLCP_DLC_STATE_IDLE:
     70         status = llcp_dlsm_idle (p_dlcb, event, p_data);
     71         break;
     72 
     73     case LLCP_DLC_STATE_W4_REMOTE_RESP:
     74         status = llcp_dlsm_w4_remote_resp (p_dlcb, event, p_data);
     75         break;
     76 
     77     case LLCP_DLC_STATE_W4_LOCAL_RESP:
     78         status = llcp_dlsm_w4_local_resp (p_dlcb, event, p_data);
     79         break;
     80 
     81     case LLCP_DLC_STATE_CONNECTED:
     82         status = llcp_dlsm_connected (p_dlcb, event, p_data);
     83         break;
     84 
     85     case LLCP_DLC_STATE_W4_REMOTE_DM:
     86         status = llcp_dlsm_w4_remote_dm (p_dlcb, event, p_data);
     87         break;
     88 
     89     default:
     90         status = LLCP_STATUS_FAIL;
     91         break;
     92     }
     93 
     94     return status;
     95 }
     96 
     97 /*******************************************************************************
     98 **
     99 ** Function         llcp_dlsm_idle
    100 **
    101 ** Description      Data link connection is in idle state
    102 **
    103 ** Returns          tLLCP_STATUS
    104 **
    105 *******************************************************************************/
    106 static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
    107 {
    108     tLLCP_STATUS            status = LLCP_STATUS_SUCCESS;
    109     tLLCP_SAP_CBACK_DATA    data;
    110     tLLCP_CONNECTION_PARAMS *p_params;
    111 
    112     switch (event)
    113     {
    114     case LLCP_DLC_EVENT_API_CONNECT_REQ:
    115 
    116         /* upper layer requests to create data link connection */
    117         p_params = (tLLCP_CONNECTION_PARAMS *)p_data;
    118 
    119         status = llcp_util_send_connect (p_dlcb, p_params);
    120 
    121         if (status == LLCP_STATUS_SUCCESS)
    122         {
    123             p_dlcb->local_miu = p_params->miu;
    124             p_dlcb->local_rw  = p_params->rw;
    125 
    126             /* wait for response from peer device */
    127             p_dlcb->state     = LLCP_DLC_STATE_W4_REMOTE_RESP;
    128 
    129             nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
    130                                    (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    131         }
    132         break;
    133 
    134     case LLCP_DLC_EVENT_PEER_CONNECT_IND:
    135 
    136         /* peer device requests to create data link connection */
    137         p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
    138 
    139         if (p_params->miu > llcp_cb.lcb.peer_miu)
    140         {
    141             LLCP_TRACE_WARNING0 ("llcp_dlsm_idle (): Peer sent data link MIU bigger than peer's link MIU");
    142             p_params->miu = llcp_cb.lcb.peer_miu;
    143         }
    144 
    145         data.connect_ind.event          = LLCP_SAP_EVT_CONNECT_IND;
    146         data.connect_ind.remote_sap     = p_dlcb->remote_sap;
    147         data.connect_ind.local_sap      = p_dlcb->local_sap;
    148         data.connect_ind.miu            = p_params->miu;
    149         data.connect_ind.rw             = p_params->rw;
    150         data.connect_ind.p_service_name = p_params->sn;
    151         data.connect_ind.server_sap     = p_dlcb->local_sap;
    152 
    153         p_dlcb->remote_miu = p_params->miu;
    154         p_dlcb->remote_rw  = p_params->rw;
    155 
    156         LLCP_TRACE_DEBUG2 ("llcp_dlsm_idle (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
    157 
    158         /* wait for response from upper layer */
    159         p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
    160 
    161         nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
    162                                (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    163 
    164         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    165 
    166         break;
    167 
    168     default:
    169         LLCP_TRACE_ERROR0 ("llcp_dlsm_idle (): Unexpected event");
    170         status = LLCP_STATUS_FAIL;
    171         break;
    172     }
    173 
    174     return status;
    175 }
    176 
    177 /*******************************************************************************
    178 **
    179 ** Function         llcp_dlsm_w4_remote_resp
    180 **
    181 ** Description      data link connection is waiting for connection confirm from peer
    182 **
    183 ** Returns          tLLCP_STATUS
    184 **
    185 *******************************************************************************/
    186 static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
    187 {
    188     tLLCP_STATUS            status = LLCP_STATUS_SUCCESS;
    189     tLLCP_SAP_CBACK_DATA    data;
    190     tLLCP_CONNECTION_PARAMS *p_params;
    191 
    192     switch (event)
    193     {
    194     case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
    195 
    196         /* peer device accepted data link connection */
    197         nfc_stop_quick_timer (&p_dlcb->timer);
    198 
    199         p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
    200 
    201         /* data link MIU must be up to link MIU */
    202         if (p_params->miu > llcp_cb.lcb.peer_miu)
    203         {
    204             LLCP_TRACE_WARNING0 ("llcp_dlsm_w4_remote_resp (): Peer sent data link MIU bigger than peer's link MIU");
    205             p_params->miu = llcp_cb.lcb.peer_miu;
    206         }
    207 
    208         p_dlcb->remote_miu = p_params->miu;
    209         p_dlcb->remote_rw  = p_params->rw;
    210 
    211         LLCP_TRACE_DEBUG2 ("llcp_dlsm_w4_remote_resp (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
    212 
    213         p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
    214         llcp_util_adjust_dl_rx_congestion ();
    215 
    216         data.connect_resp.event          = LLCP_SAP_EVT_CONNECT_RESP;
    217         data.connect_resp.remote_sap     = p_dlcb->remote_sap;
    218         data.connect_resp.local_sap      = p_dlcb->local_sap;
    219         data.connect_resp.miu            = p_params->miu;
    220         data.connect_resp.rw             = p_params->rw;
    221 
    222         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    223 
    224         if (llcp_cb.overall_rx_congested)
    225         {
    226             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
    227         }
    228         break;
    229 
    230     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
    231     case LLCP_DLC_EVENT_TIMEOUT:
    232 
    233         /* peer device rejected connection or didn't respond */
    234         data.disconnect_resp.event       = LLCP_SAP_EVT_DISCONNECT_RESP;
    235         data.disconnect_resp.local_sap   = p_dlcb->local_sap;
    236         data.disconnect_resp.remote_sap  = p_dlcb->remote_sap;
    237         data.disconnect_resp.reason      = *((UINT8*) p_data);
    238         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    239 
    240         /* stop timer, flush any pending data in queue and deallocate control block */
    241         llcp_util_deallocate_data_link (p_dlcb);
    242 
    243         llcp_util_adjust_dl_rx_congestion ();
    244         break;
    245 
    246     case LLCP_DLC_EVENT_FRAME_ERROR:
    247     case LLCP_DLC_EVENT_LINK_ERROR:
    248 
    249         /* received bad frame or link is deactivated */
    250         data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
    251         data.disconnect_ind.local_sap   = p_dlcb->local_sap;
    252         data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
    253         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    254 
    255         llcp_util_deallocate_data_link (p_dlcb);
    256         llcp_util_adjust_dl_rx_congestion ();
    257         break;
    258 
    259     default:
    260         LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_resp (): Unexpected event");
    261         status = LLCP_STATUS_FAIL;
    262         break;
    263     }
    264 
    265     return status;
    266 }
    267 
    268 /*******************************************************************************
    269 **
    270 ** Function         llcp_dlsm_w4_local_resp
    271 **
    272 ** Description      data link connection is waiting for connection confirm from application
    273 **
    274 ** Returns          tLLCP_STATUS
    275 **
    276 *******************************************************************************/
    277 static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
    278 {
    279     tLLCP_STATUS             status = LLCP_STATUS_SUCCESS;
    280     tLLCP_CONNECTION_PARAMS *p_params;
    281     tLLCP_SAP_CBACK_DATA     data;
    282     UINT8                    reason;
    283 
    284     switch (event)
    285     {
    286     case LLCP_DLC_EVENT_API_CONNECT_CFM:
    287 
    288         /* upper layer accepted data link connection */
    289         nfc_stop_quick_timer (&p_dlcb->timer);
    290 
    291         p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
    292 
    293         p_dlcb->local_miu = p_params->miu;
    294         p_dlcb->local_rw  = p_params->rw;
    295 
    296         p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
    297 
    298         if (llcp_cb.overall_rx_congested)
    299         {
    300             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
    301         }
    302 
    303         status = llcp_util_send_cc (p_dlcb, p_params);
    304 
    305         if (status == LLCP_STATUS_SUCCESS)
    306         {
    307             llcp_util_adjust_dl_rx_congestion ();
    308         }
    309         else
    310         {
    311             data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
    312             data.disconnect_ind.local_sap   = p_dlcb->local_sap;
    313             data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
    314             (*p_dlcb->p_app_cb->p_app_cback) (&data);
    315 
    316             llcp_util_deallocate_data_link (p_dlcb);
    317         }
    318         break;
    319 
    320     case LLCP_DLC_EVENT_API_CONNECT_REJECT:
    321     case LLCP_DLC_EVENT_TIMEOUT:
    322 
    323         if (event == LLCP_DLC_EVENT_TIMEOUT)
    324             reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
    325         else
    326             reason = *((UINT8*) p_data);
    327 
    328         /* upper layer rejected connection or didn't respond */
    329         llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, reason);
    330 
    331         /* stop timer, flush any pending data in queue and deallocate control block */
    332         llcp_util_deallocate_data_link (p_dlcb);
    333         llcp_util_adjust_dl_rx_congestion ();
    334         break;
    335 
    336     case LLCP_DLC_EVENT_FRAME_ERROR:
    337     case LLCP_DLC_EVENT_LINK_ERROR:
    338 
    339         /* received bad frame or link is deactivated */
    340         data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
    341         data.disconnect_ind.local_sap   = p_dlcb->local_sap;
    342         data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
    343         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    344 
    345         llcp_util_deallocate_data_link (p_dlcb);
    346         llcp_util_adjust_dl_rx_congestion ();
    347         break;
    348 
    349     default:
    350         LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_local_resp (): Unexpected event");
    351         status = LLCP_STATUS_FAIL;
    352         break;
    353     }
    354 
    355     return status;
    356 }
    357 
    358 /*******************************************************************************
    359 **
    360 ** Function         llcp_dlsm_connected
    361 **
    362 ** Description      data link connection is connected
    363 **
    364 ** Returns          tLLCP_STATUS
    365 **
    366 *******************************************************************************/
    367 static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
    368 {
    369     BOOLEAN              flush;
    370     tLLCP_STATUS         status = LLCP_STATUS_SUCCESS;
    371     tLLCP_SAP_CBACK_DATA data;
    372 
    373     switch (event)
    374     {
    375     case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
    376 
    377         /* upper layer requests to disconnect */
    378         flush = *(BOOLEAN*) (p_data);
    379 
    380         /*
    381         ** if upper layer asks to discard any pending data
    382         ** or there is no pending data/ack to send and it is not waiting for ack
    383         */
    384         if (  (flush)
    385             ||(  (p_dlcb->i_xmit_q.count == 0)
    386                &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
    387                &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )  )
    388         {
    389             /* wait for disconnect response */
    390             p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
    391 
    392             llcp_util_send_disc (p_dlcb->remote_sap, p_dlcb->local_sap );
    393 
    394             nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
    395                                    (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    396         }
    397         else
    398         {
    399             /* set flag to send DISC when tx queue is empty */
    400             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
    401         }
    402         break;
    403 
    404     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
    405 
    406         /* peer device requests to disconnect */
    407 
    408         /* send disconnect response and notify upper layer */
    409         llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
    410 
    411         data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
    412         data.disconnect_ind.local_sap   = p_dlcb->local_sap;
    413         data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
    414         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    415 
    416         llcp_util_deallocate_data_link (p_dlcb);
    417         llcp_util_adjust_dl_rx_congestion ();
    418         break;
    419 
    420     case LLCP_DLC_EVENT_API_DATA_REQ:
    421 
    422         /* upper layer requests to send data */
    423 
    424         /* if peer device can receive data */
    425         if (p_dlcb->remote_rw)
    426         {
    427             /* enqueue data and check if data can be sent */
    428             GKI_enqueue (&p_dlcb->i_xmit_q, p_data);
    429             llcp_cb.total_tx_i_pdu++;
    430 
    431             llcp_link_check_send_data ();
    432 
    433             if (  (p_dlcb->is_tx_congested)
    434                 ||(llcp_cb.overall_tx_congested)
    435                 ||(p_dlcb->remote_busy)
    436                 ||(p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)  ) /*if enough data to send next round */
    437             {
    438                 LLCP_TRACE_DEBUG3 ("llcp_dlsm_connected (): Data link (SSAP:DSAP=0x%X:0x%X) congested: xmit_q.count=%d",
    439                                     p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
    440 
    441                 /* set congested here so overall congestion check routine will not report event again */
    442                 p_dlcb->is_tx_congested = TRUE;
    443                 status = LLCP_STATUS_CONGESTED;
    444             }
    445         }
    446         else
    447         {
    448             LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Remote RW is zero: discard data");
    449             /* buffer will be freed when returned to API function */
    450             status = LLCP_STATUS_FAIL;
    451         }
    452         break;
    453 
    454     case LLCP_DLC_EVENT_PEER_DATA_IND:
    455         /* peer device sends data so notify upper layer to read data from data link connection */
    456 
    457         data.data_ind.event         = LLCP_SAP_EVT_DATA_IND;
    458         data.data_ind.local_sap     = p_dlcb->local_sap;
    459         data.data_ind.link_type     = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
    460         data.data_ind.remote_sap    = p_dlcb->remote_sap;
    461 
    462         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    463         break;
    464 
    465     case LLCP_DLC_EVENT_FRAME_ERROR:
    466     case LLCP_DLC_EVENT_LINK_ERROR:
    467 
    468         /* received bad frame or link is deactivated */
    469         data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
    470         data.disconnect_ind.local_sap   = p_dlcb->local_sap;
    471         data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
    472         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    473 
    474         llcp_util_deallocate_data_link (p_dlcb);
    475         llcp_util_adjust_dl_rx_congestion ();
    476         break;
    477 
    478     default:
    479         LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Unexpected event");
    480         status = LLCP_STATUS_FAIL;
    481         break;
    482     }
    483 
    484     return status;
    485 }
    486 
    487 /*******************************************************************************
    488 **
    489 ** Function         llcp_dlsm_w4_remote_dm
    490 **
    491 ** Description      data link connection is waiting for disconnection confirm from peer
    492 **
    493 ** Returns          tLLCP_STATUS
    494 **
    495 *******************************************************************************/
    496 static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
    497 {
    498     tLLCP_STATUS         status = LLCP_STATUS_SUCCESS;
    499     tLLCP_SAP_CBACK_DATA data;
    500 
    501     switch (event)
    502     {
    503     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
    504     case LLCP_DLC_EVENT_TIMEOUT:
    505 
    506         /* peer device sends disconnect response or didn't responde */
    507         data.disconnect_resp.event       = LLCP_SAP_EVT_DISCONNECT_RESP;
    508         data.disconnect_resp.local_sap   = p_dlcb->local_sap;
    509         data.disconnect_resp.remote_sap  = p_dlcb->remote_sap;
    510         data.disconnect_resp.reason      = LLCP_SAP_DM_REASON_RESP_DISC;
    511         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    512 
    513         llcp_util_deallocate_data_link (p_dlcb);
    514         llcp_util_adjust_dl_rx_congestion ();
    515         break;
    516 
    517     case LLCP_DLC_EVENT_FRAME_ERROR:
    518     case LLCP_DLC_EVENT_LINK_ERROR:
    519 
    520         /* received bad frame or link is deactivated */
    521         data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
    522         data.disconnect_ind.local_sap   = p_dlcb->local_sap;
    523         data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
    524         (*p_dlcb->p_app_cb->p_app_cback) (&data);
    525 
    526         llcp_util_deallocate_data_link (p_dlcb);
    527         llcp_util_adjust_dl_rx_congestion ();
    528         break;
    529 
    530     case LLCP_DLC_EVENT_PEER_DATA_IND:
    531         break;
    532 
    533     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
    534         /* it's race condition, send disconnect response and wait for DM */
    535         llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
    536         break;
    537 
    538     default:
    539         LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_dm (): Unexpected event");
    540         status = LLCP_STATUS_FAIL;
    541         break;
    542     }
    543 
    544     return status;
    545 }
    546 
    547 /*******************************************************************************
    548 **
    549 ** Function         llcp_dlc_find_dlcb_by_local_sap
    550 **
    551 ** Description      Find tLLCP_DLCB by local SAP and remote SAP
    552 **                  if remote_sap is LLCP_INVALID_SAP, it will return a DLCB which
    553 **                  is waiting for CC from peer.
    554 **
    555 ** Returns          tLLCP_DLCB *
    556 **
    557 *******************************************************************************/
    558 tLLCP_DLCB *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap)
    559 {
    560     int i;
    561 
    562     for (i = 0; i < LLCP_MAX_DATA_LINK; i++)
    563     {
    564         if (  (llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE)
    565             &&(llcp_cb.dlcb[i].local_sap == local_sap)  )
    566         {
    567             if ((remote_sap == LLCP_INVALID_SAP) && (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP))
    568             {
    569                 /* Remote SAP has not been finalized because we are watiing for CC */
    570                 return (&llcp_cb.dlcb[i]);
    571             }
    572             else if (llcp_cb.dlcb[i].remote_sap == remote_sap)
    573             {
    574                 return (&llcp_cb.dlcb[i]);
    575             }
    576         }
    577     }
    578     return NULL;
    579 }
    580 
    581 /*******************************************************************************
    582 **
    583 ** Function         llcp_dlc_flush_q
    584 **
    585 ** Description      Free buffers in tx and rx queue in data link
    586 **
    587 ** Returns          void
    588 **
    589 *******************************************************************************/
    590 void llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb)
    591 {
    592     if (p_dlcb)
    593     {
    594         LLCP_TRACE_DEBUG1 ("llcp_dlc_flush_q (): local SAP:0x%02X", p_dlcb->local_sap);
    595 
    596         /* Release any held buffers */
    597         while (p_dlcb->i_xmit_q.p_first)
    598         {
    599             GKI_freebuf (GKI_dequeue (&p_dlcb->i_xmit_q));
    600             llcp_cb.total_tx_i_pdu--;
    601         }
    602 
    603         /* discard any received I PDU on data link  including in AGF */
    604         LLCP_FlushDataLinkRxData (p_dlcb->local_sap, p_dlcb->remote_sap);
    605     }
    606     else
    607     {
    608         LLCP_TRACE_ERROR0 ("llcp_dlc_flush_q (): p_dlcb is NULL");
    609     }
    610 }
    611 
    612 /*******************************************************************************
    613 **
    614 ** Function         llcp_dlc_proc_connect_pdu
    615 **
    616 ** Description      Process CONNECT PDU
    617 **
    618 ** Returns          void
    619 **
    620 *******************************************************************************/
    621 static void llcp_dlc_proc_connect_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    622 {
    623     tLLCP_DLCB   *p_dlcb;
    624     tLLCP_STATUS  status;
    625     tLLCP_APP_CB *p_app_cb;
    626 
    627     tLLCP_CONNECTION_PARAMS  params;
    628 
    629     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_connect_pdu ()");
    630 
    631     p_app_cb = llcp_util_get_app_cb (dsap);
    632 
    633     if (  (p_app_cb == NULL)
    634         ||(p_app_cb->p_app_cback == NULL)
    635         ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)  )
    636     {
    637         LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered SAP:0x%x", dsap);
    638         llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
    639         return;
    640     }
    641 
    642     /* parse CONNECT PDU and get connection parameters */
    643     if (llcp_util_parse_connect (p_data, length, &params) != LLCP_STATUS_SUCCESS)
    644     {
    645         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Bad format CONNECT");
    646         llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
    647         return;
    648     }
    649 
    650     /* if this is connection by service name */
    651     if (dsap == LLCP_SAP_SDP)
    652     {
    653         /* find registered SAP with service name */
    654         if (strlen (params.sn))
    655             dsap = llcp_sdp_get_sap_by_name (params.sn, (UINT8) strlen (params.sn));
    656         else
    657         {
    658             llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
    659             return;
    660         }
    661 
    662         if (dsap == LLCP_SAP_SDP)
    663         {
    664             LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
    665 
    666             llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
    667             return;
    668         }
    669         else if (dsap == 0)
    670         {
    671             LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s", params.sn);
    672 
    673             llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
    674             return;
    675         }
    676         else
    677         {
    678             /* check if this application can support connection-oriented transport */
    679             p_app_cb = llcp_util_get_app_cb (dsap);
    680 
    681             if (  (p_app_cb == NULL)
    682                 ||(p_app_cb->p_app_cback == NULL)
    683                 ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)  )
    684             {
    685                 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): SAP(0x%x) doesn't support connection-oriented", dsap);
    686                 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
    687                 return;
    688             }
    689         }
    690     }
    691 
    692     /* check if any data link */
    693     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    694     if (p_dlcb)
    695     {
    696         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Data link is aleady established");
    697         llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
    698     }
    699     else
    700     {
    701         /* allocate data link connection control block and notify upper layer through state machine */
    702         p_dlcb = llcp_util_allocate_data_link (dsap, ssap);
    703 
    704         if (p_dlcb)
    705         {
    706             status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
    707             if (status != LLCP_STATUS_SUCCESS)
    708             {
    709                 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
    710                 llcp_util_deallocate_data_link (p_dlcb);
    711             }
    712         }
    713         else
    714         {
    715             LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
    716             llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
    717         }
    718     }
    719 }
    720 
    721 /*******************************************************************************
    722 **
    723 ** Function         llcp_dlc_proc_disc_pdu
    724 **
    725 ** Description      Process DISC PDU
    726 **
    727 ** Returns          void
    728 **
    729 *******************************************************************************/
    730 static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    731 {
    732     tLLCP_DLCB *p_dlcb;
    733 
    734     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
    735 
    736     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    737     if (p_dlcb)
    738     {
    739         if (length > 0)
    740         {
    741             LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
    742 
    743             llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
    744             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    745         }
    746         else
    747         {
    748             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
    749         }
    750     }
    751     else
    752     {
    753         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
    754     }
    755 }
    756 
    757 /*******************************************************************************
    758 **
    759 ** Function         llcp_dlc_proc_cc_pdu
    760 **
    761 ** Description      Process CC PDU
    762 **
    763 ** Returns          void
    764 **
    765 *******************************************************************************/
    766 static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    767 {
    768     tLLCP_DLCB              *p_dlcb;
    769     tLLCP_CONNECTION_PARAMS  params;
    770     tLLCP_STATUS             status;
    771 
    772     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
    773 
    774     /* find a DLCB waiting for CC on this local SAP */
    775     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
    776     if (p_dlcb)
    777     {
    778         /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
    779         p_dlcb->remote_sap = ssap;
    780 
    781         if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
    782         {
    783             status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
    784             if (status != LLCP_STATUS_SUCCESS)
    785             {
    786                 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
    787                 llcp_util_deallocate_data_link (p_dlcb);
    788             }
    789         }
    790         else
    791         {
    792             llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
    793             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    794         }
    795     }
    796     else
    797     {
    798         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
    799     }
    800 }
    801 
    802 /*******************************************************************************
    803 **
    804 ** Function         llcp_dlc_proc_dm_pdu
    805 **
    806 ** Description      Process DM PDU
    807 **
    808 ** Returns          void
    809 **
    810 *******************************************************************************/
    811 static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    812 {
    813     tLLCP_DLCB *p_dlcb;
    814 
    815     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
    816 
    817     if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
    818     {
    819         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
    820     }
    821     else
    822     {
    823         if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
    824         {
    825             /* local device initiated disconnecting */
    826             p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    827         }
    828         else
    829         {
    830             /* peer device rejected connection with any reason */
    831             /* find a DLCB waiting for CC on this local SAP    */
    832             p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
    833         }
    834 
    835         if (p_dlcb)
    836         {
    837             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
    838         }
    839         else
    840         {
    841             LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
    842         }
    843     }
    844 }
    845 
    846 /*******************************************************************************
    847 **
    848 ** Function         llcp_dlc_proc_i_pdu
    849 **
    850 ** Description      Process I PDU
    851 **
    852 ** Returns          void
    853 **
    854 *******************************************************************************/
    855 void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
    856 {
    857     UINT8      *p, *p_dst, send_seq, rcv_seq, error_flags;
    858     UINT16      info_len, available_bytes;
    859     tLLCP_DLCB *p_dlcb;
    860     BOOLEAN     appended;
    861     BT_HDR     *p_last_buf;
    862 
    863     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
    864 
    865     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    866 
    867     if (p_dlcb)
    868     {
    869         error_flags = 0;
    870 
    871         if (p_msg)
    872         {
    873             i_pdu_length = p_msg->len;
    874             p_i_pdu = (UINT8 *) (p_msg + 1) + p_msg->offset;
    875         }
    876 
    877         info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
    878 
    879         if (info_len > p_dlcb->local_miu)
    880         {
    881             LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
    882                                 p_dlcb->local_miu, info_len);
    883 
    884             error_flags |= LLCP_FRMR_I_ERROR_FLAG;
    885         }
    886 
    887         /* get sequence numbers */
    888         p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
    889 
    890         send_seq = LLCP_GET_NS (*p);
    891         rcv_seq  = LLCP_GET_NR (*p);
    892 
    893 #if (BT_TRACE_VERBOSE == TRUE)
    894         LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
    895                             send_seq, rcv_seq,
    896                             p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
    897                             p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
    898 #endif
    899 
    900         /* if send sequence number, N(S) is not expected one, V(R) */
    901         if (p_dlcb->next_rx_seq != send_seq)
    902         {
    903             LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
    904                                 send_seq, p_dlcb->next_rx_seq);
    905 
    906             error_flags |= LLCP_FRMR_S_ERROR_FLAG;
    907         }
    908         else
    909         {
    910             /* if peer device sends more than our receiving window size */
    911             if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
    912             {
    913                 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
    914                                     send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
    915 
    916                 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
    917             }
    918         }
    919 
    920         /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
    921         if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
    922             != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
    923         {
    924             error_flags |= LLCP_FRMR_R_ERROR_FLAG;
    925             LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
    926                                 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
    927         }
    928 
    929         /* if any error is found */
    930         if (error_flags)
    931         {
    932             llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
    933             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    934         }
    935         else
    936         {
    937             /* update local sequence variables */
    938             p_dlcb->next_rx_seq  = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
    939             p_dlcb->rcvd_ack_seq = rcv_seq;
    940 
    941             appended = FALSE;
    942 
    943             /* get last buffer in rx queue */
    944             p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
    945 
    946             if (p_last_buf)
    947             {
    948                 /* get max length to append at the end of buffer */
    949                 available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
    950 
    951                 /* if new UI PDU with length can be attached at the end of buffer */
    952                 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
    953                 {
    954                     p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
    955 
    956                     /* add length of information in I PDU */
    957                     UINT16_TO_BE_STREAM (p_dst, info_len);
    958 
    959                     /* copy information of I PDU */
    960                     p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
    961 
    962                     memcpy (p_dst, p, info_len);
    963 
    964                     p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
    965 
    966                     if (p_msg)
    967                     {
    968                         GKI_freebuf (p_msg);
    969                         p_msg = NULL;
    970                     }
    971 
    972                     appended = TRUE;
    973                 }
    974             }
    975 
    976             /* if it is not available to append */
    977             if (!appended)
    978             {
    979                 /* if it's not from AGF PDU */
    980                 if (p_msg)
    981                 {
    982                     /* add length of information in front of information */
    983                     p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
    984                     UINT16_TO_BE_STREAM (p, info_len);
    985 
    986                     p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
    987                     p_msg->len    -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
    988                     p_msg->layer_specific = 0;
    989                 }
    990                 else
    991                 {
    992                     p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
    993 
    994                     if (p_msg)
    995                     {
    996                         p_dst = (UINT8*) (p_msg + 1);
    997 
    998                         /* add length of information in front of information */
    999                         UINT16_TO_BE_STREAM (p_dst, info_len);
   1000 
   1001                         p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
   1002                         memcpy (p_dst, p, info_len);
   1003 
   1004                         p_msg->offset = 0;
   1005                         p_msg->len    = LLCP_PDU_AGF_LEN_SIZE + info_len;
   1006                         p_msg->layer_specific = 0;
   1007                     }
   1008                     else
   1009                     {
   1010                         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
   1011                     }
   1012                 }
   1013 
   1014                 /* insert I PDU in rx queue */
   1015                 if (p_msg)
   1016                 {
   1017                     GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
   1018                     p_msg = NULL;
   1019                     llcp_cb.total_rx_i_pdu++;
   1020 
   1021                     llcp_util_check_rx_congested_status ();
   1022                 }
   1023             }
   1024 
   1025             p_dlcb->num_rx_i_pdu++;
   1026 
   1027             if (  (!p_dlcb->local_busy)
   1028                 &&(p_dlcb->num_rx_i_pdu == 1)  )
   1029             {
   1030                 /* notify rx data is available so upper layer reads data until queue is empty */
   1031                 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
   1032             }
   1033 
   1034             if (  (!p_dlcb->is_rx_congested)
   1035                 &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)  )
   1036             {
   1037                 LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
   1038                                     p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
   1039 
   1040                 /* send RNR */
   1041                 p_dlcb->is_rx_congested = TRUE;
   1042                 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1043             }
   1044         }
   1045     }
   1046     else
   1047     {
   1048         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
   1049         llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
   1050     }
   1051 
   1052     if (p_msg)
   1053     {
   1054         GKI_freebuf (p_msg);
   1055     }
   1056 }
   1057 
   1058 /*******************************************************************************
   1059 **
   1060 ** Function         llcp_dlc_proc_rr_rnr_pdu
   1061 **
   1062 ** Description      Process RR or RNR PDU
   1063 **
   1064 ** Returns          void
   1065 **
   1066 *******************************************************************************/
   1067 static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
   1068 {
   1069     UINT8      rcv_seq, error_flags;
   1070     tLLCP_DLCB *p_dlcb;
   1071     BOOLEAN     flush = TRUE;
   1072     tLLCP_SAP_CBACK_DATA cback_data;
   1073 
   1074     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
   1075 
   1076     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
   1077     if (p_dlcb != NULL)
   1078     {
   1079         error_flags = 0;
   1080 
   1081         rcv_seq = LLCP_GET_NR (*p_data);
   1082 
   1083         if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
   1084         {
   1085             error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
   1086         }
   1087 
   1088         /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
   1089         if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
   1090             != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
   1091         {
   1092             error_flags |= LLCP_FRMR_R_ERROR_FLAG;
   1093             LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
   1094                                 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
   1095         }
   1096 
   1097         if (error_flags)
   1098         {
   1099             llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
   1100             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
   1101         }
   1102         else
   1103         {
   1104             p_dlcb->rcvd_ack_seq = rcv_seq;
   1105 
   1106 #if (BT_TRACE_VERBOSE == TRUE)
   1107             LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
   1108                                 rcv_seq,
   1109                                 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
   1110                                 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
   1111 #endif
   1112 
   1113             if (ptype == LLCP_PDU_RNR_TYPE)
   1114             {
   1115                 /* if upper layer hasn't get congestion started notification */
   1116                 if (  (!p_dlcb->remote_busy)
   1117                     &&(!p_dlcb->is_tx_congested)  )
   1118                 {
   1119                     LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
   1120                                           p_dlcb->local_sap, p_dlcb->remote_sap,
   1121                                           p_dlcb->i_xmit_q.count);
   1122 
   1123                     cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
   1124                     cback_data.congest.local_sap    = p_dlcb->local_sap;
   1125                     cback_data.congest.remote_sap   = p_dlcb->remote_sap;
   1126                     cback_data.congest.is_congested = TRUE;
   1127                     cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
   1128 
   1129                     (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
   1130                 }
   1131                 p_dlcb->remote_busy = TRUE;
   1132             }
   1133             else
   1134             {
   1135                 /* if upper layer hasn't get congestion ended notification and data link is not congested */
   1136                 if (  (p_dlcb->remote_busy)
   1137                     &&(!p_dlcb->is_tx_congested)  )
   1138                 {
   1139                     LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
   1140                                           p_dlcb->local_sap, p_dlcb->remote_sap,
   1141                                           p_dlcb->i_xmit_q.count);
   1142 
   1143                     cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
   1144                     cback_data.congest.local_sap    = p_dlcb->local_sap;
   1145                     cback_data.congest.remote_sap   = p_dlcb->remote_sap;
   1146                     cback_data.congest.is_congested = FALSE;
   1147                     cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
   1148 
   1149                     (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
   1150                 }
   1151                 p_dlcb->remote_busy = FALSE;
   1152             }
   1153 
   1154             /* check flag to send DISC when tx queue is empty */
   1155             if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
   1156             {
   1157                 /* if no pending data and all PDU is acked */
   1158                 if (  (p_dlcb->i_xmit_q.count == 0)
   1159                     &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
   1160                     &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
   1161                 {
   1162                     p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
   1163                     llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1164                 }
   1165             }
   1166         }
   1167     }
   1168     else
   1169     {
   1170         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
   1171     }
   1172 }
   1173 
   1174 /*******************************************************************************
   1175 **
   1176 ** Function         llcp_dlc_proc_rx_pdu
   1177 **
   1178 ** Description      Process PDU for data link
   1179 **
   1180 ** Returns          void
   1181 **
   1182 *******************************************************************************/
   1183 void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
   1184 {
   1185     tLLCP_DLCB *p_dlcb;
   1186 
   1187     LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
   1188                         dsap, ptype, ssap);
   1189 
   1190     if (dsap == LLCP_SAP_LM)
   1191     {
   1192         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
   1193         return;
   1194     }
   1195 
   1196     switch (ptype)
   1197     {
   1198     case LLCP_PDU_CONNECT_TYPE:
   1199         llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
   1200         break;
   1201 
   1202     case LLCP_PDU_DISC_TYPE:
   1203         llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
   1204         break;
   1205 
   1206     case LLCP_PDU_CC_TYPE:
   1207         llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
   1208         break;
   1209 
   1210     case LLCP_PDU_DM_TYPE:
   1211         llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
   1212         break;
   1213 
   1214     case LLCP_PDU_FRMR_TYPE:
   1215         p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
   1216         if (p_dlcb)
   1217         {
   1218             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
   1219         }
   1220         break;
   1221 
   1222     case LLCP_PDU_RR_TYPE:
   1223     case LLCP_PDU_RNR_TYPE:
   1224         llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
   1225         break;
   1226 
   1227     default:
   1228         LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
   1229 
   1230         p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
   1231         if (p_dlcb)
   1232         {
   1233             llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
   1234             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
   1235         }
   1236         break;
   1237     }
   1238 }
   1239 
   1240 /*******************************************************************************
   1241 **
   1242 ** Function         llcp_dlc_check_to_send_rr_rnr
   1243 **
   1244 ** Description      Send RR or RNR if necessary
   1245 **
   1246 ** Returns          void
   1247 **
   1248 *******************************************************************************/
   1249 void llcp_dlc_check_to_send_rr_rnr (void)
   1250 {
   1251     UINT8   idx;
   1252     BOOLEAN flush = TRUE;
   1253 
   1254     LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
   1255 
   1256     /*
   1257     ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
   1258     ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
   1259     ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
   1260     **
   1261     ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
   1262     ** V(R).
   1263     */
   1264     for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
   1265     {
   1266         if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
   1267         {
   1268             llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
   1269 
   1270             /* check flag to send DISC when tx queue is empty */
   1271             if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
   1272             {
   1273                 /* if no pending data and all PDU is acked */
   1274                 if (  (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
   1275                     &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
   1276                     &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)  )
   1277                 {
   1278                     llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
   1279                     llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1280                 }
   1281             }
   1282         }
   1283     }
   1284 }
   1285 
   1286 /*******************************************************************************
   1287 **
   1288 ** Function         llcp_dlc_is_rw_open
   1289 **
   1290 ** Description      check if receive window is open in remote
   1291 **
   1292 ** Returns          TRUE if remote can receive more data
   1293 **
   1294 *******************************************************************************/
   1295 BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
   1296 {
   1297     if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
   1298     {
   1299         return TRUE;
   1300     }
   1301     else
   1302     {
   1303         LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
   1304                            p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
   1305         return FALSE;
   1306     }
   1307 }
   1308 
   1309 /*******************************************************************************
   1310 **
   1311 ** Function         llcp_dlc_get_next_pdu
   1312 **
   1313 ** Description      Get a PDU from tx queue of data link
   1314 **
   1315 ** Returns          BT_HDR*
   1316 **
   1317 *******************************************************************************/
   1318 BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
   1319 {
   1320     BT_HDR *p_msg = NULL;
   1321     BOOLEAN flush = TRUE;
   1322     tLLCP_SAP_CBACK_DATA data;
   1323 
   1324 #if (BT_TRACE_VERBOSE == TRUE)
   1325     UINT8   send_seq = p_dlcb->next_tx_seq;
   1326 #endif
   1327 
   1328     /* if there is data to send and remote device can receive it */
   1329     if (  (p_dlcb->i_xmit_q.count)
   1330         &&(!p_dlcb->remote_busy)
   1331         &&(llcp_dlc_is_rw_open (p_dlcb))  )
   1332     {
   1333         p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
   1334         llcp_cb.total_tx_i_pdu--;
   1335 
   1336         if (p_msg->offset >= LLCP_MIN_OFFSET)
   1337         {
   1338             /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
   1339             llcp_util_build_info_pdu (p_dlcb, p_msg);
   1340 
   1341             p_dlcb->next_tx_seq  = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
   1342 
   1343 #if (BT_TRACE_VERBOSE == TRUE)
   1344             LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
   1345                                 send_seq, p_dlcb->next_rx_seq,
   1346                                 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
   1347                                 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
   1348 #endif
   1349         }
   1350         else
   1351         {
   1352             LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
   1353                                 p_msg->offset, LLCP_MIN_OFFSET );
   1354             GKI_freebuf (p_msg);
   1355             p_msg = NULL;
   1356         }
   1357     }
   1358 
   1359     /* if tx queue is empty and all PDU is acknowledged */
   1360     if (  (p_dlcb->i_xmit_q.count == 0)
   1361         &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
   1362         &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
   1363     {
   1364         /* check flag to send DISC */
   1365         if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
   1366         {
   1367             p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
   1368             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1369         }
   1370 
   1371         /* check flag to notify upper layer */
   1372         if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
   1373         {
   1374             p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
   1375 
   1376             data.tx_complete.event      = LLCP_SAP_EVT_TX_COMPLETE;
   1377             data.tx_complete.local_sap  = p_dlcb->local_sap;
   1378             data.tx_complete.remote_sap = p_dlcb->remote_sap;
   1379 
   1380             (*p_dlcb->p_app_cb->p_app_cback) (&data);
   1381         }
   1382     }
   1383 
   1384     return p_msg;
   1385 }
   1386 
   1387 /*******************************************************************************
   1388 **
   1389 ** Function         llcp_dlc_get_next_pdu_length
   1390 **
   1391 ** Description      return length of PDU which is top in tx queue of data link
   1392 **
   1393 ** Returns          length of PDU
   1394 **
   1395 *******************************************************************************/
   1396 UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
   1397 {
   1398     BT_HDR *p_msg;
   1399 
   1400     /* if there is data to send and remote device can receive it */
   1401     if (  (p_dlcb->i_xmit_q.count)
   1402         &&(!p_dlcb->remote_busy)
   1403         &&(llcp_dlc_is_rw_open (p_dlcb))  )
   1404     {
   1405         p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
   1406 
   1407         return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
   1408     }
   1409     return 0;
   1410 }
   1411 
   1412 #if (BT_TRACE_VERBOSE == TRUE)
   1413 /*******************************************************************************
   1414 **
   1415 ** Function         llcp_dlsm_get_state_name
   1416 **
   1417 ** Description      This function returns the state name.
   1418 **
   1419 ** Returns          pointer to the name
   1420 **
   1421 *******************************************************************************/
   1422 static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
   1423 {
   1424     switch (state)
   1425     {
   1426     case LLCP_DLC_STATE_IDLE:
   1427         return ("IDLE");
   1428     case LLCP_DLC_STATE_W4_REMOTE_RESP:
   1429         return ("W4_REMOTE_RESP");
   1430     case LLCP_DLC_STATE_W4_LOCAL_RESP:
   1431         return ("W4_LOCAL_RESP");
   1432     case LLCP_DLC_STATE_CONNECTED:
   1433         return ("CONNECTED");
   1434     case LLCP_DLC_STATE_W4_REMOTE_DM:
   1435         return ("W4_REMOTE_DM");
   1436     default:
   1437         return ("???? UNKNOWN STATE");
   1438     }
   1439 }
   1440 
   1441 /*******************************************************************************
   1442 **
   1443 ** Function         llcp_dlsm_get_event_name
   1444 **
   1445 ** Description      This function returns the event name.
   1446 **
   1447 ** Returns          pointer to the name
   1448 **
   1449 *******************************************************************************/
   1450 static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
   1451 {
   1452     switch (event)
   1453     {
   1454     case LLCP_DLC_EVENT_API_CONNECT_REQ:
   1455         return ("API_CONNECT_REQ");
   1456     case LLCP_DLC_EVENT_API_CONNECT_CFM:
   1457         return ("API_CONNECT_CFM");
   1458     case LLCP_DLC_EVENT_API_CONNECT_REJECT:
   1459         return ("API_CONNECT_REJECT");
   1460     case LLCP_DLC_EVENT_PEER_CONNECT_IND:
   1461         return ("PEER_CONNECT_IND");
   1462     case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
   1463         return ("PEER_CONNECT_CFM");
   1464 
   1465     case LLCP_DLC_EVENT_API_DATA_REQ:
   1466         return ("API_DATA_REQ");
   1467     case LLCP_DLC_EVENT_PEER_DATA_IND:
   1468         return ("PEER_DATA_IND");
   1469 
   1470     case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
   1471         return ("API_DISCONNECT_REQ");
   1472     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
   1473         return ("PEER_DISCONNECT_IND");
   1474     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
   1475         return ("PEER_DISCONNECT_RESP");
   1476 
   1477     case LLCP_DLC_EVENT_FRAME_ERROR:
   1478         return ("FRAME_ERROR");
   1479     case LLCP_DLC_EVENT_LINK_ERROR:
   1480         return ("LINK_ERROR");
   1481 
   1482     case LLCP_DLC_EVENT_TIMEOUT:
   1483         return ("TIMEOUT");
   1484 
   1485     default:
   1486         return ("???? UNKNOWN EVENT");
   1487     }
   1488 }
   1489 #endif /* (BT_TRACE_VERBOSE == TRUE) */
   1490 
   1491 
   1492