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