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_NO_SERVICE );
    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             /* if SN type is included without SN */
    659             if (params.sn[1] == LLCP_SN_TYPE)
    660             {
    661                 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
    662             }
    663             else
    664             {
    665                 /* SDP doesn't accept connection */
    666                 llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
    667             }
    668             return;
    669         }
    670 
    671         if (dsap == LLCP_SAP_SDP)
    672         {
    673             LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
    674 
    675             llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
    676             return;
    677         }
    678         else if (dsap == 0)
    679         {
    680             LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s", params.sn);
    681 
    682             llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
    683             return;
    684         }
    685         else
    686         {
    687             /* check if this application can support connection-oriented transport */
    688             p_app_cb = llcp_util_get_app_cb (dsap);
    689 
    690             if (  (p_app_cb == NULL)
    691                 ||(p_app_cb->p_app_cback == NULL)
    692                 ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)  )
    693             {
    694                 LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): SAP(0x%x) doesn't support connection-oriented", dsap);
    695                 llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
    696                 return;
    697             }
    698         }
    699     }
    700 
    701     /* check if any data link */
    702     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    703     if (p_dlcb)
    704     {
    705         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Data link is aleady established");
    706         llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
    707     }
    708     else
    709     {
    710         /* allocate data link connection control block and notify upper layer through state machine */
    711         p_dlcb = llcp_util_allocate_data_link (dsap, ssap);
    712 
    713         if (p_dlcb)
    714         {
    715             status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
    716             if (status != LLCP_STATUS_SUCCESS)
    717             {
    718                 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
    719                 llcp_util_deallocate_data_link (p_dlcb);
    720             }
    721         }
    722         else
    723         {
    724             LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
    725             llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
    726         }
    727     }
    728 }
    729 
    730 /*******************************************************************************
    731 **
    732 ** Function         llcp_dlc_proc_disc_pdu
    733 **
    734 ** Description      Process DISC PDU
    735 **
    736 ** Returns          void
    737 **
    738 *******************************************************************************/
    739 static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    740 {
    741     tLLCP_DLCB *p_dlcb;
    742 
    743     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
    744 
    745     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    746     if (p_dlcb)
    747     {
    748         if (length > 0)
    749         {
    750             LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
    751 
    752             llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
    753             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    754         }
    755         else
    756         {
    757             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
    758         }
    759     }
    760     else
    761     {
    762         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
    763     }
    764 }
    765 
    766 /*******************************************************************************
    767 **
    768 ** Function         llcp_dlc_proc_cc_pdu
    769 **
    770 ** Description      Process CC PDU
    771 **
    772 ** Returns          void
    773 **
    774 *******************************************************************************/
    775 static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    776 {
    777     tLLCP_DLCB              *p_dlcb;
    778     tLLCP_CONNECTION_PARAMS  params;
    779     tLLCP_STATUS             status;
    780 
    781     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
    782 
    783     /* find a DLCB waiting for CC on this local SAP */
    784     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
    785     if (p_dlcb)
    786     {
    787         /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
    788         p_dlcb->remote_sap = ssap;
    789 
    790         if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
    791         {
    792             status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
    793             if (status != LLCP_STATUS_SUCCESS)
    794             {
    795                 LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
    796                 llcp_util_deallocate_data_link (p_dlcb);
    797             }
    798         }
    799         else
    800         {
    801             llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
    802             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    803         }
    804     }
    805     else
    806     {
    807         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
    808     }
    809 }
    810 
    811 /*******************************************************************************
    812 **
    813 ** Function         llcp_dlc_proc_dm_pdu
    814 **
    815 ** Description      Process DM PDU
    816 **
    817 ** Returns          void
    818 **
    819 *******************************************************************************/
    820 static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
    821 {
    822     tLLCP_DLCB *p_dlcb;
    823 
    824     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
    825 
    826     if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
    827     {
    828         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
    829     }
    830     else
    831     {
    832         if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
    833         {
    834             /* local device initiated disconnecting */
    835             p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    836         }
    837         else
    838         {
    839             /* peer device rejected connection with any reason */
    840             /* find a DLCB waiting for CC on this local SAP    */
    841             p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
    842         }
    843 
    844         if (p_dlcb)
    845         {
    846             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
    847         }
    848         else
    849         {
    850             LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
    851         }
    852     }
    853 }
    854 
    855 /*******************************************************************************
    856 **
    857 ** Function         llcp_dlc_proc_i_pdu
    858 **
    859 ** Description      Process I PDU
    860 **
    861 ** Returns          void
    862 **
    863 *******************************************************************************/
    864 void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
    865 {
    866     UINT8      *p, *p_dst, send_seq, rcv_seq, error_flags;
    867     UINT16      info_len, available_bytes;
    868     tLLCP_DLCB *p_dlcb;
    869     BOOLEAN     appended;
    870     BT_HDR     *p_last_buf;
    871 
    872     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
    873 
    874     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
    875 
    876     if ((p_dlcb)&&(p_dlcb->state == LLCP_DLC_STATE_CONNECTED))
    877     {
    878         error_flags = 0;
    879 
    880         if (p_msg)
    881         {
    882             i_pdu_length = p_msg->len;
    883             p_i_pdu = (UINT8 *) (p_msg + 1) + p_msg->offset;
    884         }
    885 
    886         info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
    887 
    888         if (info_len > p_dlcb->local_miu)
    889         {
    890             LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
    891                                 p_dlcb->local_miu, info_len);
    892 
    893             error_flags |= LLCP_FRMR_I_ERROR_FLAG;
    894         }
    895 
    896         /* get sequence numbers */
    897         p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
    898 
    899         send_seq = LLCP_GET_NS (*p);
    900         rcv_seq  = LLCP_GET_NR (*p);
    901 
    902 #if (BT_TRACE_VERBOSE == TRUE)
    903         LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
    904                             send_seq, rcv_seq,
    905                             p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
    906                             p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
    907 #endif
    908 
    909         /* if send sequence number, N(S) is not expected one, V(R) */
    910         if (p_dlcb->next_rx_seq != send_seq)
    911         {
    912             LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
    913                                 send_seq, p_dlcb->next_rx_seq);
    914 
    915             error_flags |= LLCP_FRMR_S_ERROR_FLAG;
    916         }
    917         else
    918         {
    919             /* if peer device sends more than our receiving window size */
    920             if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
    921             {
    922                 LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
    923                                     send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
    924 
    925                 error_flags |= LLCP_FRMR_S_ERROR_FLAG;
    926             }
    927         }
    928 
    929         /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
    930         if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
    931             != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
    932         {
    933             error_flags |= LLCP_FRMR_R_ERROR_FLAG;
    934             LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
    935                                 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
    936         }
    937 
    938         /* if any error is found */
    939         if (error_flags)
    940         {
    941             llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
    942             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    943         }
    944         else
    945         {
    946             /* update local sequence variables */
    947             p_dlcb->next_rx_seq  = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
    948             p_dlcb->rcvd_ack_seq = rcv_seq;
    949 
    950             appended = FALSE;
    951 
    952             /* get last buffer in rx queue */
    953             p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
    954 
    955             if (p_last_buf)
    956             {
    957                 /* get max length to append at the end of buffer */
    958                 available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
    959 
    960                 /* if new UI PDU with length can be attached at the end of buffer */
    961                 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
    962                 {
    963                     p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
    964 
    965                     /* add length of information in I PDU */
    966                     UINT16_TO_BE_STREAM (p_dst, info_len);
    967 
    968                     /* copy information of I PDU */
    969                     p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
    970 
    971                     memcpy (p_dst, p, info_len);
    972 
    973                     p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
    974 
    975                     if (p_msg)
    976                     {
    977                         GKI_freebuf (p_msg);
    978                         p_msg = NULL;
    979                     }
    980 
    981                     appended = TRUE;
    982                 }
    983             }
    984 
    985             /* if it is not available to append */
    986             if (!appended)
    987             {
    988                 /* if it's not from AGF PDU */
    989                 if (p_msg)
    990                 {
    991                     /* add length of information in front of information */
    992                     p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
    993                     UINT16_TO_BE_STREAM (p, info_len);
    994 
    995                     p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
    996                     p_msg->len    -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
    997                     p_msg->layer_specific = 0;
    998                 }
    999                 else
   1000                 {
   1001                     p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
   1002 
   1003                     if (p_msg)
   1004                     {
   1005                         p_dst = (UINT8*) (p_msg + 1);
   1006 
   1007                         /* add length of information in front of information */
   1008                         UINT16_TO_BE_STREAM (p_dst, info_len);
   1009 
   1010                         p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
   1011                         memcpy (p_dst, p, info_len);
   1012 
   1013                         p_msg->offset = 0;
   1014                         p_msg->len    = LLCP_PDU_AGF_LEN_SIZE + info_len;
   1015                         p_msg->layer_specific = 0;
   1016                     }
   1017                     else
   1018                     {
   1019                         LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
   1020                     }
   1021                 }
   1022 
   1023                 /* insert I PDU in rx queue */
   1024                 if (p_msg)
   1025                 {
   1026                     GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
   1027                     p_msg = NULL;
   1028                     llcp_cb.total_rx_i_pdu++;
   1029 
   1030                     llcp_util_check_rx_congested_status ();
   1031                 }
   1032             }
   1033 
   1034             p_dlcb->num_rx_i_pdu++;
   1035 
   1036             if (  (!p_dlcb->local_busy)
   1037                 &&(p_dlcb->num_rx_i_pdu == 1)  )
   1038             {
   1039                 /* notify rx data is available so upper layer reads data until queue is empty */
   1040                 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
   1041             }
   1042 
   1043             if (  (!p_dlcb->is_rx_congested)
   1044                 &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)  )
   1045             {
   1046                 LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
   1047                                     p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
   1048 
   1049                 /* send RNR */
   1050                 p_dlcb->is_rx_congested = TRUE;
   1051                 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1052             }
   1053         }
   1054     }
   1055     else
   1056     {
   1057         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
   1058         llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
   1059     }
   1060 
   1061     if (p_msg)
   1062     {
   1063         GKI_freebuf (p_msg);
   1064     }
   1065 }
   1066 
   1067 /*******************************************************************************
   1068 **
   1069 ** Function         llcp_dlc_proc_rr_rnr_pdu
   1070 **
   1071 ** Description      Process RR or RNR PDU
   1072 **
   1073 ** Returns          void
   1074 **
   1075 *******************************************************************************/
   1076 static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
   1077 {
   1078     UINT8      rcv_seq, error_flags;
   1079     tLLCP_DLCB *p_dlcb;
   1080     BOOLEAN     flush = TRUE;
   1081     tLLCP_SAP_CBACK_DATA cback_data;
   1082     BOOLEAN              old_remote_busy;
   1083 
   1084     LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
   1085 
   1086     p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
   1087     if (p_dlcb != NULL)
   1088     {
   1089         error_flags = 0;
   1090 
   1091         rcv_seq = LLCP_GET_NR (*p_data);
   1092 
   1093         if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
   1094         {
   1095             error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
   1096         }
   1097 
   1098         /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
   1099         if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
   1100             != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
   1101         {
   1102             error_flags |= LLCP_FRMR_R_ERROR_FLAG;
   1103             LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
   1104                                 rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
   1105         }
   1106 
   1107         if (error_flags)
   1108         {
   1109             llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
   1110             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
   1111         }
   1112         else
   1113         {
   1114             p_dlcb->rcvd_ack_seq = rcv_seq;
   1115 
   1116 #if (BT_TRACE_VERBOSE == TRUE)
   1117             LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
   1118                                 rcv_seq,
   1119                                 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
   1120                                 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
   1121 #endif
   1122             old_remote_busy = p_dlcb->remote_busy;
   1123             if (ptype == LLCP_PDU_RNR_TYPE)
   1124             {
   1125                 p_dlcb->remote_busy = TRUE;
   1126                 /* if upper layer hasn't get congestion started notification */
   1127                 if (  (!old_remote_busy)
   1128                     &&(!p_dlcb->is_tx_congested)  )
   1129                 {
   1130                     LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
   1131                                           p_dlcb->local_sap, p_dlcb->remote_sap,
   1132                                           p_dlcb->i_xmit_q.count);
   1133 
   1134                     cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
   1135                     cback_data.congest.local_sap    = p_dlcb->local_sap;
   1136                     cback_data.congest.remote_sap   = p_dlcb->remote_sap;
   1137                     cback_data.congest.is_congested = TRUE;
   1138                     cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
   1139 
   1140                     (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
   1141                 }
   1142             }
   1143             else
   1144             {
   1145                 p_dlcb->remote_busy = FALSE;
   1146                 /* if upper layer hasn't get congestion ended notification and data link is not congested */
   1147                 if (  (old_remote_busy)
   1148                     &&(!p_dlcb->is_tx_congested)  )
   1149                 {
   1150                     LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
   1151                                           p_dlcb->local_sap, p_dlcb->remote_sap,
   1152                                           p_dlcb->i_xmit_q.count);
   1153 
   1154                     cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
   1155                     cback_data.congest.local_sap    = p_dlcb->local_sap;
   1156                     cback_data.congest.remote_sap   = p_dlcb->remote_sap;
   1157                     cback_data.congest.is_congested = FALSE;
   1158                     cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
   1159 
   1160                     (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
   1161                 }
   1162             }
   1163 
   1164             /* check flag to send DISC when tx queue is empty */
   1165             if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
   1166             {
   1167                 /* if no pending data and all PDU is acked */
   1168                 if (  (p_dlcb->i_xmit_q.count == 0)
   1169                     &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
   1170                     &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
   1171                 {
   1172                     p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
   1173                     llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1174                 }
   1175             }
   1176         }
   1177     }
   1178     else
   1179     {
   1180         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
   1181     }
   1182 }
   1183 
   1184 /*******************************************************************************
   1185 **
   1186 ** Function         llcp_dlc_proc_rx_pdu
   1187 **
   1188 ** Description      Process PDU for data link
   1189 **
   1190 ** Returns          void
   1191 **
   1192 *******************************************************************************/
   1193 void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
   1194 {
   1195     tLLCP_DLCB *p_dlcb;
   1196 
   1197     LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
   1198                         dsap, ptype, ssap);
   1199 
   1200     if (dsap == LLCP_SAP_LM)
   1201     {
   1202         LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
   1203         return;
   1204     }
   1205 
   1206     switch (ptype)
   1207     {
   1208     case LLCP_PDU_CONNECT_TYPE:
   1209         llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
   1210         break;
   1211 
   1212     case LLCP_PDU_DISC_TYPE:
   1213         llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
   1214         break;
   1215 
   1216     case LLCP_PDU_CC_TYPE:
   1217         llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
   1218         break;
   1219 
   1220     case LLCP_PDU_DM_TYPE:
   1221         llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
   1222         break;
   1223 
   1224     case LLCP_PDU_FRMR_TYPE:
   1225         p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
   1226         if (p_dlcb)
   1227         {
   1228             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
   1229         }
   1230         break;
   1231 
   1232     case LLCP_PDU_RR_TYPE:
   1233     case LLCP_PDU_RNR_TYPE:
   1234         llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
   1235         break;
   1236 
   1237     default:
   1238         LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
   1239 
   1240         p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
   1241         if (p_dlcb)
   1242         {
   1243             llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
   1244             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
   1245         }
   1246         break;
   1247     }
   1248 }
   1249 
   1250 /*******************************************************************************
   1251 **
   1252 ** Function         llcp_dlc_check_to_send_rr_rnr
   1253 **
   1254 ** Description      Send RR or RNR if necessary
   1255 **
   1256 ** Returns          void
   1257 **
   1258 *******************************************************************************/
   1259 void llcp_dlc_check_to_send_rr_rnr (void)
   1260 {
   1261     UINT8   idx;
   1262     BOOLEAN flush = TRUE;
   1263 
   1264     LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
   1265 
   1266     /*
   1267     ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
   1268     ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
   1269     ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
   1270     **
   1271     ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
   1272     ** V(R).
   1273     */
   1274     for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
   1275     {
   1276         if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
   1277         {
   1278             llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
   1279 
   1280             /* check flag to send DISC when tx queue is empty */
   1281             if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
   1282             {
   1283                 /* if no pending data and all PDU is acked */
   1284                 if (  (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
   1285                     &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
   1286                     &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)  )
   1287                 {
   1288                     llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
   1289                     llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1290                 }
   1291             }
   1292         }
   1293     }
   1294 }
   1295 
   1296 /*******************************************************************************
   1297 **
   1298 ** Function         llcp_dlc_is_rw_open
   1299 **
   1300 ** Description      check if receive window is open in remote
   1301 **
   1302 ** Returns          TRUE if remote can receive more data
   1303 **
   1304 *******************************************************************************/
   1305 BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
   1306 {
   1307     if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
   1308     {
   1309         return TRUE;
   1310     }
   1311     else
   1312     {
   1313         LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
   1314                            p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
   1315         return FALSE;
   1316     }
   1317 }
   1318 
   1319 /*******************************************************************************
   1320 **
   1321 ** Function         llcp_dlc_get_next_pdu
   1322 **
   1323 ** Description      Get a PDU from tx queue of data link
   1324 **
   1325 ** Returns          BT_HDR*
   1326 **
   1327 *******************************************************************************/
   1328 BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
   1329 {
   1330     BT_HDR *p_msg = NULL;
   1331     BOOLEAN flush = TRUE;
   1332     tLLCP_SAP_CBACK_DATA data;
   1333 
   1334 #if (BT_TRACE_VERBOSE == TRUE)
   1335     UINT8   send_seq = p_dlcb->next_tx_seq;
   1336 #endif
   1337 
   1338     /* if there is data to send and remote device can receive it */
   1339     if (  (p_dlcb->i_xmit_q.count)
   1340         &&(!p_dlcb->remote_busy)
   1341         &&(llcp_dlc_is_rw_open (p_dlcb))  )
   1342     {
   1343         p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
   1344         llcp_cb.total_tx_i_pdu--;
   1345 
   1346         if (p_msg->offset >= LLCP_MIN_OFFSET)
   1347         {
   1348             /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
   1349             llcp_util_build_info_pdu (p_dlcb, p_msg);
   1350 
   1351             p_dlcb->next_tx_seq  = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
   1352 
   1353 #if (BT_TRACE_VERBOSE == TRUE)
   1354             LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
   1355                                 send_seq, p_dlcb->next_rx_seq,
   1356                                 p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
   1357                                 p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
   1358 #endif
   1359         }
   1360         else
   1361         {
   1362             LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
   1363                                 p_msg->offset, LLCP_MIN_OFFSET );
   1364             GKI_freebuf (p_msg);
   1365             p_msg = NULL;
   1366         }
   1367     }
   1368 
   1369     /* if tx queue is empty and all PDU is acknowledged */
   1370     if (  (p_dlcb->i_xmit_q.count == 0)
   1371         &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
   1372         &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
   1373     {
   1374         /* check flag to send DISC */
   1375         if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
   1376         {
   1377             p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
   1378             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1379         }
   1380 
   1381         /* check flag to notify upper layer */
   1382         if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
   1383         {
   1384             p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
   1385 
   1386             data.tx_complete.event      = LLCP_SAP_EVT_TX_COMPLETE;
   1387             data.tx_complete.local_sap  = p_dlcb->local_sap;
   1388             data.tx_complete.remote_sap = p_dlcb->remote_sap;
   1389 
   1390             (*p_dlcb->p_app_cb->p_app_cback) (&data);
   1391         }
   1392     }
   1393 
   1394     return p_msg;
   1395 }
   1396 
   1397 /*******************************************************************************
   1398 **
   1399 ** Function         llcp_dlc_get_next_pdu_length
   1400 **
   1401 ** Description      return length of PDU which is top in tx queue of data link
   1402 **
   1403 ** Returns          length of PDU
   1404 **
   1405 *******************************************************************************/
   1406 UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
   1407 {
   1408     BT_HDR *p_msg;
   1409 
   1410     /* if there is data to send and remote device can receive it */
   1411     if (  (p_dlcb->i_xmit_q.count)
   1412         &&(!p_dlcb->remote_busy)
   1413         &&(llcp_dlc_is_rw_open (p_dlcb))  )
   1414     {
   1415         p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
   1416 
   1417         return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
   1418     }
   1419     return 0;
   1420 }
   1421 
   1422 #if (BT_TRACE_VERBOSE == TRUE)
   1423 /*******************************************************************************
   1424 **
   1425 ** Function         llcp_dlsm_get_state_name
   1426 **
   1427 ** Description      This function returns the state name.
   1428 **
   1429 ** Returns          pointer to the name
   1430 **
   1431 *******************************************************************************/
   1432 static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
   1433 {
   1434     switch (state)
   1435     {
   1436     case LLCP_DLC_STATE_IDLE:
   1437         return ("IDLE");
   1438     case LLCP_DLC_STATE_W4_REMOTE_RESP:
   1439         return ("W4_REMOTE_RESP");
   1440     case LLCP_DLC_STATE_W4_LOCAL_RESP:
   1441         return ("W4_LOCAL_RESP");
   1442     case LLCP_DLC_STATE_CONNECTED:
   1443         return ("CONNECTED");
   1444     case LLCP_DLC_STATE_W4_REMOTE_DM:
   1445         return ("W4_REMOTE_DM");
   1446     default:
   1447         return ("???? UNKNOWN STATE");
   1448     }
   1449 }
   1450 
   1451 /*******************************************************************************
   1452 **
   1453 ** Function         llcp_dlsm_get_event_name
   1454 **
   1455 ** Description      This function returns the event name.
   1456 **
   1457 ** Returns          pointer to the name
   1458 **
   1459 *******************************************************************************/
   1460 static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
   1461 {
   1462     switch (event)
   1463     {
   1464     case LLCP_DLC_EVENT_API_CONNECT_REQ:
   1465         return ("API_CONNECT_REQ");
   1466     case LLCP_DLC_EVENT_API_CONNECT_CFM:
   1467         return ("API_CONNECT_CFM");
   1468     case LLCP_DLC_EVENT_API_CONNECT_REJECT:
   1469         return ("API_CONNECT_REJECT");
   1470     case LLCP_DLC_EVENT_PEER_CONNECT_IND:
   1471         return ("PEER_CONNECT_IND");
   1472     case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
   1473         return ("PEER_CONNECT_CFM");
   1474 
   1475     case LLCP_DLC_EVENT_API_DATA_REQ:
   1476         return ("API_DATA_REQ");
   1477     case LLCP_DLC_EVENT_PEER_DATA_IND:
   1478         return ("PEER_DATA_IND");
   1479 
   1480     case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
   1481         return ("API_DISCONNECT_REQ");
   1482     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
   1483         return ("PEER_DISCONNECT_IND");
   1484     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
   1485         return ("PEER_DISCONNECT_RESP");
   1486 
   1487     case LLCP_DLC_EVENT_FRAME_ERROR:
   1488         return ("FRAME_ERROR");
   1489     case LLCP_DLC_EVENT_LINK_ERROR:
   1490         return ("LINK_ERROR");
   1491 
   1492     case LLCP_DLC_EVENT_TIMEOUT:
   1493         return ("TIMEOUT");
   1494 
   1495     default:
   1496         return ("???? UNKNOWN EVENT");
   1497     }
   1498 }
   1499 #endif /* (BT_TRACE_VERBOSE == TRUE) */
   1500 
   1501 
   1502