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