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 API code
     23  *
     24  ******************************************************************************/
     25 
     26 #include <string.h>
     27 #include "gki.h"
     28 #include "nfc_target.h"
     29 #include "bt_types.h"
     30 #include "llcp_api.h"
     31 #include "llcp_int.h"
     32 #include "llcp_defs.h"
     33 
     34 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
     35 
     36 tLLCP_TEST_PARAMS llcp_test_params =
     37 {
     38     LLCP_VERSION_VALUE,
     39     0,                             /* not override */
     40 };
     41 
     42 /*******************************************************************************
     43 **
     44 ** Function         LLCP_SetTestParams
     45 **
     46 ** Description      Set test parameters for LLCP
     47 **
     48 **
     49 ** Returns          void
     50 **
     51 *******************************************************************************/
     52 void LLCP_SetTestParams (UINT8 version, UINT16 wks)
     53 {
     54     LLCP_TRACE_API2 ("LLCP_SetTestParams () version:0x%02X, wks:0x%04X",
     55                      version, wks);
     56 
     57     if (version != 0xFF)
     58         llcp_test_params.version = version;
     59 
     60     if (wks != 0xFFFF)
     61         llcp_test_params.wks = wks;
     62 }
     63 #endif
     64 
     65 /*******************************************************************************
     66 **
     67 ** Function         LLCP_SetConfig
     68 **
     69 ** Description      Set configuration parameters for LLCP
     70 **                  - Local Link MIU
     71 **                  - Option parameter
     72 **                  - Response Waiting Time Index
     73 **                  - Local Link Timeout
     74 **                  - Inactivity Timeout as initiator role
     75 **                  - Inactivity Timeout as target role
     76 **                  - Delay SYMM response
     77 **                  - Data link connection timeout
     78 **                  - Delay timeout to send first PDU as initiator
     79 **
     80 ** Returns          void
     81 **
     82 *******************************************************************************/
     83 void LLCP_SetConfig (UINT16 link_miu,
     84                      UINT8  opt,
     85                      UINT8  wt,
     86                      UINT16 link_timeout,
     87                      UINT16 inact_timeout_init,
     88                      UINT16 inact_timeout_target,
     89                      UINT16 symm_delay,
     90                      UINT16 data_link_timeout,
     91                      UINT16 delay_first_pdu_timeout)
     92 {
     93     LLCP_TRACE_API4 ("LLCP_SetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
     94                      link_miu, opt, wt, link_timeout);
     95     LLCP_TRACE_API4 ("                 inact_timeout (init:%d,target:%d), symm_delay:%d, data_link_timeout:%d",
     96                      inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout);
     97     LLCP_TRACE_API1 ("                 delay_first_pdu_timeout:%d", delay_first_pdu_timeout);
     98 
     99     if (link_miu < LLCP_DEFAULT_MIU)
    100     {
    101         LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be smaller than LLCP_DEFAULT_MIU (%d)",
    102                             LLCP_DEFAULT_MIU);
    103         link_miu = LLCP_DEFAULT_MIU;
    104     }
    105     else if (link_miu > LLCP_MAX_MIU)
    106     {
    107         LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MAX_MIU (%d)",
    108                             LLCP_MAX_MIU);
    109         link_miu = LLCP_MAX_MIU;
    110     }
    111 
    112     /* if Link MIU is bigger than GKI buffer */
    113     if (link_miu > LLCP_MIU)
    114     {
    115         LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_miu shall not be bigger than LLCP_MIU (%d)",
    116                             LLCP_MIU);
    117         llcp_cb.lcb.local_link_miu = LLCP_MIU;
    118     }
    119     else
    120         llcp_cb.lcb.local_link_miu = link_miu;
    121 
    122     llcp_cb.lcb.local_opt = opt;
    123     llcp_cb.lcb.local_wt  = wt;
    124 
    125     if (link_timeout < LLCP_LTO_UNIT)
    126     {
    127         LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be smaller than LLCP_LTO_UNIT (%d ms)",
    128                             LLCP_LTO_UNIT);
    129         llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS;
    130     }
    131     else if (link_timeout > LLCP_MAX_LTO_IN_MS)
    132     {
    133         LLCP_TRACE_ERROR1 ("LLCP_SetConfig (): link_timeout shall not be bigger than LLCP_MAX_LTO_IN_MS (%d ms)",
    134                             LLCP_MAX_LTO_IN_MS);
    135         llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS;
    136     }
    137     else
    138         llcp_cb.lcb.local_lto = link_timeout;
    139 
    140     llcp_cb.lcb.inact_timeout_init   = inact_timeout_init;
    141     llcp_cb.lcb.inact_timeout_target = inact_timeout_target;
    142     llcp_cb.lcb.symm_delay           = symm_delay;
    143     llcp_cb.lcb.data_link_timeout    = data_link_timeout;
    144     llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout;
    145 }
    146 
    147 /*******************************************************************************
    148 **
    149 ** Function         LLCP_GetConfig
    150 **
    151 ** Description      Get configuration parameters for LLCP
    152 **                  - Local Link MIU
    153 **                  - Option parameter
    154 **                  - Response Waiting Time Index
    155 **                  - Local Link Timeout
    156 **                  - Inactivity Timeout as initiator role
    157 **                  - Inactivity Timeout as target role
    158 **                  - Delay SYMM response
    159 **                  - Data link connection timeout
    160 **                  - Delay timeout to send first PDU as initiator
    161 **
    162 ** Returns          void
    163 **
    164 *******************************************************************************/
    165 void LLCP_GetConfig (UINT16 *p_link_miu,
    166                      UINT8  *p_opt,
    167                      UINT8  *p_wt,
    168                      UINT16 *p_link_timeout,
    169                      UINT16 *p_inact_timeout_init,
    170                      UINT16 *p_inact_timeout_target,
    171                      UINT16 *p_symm_delay,
    172                      UINT16 *p_data_link_timeout,
    173                      UINT16 *p_delay_first_pdu_timeout)
    174 {
    175     *p_link_miu             = llcp_cb.lcb.local_link_miu;
    176     *p_opt                  = llcp_cb.lcb.local_opt;
    177     *p_wt                   = llcp_cb.lcb.local_wt;
    178     *p_link_timeout         = llcp_cb.lcb.local_lto;
    179     *p_inact_timeout_init   = llcp_cb.lcb.inact_timeout_init;
    180     *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target;
    181     *p_symm_delay           = llcp_cb.lcb.symm_delay;
    182     *p_data_link_timeout    = llcp_cb.lcb.data_link_timeout;
    183     *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout;
    184 
    185     LLCP_TRACE_API4 ("LLCP_GetConfig () link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d",
    186                      *p_link_miu, *p_opt, *p_wt, *p_link_timeout);
    187     LLCP_TRACE_API4 ("                 inact_timeout (init:%d, target:%d), symm_delay:%d, data_link_timeout:%d",
    188                      *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, *p_data_link_timeout);
    189     LLCP_TRACE_API1 ("                 delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout);
    190 }
    191 
    192 /*******************************************************************************
    193 **
    194 ** Function         LLCP_GetDiscoveryConfig
    195 **
    196 ** Description      Returns discovery config for ISO 18092 MAC link activation
    197 **                  This function is called to get general bytes for NFC_PMID_ATR_REQ_GEN_BYTES
    198 **                  or NFC_PMID_ATR_RES_GEN_BYTES before starting discovery.
    199 **
    200 **                  wt:Waiting time 0 - 8, only for listen
    201 **                  p_gen_bytes: pointer to store LLCP magic number and paramters
    202 **                  p_gen_bytes_len: length of buffer for gen bytes as input
    203 **                                   (NOTE:it must be bigger than LLCP_MIN_GEN_BYTES)
    204 **                                   actual gen bytes size as output
    205 **
    206 **                  Restrictions on the use of ISO 18092
    207 **                  1. The DID features shall not be used.
    208 **                  2. the NAD features shall not be used.
    209 **                  3. Frame waiting time extentions (WTX) shall not be used.
    210 **
    211 ** Returns          None
    212 **
    213 *******************************************************************************/
    214 void LLCP_GetDiscoveryConfig (UINT8 *p_wt,
    215                               UINT8 *p_gen_bytes,
    216                               UINT8 *p_gen_bytes_len)
    217 {
    218     UINT8      *p = p_gen_bytes;
    219 
    220     LLCP_TRACE_API0 ("LLCP_GetDiscoveryConfig ()");
    221 
    222     if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES)
    223     {
    224         LLCP_TRACE_ERROR1 ("LLCP_GetDiscoveryConfig (): GenBytes length shall not be smaller than LLCP_MIN_GEN_BYTES (%d)",
    225                             LLCP_MIN_GEN_BYTES);
    226         *p_gen_bytes_len = 0;
    227         return;
    228     }
    229 
    230     *p_wt = llcp_cb.lcb.local_wt;
    231 
    232     UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE0);
    233     UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE1);
    234     UINT8_TO_BE_STREAM (p, LLCP_MAGIC_NUMBER_BYTE2);
    235 
    236 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
    237     UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
    238     UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
    239     UINT8_TO_BE_STREAM (p, llcp_test_params.version);
    240 
    241     UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
    242     UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
    243     UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
    244 
    245     UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
    246     UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
    247     if (llcp_test_params.wks == 0)  /* not override */
    248     {
    249         UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
    250     }
    251     else
    252     {
    253         UINT16_TO_BE_STREAM (p, llcp_test_params.wks);
    254     }
    255 #else
    256     UINT8_TO_BE_STREAM (p, LLCP_VERSION_TYPE);
    257     UINT8_TO_BE_STREAM (p, LLCP_VERSION_LEN);
    258     UINT8_TO_BE_STREAM (p, LLCP_VERSION_VALUE);
    259 
    260     UINT8_TO_BE_STREAM (p, LLCP_MIUX_TYPE);
    261     UINT8_TO_BE_STREAM (p, LLCP_MIUX_LEN);
    262     UINT16_TO_BE_STREAM (p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU));
    263 
    264     UINT8_TO_BE_STREAM (p, LLCP_WKS_TYPE);
    265     UINT8_TO_BE_STREAM (p, LLCP_WKS_LEN);
    266     UINT16_TO_BE_STREAM (p, llcp_cb.lcb.wks);
    267 #endif
    268 
    269     UINT8_TO_BE_STREAM (p, LLCP_LTO_TYPE);
    270     UINT8_TO_BE_STREAM (p, LLCP_LTO_LEN);
    271     UINT8_TO_BE_STREAM (p, (llcp_cb.lcb.local_lto/LLCP_LTO_UNIT));
    272 
    273     UINT8_TO_BE_STREAM (p, LLCP_OPT_TYPE);
    274     UINT8_TO_BE_STREAM (p, LLCP_OPT_LEN);
    275     UINT8_TO_BE_STREAM (p, llcp_cb.lcb.local_opt);
    276 
    277     *p_gen_bytes_len = (UINT8) (p - p_gen_bytes);
    278 }
    279 
    280 /*******************************************************************************
    281 **
    282 ** Function         LLCP_ActivateLink
    283 **
    284 ** Description      This function will activate LLCP link with LR, WT and Gen Bytes
    285 **                  in activation NTF from NFCC.
    286 **
    287 **                  LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through
    288 **                  callback function if successful.
    289 **                  Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned.
    290 **
    291 ** Returns          LLCP_STATUS_SUCCESS if success
    292 **
    293 *******************************************************************************/
    294 tLLCP_STATUS LLCP_ActivateLink (tLLCP_ACTIVATE_CONFIG config,
    295                                 tLLCP_LINK_CBACK     *p_link_cback)
    296 {
    297     LLCP_TRACE_API1 ("LLCP_ActivateLink () link_state = %d", llcp_cb.lcb.link_state);
    298 
    299     if (  (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED)
    300         &&(p_link_cback)  )
    301     {
    302         llcp_cb.lcb.p_link_cback = p_link_cback;
    303         return (llcp_link_activate (&config));
    304     }
    305     else
    306         return LLCP_STATUS_FAIL;
    307 }
    308 
    309 /*******************************************************************************
    310 **
    311 ** Function         LLCP_DeactivateLink
    312 **
    313 ** Description      Deactivate LLCP link
    314 **
    315 **                  LLCP_LINK_DEACTIVATED_EVT will be returned through callback
    316 **                  when LLCP link is deactivated. Then NFC link may be deactivated.
    317 **
    318 ** Returns          LLCP_STATUS_SUCCESS if success
    319 **
    320 *******************************************************************************/
    321 tLLCP_STATUS LLCP_DeactivateLink (void)
    322 {
    323     LLCP_TRACE_API1 ("LLCP_DeactivateLink () link_state = %d", llcp_cb.lcb.link_state);
    324 
    325     if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED)
    326     {
    327         llcp_link_deactivate (LLCP_LINK_LOCAL_INITIATED);
    328         return LLCP_STATUS_SUCCESS;
    329     }
    330     else
    331         return LLCP_STATUS_FAIL;
    332 }
    333 
    334 /*******************************************************************************
    335 **
    336 ** Function         LLCP_RegisterServer
    337 **
    338 ** Description      Register server and callback function
    339 **
    340 **                  reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F)
    341 **                            Advertized by SDP (0x10 - 0x1F)
    342 **                            LLCP_INVALID_SAP, LLCP will allocate between 0x10 and 0x1F
    343 **                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
    344 **                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
    345 **                  p_service_name : Null-terminated string up to LLCP_MAX_SN_LEN
    346 **
    347 ** Returns          SAP between 0x02 and 0x1F, if success
    348 **                  LLCP_INVALID_SAP, otherwise
    349 **
    350 *******************************************************************************/
    351 UINT8 LLCP_RegisterServer (UINT8           reg_sap,
    352                            UINT8           link_type,
    353                            char            *p_service_name,
    354                            tLLCP_APP_CBACK *p_app_cback)
    355 {
    356     UINT8  sap;
    357     UINT16 length;
    358     tLLCP_APP_CB *p_app_cb;
    359 
    360     LLCP_TRACE_API3 ("LLCP_RegisterServer (): SAP:0x%x, link_type:0x%x, ServiceName:<%s>",
    361                      reg_sap, link_type, ((p_service_name == NULL) ? "" : p_service_name));
    362 
    363     if (!p_app_cback)
    364     {
    365         LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Callback must be provided");
    366         return LLCP_INVALID_SAP;
    367     }
    368     else if (  ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
    369              &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)  )
    370     {
    371         LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): link type (0x%x) must be specified", link_type);
    372         return LLCP_INVALID_SAP;
    373     }
    374 
    375     if (reg_sap == LLCP_INVALID_SAP)
    376     {
    377         /* allocate a SAP between 0x10 and 0x1F */
    378         for (sap = 0; sap < LLCP_MAX_SERVER; sap++)
    379         {
    380             if (llcp_cb.server_cb[sap].p_app_cback == NULL)
    381             {
    382                 p_app_cb = &llcp_cb.server_cb[sap];
    383                 reg_sap  = LLCP_LOWER_BOUND_SDP_SAP + sap;
    384                 break;
    385             }
    386         }
    387 
    388         if (reg_sap == LLCP_INVALID_SAP)
    389         {
    390             LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): out of resource");
    391             return LLCP_INVALID_SAP;
    392         }
    393     }
    394     else if (reg_sap == LLCP_SAP_LM)
    395     {
    396         LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is for link manager", reg_sap);
    397         return LLCP_INVALID_SAP;
    398     }
    399     else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
    400     {
    401         if (reg_sap >= LLCP_MAX_WKS)
    402         {
    403             LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
    404             return LLCP_INVALID_SAP;
    405         }
    406         else if (llcp_cb.wks_cb[reg_sap].p_app_cback)
    407         {
    408             LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
    409             return LLCP_INVALID_SAP;
    410         }
    411         else
    412         {
    413             p_app_cb = &llcp_cb.wks_cb[reg_sap];
    414         }
    415     }
    416     else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP)
    417     {
    418         if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER)
    419         {
    420             LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): out of resource for SAP (0x%x)", reg_sap);
    421             return LLCP_INVALID_SAP;
    422         }
    423         else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP].p_app_cback)
    424         {
    425             LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): SAP (0x%x) is already registered", reg_sap);
    426             return LLCP_INVALID_SAP;
    427         }
    428         else
    429         {
    430             p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP];
    431         }
    432     }
    433     else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP)
    434     {
    435         LLCP_TRACE_ERROR2 ("LLCP_RegisterServer (): SAP (0x%x) must be less than 0x%x",
    436                             reg_sap, LLCP_LOWER_BOUND_LOCAL_SAP);
    437         return LLCP_INVALID_SAP;
    438     }
    439 
    440     memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
    441 
    442     if (p_service_name)
    443     {
    444         length = (UINT8) strlen (p_service_name);
    445         if (length > LLCP_MAX_SN_LEN)
    446         {
    447             LLCP_TRACE_ERROR1 ("LLCP_RegisterServer (): Service Name (%d bytes) is too long", length);
    448             return LLCP_INVALID_SAP;
    449         }
    450 
    451         p_app_cb->p_service_name = (UINT8 *) GKI_getbuf ((UINT16) (length + 1));
    452         if (p_app_cb->p_service_name == NULL)
    453         {
    454             LLCP_TRACE_ERROR0 ("LLCP_RegisterServer (): Out of resource");
    455             return LLCP_INVALID_SAP;
    456         }
    457 
    458         BCM_STRNCPY_S ((char *) p_app_cb->p_service_name, length + 1, (char *) p_service_name, length + 1);
    459         p_app_cb->p_service_name[length] = 0;
    460     }
    461     else
    462         p_app_cb->p_service_name = NULL;
    463 
    464     p_app_cb->p_app_cback = p_app_cback;
    465     p_app_cb->link_type   = link_type;
    466 
    467     if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP)
    468     {
    469         llcp_cb.lcb.wks |= (1 << reg_sap);
    470     }
    471 
    472     LLCP_TRACE_DEBUG1 ("LLCP_RegisterServer (): Registered SAP = 0x%02X", reg_sap);
    473 
    474     if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
    475     {
    476         llcp_cb.num_logical_data_link++;
    477         llcp_util_adjust_ll_congestion ();
    478     }
    479 
    480     return reg_sap;
    481 }
    482 
    483 /*******************************************************************************
    484 **
    485 ** Function         LLCP_RegisterClient
    486 **
    487 ** Description      Register client and callback function
    488 **
    489 **                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
    490 **                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
    491 **
    492 ** Returns          SAP between 0x20 and 0x3F, if success
    493 **                  LLCP_INVALID_SAP, otherwise
    494 **
    495 *******************************************************************************/
    496 UINT8 LLCP_RegisterClient (UINT8           link_type,
    497                            tLLCP_APP_CBACK *p_app_cback)
    498 {
    499     UINT8 reg_sap = LLCP_INVALID_SAP;
    500     UINT8 sap;
    501     tLLCP_APP_CB *p_app_cb;
    502 
    503     LLCP_TRACE_API1 ("LLCP_RegisterClient (): link_type = 0x%x", link_type);
    504 
    505     if (!p_app_cback)
    506     {
    507         LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): Callback must be provided");
    508         return LLCP_INVALID_SAP;
    509     }
    510     else if (  ((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00)
    511              &&((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)  )
    512     {
    513         LLCP_TRACE_ERROR1 ("LLCP_RegisterClient (): link type (0x%x) must be specified", link_type);
    514         return LLCP_INVALID_SAP;
    515     }
    516 
    517     /* allocate a SAP between 0x20 and 0x3F */
    518     for (sap = 0; sap < LLCP_MAX_CLIENT; sap++)
    519     {
    520         if (llcp_cb.client_cb[sap].p_app_cback == NULL)
    521         {
    522             p_app_cb = &llcp_cb.client_cb[sap];
    523             memset (p_app_cb, 0x00, sizeof (tLLCP_APP_CB));
    524             reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
    525             break;
    526         }
    527     }
    528 
    529     if (reg_sap == LLCP_INVALID_SAP)
    530     {
    531         LLCP_TRACE_ERROR0 ("LLCP_RegisterClient (): out of resource");
    532         return LLCP_INVALID_SAP;
    533     }
    534 
    535     p_app_cb->p_app_cback    = p_app_cback;
    536     p_app_cb->p_service_name = NULL;
    537     p_app_cb->link_type      = link_type;
    538 
    539     LLCP_TRACE_DEBUG1 ("LLCP_RegisterClient (): Registered SAP = 0x%02X", reg_sap);
    540 
    541     if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
    542     {
    543         llcp_cb.num_logical_data_link++;
    544         llcp_util_adjust_ll_congestion ();
    545     }
    546 
    547     return reg_sap;
    548 }
    549 
    550 /*******************************************************************************
    551 **
    552 ** Function         LLCP_Deregister
    553 **
    554 ** Description      Deregister server or client
    555 **
    556 **
    557 ** Returns          LLCP_STATUS_SUCCESS if success
    558 **
    559 *******************************************************************************/
    560 tLLCP_STATUS LLCP_Deregister (UINT8 local_sap)
    561 {
    562     UINT8 idx;
    563     tLLCP_APP_CB *p_app_cb;
    564 
    565     LLCP_TRACE_API1 ("LLCP_Deregister () SAP:0x%x", local_sap);
    566 
    567     p_app_cb = llcp_util_get_app_cb (local_sap);
    568 
    569     if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL))
    570     {
    571         LLCP_TRACE_ERROR1 ("LLCP_Deregister (): SAP (0x%x) is not registered", local_sap);
    572         return LLCP_STATUS_FAIL;
    573     }
    574 
    575     if (p_app_cb->p_service_name)
    576         GKI_freebuf (p_app_cb->p_service_name);
    577 
    578     /* update WKS bit map */
    579     if (local_sap <= LLCP_UPPER_BOUND_WK_SAP)
    580     {
    581         llcp_cb.lcb.wks &= ~ (1 << local_sap);
    582     }
    583 
    584     /* discard any received UI PDU on this SAP */
    585     LLCP_FlushLogicalLinkRxData (local_sap);
    586     llcp_cb.total_rx_ui_pdu = 0;
    587 
    588     /* deallocate any data link connection on this SAP */
    589     for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
    590     {
    591         if (  (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE)
    592             &&(llcp_cb.dlcb[idx].local_sap == local_sap)  )
    593         {
    594             llcp_util_deallocate_data_link (&llcp_cb.dlcb[idx]);
    595         }
    596     }
    597 
    598     p_app_cb->p_app_cback = NULL;
    599 
    600     /* discard any pending tx UI PDU from this SAP */
    601     while (p_app_cb->ui_xmit_q.p_first)
    602     {
    603         GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q));
    604         llcp_cb.total_tx_ui_pdu--;
    605     }
    606 
    607     if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)
    608     {
    609         llcp_cb.num_logical_data_link--;
    610         llcp_util_adjust_ll_congestion ();
    611     }
    612 
    613     /* check rx congestion status */
    614     llcp_util_check_rx_congested_status ();
    615 
    616     return LLCP_STATUS_SUCCESS;
    617 }
    618 
    619 /*******************************************************************************
    620 **
    621 ** Function         LLCP_IsLogicalLinkCongested
    622 **
    623 ** Description      Check if logical link is congested
    624 **
    625 **
    626 ** Returns          TRUE if congested
    627 **
    628 *******************************************************************************/
    629 BOOLEAN LLCP_IsLogicalLinkCongested (UINT8 local_sap,
    630                                      UINT8 num_pending_ui_pdu,
    631                                      UINT8 total_pending_ui_pdu,
    632                                      UINT8 total_pending_i_pdu)
    633 {
    634     tLLCP_APP_CB *p_app_cb;
    635 
    636     LLCP_TRACE_API4 ("LLCP_IsLogicalLinkCongested () Local SAP:0x%x, pending = (%d, %d, %d)",
    637                      local_sap, num_pending_ui_pdu, total_pending_ui_pdu, total_pending_i_pdu);
    638 
    639     p_app_cb = llcp_util_get_app_cb (local_sap);
    640 
    641     if (  (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
    642         ||(p_app_cb == NULL)
    643         ||(p_app_cb->p_app_cback == NULL)
    644         ||((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
    645         ||(p_app_cb->is_ui_tx_congested)  )
    646     {
    647         return (TRUE);
    648     }
    649     else if (  (num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >= llcp_cb.ll_tx_congest_start)
    650              ||(total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >= llcp_cb.max_num_ll_tx_buff)
    651              ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)  )
    652     {
    653         /* set flag so LLCP can notify uncongested status later */
    654         p_app_cb->is_ui_tx_congested = TRUE;
    655 
    656         return (TRUE);
    657     }
    658     return (FALSE);
    659 }
    660 
    661 /*******************************************************************************
    662 **
    663 ** Function         LLCP_SendUI
    664 **
    665 ** Description      Send connnectionless data to DSAP
    666 **
    667 **
    668 ** Returns          LLCP_STATUS_SUCCESS if success
    669 **                  LLCP_STATUS_CONGESTED if logical link is congested
    670 **                  LLCP_STATUS_FAIL, otherwise
    671 **
    672 *******************************************************************************/
    673 tLLCP_STATUS LLCP_SendUI (UINT8   ssap,
    674                           UINT8   dsap,
    675                           BT_HDR *p_buf)
    676 {
    677     tLLCP_STATUS status = LLCP_STATUS_FAIL;
    678     tLLCP_APP_CB *p_app_cb;
    679 
    680     LLCP_TRACE_API2 ("LLCP_SendUI () SSAP=0x%x, DSAP=0x%x", ssap, dsap);
    681 
    682     p_app_cb = llcp_util_get_app_cb (ssap);
    683 
    684     if (  (p_app_cb == NULL)
    685         ||(p_app_cb->p_app_cback == NULL)  )
    686     {
    687         LLCP_TRACE_ERROR1 ("LLCP_SendUI (): SSAP (0x%x) is not registered", ssap);
    688     }
    689     else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0)
    690     {
    691         LLCP_TRACE_ERROR1 ("LLCP_SendUI (): Logical link on SSAP (0x%x) is not enabled", ssap);
    692     }
    693     else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
    694     {
    695         LLCP_TRACE_ERROR0 ("LLCP_SendUI (): LLCP link is not activated");
    696     }
    697     else if (  (llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN)
    698              ||(llcp_cb.lcb.peer_opt & LLCP_LSC_1)  )
    699     {
    700         if (p_buf->len <= llcp_cb.lcb.peer_miu)
    701         {
    702             if (p_buf->offset >= LLCP_MIN_OFFSET)
    703             {
    704                 status = llcp_util_send_ui (ssap, dsap, p_app_cb, p_buf);
    705             }
    706             else
    707             {
    708                 LLCP_TRACE_ERROR2 ("LLCP_SendUI (): offset (%d) must be %d at least",
    709                                     p_buf->offset, LLCP_MIN_OFFSET );
    710             }
    711         }
    712         else
    713         {
    714             LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Data length shall not be bigger than peer's link MIU");
    715         }
    716     }
    717     else
    718     {
    719         LLCP_TRACE_ERROR0 ("LLCP_SendUI (): Peer doesn't support connectionless link");
    720     }
    721 
    722     if (status == LLCP_STATUS_FAIL)
    723     {
    724         GKI_freebuf (p_buf);
    725     }
    726 
    727     return status;
    728 }
    729 
    730 /*******************************************************************************
    731 **
    732 ** Function         LLCP_ReadLogicalLinkData
    733 **
    734 ** Description      Read information of UI PDU for local SAP
    735 **
    736 **                  - Remote SAP who sent UI PDU is returned.
    737 **                  - Information of UI PDU up to max_data_len is copied into p_data.
    738 **                  - Information of next UI PDU is not concatenated.
    739 **                  - Recommended max_data_len is link MIU of local device
    740 **
    741 ** Returns          TRUE if more information of UI PDU or more UI PDU in queue
    742 **
    743 *******************************************************************************/
    744 BOOLEAN LLCP_ReadLogicalLinkData (UINT8  local_sap,
    745                                   UINT32 max_data_len,
    746                                   UINT8  *p_remote_sap,
    747                                   UINT32 *p_data_len,
    748                                   UINT8  *p_data)
    749 {
    750     tLLCP_APP_CB *p_app_cb;
    751     BT_HDR       *p_buf;
    752     UINT8        *p_ui_pdu;
    753     UINT16       pdu_hdr, ui_pdu_length;
    754 
    755     LLCP_TRACE_API1 ("LLCP_ReadLogicalLinkData () Local SAP:0x%x", local_sap);
    756 
    757     *p_data_len = 0;
    758 
    759     p_app_cb = llcp_util_get_app_cb (local_sap);
    760 
    761     /* if application is registered */
    762     if ((p_app_cb) && (p_app_cb->p_app_cback))
    763     {
    764         /* if any UI PDU in rx queue */
    765         if (p_app_cb->ui_rx_q.p_first)
    766         {
    767             p_buf    = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
    768             p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
    769 
    770             /* get length of UI PDU */
    771             BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
    772 
    773             /* get remote SAP from LLCP header */
    774             BE_STREAM_TO_UINT16 (pdu_hdr, p_ui_pdu);
    775             *p_remote_sap = LLCP_GET_SSAP (pdu_hdr);
    776 
    777             /* layer_specific has the offset to read within UI PDU */
    778             p_ui_pdu += p_buf->layer_specific;
    779 
    780             /* copy data up to max_data_len */
    781             if (max_data_len >= (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific))
    782             {
    783                 /* copy information without LLCP header */
    784                 *p_data_len = (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
    785 
    786                 /* move to next UI PDU if any */
    787                 p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next UI PDU */
    788                 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
    789                 p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
    790             }
    791             else
    792             {
    793                 *p_data_len = max_data_len;
    794 
    795                 /* update offset to read from remaining UI PDU next time */
    796                 p_buf->layer_specific += max_data_len;
    797             }
    798 
    799             memcpy (p_data, p_ui_pdu, *p_data_len);
    800 
    801             /* if read all of UI PDU */
    802             if (p_buf->len == 0)
    803             {
    804                 GKI_dequeue (&p_app_cb->ui_rx_q);
    805                 GKI_freebuf (p_buf);
    806 
    807                 /* decrease number of received UI PDU in in all of ui_rx_q and check rx congestion status */
    808                 llcp_cb.total_rx_ui_pdu--;
    809                 llcp_util_check_rx_congested_status ();
    810             }
    811         }
    812 
    813         /* if there is more UI PDU in rx queue */
    814         if (p_app_cb->ui_rx_q.p_first)
    815         {
    816             return (TRUE);
    817         }
    818         else
    819         {
    820             return (FALSE);
    821         }
    822     }
    823     else
    824     {
    825         LLCP_TRACE_ERROR1 ("LLCP_ReadLogicalLinkData (): Unregistered SAP:0x%x", local_sap);
    826 
    827         return (FALSE);
    828     }
    829 }
    830 
    831 /*******************************************************************************
    832 **
    833 ** Function         LLCP_FlushLogicalLinkRxData
    834 **
    835 ** Description      Discard received data in logical data link of local SAP
    836 **
    837 **
    838 ** Returns          length of data flushed
    839 **
    840 *******************************************************************************/
    841 UINT32 LLCP_FlushLogicalLinkRxData (UINT8 local_sap)
    842 {
    843     BT_HDR       *p_buf;
    844     UINT32       flushed_length = 0;
    845     tLLCP_APP_CB *p_app_cb;
    846     UINT8        *p_ui_pdu;
    847     UINT16       ui_pdu_length;
    848 
    849     LLCP_TRACE_API1 ("LLCP_FlushLogicalLinkRxData () Local SAP:0x%x", local_sap);
    850 
    851     p_app_cb = llcp_util_get_app_cb (local_sap);
    852 
    853     /* if application is registered */
    854     if ((p_app_cb) && (p_app_cb->p_app_cback))
    855     {
    856         /* if any UI PDU in rx queue */
    857         while (p_app_cb->ui_rx_q.p_first)
    858         {
    859             p_buf    = (BT_HDR *) p_app_cb->ui_rx_q.p_first;
    860             p_ui_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
    861 
    862             /* get length of UI PDU */
    863             BE_STREAM_TO_UINT16 (ui_pdu_length, p_ui_pdu);
    864 
    865             flushed_length += (UINT32) (ui_pdu_length - LLCP_PDU_HEADER_SIZE - p_buf->layer_specific);
    866 
    867             /* move to next UI PDU if any */
    868             p_buf->layer_specific = 0;  /* offset */
    869             p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
    870             p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
    871 
    872             /* if read all of UI PDU */
    873             if (p_buf->len == 0)
    874             {
    875                 GKI_dequeue (&p_app_cb->ui_rx_q);
    876                 GKI_freebuf (p_buf);
    877                 llcp_cb.total_rx_ui_pdu--;
    878             }
    879         }
    880 
    881         /* number of received UI PDU is decreased so check rx congestion status */
    882         llcp_util_check_rx_congested_status ();
    883     }
    884     else
    885     {
    886         LLCP_TRACE_ERROR1 ("LLCP_FlushLogicalLinkRxData (): Unregistered SAP:0x%x", local_sap);
    887     }
    888 
    889     return (flushed_length);
    890 }
    891 
    892 /*******************************************************************************
    893 **
    894 ** Function         LLCP_ConnectReq
    895 **
    896 ** Description      Create data link connection between registered SAP and DSAP
    897 **                  in peer LLCP,
    898 **
    899 **
    900 ** Returns          LLCP_STATUS_SUCCESS if success
    901 **                  LLCP_STATUS_FAIL, otherwise
    902 **
    903 *******************************************************************************/
    904 tLLCP_STATUS LLCP_ConnectReq (UINT8                    reg_sap,
    905                               UINT8                    dsap,
    906                               tLLCP_CONNECTION_PARAMS *p_params)
    907 {
    908     tLLCP_DLCB   *p_dlcb;
    909     tLLCP_STATUS status;
    910     tLLCP_APP_CB *p_app_cb;
    911 
    912     LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
    913 
    914     if (  (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
    915         &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)  )
    916     {
    917         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
    918         return LLCP_STATUS_FAIL;
    919     }
    920 
    921     p_app_cb = llcp_util_get_app_cb (reg_sap);
    922 
    923     /* if application is registered */
    924     if (  (p_app_cb == NULL)
    925         ||(p_app_cb->p_app_cback == NULL)  )
    926     {
    927         LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
    928         return LLCP_STATUS_FAIL;
    929     }
    930 
    931     if (dsap == LLCP_SAP_LM)
    932     {
    933         LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
    934         return LLCP_STATUS_FAIL;
    935     }
    936 
    937     if (dsap == LLCP_SAP_SDP)
    938     {
    939         if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
    940         {
    941             LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
    942                                strlen (p_params->sn));
    943             return LLCP_STATUS_FAIL;
    944         }
    945     }
    946 
    947     if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
    948     {
    949         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
    950         return LLCP_STATUS_FAIL;
    951     }
    952 
    953     /* check if any pending connection request on this reg_sap */
    954     p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
    955     if (p_dlcb)
    956     {
    957         /*
    958         ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
    959         ** if there is multiple pending connection request on the same local SAP.
    960         */
    961         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
    962         return LLCP_STATUS_FAIL;
    963     }
    964 
    965     p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
    966 
    967     if (p_dlcb)
    968     {
    969         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
    970         if (status != LLCP_STATUS_SUCCESS)
    971         {
    972             LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
    973             llcp_util_deallocate_data_link (p_dlcb);
    974             return LLCP_STATUS_FAIL;
    975         }
    976     }
    977     else
    978     {
    979         return LLCP_STATUS_FAIL;
    980     }
    981 
    982     return LLCP_STATUS_SUCCESS;
    983 }
    984 
    985 /*******************************************************************************
    986 **
    987 ** Function         LLCP_ConnectCfm
    988 **
    989 ** Description      Accept connection request from peer LLCP
    990 **
    991 **
    992 ** Returns          LLCP_STATUS_SUCCESS if success
    993 **                  LLCP_STATUS_FAIL, otherwise
    994 **
    995 *******************************************************************************/
    996 tLLCP_STATUS LLCP_ConnectCfm (UINT8                    local_sap,
    997                               UINT8                    remote_sap,
    998                               tLLCP_CONNECTION_PARAMS *p_params)
    999 {
   1000     tLLCP_STATUS  status;
   1001     tLLCP_DLCB   *p_dlcb;
   1002 
   1003     LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
   1004                      local_sap, remote_sap);
   1005 
   1006     if (!p_params)
   1007     {
   1008         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): tLLCP_CONNECTION_PARAMS must be provided");
   1009         return LLCP_STATUS_FAIL;
   1010     }
   1011     else if (p_params->miu > llcp_cb.lcb.local_link_miu)
   1012     {
   1013         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
   1014         return LLCP_STATUS_FAIL;
   1015     }
   1016 
   1017     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1018 
   1019     if (p_dlcb)
   1020     {
   1021         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
   1022     }
   1023     else
   1024     {
   1025         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
   1026         status = LLCP_STATUS_FAIL;
   1027     }
   1028 
   1029     return status;
   1030 }
   1031 
   1032 /*******************************************************************************
   1033 **
   1034 ** Function         LLCP_ConnectReject
   1035 **
   1036 ** Description      Reject connection request from peer LLCP
   1037 **
   1038 **                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
   1039 **                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
   1040 **                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
   1041 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
   1042 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
   1043 **
   1044 ** Returns          LLCP_STATUS_SUCCESS if success
   1045 **                  LLCP_STATUS_FAIL, otherwise
   1046 **
   1047 *******************************************************************************/
   1048 tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
   1049                                  UINT8 remote_sap,
   1050                                  UINT8 reason)
   1051 {
   1052     tLLCP_STATUS  status;
   1053     tLLCP_DLCB   *p_dlcb;
   1054 
   1055     LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
   1056                      local_sap, remote_sap, reason);
   1057 
   1058     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1059 
   1060     if (p_dlcb)
   1061     {
   1062         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
   1063         llcp_util_deallocate_data_link (p_dlcb);
   1064     }
   1065     else
   1066     {
   1067         LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
   1068         status = LLCP_STATUS_FAIL;
   1069     }
   1070 
   1071     return status;
   1072 }
   1073 
   1074 /*******************************************************************************
   1075 **
   1076 ** Function         LLCP_IsDataLinkCongested
   1077 **
   1078 ** Description      Check if data link connection is congested
   1079 **
   1080 **
   1081 ** Returns          TRUE if congested
   1082 **
   1083 *******************************************************************************/
   1084 BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
   1085                                   UINT8 remote_sap,
   1086                                   UINT8 num_pending_i_pdu,
   1087                                   UINT8 total_pending_ui_pdu,
   1088                                   UINT8 total_pending_i_pdu)
   1089 {
   1090     tLLCP_DLCB   *p_dlcb;
   1091 
   1092     LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
   1093                      local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
   1094 
   1095     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1096 
   1097     if (p_dlcb)
   1098     {
   1099         if (  (p_dlcb->is_tx_congested)
   1100             ||(p_dlcb->remote_busy)  )
   1101         {
   1102             return (TRUE);
   1103         }
   1104         else if (  (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
   1105                  ||(total_pending_ui_pdu + total_pending_i_pdu + llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff)  )
   1106         {
   1107             /* set flag so LLCP can notify uncongested status later */
   1108             p_dlcb->is_tx_congested = TRUE;
   1109             return (TRUE);
   1110         }
   1111         return (FALSE);
   1112     }
   1113     return (TRUE);
   1114 }
   1115 
   1116 /*******************************************************************************
   1117 **
   1118 ** Function         LLCP_SendData
   1119 **
   1120 ** Description      Send connection-oriented data
   1121 **
   1122 **
   1123 ** Returns          LLCP_STATUS_SUCCESS if success
   1124 **                  LLCP_STATUS_CONGESTED if data link is congested
   1125 **
   1126 *******************************************************************************/
   1127 tLLCP_STATUS LLCP_SendData (UINT8   local_sap,
   1128                             UINT8   remote_sap,
   1129                             BT_HDR *p_buf)
   1130 {
   1131     tLLCP_STATUS  status = LLCP_STATUS_FAIL;
   1132     tLLCP_DLCB   *p_dlcb;
   1133 
   1134     LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
   1135                      local_sap, remote_sap);
   1136 
   1137     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1138 
   1139     if (p_dlcb)
   1140     {
   1141         if (p_dlcb->remote_miu >= p_buf->len)
   1142         {
   1143             if (p_buf->offset >= LLCP_MIN_OFFSET)
   1144             {
   1145                 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
   1146             }
   1147             else
   1148             {
   1149                 LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
   1150                                     p_buf->offset, LLCP_MIN_OFFSET );
   1151             }
   1152         }
   1153         else
   1154         {
   1155             LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
   1156                                 p_buf->len, p_dlcb->remote_miu);
   1157         }
   1158     }
   1159     else
   1160     {
   1161         LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
   1162     }
   1163 
   1164     if (status == LLCP_STATUS_FAIL)
   1165     {
   1166         GKI_freebuf (p_buf);
   1167     }
   1168 
   1169     return status;
   1170 }
   1171 
   1172 /*******************************************************************************
   1173 **
   1174 ** Function         LLCP_ReadDataLinkData
   1175 **
   1176 ** Description      Read information of I PDU for data link connection
   1177 **
   1178 **                  - Information of I PDU up to max_data_len is copied into p_data.
   1179 **                  - Information of next I PDU is not concatenated.
   1180 **                  - Recommended max_data_len is data link connection MIU of local
   1181 **                    end point
   1182 **
   1183 ** Returns          TRUE if more data in queue
   1184 **
   1185 *******************************************************************************/
   1186 BOOLEAN LLCP_ReadDataLinkData (UINT8  local_sap,
   1187                                UINT8  remote_sap,
   1188                                UINT32 max_data_len,
   1189                                UINT32 *p_data_len,
   1190                                UINT8  *p_data)
   1191 {
   1192     tLLCP_DLCB *p_dlcb;
   1193     BT_HDR     *p_buf;
   1194     UINT8      *p_i_pdu;
   1195     UINT16     i_pdu_length;
   1196 
   1197     LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
   1198                       local_sap, remote_sap);
   1199 
   1200     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1201 
   1202     *p_data_len = 0;
   1203     if (p_dlcb)
   1204     {
   1205         /* if any I PDU in rx queue */
   1206         if (p_dlcb->i_rx_q.p_first)
   1207         {
   1208             p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
   1209             p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
   1210 
   1211             /* get length of I PDU */
   1212             BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
   1213 
   1214             /* layer_specific has the offset to read within I PDU */
   1215             p_i_pdu += p_buf->layer_specific;
   1216 
   1217             /* copy data up to max_data_len */
   1218             if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
   1219             {
   1220                 /* copy information */
   1221                 *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
   1222 
   1223                 /* move to next I PDU if any */
   1224                 p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next I PDU */
   1225                 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1226                 p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1227             }
   1228             else
   1229             {
   1230                 *p_data_len = max_data_len;
   1231 
   1232                 /* update offset to read from remaining I PDU next time */
   1233                 p_buf->layer_specific += max_data_len;
   1234             }
   1235 
   1236             memcpy (p_data, p_i_pdu, *p_data_len);
   1237 
   1238             if (p_buf->layer_specific == 0)
   1239             {
   1240                 p_dlcb->num_rx_i_pdu--;
   1241             }
   1242 
   1243             /* if read all of I PDU */
   1244             if (p_buf->len == 0)
   1245             {
   1246                 GKI_dequeue (&p_dlcb->i_rx_q);
   1247                 GKI_freebuf (p_buf);
   1248 
   1249                 /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
   1250                 llcp_cb.total_rx_i_pdu--;
   1251                 llcp_util_check_rx_congested_status ();
   1252             }
   1253         }
   1254 
   1255         /* if getting out of rx congestion */
   1256         if (  (!p_dlcb->local_busy)
   1257             &&(p_dlcb->is_rx_congested)
   1258             &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)  )
   1259         {
   1260             /* send RR */
   1261             p_dlcb->is_rx_congested = FALSE;
   1262             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1263         }
   1264 
   1265         /* if there is more I PDU in rx queue */
   1266         if (p_dlcb->i_rx_q.p_first)
   1267         {
   1268             return (TRUE);
   1269         }
   1270         else
   1271         {
   1272             return (FALSE);
   1273         }
   1274     }
   1275     else
   1276     {
   1277         LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
   1278 
   1279         return (FALSE);
   1280     }
   1281 }
   1282 
   1283 /*******************************************************************************
   1284 **
   1285 ** Function         LLCP_FlushDataLinkRxData
   1286 **
   1287 ** Description      Discard received data in data link connection
   1288 **
   1289 **
   1290 ** Returns          length of rx data flushed
   1291 **
   1292 *******************************************************************************/
   1293 UINT32 LLCP_FlushDataLinkRxData (UINT8  local_sap,
   1294                                  UINT8  remote_sap)
   1295 {
   1296     tLLCP_DLCB *p_dlcb;
   1297     BT_HDR     *p_buf;
   1298     UINT32     flushed_length = 0;
   1299     UINT8      *p_i_pdu;
   1300     UINT16     i_pdu_length;
   1301 
   1302     LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
   1303                       local_sap, remote_sap);
   1304 
   1305     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1306 
   1307     if (p_dlcb)
   1308     {
   1309         /* if any I PDU in rx queue */
   1310         while (p_dlcb->i_rx_q.p_first)
   1311         {
   1312             p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
   1313             p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
   1314 
   1315             /* get length of I PDU */
   1316             BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
   1317 
   1318             flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
   1319 
   1320             /* move to next I PDU if any */
   1321             p_buf->layer_specific = 0;  /* offset */
   1322             p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1323             p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1324 
   1325             /* if read all of I PDU */
   1326             if (p_buf->len == 0)
   1327             {
   1328                 GKI_dequeue (&p_dlcb->i_rx_q);
   1329                 GKI_freebuf (p_buf);
   1330                 llcp_cb.total_rx_i_pdu--;
   1331             }
   1332         }
   1333 
   1334         p_dlcb->num_rx_i_pdu = 0;
   1335 
   1336         /* if getting out of rx congestion */
   1337         if (  (!p_dlcb->local_busy)
   1338             &&(p_dlcb->is_rx_congested)  )
   1339         {
   1340             /* send RR */
   1341             p_dlcb->is_rx_congested = FALSE;
   1342             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1343         }
   1344 
   1345         /* number of received I PDU is decreased so check rx congestion status */
   1346         llcp_util_check_rx_congested_status ();
   1347     }
   1348     else
   1349     {
   1350         LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
   1351     }
   1352 
   1353     return (flushed_length);
   1354 }
   1355 
   1356 /*******************************************************************************
   1357 **
   1358 ** Function         LLCP_DisconnectReq
   1359 **
   1360 ** Description      Disconnect data link
   1361 **                  discard any pending data if flush is set to TRUE
   1362 **
   1363 ** Returns          LLCP_STATUS_SUCCESS if success
   1364 **
   1365 *******************************************************************************/
   1366 tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
   1367                                  UINT8 remote_sap,
   1368                                  BOOLEAN flush)
   1369 {
   1370     tLLCP_STATUS  status;
   1371     tLLCP_DLCB   *p_dlcb;
   1372 
   1373     LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
   1374                      local_sap, remote_sap, flush);
   1375 
   1376     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1377 
   1378     if (p_dlcb)
   1379     {
   1380         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1381     }
   1382     else
   1383     {
   1384         LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
   1385         status = LLCP_STATUS_FAIL;
   1386     }
   1387 
   1388     return status;
   1389 }
   1390 
   1391 /*******************************************************************************
   1392 **
   1393 ** Function         LLCP_SetTxCompleteNtf
   1394 **
   1395 ** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
   1396 **                  when Tx queue is empty and all PDU is acked.
   1397 **                  This is one time event, so upper layer shall call this function
   1398 **                  again to get next LLCP_SERVICE_TX_COMPLETE.
   1399 **
   1400 ** Returns          LLCP_STATUS_SUCCESS if success
   1401 **
   1402 *******************************************************************************/
   1403 tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8   local_sap,
   1404                                     UINT8   remote_sap)
   1405 {
   1406     tLLCP_STATUS  status;
   1407     tLLCP_DLCB   *p_dlcb;
   1408 
   1409     LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
   1410                       local_sap, remote_sap);
   1411 
   1412     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1413 
   1414     if (p_dlcb)
   1415     {
   1416         /* set flag to notify upper later when tx complete */
   1417         p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
   1418         status = LLCP_STATUS_SUCCESS;
   1419     }
   1420     else
   1421     {
   1422         LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
   1423         status = LLCP_STATUS_FAIL;
   1424     }
   1425 
   1426     return status;
   1427 }
   1428 
   1429 /*******************************************************************************
   1430 **
   1431 ** Function         LLCP_SetLocalBusyStatus
   1432 **
   1433 ** Description      Set local busy status
   1434 **
   1435 **
   1436 ** Returns          LLCP_STATUS_SUCCESS if success
   1437 **
   1438 *******************************************************************************/
   1439 tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8   local_sap,
   1440                                       UINT8   remote_sap,
   1441                                       BOOLEAN is_busy)
   1442 {
   1443     tLLCP_STATUS  status;
   1444     tLLCP_DLCB   *p_dlcb;
   1445 
   1446     LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
   1447                       local_sap, is_busy);
   1448 
   1449     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1450 
   1451     if (p_dlcb)
   1452     {
   1453         if (p_dlcb->local_busy != is_busy)
   1454         {
   1455             p_dlcb->local_busy = is_busy;
   1456 
   1457             /* send RR or RNR with valid sequence */
   1458             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1459 
   1460             if (is_busy == FALSE)
   1461             {
   1462                 if (p_dlcb->i_rx_q.count)
   1463                 {
   1464                     llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
   1465                 }
   1466             }
   1467         }
   1468         status = LLCP_STATUS_SUCCESS;
   1469     }
   1470     else
   1471     {
   1472         LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
   1473         status = LLCP_STATUS_FAIL;
   1474     }
   1475 
   1476     return status;
   1477 }
   1478 
   1479 /*******************************************************************************
   1480 **
   1481 ** Function         LLCP_GetRemoteWKS
   1482 **
   1483 ** Description      Return well-known service bitmap of connected device
   1484 **
   1485 **
   1486 ** Returns          WKS bitmap if success
   1487 **
   1488 *******************************************************************************/
   1489 UINT16 LLCP_GetRemoteWKS (void)
   1490 {
   1491     LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
   1492                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
   1493 
   1494     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1495         return (llcp_cb.lcb.peer_wks);
   1496     else
   1497         return (0);
   1498 }
   1499 
   1500 /*******************************************************************************
   1501 **
   1502 ** Function         LLCP_GetRemoteLSC
   1503 **
   1504 ** Description      Return link service class of connected device
   1505 **
   1506 **
   1507 ** Returns          link service class
   1508 **
   1509 *******************************************************************************/
   1510 UINT8 LLCP_GetRemoteLSC (void)
   1511 {
   1512     LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
   1513                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1514                      ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
   1515 
   1516     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1517         return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
   1518     else
   1519         return (LLCP_LSC_UNKNOWN);
   1520 }
   1521 
   1522 /*******************************************************************************
   1523 **
   1524 ** Function         LLCP_GetLinkMIU
   1525 **
   1526 ** Description      Return local and remote link MIU
   1527 **
   1528 **
   1529 ** Returns          None
   1530 **
   1531 *******************************************************************************/
   1532 LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
   1533                                UINT16 *p_remote_link_miu)
   1534 {
   1535     LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
   1536 
   1537     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1538     {
   1539         *p_local_link_miu  = llcp_cb.lcb.local_link_miu;
   1540         *p_remote_link_miu = llcp_cb.lcb.effective_miu;
   1541     }
   1542     else
   1543     {
   1544         *p_local_link_miu  = 0;
   1545         *p_remote_link_miu = 0;
   1546     }
   1547 
   1548     LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
   1549                        *p_local_link_miu, *p_remote_link_miu);
   1550 }
   1551 
   1552 /*******************************************************************************
   1553 **
   1554 ** Function         LLCP_DiscoverService
   1555 **
   1556 ** Description      Return SAP of service name in connected device through callback
   1557 **
   1558 **
   1559 ** Returns          LLCP_STATUS_SUCCESS if success
   1560 **
   1561 *******************************************************************************/
   1562 tLLCP_STATUS LLCP_DiscoverService (char            *p_name,
   1563                                    tLLCP_SDP_CBACK *p_cback,
   1564                                    UINT8           *p_tid)
   1565 {
   1566     tLLCP_STATUS  status;
   1567     UINT8         i;
   1568 
   1569     LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
   1570                       p_name);
   1571 
   1572     if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
   1573     {
   1574         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
   1575         return LLCP_STATUS_FAIL;
   1576     }
   1577 
   1578     if (!p_cback)
   1579     {
   1580         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
   1581         return LLCP_STATUS_FAIL;
   1582     }
   1583 
   1584     /* if peer version is less than V1.1 then SNL is not supported */
   1585     if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
   1586     {
   1587         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
   1588         return LLCP_STATUS_FAIL;
   1589     }
   1590 
   1591     for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
   1592     {
   1593         if (!llcp_cb.sdp_cb.transac[i].p_cback)
   1594         {
   1595             llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
   1596             llcp_cb.sdp_cb.next_tid++;
   1597             llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
   1598 
   1599             status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
   1600 
   1601             if (status == LLCP_STATUS_FAIL)
   1602             {
   1603                 llcp_cb.sdp_cb.transac[i].p_cback = NULL;
   1604             }
   1605 
   1606             *p_tid = llcp_cb.sdp_cb.transac[i].tid;
   1607             return (status);
   1608         }
   1609     }
   1610 
   1611     LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
   1612 
   1613     return LLCP_STATUS_FAIL;
   1614 }
   1615 
   1616