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