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