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 Link Management
     23  *
     24  ******************************************************************************/
     25 
     26 #include <string.h>
     27 #include "gki.h"
     28 #include "nfc_target.h"
     29 #include "bt_types.h"
     30 #include "trace_api.h"
     31 #include "llcp_int.h"
     32 #include "llcp_defs.h"
     33 #include "nfc_int.h"
     34 
     35 const UINT16 llcp_link_rwt[15] =  /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
     36 {
     37        1, /* WT=0,     302us */
     38        1, /* WT=1,     604us */
     39        2, /* WT=2,    1208us */
     40        3, /* WT=3,     2.4ms */
     41        5, /* WT=4,     4.8ms */
     42       10, /* WT=5,     9.7ms */
     43       20, /* WT=6,    19.3ms */
     44       39, /* WT=7,    38.7ms */
     45       78, /* WT=8,    77.3ms */
     46      155, /* WT=9,   154.6ms */
     47      310, /* WT=10,  309.2ms */
     48      619, /* WT=11,  618.5ms */
     49     1237, /* WT=12, 1237.0ms */
     50     2474, /* WT=13, 2474.0ms */
     51     4948, /* WT=14, 4948.0ms */
     52 };
     53 
     54 static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes);
     55 static BOOLEAN llcp_link_version_agreement (void);
     56 
     57 static void    llcp_link_send_SYMM (void);
     58 static void    llcp_link_update_status (BOOLEAN is_activated);
     59 static void    llcp_link_check_congestion (void);
     60 static void    llcp_link_check_uncongested (void);
     61 static void    llcp_link_proc_ui_pdu (UINT8 local_sap, UINT8 remote_sap, UINT16 ui_pdu_length, UINT8 *p_ui_pdu, BT_HDR *p_msg);
     62 static void    llcp_link_proc_agf_pdu (BT_HDR *p_msg);
     63 static void    llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg);
     64 static void    llcp_link_proc_rx_data (BT_HDR *p_msg);
     65 
     66 static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length);
     67 static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_agf);
     68 static void    llcp_link_send_to_lower (BT_HDR *p_msg);
     69 
     70 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
     71 extern tLLCP_TEST_PARAMS llcp_test_params;
     72 #endif
     73 
     74 /* debug functions type */
     75 #if (BT_TRACE_VERBOSE == TRUE)
     76 static char *llcp_pdu_type (UINT8 ptype);
     77 #endif
     78 
     79 /*******************************************************************************
     80 **
     81 ** Function         llcp_link_start_inactivity_timer
     82 **
     83 ** Description      This function start LLCP link inactivity timer.
     84 **
     85 ** Returns          void
     86 **
     87 *******************************************************************************/
     88 static void llcp_link_start_inactivity_timer (void)
     89 {
     90     if (  (llcp_cb.lcb.inact_timer.in_use == FALSE)
     91         &&(llcp_cb.lcb.inact_timeout > 0)  )
     92     {
     93         LLCP_TRACE_DEBUG1 ("Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout);
     94 
     95         nfc_start_quick_timer (&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
     96                                ((UINT32) llcp_cb.lcb.inact_timeout) * QUICK_TIMER_TICKS_PER_SEC / 1000);
     97     }
     98 }
     99 
    100 /*******************************************************************************
    101 **
    102 ** Function         llcp_link_stop_inactivity_timer
    103 **
    104 ** Description      This function stop LLCP link inactivity timer.
    105 **
    106 ** Returns          void
    107 **
    108 *******************************************************************************/
    109 static void llcp_link_stop_inactivity_timer (void)
    110 {
    111     if (llcp_cb.lcb.inact_timer.in_use)
    112     {
    113         LLCP_TRACE_DEBUG0 ("Stop inactivity_timer");
    114 
    115         nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer);
    116     }
    117 }
    118 
    119 /*******************************************************************************
    120 **
    121 ** Function         llcp_link_start_link_timer
    122 **
    123 ** Description      This function starts LLCP link timer (LTO or delay response).
    124 **
    125 ** Returns          void
    126 **
    127 *******************************************************************************/
    128 static void llcp_link_start_link_timer (void)
    129 {
    130     if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
    131     {
    132         /* wait for application layer sending data */
    133         nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
    134                                (((UINT32) llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    135     }
    136     else
    137     {
    138         /* wait for data to receive from remote */
    139         nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
    140                                ((UINT32) llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
    141     }
    142 }
    143 
    144 /*******************************************************************************
    145 **
    146 ** Function         llcp_link_stop_link_timer
    147 **
    148 ** Description      This function stop LLCP link timer (LTO or delay response).
    149 **
    150 ** Returns          void
    151 **
    152 *******************************************************************************/
    153 static void llcp_link_stop_link_timer (void)
    154 {
    155     nfc_stop_quick_timer (&llcp_cb.lcb.timer);
    156 }
    157 
    158 /*******************************************************************************
    159 **
    160 ** Function         llcp_link_activate
    161 **
    162 ** Description      Activate LLCP link
    163 **
    164 ** Returns          tLLCP_STATUS
    165 **
    166 *******************************************************************************/
    167 tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config)
    168 {
    169     LLCP_TRACE_DEBUG0 ("llcp_link_activate ()");
    170 
    171     /* At this point, MAC link activation procedure has been successfully completed */
    172 
    173     /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
    174     if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE)
    175     {
    176         LLCP_TRACE_WARNING2 ("llcp_link_activate (): max payload size (%d) must be %d bytes",
    177                              p_config->max_payload_size, LLCP_NCI_MAX_PAYL_SIZE);
    178     }
    179 
    180     /* Processing the parametes that have been received with the MAC link activation */
    181     if (llcp_link_parse_gen_bytes (p_config->gen_bytes_len,
    182                                    p_config->p_gen_bytes ) == FALSE)
    183     {
    184         LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to parse general bytes");
    185         (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_BAD_GEN_BYTES);
    186         return LLCP_STATUS_FAIL;
    187     }
    188 
    189     /*
    190     ** For the Target device, the scaled value of RWT MUST be less than or equal to the
    191     ** scaled value of the LLC Link Timeout (LTO).
    192     */
    193     if ((p_config->is_initiator) && (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto))
    194     {
    195         LLCP_TRACE_WARNING3 ("llcp_link_activate (): WT (%d, %dms) must be less than or equal to LTO (%dms)",
    196                              p_config->waiting_time,
    197                              llcp_link_rwt[p_config->waiting_time],
    198                              llcp_cb.lcb.peer_lto);
    199     }
    200 
    201     /* extend LTO as much as internally required processing time and propagation delays */
    202     llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY;
    203 
    204     /* LLCP version number agreement */
    205     if (llcp_link_version_agreement () == FALSE)
    206     {
    207         LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to agree version");
    208         (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_VERSION_FAILED);
    209         return LLCP_STATUS_FAIL;
    210     }
    211 
    212     llcp_cb.lcb.received_first_packet = FALSE;
    213     llcp_cb.lcb.is_initiator = p_config->is_initiator;
    214 
    215     /* reset internal flags */
    216     llcp_cb.lcb.flags = 0x00;
    217 
    218     /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */
    219 
    220     if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu)
    221         llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu;
    222     else
    223         llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu;
    224 
    225     /*
    226     ** When entering the normal operation phase, LLCP shall initialize the symmetry
    227     ** procedure.
    228     */
    229     if (llcp_cb.lcb.is_initiator)
    230     {
    231         LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Initiator");
    232 
    233         llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init;
    234         llcp_cb.lcb.symm_state    = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
    235 
    236         if (llcp_cb.lcb.delay_first_pdu_timeout > 0)
    237         {
    238             /* give a chance to upper layer to send PDU if need */
    239             nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU,
    240                                    (((UINT32) llcp_cb.lcb.delay_first_pdu_timeout) * QUICK_TIMER_TICKS_PER_SEC) / 1000);
    241         }
    242         else
    243         {
    244             llcp_link_send_SYMM ();
    245         }
    246     }
    247     else
    248     {
    249         LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Target");
    250         llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
    251         llcp_cb.lcb.symm_state    = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
    252 
    253         /* wait for data to receive from remote */
    254         llcp_link_start_link_timer ();
    255     }
    256 
    257 
    258     /*
    259     ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set data callback
    260     ** because LLCP PDU could be in NCI queue.
    261     */
    262     llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
    263 
    264     /* LLCP Link Activation completed */
    265     (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_COMPLETE_EVT, LLCP_LINK_SUCCESS);
    266 
    267     /* Update link status to service layer */
    268     llcp_link_update_status (TRUE);
    269 
    270     NFC_SetStaticRfCback (llcp_link_connection_cback);
    271 
    272     return (LLCP_STATUS_SUCCESS);
    273 }
    274 
    275 /*******************************************************************************
    276 **
    277 ** Function         llcp_deactivate_cleanup
    278 **
    279 ** Description      Clean up for link deactivation
    280 **
    281 ** Returns          void
    282 **
    283 *******************************************************************************/
    284 static void llcp_deactivate_cleanup  (UINT8 reason)
    285 {
    286     /* report SDP failure for any pending request */
    287     llcp_sdp_proc_deactivation ();
    288 
    289     /* Update link status to service layer */
    290     llcp_link_update_status (FALSE);
    291 
    292     /* We had sent out DISC */
    293     llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
    294 
    295     llcp_link_stop_link_timer ();
    296 
    297     /* stop inactivity timer */
    298     llcp_link_stop_inactivity_timer ();
    299 
    300     /* Let upper layer deactivate local link */
    301     (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_DEACTIVATED_EVT, reason);
    302 }
    303 
    304 /*******************************************************************************
    305 **
    306 ** Function         llcp_link_process_link_timeout
    307 **
    308 ** Description      Process timeout events for LTO, SYMM and deactivating
    309 **
    310 ** Returns          void
    311 **
    312 *******************************************************************************/
    313 void llcp_link_process_link_timeout (void)
    314 {
    315     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
    316     {
    317         if ((llcp_cb.lcb.symm_delay > 0) && (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT))
    318         {
    319             /* upper layer doesn't have anything to send */
    320             LLCP_TRACE_DEBUG0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
    321             llcp_link_send_SYMM ();
    322 
    323             /* wait for data to receive from remote */
    324             llcp_link_start_link_timer ();
    325 
    326             /* start inactivity timer */
    327             if (llcp_cb.num_data_link_connection == 0)
    328             {
    329                 llcp_link_start_inactivity_timer ();
    330             }
    331         }
    332         else
    333         {
    334             LLCP_TRACE_ERROR0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
    335             llcp_link_deactivate (LLCP_LINK_TIMEOUT);
    336         }
    337     }
    338     else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
    339     {
    340         llcp_deactivate_cleanup (llcp_cb.lcb.link_deact_reason);
    341 
    342         NFC_SetStaticRfCback (NULL);
    343     }
    344 }
    345 
    346 /*******************************************************************************
    347 **
    348 ** Function         llcp_link_deactivate
    349 **
    350 ** Description      Deactivate LLCP link
    351 **
    352 ** Returns          void
    353 **
    354 *******************************************************************************/
    355 void llcp_link_deactivate (UINT8 reason)
    356 {
    357     UINT8        local_sap, idx;
    358     tLLCP_DLCB   *p_dlcb;
    359     tLLCP_APP_CB *p_app_cb;
    360 
    361     LLCP_TRACE_DEBUG1 ("llcp_link_deactivate () reason = 0x%x", reason);
    362 
    363     /* Release any held buffers in signaling PDU queue */
    364     while (llcp_cb.lcb.sig_xmit_q.p_first)
    365         GKI_freebuf (GKI_dequeue (&llcp_cb.lcb.sig_xmit_q));
    366 
    367     /* Release any held buffers in UI PDU queue */
    368     for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++)
    369     {
    370         p_app_cb = llcp_util_get_app_cb (local_sap);
    371 
    372         if (  (p_app_cb)
    373             &&(p_app_cb->p_app_cback)  )
    374         {
    375             while (p_app_cb->ui_xmit_q.p_first)
    376                 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
    377 
    378             p_app_cb->is_ui_tx_congested = FALSE;
    379 
    380             while (p_app_cb->ui_rx_q.p_first)
    381                 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
    382         }
    383     }
    384 
    385     llcp_cb.total_tx_ui_pdu = 0;
    386     llcp_cb.total_rx_ui_pdu = 0;
    387 
    388     /* Notify all of data link */
    389     for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
    390     {
    391         if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
    392         {
    393             p_dlcb = &(llcp_cb.dlcb[idx]);
    394 
    395             llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL);
    396         }
    397     }
    398     llcp_cb.total_tx_i_pdu = 0;
    399     llcp_cb.total_rx_i_pdu = 0;
    400 
    401     llcp_cb.overall_tx_congested = FALSE;
    402     llcp_cb.overall_rx_congested = FALSE;
    403 
    404     if (  (reason == LLCP_LINK_FRAME_ERROR)
    405         ||(reason == LLCP_LINK_LOCAL_INITIATED)  )
    406     {
    407         /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP */
    408         NFC_FlushData (NFC_RF_CONN_ID);
    409 
    410         llcp_util_send_disc (LLCP_SAP_LM, LLCP_SAP_LM);
    411 
    412         /* Wait until DISC is sent to peer */
    413         LLCP_TRACE_DEBUG0 ("llcp_link_deactivate (): Wait until DISC is sent to peer");
    414 
    415         llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
    416 
    417         if (llcp_cb.lcb.sig_xmit_q.count == 0)
    418         {
    419             /* if DISC is sent to NFCC, wait for short period for NFCC to send it to peer */
    420             nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
    421                                    ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
    422         }
    423 
    424         llcp_cb.lcb.link_deact_reason = reason;
    425         return;
    426     }
    427     else if (  (reason == LLCP_LINK_REMOTE_INITIATED)
    428              &&(!llcp_cb.lcb.is_initiator)  )
    429     {
    430         /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
    431         llcp_link_send_SYMM ();
    432     }
    433     else /*  for link timeout and interface error */
    434     {
    435         /* if got RF link loss receiving no LLC PDU from peer */
    436         NFC_FlushData (NFC_RF_CONN_ID);
    437     }
    438 
    439     llcp_deactivate_cleanup (reason);
    440 }
    441 
    442 /*******************************************************************************
    443 **
    444 ** Function         llcp_link_parse_gen_bytes
    445 **
    446 ** Description      Check LLCP magic number and get parameters in general bytes
    447 **
    448 ** Returns          TRUE if success
    449 **
    450 *******************************************************************************/
    451 static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes)
    452 {
    453     UINT8 *p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
    454     UINT8 length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
    455 
    456     if (  (gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN)
    457         &&(*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0)
    458         &&(*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1)
    459         &&(*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2)  )
    460     {
    461         /* in case peer didn't include these */
    462         llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
    463         llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
    464 
    465         return (llcp_util_parse_link_params (length, p));
    466     }
    467     else /* if this is not LLCP */
    468     {
    469         return (FALSE);
    470     }
    471 
    472     return (TRUE);
    473 }
    474 
    475 /*******************************************************************************
    476 **
    477 ** Function         llcp_link_version_agreement
    478 **
    479 ** Description      LLCP version number agreement
    480 **
    481 ** Returns          TRUE if success
    482 **
    483 *******************************************************************************/
    484 static BOOLEAN llcp_link_version_agreement (void)
    485 {
    486     UINT8 peer_major_version, peer_minor_version;
    487 
    488     peer_major_version = LLCP_GET_MAJOR_VERSION (llcp_cb.lcb.peer_version);
    489     peer_minor_version = LLCP_GET_MINOR_VERSION (llcp_cb.lcb.peer_version);
    490 
    491     if (peer_major_version < LLCP_MIN_MAJOR_VERSION)
    492     {
    493         LLCP_TRACE_ERROR1("llcp_link_version_agreement(): unsupported peer version number. Peer Major Version:%d", peer_major_version);
    494         return FALSE;
    495     }
    496     else
    497     {
    498         if (peer_major_version == LLCP_VERSION_MAJOR)
    499         {
    500             llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
    501             if (peer_minor_version >= LLCP_VERSION_MINOR)
    502             {
    503                 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
    504             }
    505             else
    506             {
    507                 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
    508             }
    509         }
    510         else if (peer_major_version < LLCP_VERSION_MAJOR)
    511         {
    512             /* so far we can support backward compatibility */
    513             llcp_cb.lcb.agreed_major_version = peer_major_version;
    514             llcp_cb.lcb.agreed_minor_version = peer_minor_version;
    515         }
    516         else
    517         {
    518             /* let peer (higher major version) decide it */
    519             llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
    520             llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
    521         }
    522 
    523         LLCP_TRACE_DEBUG6 ("local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
    524                             LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR,
    525                             peer_major_version, peer_minor_version,
    526                             llcp_cb.lcb.agreed_major_version, llcp_cb.lcb.agreed_minor_version);
    527 
    528         return (TRUE);
    529     }
    530 }
    531 
    532 /*******************************************************************************
    533 **
    534 ** Function         llcp_link_update_status
    535 **
    536 ** Description      Notify all of service layer client link status change
    537 **
    538 ** Returns          void
    539 **
    540 *******************************************************************************/
    541 static void llcp_link_update_status (BOOLEAN is_activated)
    542 {
    543     tLLCP_SAP_CBACK_DATA data;
    544     tLLCP_APP_CB *p_app_cb;
    545     UINT8 sap;
    546 
    547     data.link_status.event        = LLCP_SAP_EVT_LINK_STATUS;
    548     data.link_status.is_activated = is_activated;
    549     data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
    550 
    551     /* notify all SAP so they can create connection while link is activated */
    552     for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
    553     {
    554         p_app_cb = llcp_util_get_app_cb (sap);
    555 
    556         if (  (p_app_cb)
    557             &&(p_app_cb->p_app_cback)  )
    558         {
    559             data.link_status.local_sap = sap;
    560             p_app_cb->p_app_cback (&data);
    561         }
    562     }
    563 }
    564 
    565 /*******************************************************************************
    566 **
    567 ** Function         llcp_link_check_congestion
    568 **
    569 ** Description      Check overall congestion status
    570 **                  Notify to all of upper layer if congested
    571 **
    572 ** Returns          void
    573 **
    574 *******************************************************************************/
    575 static void llcp_link_check_congestion (void)
    576 {
    577     tLLCP_SAP_CBACK_DATA data;
    578     tLLCP_APP_CB *p_app_cb;
    579     UINT8 sap, idx;
    580 
    581     if (llcp_cb.overall_tx_congested)
    582     {
    583         /* already congested so no need to check again */
    584         return;
    585     }
    586 
    587     if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)
    588     {
    589         /* overall buffer usage is high */
    590         llcp_cb.overall_tx_congested = TRUE;
    591 
    592         LLCP_TRACE_WARNING2 ("overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
    593                               llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
    594 
    595         data.congest.event        = LLCP_SAP_EVT_CONGEST;
    596         data.congest.is_congested = TRUE;
    597 
    598         /* notify logical data link congestion status */
    599         data.congest.remote_sap = LLCP_INVALID_SAP;
    600         data.congest.link_type  = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
    601 
    602         for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++)
    603         {
    604             p_app_cb = llcp_util_get_app_cb (sap);
    605 
    606             if (  (p_app_cb)
    607                 &&(p_app_cb->p_app_cback)
    608                 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)  )
    609             {
    610                 /* if already congested then no need to notify again */
    611                 if (!p_app_cb->is_ui_tx_congested)
    612                 {
    613                     p_app_cb->is_ui_tx_congested = TRUE;
    614 
    615                     LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congestion start: count=%d",
    616                                           sap, p_app_cb->ui_xmit_q.count);
    617 
    618                     data.congest.local_sap = sap;
    619                     p_app_cb->p_app_cback (&data);
    620                 }
    621             }
    622         }
    623 
    624         /* notify data link connection congestion status */
    625         data.congest.link_type  = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
    626 
    627         for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++ )
    628         {
    629             if (  (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
    630                 &&(llcp_cb.dlcb[idx].remote_busy == FALSE)
    631                 &&(llcp_cb.dlcb[idx].is_tx_congested == FALSE)  )
    632             {
    633                 llcp_cb.dlcb[idx].is_tx_congested = TRUE;
    634 
    635                 LLCP_TRACE_WARNING3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
    636                                       llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
    637                                       llcp_cb.dlcb[idx].i_xmit_q.count);
    638 
    639                 data.congest.local_sap  = llcp_cb.dlcb[idx].local_sap;
    640                 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
    641 
    642                 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
    643             }
    644         }
    645     }
    646 }
    647 
    648 /*******************************************************************************
    649 **
    650 ** Function         llcp_link_check_uncongested
    651 **
    652 ** Description      Check overall congestion status, logical data link and
    653 **                  data link connection congestion status
    654 **                  Notify to each upper layer if uncongested
    655 **
    656 ** Returns          void
    657 **
    658 *******************************************************************************/
    659 static void llcp_link_check_uncongested (void)
    660 {
    661     tLLCP_SAP_CBACK_DATA data;
    662     tLLCP_APP_CB *p_app_cb;
    663     UINT8 xx, sap, idx;
    664 
    665     if (llcp_cb.overall_tx_congested)
    666     {
    667         if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <= llcp_cb.max_num_tx_buff / 2)
    668         {
    669             /* overall congestion is cleared */
    670             llcp_cb.overall_tx_congested = FALSE;
    671 
    672             LLCP_TRACE_WARNING2 ("overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
    673                                   llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
    674         }
    675         else
    676         {
    677             /* wait until more data packets are sent out */
    678             return;
    679         }
    680     }
    681 
    682     data.congest.event        = LLCP_SAP_EVT_CONGEST;
    683     data.congest.is_congested = FALSE;
    684 
    685     /* if total number of UI PDU is below threshold */
    686     if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff)
    687     {
    688         /* check and notify logical data link congestion status */
    689         data.congest.remote_sap = LLCP_INVALID_SAP;
    690         data.congest.link_type  = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
    691 
    692         /*
    693         ** start point of uncongested status notification is in round robin
    694         ** so each logical data link has equal chance of transmitting.
    695         */
    696         sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
    697 
    698         for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++)
    699         {
    700             /* no logical data link on LM and SDP */
    701             if (sap > LLCP_SAP_SDP)
    702             {
    703                 p_app_cb = llcp_util_get_app_cb (sap);
    704 
    705                 if (  (p_app_cb)
    706                     &&(p_app_cb->p_app_cback)
    707                     &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
    708                     &&(p_app_cb->is_ui_tx_congested)
    709                     &&(p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end)  )
    710                 {
    711                     /* if it was congested but now tx queue count is below threshold */
    712                     p_app_cb->is_ui_tx_congested = FALSE;
    713 
    714                     LLCP_TRACE_DEBUG2 ("Logical link (SAP=0x%X) congestion end: count=%d",
    715                                         sap, p_app_cb->ui_xmit_q.count);
    716 
    717                     data.congest.local_sap = sap;
    718                     p_app_cb->p_app_cback (&data);
    719                 }
    720             }
    721 
    722             sap = (sap + 1) % LLCP_NUM_SAPS;
    723         }
    724 
    725         /* move start point for next logical data link */
    726         for (xx = 0; xx < LLCP_NUM_SAPS; xx++)
    727         {
    728             sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
    729 
    730             if (sap > LLCP_SAP_SDP)
    731             {
    732                 p_app_cb = llcp_util_get_app_cb (sap);
    733 
    734                 if (  (p_app_cb)
    735                     &&(p_app_cb->p_app_cback)
    736                     &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)  )
    737                 {
    738                     llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
    739                     break;
    740                 }
    741             }
    742         }
    743     }
    744 
    745     /* notify data link connection congestion status */
    746     data.congest.link_type  = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
    747 
    748     /*
    749     ** start point of uncongested status notification is in round robin
    750     ** so each data link connection has equal chance of transmitting.
    751     */
    752     idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
    753 
    754     for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
    755     {
    756         /* if it was congested but now tx queue is below threshold (receiving window) */
    757         if (  (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
    758             &&(llcp_cb.dlcb[idx].is_tx_congested)
    759             &&(llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2)  )
    760         {
    761             llcp_cb.dlcb[idx].is_tx_congested = FALSE;
    762 
    763             if (llcp_cb.dlcb[idx].remote_busy == FALSE)
    764             {
    765                 LLCP_TRACE_DEBUG3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
    766                                     llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
    767                                     llcp_cb.dlcb[idx].i_xmit_q.count);
    768 
    769                 data.congest.local_sap  = llcp_cb.dlcb[idx].local_sap;
    770                 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
    771 
    772                 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data);
    773             }
    774         }
    775         idx = (idx + 1) % LLCP_MAX_DATA_LINK;
    776     }
    777 
    778     /* move start point for next data link connection */
    779     for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ )
    780     {
    781         idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
    782         if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
    783         {
    784             llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
    785             break;
    786         }
    787     }
    788 }
    789 
    790 /*******************************************************************************
    791 **
    792 ** Function         llcp_link_send_SYMM
    793 **
    794 ** Description      Send SYMM PDU
    795 **
    796 ** Returns          void
    797 **
    798 *******************************************************************************/
    799 static void llcp_link_send_SYMM (void)
    800 {
    801     BT_HDR *p_msg;
    802     UINT8  *p;
    803 
    804     p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
    805 
    806     if (p_msg)
    807     {
    808         p_msg->len    = LLCP_PDU_SYMM_SIZE;
    809         p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
    810 
    811         p = (UINT8 *) (p_msg + 1) + p_msg->offset;
    812         UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM ));
    813 
    814         llcp_link_send_to_lower (p_msg);
    815     }
    816 }
    817 
    818 /*******************************************************************************
    819 **
    820 ** Function         llcp_link_check_send_data
    821 **
    822 ** Description      Send PDU to peer
    823 **
    824 ** Returns          void
    825 **
    826 *******************************************************************************/
    827 void llcp_link_check_send_data (void)
    828 {
    829     BT_HDR *p_pdu;
    830 
    831     /* don't re-enter while processing to prevent out of sequence */
    832     if (llcp_cb.lcb.is_sending_data)
    833         return;
    834     else
    835         llcp_cb.lcb.is_sending_data = TRUE;
    836 
    837     /*
    838     ** check overall congestion due to high usage of buffer pool
    839     ** if congested then notify all of upper layers not to send any more data
    840     */
    841     llcp_link_check_congestion ();
    842 
    843     if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)
    844     {
    845         LLCP_TRACE_DEBUG0 ("llcp_link_check_send_data () in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
    846 
    847         p_pdu = llcp_link_build_next_pdu (NULL);
    848 
    849         /*
    850         ** For data link connection,
    851         ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in this transmission.
    852         ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's not congested,
    853         ** then RR PDU will be sent.
    854         ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's congested,
    855         ** then RNR PDU will be sent.
    856         ** If local busy state has been changed then RR or RNR PDU may be sent.
    857         */
    858         llcp_dlc_check_to_send_rr_rnr ();
    859 
    860         /* add RR/RNR PDU to be sent if any */
    861         p_pdu = llcp_link_build_next_pdu (p_pdu);
    862 
    863         if (p_pdu != NULL)
    864         {
    865             llcp_link_send_to_lower (p_pdu);
    866 
    867             /* stop inactivity timer */
    868             llcp_link_stop_inactivity_timer ();
    869 
    870             /* check congestion status after sending out some data */
    871             llcp_link_check_uncongested ();
    872         }
    873         else
    874         {
    875             /* There is no data to send, so send SYMM */
    876             if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
    877             {
    878                 if (llcp_cb.lcb.symm_delay > 0)
    879                 {
    880                     /* wait for application layer sending data */
    881                     llcp_link_start_link_timer ();
    882                     llcp_cb.lcb.is_sending_data = FALSE;
    883                     return;
    884                 }
    885                 else
    886                 {
    887                     llcp_link_send_SYMM ();
    888 
    889                     /* start inactivity timer */
    890                     if (llcp_cb.num_data_link_connection == 0)
    891                     {
    892                         llcp_link_start_inactivity_timer ();
    893                     }
    894                 }
    895             }
    896             else
    897             {
    898                 llcp_cb.lcb.is_sending_data = FALSE;
    899                 return;
    900             }
    901         }
    902 
    903         if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
    904         {
    905             /* wait for short period for NFCC to send DISC */
    906             nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
    907                                    ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
    908         }
    909         else
    910         {
    911             /* wait for data to receive from remote */
    912             llcp_link_start_link_timer ();
    913         }
    914     }
    915 
    916     llcp_cb.lcb.is_sending_data = FALSE;
    917 }
    918 
    919 /*******************************************************************************
    920 **
    921 ** Function         llcp_link_proc_ui_pdu
    922 **
    923 ** Description      Process UI PDU from peer device
    924 **
    925 ** Returns          None
    926 **
    927 *******************************************************************************/
    928 static void llcp_link_proc_ui_pdu (UINT8  local_sap,
    929                                    UINT8  remote_sap,
    930                                    UINT16 ui_pdu_length,
    931                                    UINT8  *p_ui_pdu,
    932                                    BT_HDR *p_msg)
    933 {
    934     BOOLEAN      appended;
    935     BT_HDR       *p_last_buf;
    936     UINT16       available_bytes;
    937     UINT8        *p_dst;
    938     tLLCP_APP_CB *p_app_cb;
    939     tLLCP_SAP_CBACK_DATA data;
    940     tLLCP_DLCB   *p_dlcb;
    941 
    942     p_app_cb = llcp_util_get_app_cb (local_sap);
    943         /*if UI PDU sent to SAP with data link connection*/
    944     if ((p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap)))
    945     {
    946         llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
    947         llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
    948         if (p_msg)
    949         {
    950             GKI_freebuf (p_msg);
    951         }
    952         return;
    953     }
    954 
    955     /* if application is registered and expecting UI PDU on logical data link */
    956     if (  (p_app_cb)
    957         &&(p_app_cb->p_app_cback)
    958         &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)  )
    959     {
    960         LLCP_TRACE_DEBUG2 ("llcp_link_proc_ui_pdu () Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
    961 
    962         /* if this is not from AGF PDU */
    963         if (p_msg)
    964         {
    965             ui_pdu_length = p_msg->len; /* including LLCP header */
    966             p_ui_pdu      = (UINT8*) (p_msg + 1) + p_msg->offset;
    967         }
    968 
    969         appended = FALSE;
    970 
    971         /* get last buffer in rx queue */
    972         p_last_buf = (BT_HDR *) GKI_getlast (&p_app_cb->ui_rx_q);
    973 
    974         if (p_last_buf)
    975         {
    976             /* get max length to append at the end of buffer */
    977             available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
    978 
    979             /* if new UI PDU with length can be attached at the end of buffer */
    980             if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length)
    981             {
    982                 p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
    983 
    984                 /* add length of UI PDU */
    985                 UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
    986 
    987                 /* copy UI PDU with LLCP header */
    988                 memcpy (p_dst, p_ui_pdu, ui_pdu_length);
    989 
    990                 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
    991 
    992                 if (p_msg)
    993                     GKI_freebuf (p_msg);
    994 
    995                 appended = TRUE;
    996             }
    997         }
    998 
    999         /* if it is not available to append */
   1000         if (!appended)
   1001         {
   1002             /* if it's not from AGF PDU */
   1003             if (p_msg)
   1004             {
   1005                 /* add length of PDU in front of UI PDU (reuse room for NCI header) */
   1006                 p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
   1007                 UINT16_TO_BE_STREAM (p_ui_pdu, ui_pdu_length);
   1008 
   1009                 p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
   1010                 p_msg->len    += LLCP_PDU_AGF_LEN_SIZE;
   1011                 p_msg->layer_specific = 0;
   1012             }
   1013             else
   1014             {
   1015                 p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
   1016 
   1017                 if (p_msg)
   1018                 {
   1019                     p_dst = (UINT8*) (p_msg + 1);
   1020 
   1021                     /* add length of PDU in front of UI PDU */
   1022                     UINT16_TO_BE_STREAM (p_dst, ui_pdu_length);
   1023 
   1024                     memcpy (p_dst, p_ui_pdu, ui_pdu_length);
   1025 
   1026                     p_msg->offset = 0;
   1027                     p_msg->len    = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
   1028                     p_msg->layer_specific = 0;
   1029                 }
   1030                 else
   1031                 {
   1032                     LLCP_TRACE_ERROR0 ("llcp_link_proc_ui_pdu (): out of buffer");
   1033                 }
   1034             }
   1035 
   1036             /* insert UI PDU in rx queue */
   1037             if (p_msg)
   1038             {
   1039                 GKI_enqueue (&p_app_cb->ui_rx_q, p_msg);
   1040                 llcp_cb.total_rx_ui_pdu++;
   1041             }
   1042         }
   1043 
   1044         if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start)
   1045         {
   1046             LLCP_TRACE_WARNING2 ("llcp_link_proc_ui_pdu (): SAP:0x%x, rx link is congested (%d), discard oldest UI PDU",
   1047                                  local_sap, p_app_cb->ui_rx_q.count);
   1048 
   1049             GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q));
   1050             llcp_cb.total_rx_ui_pdu--;
   1051         }
   1052 
   1053         if ((p_app_cb->ui_rx_q.count == 1) && (appended == FALSE))
   1054         {
   1055             data.data_ind.event         = LLCP_SAP_EVT_DATA_IND;
   1056             data.data_ind.local_sap     = local_sap;
   1057             data.data_ind.remote_sap    = remote_sap;
   1058             data.data_ind.link_type     = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
   1059             (*p_app_cb->p_app_cback) (&data);
   1060         }
   1061     }
   1062     else
   1063     {
   1064         LLCP_TRACE_ERROR1 ("llcp_link_proc_ui_pdu (): Unregistered SAP:0x%x", local_sap);
   1065 
   1066         if (p_msg)
   1067         {
   1068             GKI_freebuf (p_msg);
   1069         }
   1070     }
   1071 }
   1072 
   1073 /*******************************************************************************
   1074 **
   1075 ** Function         llcp_link_proc_agf_pdu
   1076 **
   1077 ** Description      Process AGF PDU from peer device
   1078 **
   1079 ** Returns          void
   1080 **
   1081 *******************************************************************************/
   1082 static void llcp_link_proc_agf_pdu (BT_HDR *p_agf)
   1083 {
   1084     UINT16 agf_length;
   1085     UINT8 *p, *p_info, *p_pdu_length;
   1086     UINT16 pdu_hdr, pdu_length;
   1087     UINT8  dsap, ptype, ssap;
   1088 
   1089     p_agf->len    -= LLCP_PDU_HEADER_SIZE;
   1090     p_agf->offset += LLCP_PDU_HEADER_SIZE;
   1091 
   1092     /*
   1093     ** check integrity of AGF PDU and get number of PDUs in AGF PDU
   1094     */
   1095     agf_length = p_agf->len;
   1096     p = (UINT8 *) (p_agf + 1) + p_agf->offset;
   1097 
   1098     while (agf_length > 0)
   1099     {
   1100         if (agf_length > LLCP_PDU_AGF_LEN_SIZE)
   1101         {
   1102             BE_STREAM_TO_UINT16 (pdu_length, p);
   1103             agf_length -= LLCP_PDU_AGF_LEN_SIZE;
   1104         }
   1105         else
   1106         {
   1107             break;
   1108         }
   1109 
   1110         if (pdu_length <= agf_length)
   1111         {
   1112             p += pdu_length;
   1113             agf_length -= pdu_length;
   1114         }
   1115         else
   1116         {
   1117             break;
   1118         }
   1119     }
   1120 
   1121     if (agf_length != 0)
   1122     {
   1123         LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): Received invalid AGF PDU");
   1124         GKI_freebuf (p_agf);
   1125         return;
   1126     }
   1127 
   1128     /*
   1129     ** Process PDUs in AGF
   1130     */
   1131     agf_length = p_agf->len;
   1132     p = (UINT8 *) (p_agf + 1) + p_agf->offset;
   1133 
   1134     while (agf_length > 0)
   1135     {
   1136         /* get length of PDU */
   1137         p_pdu_length = p;
   1138         BE_STREAM_TO_UINT16 (pdu_length, p);
   1139         agf_length -= LLCP_PDU_AGF_LEN_SIZE;
   1140 
   1141         /* get DSAP/PTYPE/SSAP */
   1142         p_info = p;
   1143         BE_STREAM_TO_UINT16 (pdu_hdr, p_info );
   1144 
   1145         dsap  = LLCP_GET_DSAP (pdu_hdr);
   1146         ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
   1147         ssap  = LLCP_GET_SSAP (pdu_hdr);
   1148 
   1149 #if (BT_TRACE_VERBOSE == TRUE)
   1150         LLCP_TRACE_DEBUG4 ("llcp_link_proc_agf_pdu (): Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x in AGF",
   1151                            dsap, llcp_pdu_type (ptype), ptype, ssap);
   1152 #endif
   1153 
   1154         if (  (ptype == LLCP_PDU_DISC_TYPE)
   1155             &&(dsap == LLCP_SAP_LM)
   1156             &&(ssap == LLCP_SAP_LM)  )
   1157         {
   1158             GKI_freebuf (p_agf);
   1159             llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
   1160             return;
   1161         }
   1162         else if (ptype == LLCP_PDU_SYMM_TYPE)
   1163         {
   1164             LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): SYMM PDU exchange shall not be in AGF");
   1165         }
   1166         else if (ptype == LLCP_PDU_PAX_TYPE)
   1167         {
   1168             LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): PAX PDU exchange shall not be used");
   1169         }
   1170         else if (ptype == LLCP_PDU_SNL_TYPE)
   1171         {
   1172             llcp_sdp_proc_snl ((UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
   1173         }
   1174         else if ((ptype == LLCP_PDU_UI_TYPE) && (pdu_length > LLCP_PDU_HEADER_SIZE))
   1175         {
   1176             llcp_link_proc_ui_pdu (dsap, ssap, pdu_length, p, NULL);
   1177         }
   1178         else if (ptype == LLCP_PDU_I_TYPE)
   1179         {
   1180             llcp_dlc_proc_i_pdu (dsap, ssap, pdu_length, p, NULL);
   1181         }
   1182         else /* let data link connection handle PDU */
   1183         {
   1184             llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
   1185         }
   1186 
   1187         p += pdu_length;
   1188         agf_length -= pdu_length;
   1189     }
   1190 
   1191     GKI_freebuf (p_agf);
   1192 }
   1193 
   1194 /*******************************************************************************
   1195 **
   1196 ** Function         llcp_link_proc_rx_pdu
   1197 **
   1198 ** Description      Process received PDU from peer device
   1199 **
   1200 ** Returns          void
   1201 **
   1202 *******************************************************************************/
   1203 static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg)
   1204 {
   1205     BOOLEAN free_buffer = TRUE;
   1206     UINT8   *p_data;
   1207 
   1208     switch (ptype)
   1209     {
   1210     case LLCP_PDU_PAX_TYPE:
   1211         LLCP_TRACE_ERROR0 ("llcp_link_proc_rx_pdu (); PAX PDU exchange shall not be used");
   1212         break;
   1213 
   1214     case LLCP_PDU_DISC_TYPE:
   1215         if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM))
   1216         {
   1217             llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
   1218         }
   1219         else
   1220         {
   1221             p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
   1222             llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
   1223         }
   1224         break;
   1225 
   1226     case LLCP_PDU_SNL_TYPE:
   1227         p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
   1228         llcp_sdp_proc_snl ((UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
   1229         break;
   1230 
   1231     case LLCP_PDU_AGF_TYPE:
   1232         llcp_link_proc_agf_pdu (p_msg);
   1233         free_buffer = FALSE;
   1234         break;
   1235 
   1236     case LLCP_PDU_UI_TYPE:
   1237         llcp_link_proc_ui_pdu (dsap, ssap, 0, NULL, p_msg);
   1238         free_buffer = FALSE;
   1239         break;
   1240 
   1241     case LLCP_PDU_I_TYPE:
   1242         llcp_dlc_proc_i_pdu (dsap, ssap, 0, NULL, p_msg);
   1243         free_buffer = FALSE;
   1244         break;
   1245 
   1246     default:
   1247         p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
   1248         llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
   1249         break;
   1250     }
   1251 
   1252     if (free_buffer)
   1253         GKI_freebuf (p_msg);
   1254 }
   1255 
   1256 /*******************************************************************************
   1257 **
   1258 ** Function         llcp_link_proc_rx_data
   1259 **
   1260 ** Description      Process received data from NFCC and maintain symmetry state
   1261 **
   1262 ** Returns          void
   1263 **
   1264 *******************************************************************************/
   1265 static void llcp_link_proc_rx_data (BT_HDR *p_msg)
   1266 {
   1267     UINT8  *p;
   1268     UINT16  pdu_hdr, info_length = 0;
   1269     UINT8   dsap, ptype, ssap;
   1270     BOOLEAN free_buffer = TRUE;
   1271     BOOLEAN frame_error = FALSE;
   1272 
   1273     if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT)
   1274     {
   1275         llcp_link_stop_link_timer ();
   1276 
   1277         if (llcp_cb.lcb.received_first_packet == FALSE)
   1278         {
   1279             llcp_cb.lcb.received_first_packet = TRUE;
   1280             (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_FIRST_PACKET_RECEIVED_EVT, LLCP_LINK_SUCCESS);
   1281         }
   1282         if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
   1283             &&(llcp_cb.lcb.sig_xmit_q.count == 0)  )
   1284         {
   1285             /* this indicates that DISC PDU had been sent out to peer */
   1286             /* initiator may wait for SYMM PDU */
   1287             llcp_link_process_link_timeout ();
   1288         }
   1289         else
   1290         {
   1291             if (p_msg->len < LLCP_PDU_HEADER_SIZE)
   1292             {
   1293                 LLCP_TRACE_ERROR1 ("Received too small PDU: got %d bytes", p_msg->len);
   1294                 frame_error = TRUE;
   1295             }
   1296             else
   1297             {
   1298                 p = (UINT8 *) (p_msg + 1) + p_msg->offset;
   1299                 BE_STREAM_TO_UINT16 (pdu_hdr, p );
   1300 
   1301                 dsap  = LLCP_GET_DSAP (pdu_hdr);
   1302                 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
   1303                 ssap  = LLCP_GET_SSAP (pdu_hdr);
   1304 
   1305                 /* get length of information per PDU type */
   1306                 if (  (ptype == LLCP_PDU_I_TYPE)
   1307                     ||(ptype == LLCP_PDU_RR_TYPE)
   1308                     ||(ptype == LLCP_PDU_RNR_TYPE)  )
   1309                 {
   1310                     if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
   1311                     {
   1312                         info_length = p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
   1313                     }
   1314                     else
   1315                     {
   1316                         LLCP_TRACE_ERROR0 ("Received I/RR/RNR PDU without sequence");
   1317                         frame_error = TRUE;
   1318                     }
   1319                 }
   1320                 else
   1321                 {
   1322                     info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
   1323                 }
   1324 
   1325                 /* check if length of information is bigger than link MIU */
   1326                 if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu))
   1327                 {
   1328                     LLCP_TRACE_ERROR2 ("Received exceeding MIU (%d): got %d bytes SDU",
   1329                                        llcp_cb.lcb.local_link_miu, info_length);
   1330 
   1331                     frame_error = TRUE;
   1332                 }
   1333                 else
   1334                 {
   1335 #if (BT_TRACE_VERBOSE == TRUE)
   1336                     LLCP_TRACE_DEBUG4 ("llcp_link_proc_rx_data (): DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x",
   1337                                        dsap, llcp_pdu_type (ptype), ptype, ssap);
   1338 #endif
   1339 
   1340                     if (ptype == LLCP_PDU_SYMM_TYPE)
   1341                     {
   1342                         if (info_length > 0)
   1343                         {
   1344                             LLCP_TRACE_ERROR1 ("Received extra data (%d bytes) in SYMM PDU", info_length);
   1345                             frame_error = TRUE;
   1346                         }
   1347                     }
   1348                     else
   1349                     {
   1350                         /* received other than SYMM */
   1351                         llcp_link_stop_inactivity_timer ();
   1352 
   1353                         llcp_link_proc_rx_pdu (dsap, ptype, ssap, p_msg);
   1354                         free_buffer = FALSE;
   1355                     }
   1356                 }
   1357             }
   1358 
   1359             llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
   1360 
   1361             /* check if any pending packet */
   1362             llcp_link_check_send_data ();
   1363         }
   1364     }
   1365     else
   1366     {
   1367         LLCP_TRACE_ERROR0 ("Received PDU in state of SYMM_MUST_XMIT_NEXT");
   1368     }
   1369 
   1370     if (free_buffer)
   1371         GKI_freebuf (p_msg);
   1372 }
   1373 
   1374 /*******************************************************************************
   1375 **
   1376 ** Function         llcp_link_get_next_pdu
   1377 **
   1378 ** Description      Get next PDU from link manager or data links w/wo dequeue
   1379 **
   1380 ** Returns          pointer of a PDU to send if length_only is FALSE
   1381 **                  NULL otherwise
   1382 **
   1383 *******************************************************************************/
   1384 static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length)
   1385 {
   1386     BT_HDR *p_msg;
   1387     int     count, xx;
   1388     tLLCP_APP_CB *p_app_cb;
   1389 
   1390     /* processing signalling PDU first */
   1391     if (llcp_cb.lcb.sig_xmit_q.p_first)
   1392     {
   1393         if (length_only)
   1394         {
   1395             p_msg = (BT_HDR*) llcp_cb.lcb.sig_xmit_q.p_first;
   1396             *p_next_pdu_length = p_msg->len;
   1397             return NULL;
   1398         }
   1399         else
   1400             p_msg = (BT_HDR*) GKI_dequeue (&llcp_cb.lcb.sig_xmit_q);
   1401 
   1402         return p_msg;
   1403     }
   1404     else
   1405     {
   1406         /* transmitting logical data link and data link connection equaly */
   1407         for (xx = 0; xx < 2; xx++)
   1408         {
   1409             if (!llcp_cb.lcb.ll_served)
   1410             {
   1411                 /* Get one from logical link connection */
   1412                 for (count = 0; count < LLCP_NUM_SAPS; count++)
   1413                 {
   1414                     /* round robin schedule without priority  */
   1415                     p_app_cb = llcp_util_get_app_cb (llcp_cb.lcb.ll_idx);
   1416 
   1417                     if (  (p_app_cb)
   1418                         &&(p_app_cb->p_app_cback)
   1419                         &&(p_app_cb->ui_xmit_q.count)  )
   1420                     {
   1421                         if (length_only)
   1422                         {
   1423                             /* don't alternate next data link to return the same length of PDU */
   1424                             p_msg = (BT_HDR *) p_app_cb->ui_xmit_q.p_first;
   1425                             *p_next_pdu_length = p_msg->len;
   1426                             return NULL;
   1427                         }
   1428                         else
   1429                         {
   1430                             /* check data link connection first in next time */
   1431                             llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
   1432 
   1433                             p_msg = (BT_HDR*) GKI_dequeue (&p_app_cb->ui_xmit_q);
   1434                             llcp_cb.total_tx_ui_pdu--;
   1435 
   1436                             /* this logical link has been served, so start from next logical link next time */
   1437                             llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
   1438 
   1439                             return p_msg;
   1440                         }
   1441                     }
   1442                     else
   1443                     {
   1444                         /* check next logical link connection */
   1445                         llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
   1446                     }
   1447                 }
   1448 
   1449                 /* no data, so check data link connection if not checked yet */
   1450                 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
   1451             }
   1452             else
   1453             {
   1454                 /* Get one from data link connection */
   1455                 for (count = 0; count < LLCP_MAX_DATA_LINK; count++)
   1456                 {
   1457                     /* round robin schedule without priority  */
   1458                     if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE)
   1459                     {
   1460                         if (length_only)
   1461                         {
   1462                             *p_next_pdu_length = llcp_dlc_get_next_pdu_length (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
   1463 
   1464                             if (*p_next_pdu_length > 0 )
   1465                             {
   1466                                 /* don't change data link connection to return the same length of PDU */
   1467                                 return NULL;
   1468                             }
   1469                             else
   1470                             {
   1471                                 /* no data, so check next data link connection */
   1472                                 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
   1473                             }
   1474                         }
   1475                         else
   1476                         {
   1477                             p_msg = llcp_dlc_get_next_pdu (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
   1478 
   1479                             /* this data link has been served, so start from next data link next time */
   1480                             llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
   1481 
   1482                             if (p_msg)
   1483                             {
   1484                                 /* serve logical data link next time */
   1485                                 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
   1486                                 return p_msg;
   1487                             }
   1488                         }
   1489                     }
   1490                     else
   1491                     {
   1492                         /* check next data link connection */
   1493                         llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
   1494                     }
   1495                 }
   1496 
   1497                 /* if all of data link connection doesn't have data to send */
   1498                 if (count >= LLCP_MAX_DATA_LINK)
   1499                 {
   1500                     llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
   1501                 }
   1502             }
   1503         }
   1504     }
   1505 
   1506     /* nothing to send */
   1507     *p_next_pdu_length = 0;
   1508     return NULL;
   1509 }
   1510 
   1511 /*******************************************************************************
   1512 **
   1513 ** Function         llcp_link_build_next_pdu
   1514 **
   1515 ** Description      Build a PDU from Link Manager and Data Link
   1516 **                  Perform aggregation procedure if necessary
   1517 **
   1518 ** Returns          BT_HDR* if sent any PDU
   1519 **
   1520 *******************************************************************************/
   1521 static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_pdu)
   1522 {
   1523     BT_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu;
   1524     UINT8  *p, ptype;
   1525     UINT16  next_pdu_length, pdu_hdr;
   1526 
   1527     LLCP_TRACE_DEBUG0 ("llcp_link_build_next_pdu ()");
   1528 
   1529     /* add any pending SNL PDU into sig_xmit_q for transmitting */
   1530     llcp_sdp_check_send_snl ();
   1531 
   1532     if (p_pdu)
   1533     {
   1534         /* get PDU type */
   1535         p = (UINT8 *) (p_pdu + 1) + p_pdu->offset;
   1536         BE_STREAM_TO_UINT16 (pdu_hdr, p);
   1537 
   1538         ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr));
   1539 
   1540         if (ptype == LLCP_PDU_AGF_TYPE)
   1541         {
   1542             /* add more PDU into this AGF PDU */
   1543             p_agf = p_pdu;
   1544         }
   1545         else
   1546         {
   1547             p_msg = p_pdu;
   1548         }
   1549     }
   1550     else
   1551     {
   1552         /* Get a PDU from link manager or data links */
   1553         p_msg = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
   1554 
   1555         if (!p_msg)
   1556         {
   1557             return NULL;
   1558         }
   1559     }
   1560 
   1561     /* Get length of next PDU from link manager or data links without dequeue */
   1562     llcp_link_get_next_pdu (TRUE, &next_pdu_length);
   1563     while (next_pdu_length > 0)
   1564     {
   1565         /* if it's first visit */
   1566         if (!p_agf)
   1567         {
   1568             /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
   1569             if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
   1570             {
   1571                 p_agf = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID);
   1572                 if (p_agf)
   1573                 {
   1574                     p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
   1575 
   1576                     p = (UINT8 *) (p_agf + 1) + p_agf->offset;
   1577 
   1578                     UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM ));
   1579                     UINT16_TO_BE_STREAM (p, p_msg->len);
   1580                     memcpy(p, (UINT8 *) (p_msg + 1) + p_msg->offset, p_msg->len);
   1581 
   1582                     p_agf->len      = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
   1583 
   1584                     GKI_freebuf (p_msg);
   1585                     p_msg = p_agf;
   1586                 }
   1587                 else
   1588                 {
   1589                     LLCP_TRACE_ERROR0 ("llcp_link_build_next_pdu (): Out of buffer");
   1590                     return p_msg;
   1591                 }
   1592             }
   1593             else
   1594             {
   1595                 break;
   1596             }
   1597         }
   1598 
   1599         /* if next PDU fits into MIU, copy the next PDU into AGF */
   1600         if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
   1601         {
   1602             /* Get a next PDU from link manager or data links */
   1603             p_next_pdu = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
   1604 
   1605             p = (UINT8 *) (p_agf + 1) + p_agf->offset + p_agf->len;
   1606 
   1607             UINT16_TO_BE_STREAM (p, p_next_pdu->len);
   1608             memcpy (p, (UINT8 *) (p_next_pdu + 1) + p_next_pdu->offset, p_next_pdu->len);
   1609 
   1610             p_agf->len += 2 + p_next_pdu->len;
   1611 
   1612             GKI_freebuf (p_next_pdu);
   1613 
   1614             /* Get next PDU length from link manager or data links without dequeue */
   1615             llcp_link_get_next_pdu (TRUE, &next_pdu_length);
   1616         }
   1617         else
   1618         {
   1619             break;
   1620         }
   1621     }
   1622 
   1623     if (p_agf)
   1624         return p_agf;
   1625     else
   1626         return p_msg;
   1627 }
   1628 
   1629 /*******************************************************************************
   1630 **
   1631 ** Function         llcp_link_send_to_lower
   1632 **
   1633 ** Description      Send PDU to lower layer
   1634 **
   1635 ** Returns          void
   1636 **
   1637 *******************************************************************************/
   1638 static void llcp_link_send_to_lower (BT_HDR *p_pdu)
   1639 {
   1640 #if (BT_TRACE_PROTOCOL == TRUE)
   1641     DispLLCP (p_pdu, FALSE);
   1642 #endif
   1643 
   1644     llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
   1645 
   1646     NFC_SendData (NFC_RF_CONN_ID, p_pdu);
   1647 }
   1648 
   1649 /*******************************************************************************
   1650 **
   1651 ** Function         llcp_link_connection_cback
   1652 **
   1653 ** Description      processing incoming data
   1654 **
   1655 ** Returns          void
   1656 **
   1657 *******************************************************************************/
   1658 void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
   1659 {
   1660     if (event == NFC_DATA_CEVT)
   1661     {
   1662 #if (BT_TRACE_PROTOCOL == TRUE)
   1663         DispLLCP ((BT_HDR *)p_data->data.p_data, TRUE);
   1664 #endif
   1665         if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
   1666         {
   1667             /* respoding SYMM while LLCP is deactivated but RF link is not deactivated yet */
   1668             llcp_link_send_SYMM ();
   1669             GKI_freebuf ((BT_HDR *) p_data->data.p_data);
   1670         }
   1671         else
   1672         {
   1673             llcp_cb.lcb.flags |= LLCP_LINK_FLAGS_RX_ANY_LLC_PDU;
   1674             llcp_link_proc_rx_data ((BT_HDR *) p_data->data.p_data);
   1675         }
   1676     }
   1677     else if (event == NFC_ERROR_CEVT)
   1678     {
   1679         /* RF interface specific status code */
   1680         llcp_link_deactivate (*(UINT8*) p_data);
   1681     }
   1682     else if (event == NFC_DEACTIVATE_CEVT)
   1683     {
   1684         if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
   1685             &&(!llcp_cb.lcb.is_initiator)  )
   1686         {
   1687             /* peer initiates NFC link deactivation before timeout */
   1688             llcp_link_stop_link_timer ();
   1689             llcp_link_process_link_timeout ();
   1690         }
   1691         else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
   1692         {
   1693             llcp_link_deactivate (LLCP_LINK_RF_LINK_LOSS_ERR);
   1694         }
   1695         NFC_SetStaticRfCback (NULL);
   1696     }
   1697 
   1698     /* LLCP ignores the following events
   1699 
   1700         NFC_CONN_CREATE_CEVT
   1701         NFC_CONN_CLOSE_CEVT
   1702     */
   1703 }
   1704 
   1705 #if (BT_TRACE_VERBOSE == TRUE)
   1706 /*******************************************************************************
   1707 **
   1708 ** Function         llcp_pdu_type
   1709 **
   1710 ** Description
   1711 **
   1712 ** Returns          string of PDU type
   1713 **
   1714 *******************************************************************************/
   1715 static char *llcp_pdu_type (UINT8 ptype)
   1716 {
   1717     switch(ptype)
   1718     {
   1719     case LLCP_PDU_SYMM_TYPE:
   1720         return "SYMM";
   1721     case LLCP_PDU_PAX_TYPE:
   1722         return "PAX";
   1723     case LLCP_PDU_AGF_TYPE:
   1724         return "AGF";
   1725     case LLCP_PDU_UI_TYPE:
   1726         return "UI";
   1727     case LLCP_PDU_CONNECT_TYPE:
   1728         return "CONNECT";
   1729     case LLCP_PDU_DISC_TYPE:
   1730         return "DISC";
   1731     case LLCP_PDU_CC_TYPE:
   1732         return "CC";
   1733     case LLCP_PDU_DM_TYPE:
   1734         return "DM";
   1735     case LLCP_PDU_FRMR_TYPE:
   1736         return "FRMR";
   1737     case LLCP_PDU_SNL_TYPE:
   1738         return "SNL";
   1739     case LLCP_PDU_I_TYPE:
   1740         return "I";
   1741     case LLCP_PDU_RR_TYPE:
   1742         return "RR";
   1743     case LLCP_PDU_RNR_TYPE:
   1744         return "RNR";
   1745 
   1746     default:
   1747         return "RESERVED";
   1748     }
   1749 }
   1750 
   1751 #endif
   1752 
   1753