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