Home | History | Annotate | Download | only in llcp
      1 /******************************************************************************
      2  *
      3  *  Copyright (C) 2010-2014 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     tLLCP_CONNECTION_PARAMS params;
    912 
    913     LLCP_TRACE_API2 ("LLCP_ConnectReq () reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
    914 
    915     if (  (llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN)
    916         &&((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)  )
    917     {
    918         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Peer doesn't support connection-oriented link");
    919         return LLCP_STATUS_FAIL;
    920     }
    921 
    922     if (!p_params)
    923     {
    924         params.miu   = LLCP_DEFAULT_MIU;
    925         params.rw    = LLCP_DEFAULT_RW;
    926         params.sn[0] = 0;
    927         p_params     = &params;
    928     }
    929 
    930     p_app_cb = llcp_util_get_app_cb (reg_sap);
    931 
    932     /* if application is registered */
    933     if (  (p_app_cb == NULL)
    934         ||(p_app_cb->p_app_cback == NULL)  )
    935     {
    936         LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): SSAP (0x%x) is not registered", reg_sap);
    937         return LLCP_STATUS_FAIL;
    938     }
    939 
    940     if (dsap == LLCP_SAP_LM)
    941     {
    942         LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): DSAP (0x%x) must not be link manager SAP", dsap);
    943         return LLCP_STATUS_FAIL;
    944     }
    945 
    946     if (dsap == LLCP_SAP_SDP)
    947     {
    948         if (strlen (p_params->sn) > LLCP_MAX_SN_LEN)
    949         {
    950             LLCP_TRACE_ERROR1 ("LLCP_ConnectReq (): Service Name (%d bytes) is too long",
    951                                strlen (p_params->sn));
    952             return LLCP_STATUS_FAIL;
    953         }
    954     }
    955 
    956     if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu))
    957     {
    958         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Data link MIU shall not be bigger than local link MIU");
    959         return LLCP_STATUS_FAIL;
    960     }
    961 
    962     /* check if any pending connection request on this reg_sap */
    963     p_dlcb = llcp_dlc_find_dlcb_by_sap (reg_sap, LLCP_INVALID_SAP);
    964     if (p_dlcb)
    965     {
    966         /*
    967         ** Accepting LLCP may change SAP in CC, so we cannot find right data link connection
    968         ** if there is multiple pending connection request on the same local SAP.
    969         */
    970         LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): There is pending connect request on this reg_sap");
    971         return LLCP_STATUS_FAIL;
    972     }
    973 
    974     p_dlcb = llcp_util_allocate_data_link (reg_sap, dsap);
    975 
    976     if (p_dlcb)
    977     {
    978         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
    979         if (status != LLCP_STATUS_SUCCESS)
    980         {
    981             LLCP_TRACE_ERROR0 ("LLCP_ConnectReq (): Error in state machine");
    982             llcp_util_deallocate_data_link (p_dlcb);
    983             return LLCP_STATUS_FAIL;
    984         }
    985     }
    986     else
    987     {
    988         return LLCP_STATUS_FAIL;
    989     }
    990 
    991     return LLCP_STATUS_SUCCESS;
    992 }
    993 
    994 /*******************************************************************************
    995 **
    996 ** Function         LLCP_ConnectCfm
    997 **
    998 ** Description      Accept connection request from peer LLCP
    999 **
   1000 **
   1001 ** Returns          LLCP_STATUS_SUCCESS if success
   1002 **                  LLCP_STATUS_FAIL, otherwise
   1003 **
   1004 *******************************************************************************/
   1005 tLLCP_STATUS LLCP_ConnectCfm (UINT8                    local_sap,
   1006                               UINT8                    remote_sap,
   1007                               tLLCP_CONNECTION_PARAMS *p_params)
   1008 {
   1009     tLLCP_STATUS  status;
   1010     tLLCP_DLCB   *p_dlcb;
   1011     tLLCP_CONNECTION_PARAMS params;
   1012 
   1013     LLCP_TRACE_API2 ("LLCP_ConnectCfm () Local SAP:0x%x, Remote SAP:0x%x)",
   1014                      local_sap, remote_sap);
   1015 
   1016     if (!p_params)
   1017     {
   1018         params.miu   = LLCP_DEFAULT_MIU;
   1019         params.rw    = LLCP_DEFAULT_RW;
   1020         params.sn[0] = 0;
   1021         p_params     = &params;
   1022     }
   1023     if (p_params->miu > llcp_cb.lcb.local_link_miu)
   1024     {
   1025         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): Data link MIU shall not be bigger than local link MIU");
   1026         return LLCP_STATUS_FAIL;
   1027     }
   1028 
   1029     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1030 
   1031     if (p_dlcb)
   1032     {
   1033         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
   1034     }
   1035     else
   1036     {
   1037         LLCP_TRACE_ERROR0 ("LLCP_ConnectCfm (): No data link");
   1038         status = LLCP_STATUS_FAIL;
   1039     }
   1040 
   1041     return status;
   1042 }
   1043 
   1044 /*******************************************************************************
   1045 **
   1046 ** Function         LLCP_ConnectReject
   1047 **
   1048 ** Description      Reject connection request from peer LLCP
   1049 **
   1050 **                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
   1051 **                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
   1052 **                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
   1053 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
   1054 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
   1055 **
   1056 ** Returns          LLCP_STATUS_SUCCESS if success
   1057 **                  LLCP_STATUS_FAIL, otherwise
   1058 **
   1059 *******************************************************************************/
   1060 tLLCP_STATUS LLCP_ConnectReject (UINT8 local_sap,
   1061                                  UINT8 remote_sap,
   1062                                  UINT8 reason)
   1063 {
   1064     tLLCP_STATUS  status;
   1065     tLLCP_DLCB   *p_dlcb;
   1066 
   1067     LLCP_TRACE_API3 ("LLCP_ConnectReject () Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x",
   1068                      local_sap, remote_sap, reason);
   1069 
   1070     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1071 
   1072     if (p_dlcb)
   1073     {
   1074         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
   1075         llcp_util_deallocate_data_link (p_dlcb);
   1076     }
   1077     else
   1078     {
   1079         LLCP_TRACE_ERROR0 ("LLCP_ConnectReject (): No data link");
   1080         status = LLCP_STATUS_FAIL;
   1081     }
   1082 
   1083     return status;
   1084 }
   1085 
   1086 /*******************************************************************************
   1087 **
   1088 ** Function         LLCP_IsDataLinkCongested
   1089 **
   1090 ** Description      Check if data link connection is congested
   1091 **
   1092 **
   1093 ** Returns          TRUE if congested
   1094 **
   1095 *******************************************************************************/
   1096 BOOLEAN LLCP_IsDataLinkCongested (UINT8 local_sap,
   1097                                   UINT8 remote_sap,
   1098                                   UINT8 num_pending_i_pdu,
   1099                                   UINT8 total_pending_ui_pdu,
   1100                                   UINT8 total_pending_i_pdu)
   1101 {
   1102     tLLCP_DLCB   *p_dlcb;
   1103 
   1104     LLCP_TRACE_API5 ("LLCP_IsDataLinkCongested () Local SAP:0x%x, Remote SAP:0x%x, pending = (%d, %d, %d)",
   1105                      local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, total_pending_i_pdu);
   1106 
   1107     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1108 
   1109     if (p_dlcb)
   1110     {
   1111         if (  (p_dlcb->is_tx_congested)
   1112             ||(p_dlcb->remote_busy)  )
   1113         {
   1114             return (TRUE);
   1115         }
   1116         else if (  (num_pending_i_pdu + p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)
   1117                  ||(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)  )
   1118         {
   1119             /* set flag so LLCP can notify uncongested status later */
   1120             p_dlcb->is_tx_congested = TRUE;
   1121             return (TRUE);
   1122         }
   1123         return (FALSE);
   1124     }
   1125     return (TRUE);
   1126 }
   1127 
   1128 /*******************************************************************************
   1129 **
   1130 ** Function         LLCP_SendData
   1131 **
   1132 ** Description      Send connection-oriented data
   1133 **
   1134 **
   1135 ** Returns          LLCP_STATUS_SUCCESS if success
   1136 **                  LLCP_STATUS_CONGESTED if data link is congested
   1137 **
   1138 *******************************************************************************/
   1139 tLLCP_STATUS LLCP_SendData (UINT8   local_sap,
   1140                             UINT8   remote_sap,
   1141                             BT_HDR *p_buf)
   1142 {
   1143     tLLCP_STATUS  status = LLCP_STATUS_FAIL;
   1144     tLLCP_DLCB   *p_dlcb;
   1145 
   1146     LLCP_TRACE_API2 ("LLCP_SendData () Local SAP:0x%x, Remote SAP:0x%x",
   1147                      local_sap, remote_sap);
   1148 
   1149     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1150 
   1151     if (p_dlcb)
   1152     {
   1153         if (p_dlcb->remote_miu >= p_buf->len)
   1154         {
   1155             if (p_buf->offset >= LLCP_MIN_OFFSET)
   1156             {
   1157                 status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
   1158             }
   1159             else
   1160             {
   1161                 LLCP_TRACE_ERROR2 ("LLCP_SendData (): offset (%d) must be %d at least",
   1162                                     p_buf->offset, LLCP_MIN_OFFSET );
   1163             }
   1164         }
   1165         else
   1166         {
   1167             LLCP_TRACE_ERROR2 ("LLCP_SendData (): Information (%d bytes) cannot be more than peer MIU (%d bytes)",
   1168                                 p_buf->len, p_dlcb->remote_miu);
   1169         }
   1170     }
   1171     else
   1172     {
   1173         LLCP_TRACE_ERROR0 ("LLCP_SendData (): No data link");
   1174     }
   1175 
   1176     if (status == LLCP_STATUS_FAIL)
   1177     {
   1178         GKI_freebuf (p_buf);
   1179     }
   1180 
   1181     return status;
   1182 }
   1183 
   1184 /*******************************************************************************
   1185 **
   1186 ** Function         LLCP_ReadDataLinkData
   1187 **
   1188 ** Description      Read information of I PDU for data link connection
   1189 **
   1190 **                  - Information of I PDU up to max_data_len is copied into p_data.
   1191 **                  - Information of next I PDU is not concatenated.
   1192 **                  - Recommended max_data_len is data link connection MIU of local
   1193 **                    end point
   1194 **
   1195 ** Returns          TRUE if more data in queue
   1196 **
   1197 *******************************************************************************/
   1198 BOOLEAN LLCP_ReadDataLinkData (UINT8  local_sap,
   1199                                UINT8  remote_sap,
   1200                                UINT32 max_data_len,
   1201                                UINT32 *p_data_len,
   1202                                UINT8  *p_data)
   1203 {
   1204     tLLCP_DLCB *p_dlcb;
   1205     BT_HDR     *p_buf;
   1206     UINT8      *p_i_pdu;
   1207     UINT16     i_pdu_length;
   1208 
   1209     LLCP_TRACE_API2 ("LLCP_ReadDataLinkData () Local SAP:0x%x, Remote SAP:0x%x",
   1210                       local_sap, remote_sap);
   1211 
   1212     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1213 
   1214     *p_data_len = 0;
   1215     if (p_dlcb)
   1216     {
   1217         /* if any I PDU in rx queue */
   1218         if (p_dlcb->i_rx_q.p_first)
   1219         {
   1220             p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
   1221             p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
   1222 
   1223             /* get length of I PDU */
   1224             BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
   1225 
   1226             /* layer_specific has the offset to read within I PDU */
   1227             p_i_pdu += p_buf->layer_specific;
   1228 
   1229             /* copy data up to max_data_len */
   1230             if (max_data_len >= (UINT32) (i_pdu_length - p_buf->layer_specific))
   1231             {
   1232                 /* copy information */
   1233                 *p_data_len = (UINT32) (i_pdu_length - p_buf->layer_specific);
   1234 
   1235                 /* move to next I PDU if any */
   1236                 p_buf->layer_specific = 0;  /* reset offset to read from the first byte of next I PDU */
   1237                 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1238                 p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1239             }
   1240             else
   1241             {
   1242                 *p_data_len = max_data_len;
   1243 
   1244                 /* update offset to read from remaining I PDU next time */
   1245                 p_buf->layer_specific += max_data_len;
   1246             }
   1247 
   1248             memcpy (p_data, p_i_pdu, *p_data_len);
   1249 
   1250             if (p_buf->layer_specific == 0)
   1251             {
   1252                 p_dlcb->num_rx_i_pdu--;
   1253             }
   1254 
   1255             /* if read all of I PDU */
   1256             if (p_buf->len == 0)
   1257             {
   1258                 GKI_dequeue (&p_dlcb->i_rx_q);
   1259                 GKI_freebuf (p_buf);
   1260 
   1261                 /* decrease number of received I PDU in in all of ui_rx_q and check rx congestion status */
   1262                 llcp_cb.total_rx_i_pdu--;
   1263                 llcp_util_check_rx_congested_status ();
   1264             }
   1265         }
   1266 
   1267         /* if getting out of rx congestion */
   1268         if (  (!p_dlcb->local_busy)
   1269             &&(p_dlcb->is_rx_congested)
   1270             &&(p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)  )
   1271         {
   1272             /* send RR */
   1273             p_dlcb->is_rx_congested = FALSE;
   1274             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1275         }
   1276 
   1277         /* if there is more I PDU in rx queue */
   1278         if (p_dlcb->i_rx_q.p_first)
   1279         {
   1280             return (TRUE);
   1281         }
   1282         else
   1283         {
   1284             return (FALSE);
   1285         }
   1286     }
   1287     else
   1288     {
   1289         LLCP_TRACE_ERROR0 ("LLCP_ReadDataLinkData (): No data link connection");
   1290 
   1291         return (FALSE);
   1292     }
   1293 }
   1294 
   1295 /*******************************************************************************
   1296 **
   1297 ** Function         LLCP_FlushDataLinkRxData
   1298 **
   1299 ** Description      Discard received data in data link connection
   1300 **
   1301 **
   1302 ** Returns          length of rx data flushed
   1303 **
   1304 *******************************************************************************/
   1305 UINT32 LLCP_FlushDataLinkRxData (UINT8  local_sap,
   1306                                  UINT8  remote_sap)
   1307 {
   1308     tLLCP_DLCB *p_dlcb;
   1309     BT_HDR     *p_buf;
   1310     UINT32     flushed_length = 0;
   1311     UINT8      *p_i_pdu;
   1312     UINT16     i_pdu_length;
   1313 
   1314     LLCP_TRACE_API2 ("LLCP_FlushDataLinkRxData () Local SAP:0x%x, Remote SAP:0x%x",
   1315                       local_sap, remote_sap);
   1316 
   1317     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1318 
   1319     if (p_dlcb)
   1320     {
   1321         /* if any I PDU in rx queue */
   1322         while (p_dlcb->i_rx_q.p_first)
   1323         {
   1324             p_buf   = (BT_HDR *) p_dlcb->i_rx_q.p_first;
   1325             p_i_pdu = (UINT8*) (p_buf + 1) + p_buf->offset;
   1326 
   1327             /* get length of I PDU */
   1328             BE_STREAM_TO_UINT16 (i_pdu_length, p_i_pdu);
   1329 
   1330             flushed_length += (UINT32) (i_pdu_length - p_buf->layer_specific);
   1331 
   1332             /* move to next I PDU if any */
   1333             p_buf->layer_specific = 0;  /* offset */
   1334             p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1335             p_buf->len    -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
   1336 
   1337             /* if read all of I PDU */
   1338             if (p_buf->len == 0)
   1339             {
   1340                 GKI_dequeue (&p_dlcb->i_rx_q);
   1341                 GKI_freebuf (p_buf);
   1342                 llcp_cb.total_rx_i_pdu--;
   1343             }
   1344         }
   1345 
   1346         p_dlcb->num_rx_i_pdu = 0;
   1347 
   1348         /* if getting out of rx congestion */
   1349         if (  (!p_dlcb->local_busy)
   1350             &&(p_dlcb->is_rx_congested)  )
   1351         {
   1352             /* send RR */
   1353             p_dlcb->is_rx_congested = FALSE;
   1354             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1355         }
   1356 
   1357         /* number of received I PDU is decreased so check rx congestion status */
   1358         llcp_util_check_rx_congested_status ();
   1359     }
   1360     else
   1361     {
   1362         LLCP_TRACE_ERROR0 ("LLCP_FlushDataLinkRxData (): No data link connection");
   1363     }
   1364 
   1365     return (flushed_length);
   1366 }
   1367 
   1368 /*******************************************************************************
   1369 **
   1370 ** Function         LLCP_DisconnectReq
   1371 **
   1372 ** Description      Disconnect data link
   1373 **                  discard any pending data if flush is set to TRUE
   1374 **
   1375 ** Returns          LLCP_STATUS_SUCCESS if success
   1376 **
   1377 *******************************************************************************/
   1378 tLLCP_STATUS LLCP_DisconnectReq (UINT8 local_sap,
   1379                                  UINT8 remote_sap,
   1380                                  BOOLEAN flush)
   1381 {
   1382     tLLCP_STATUS  status;
   1383     tLLCP_DLCB   *p_dlcb;
   1384 
   1385     LLCP_TRACE_API3 ("LLCP_DisconnectReq () Local SAP:0x%x, Remote SAP:0x%x, flush=%d",
   1386                      local_sap, remote_sap, flush);
   1387 
   1388     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1389 
   1390     if (p_dlcb)
   1391     {
   1392         status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
   1393     }
   1394     else
   1395     {
   1396         LLCP_TRACE_ERROR0 ("LLCP_DisconnectReq (): No data link");
   1397         status = LLCP_STATUS_FAIL;
   1398     }
   1399 
   1400     return status;
   1401 }
   1402 
   1403 /*******************************************************************************
   1404 **
   1405 ** Function         LLCP_SetTxCompleteNtf
   1406 **
   1407 ** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
   1408 **                  when Tx queue is empty and all PDU is acked.
   1409 **                  This is one time event, so upper layer shall call this function
   1410 **                  again to get next LLCP_SERVICE_TX_COMPLETE.
   1411 **
   1412 ** Returns          LLCP_STATUS_SUCCESS if success
   1413 **
   1414 *******************************************************************************/
   1415 tLLCP_STATUS LLCP_SetTxCompleteNtf (UINT8   local_sap,
   1416                                     UINT8   remote_sap)
   1417 {
   1418     tLLCP_STATUS  status;
   1419     tLLCP_DLCB   *p_dlcb;
   1420 
   1421     LLCP_TRACE_API2 ("LLCP_SetTxCompleteNtf () Local SAP:0x%x, Remote SAP:0x%x",
   1422                       local_sap, remote_sap);
   1423 
   1424     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1425 
   1426     if (p_dlcb)
   1427     {
   1428         /* set flag to notify upper later when tx complete */
   1429         p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
   1430         status = LLCP_STATUS_SUCCESS;
   1431     }
   1432     else
   1433     {
   1434         LLCP_TRACE_ERROR0 ("LLCP_SetTxCompleteNtf (): No data link");
   1435         status = LLCP_STATUS_FAIL;
   1436     }
   1437 
   1438     return status;
   1439 }
   1440 
   1441 /*******************************************************************************
   1442 **
   1443 ** Function         LLCP_SetLocalBusyStatus
   1444 **
   1445 ** Description      Set local busy status
   1446 **
   1447 **
   1448 ** Returns          LLCP_STATUS_SUCCESS if success
   1449 **
   1450 *******************************************************************************/
   1451 tLLCP_STATUS LLCP_SetLocalBusyStatus (UINT8   local_sap,
   1452                                       UINT8   remote_sap,
   1453                                       BOOLEAN is_busy)
   1454 {
   1455     tLLCP_STATUS  status;
   1456     tLLCP_DLCB   *p_dlcb;
   1457 
   1458     LLCP_TRACE_API2 ("LLCP_SetLocalBusyStatus () Local SAP:0x%x, is_busy=%d",
   1459                       local_sap, is_busy);
   1460 
   1461     p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap);
   1462 
   1463     if (p_dlcb)
   1464     {
   1465         if (p_dlcb->local_busy != is_busy)
   1466         {
   1467             p_dlcb->local_busy = is_busy;
   1468 
   1469             /* send RR or RNR with valid sequence */
   1470             p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
   1471 
   1472             if (is_busy == FALSE)
   1473             {
   1474                 if (p_dlcb->i_rx_q.count)
   1475                 {
   1476                     llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
   1477                 }
   1478             }
   1479         }
   1480         status = LLCP_STATUS_SUCCESS;
   1481     }
   1482     else
   1483     {
   1484         LLCP_TRACE_ERROR0 ("LLCP_SetLocalBusyStatus (): No data link");
   1485         status = LLCP_STATUS_FAIL;
   1486     }
   1487 
   1488     return status;
   1489 }
   1490 
   1491 /*******************************************************************************
   1492 **
   1493 ** Function         LLCP_GetRemoteWKS
   1494 **
   1495 ** Description      Return well-known service bitmap of connected device
   1496 **
   1497 **
   1498 ** Returns          WKS bitmap if success
   1499 **
   1500 *******************************************************************************/
   1501 UINT16 LLCP_GetRemoteWKS (void)
   1502 {
   1503     LLCP_TRACE_API1 ("LLCP_GetRemoteWKS () WKS:0x%04x",
   1504                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) ? llcp_cb.lcb.peer_wks :0);
   1505 
   1506     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1507         return (llcp_cb.lcb.peer_wks);
   1508     else
   1509         return (0);
   1510 }
   1511 
   1512 /*******************************************************************************
   1513 **
   1514 ** Function         LLCP_GetRemoteLSC
   1515 **
   1516 ** Description      Return link service class of connected device
   1517 **
   1518 **
   1519 ** Returns          link service class
   1520 **
   1521 *******************************************************************************/
   1522 UINT8 LLCP_GetRemoteLSC (void)
   1523 {
   1524     LLCP_TRACE_API1 ("LLCP_GetRemoteLSC () LSC:0x%x",
   1525                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1526                      ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) :0);
   1527 
   1528     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1529         return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
   1530     else
   1531         return (LLCP_LSC_UNKNOWN);
   1532 }
   1533 
   1534 /*******************************************************************************
   1535 **
   1536 ** Function         LLCP_GetRemoteVersion
   1537 **
   1538 ** Description      Return LLCP version of connected device
   1539 **
   1540 **
   1541 ** Returns          LLCP version
   1542 **
   1543 *******************************************************************************/
   1544 UINT8 LLCP_GetRemoteVersion (void)
   1545 {
   1546     LLCP_TRACE_API1 ("LLCP_GetRemoteVersion () Version: 0x%x",
   1547                      (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1548                      ? llcp_cb.lcb.peer_version : 0);
   1549 
   1550     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1551         return (llcp_cb.lcb.peer_version);
   1552     else
   1553         return 0;
   1554 }
   1555 
   1556 /*******************************************************************************
   1557 **
   1558 ** Function         LLCP_GetLinkMIU
   1559 **
   1560 ** Description      Return local and remote link MIU
   1561 **
   1562 **
   1563 ** Returns          None
   1564 **
   1565 *******************************************************************************/
   1566 LLCP_API void LLCP_GetLinkMIU (UINT16 *p_local_link_miu,
   1567                                UINT16 *p_remote_link_miu)
   1568 {
   1569     LLCP_TRACE_API0 ("LLCP_GetLinkMIU ()");
   1570 
   1571     if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
   1572     {
   1573         *p_local_link_miu  = llcp_cb.lcb.local_link_miu;
   1574         *p_remote_link_miu = llcp_cb.lcb.effective_miu;
   1575     }
   1576     else
   1577     {
   1578         *p_local_link_miu  = 0;
   1579         *p_remote_link_miu = 0;
   1580     }
   1581 
   1582     LLCP_TRACE_DEBUG2 ("LLCP_GetLinkMIU (): local_link_miu = %d, remote_link_miu = %d",
   1583                        *p_local_link_miu, *p_remote_link_miu);
   1584 }
   1585 
   1586 /*******************************************************************************
   1587 **
   1588 ** Function         LLCP_DiscoverService
   1589 **
   1590 ** Description      Return SAP of service name in connected device through callback
   1591 **
   1592 **
   1593 ** Returns          LLCP_STATUS_SUCCESS if success
   1594 **
   1595 *******************************************************************************/
   1596 tLLCP_STATUS LLCP_DiscoverService (char            *p_name,
   1597                                    tLLCP_SDP_CBACK *p_cback,
   1598                                    UINT8           *p_tid)
   1599 {
   1600     tLLCP_STATUS  status;
   1601     UINT8         i;
   1602 
   1603     LLCP_TRACE_API1 ("LLCP_DiscoverService () Service Name:%s",
   1604                       p_name);
   1605 
   1606     if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED)
   1607     {
   1608         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Link is not activated");
   1609         return LLCP_STATUS_FAIL;
   1610     }
   1611 
   1612     if (!p_cback)
   1613     {
   1614         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Callback must be provided.");
   1615         return LLCP_STATUS_FAIL;
   1616     }
   1617 
   1618     /* if peer version is less than V1.1 then SNL is not supported */
   1619     if ((llcp_cb.lcb.agreed_major_version == 0x01) && (llcp_cb.lcb.agreed_minor_version < 0x01))
   1620     {
   1621         LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Peer doesn't support SNL");
   1622         return LLCP_STATUS_FAIL;
   1623     }
   1624 
   1625     for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++)
   1626     {
   1627         if (!llcp_cb.sdp_cb.transac[i].p_cback)
   1628         {
   1629             llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
   1630             llcp_cb.sdp_cb.next_tid++;
   1631             llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
   1632 
   1633             status = llcp_sdp_send_sdreq (llcp_cb.sdp_cb.transac[i].tid, p_name);
   1634 
   1635             if (status == LLCP_STATUS_FAIL)
   1636             {
   1637                 llcp_cb.sdp_cb.transac[i].p_cback = NULL;
   1638             }
   1639 
   1640             *p_tid = llcp_cb.sdp_cb.transac[i].tid;
   1641             return (status);
   1642         }
   1643     }
   1644 
   1645     LLCP_TRACE_ERROR0 ("LLCP_DiscoverService (): Out of resource");
   1646 
   1647     return LLCP_STATUS_FAIL;
   1648 }
   1649 
   1650