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