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