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 
32 using android::base::StringPrintf;
33 
34 extern bool nfc_debug_enabled;
35 
36 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
37 
38 tLLCP_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 *******************************************************************************/
LLCP_SetTestParams(uint8_t version,uint16_t wks)52 void 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 *******************************************************************************/
LLCP_RegisterDtaCback(tLLCP_DTA_CBACK * p_dta_cback)72 void 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 *******************************************************************************/
LLCP_SetConfig(uint16_t link_miu,uint8_t opt,uint8_t wt,uint16_t link_timeout,uint16_t inact_timeout_init,uint16_t inact_timeout_target,uint16_t symm_delay,uint16_t data_link_timeout,uint16_t delay_first_pdu_timeout)96 void 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 *******************************************************************************/
LLCP_GetConfig(uint16_t * p_link_miu,uint8_t * p_opt,uint8_t * p_wt,uint16_t * p_link_timeout,uint16_t * p_inact_timeout_init,uint16_t * p_inact_timeout_target,uint16_t * p_symm_delay,uint16_t * p_data_link_timeout,uint16_t * p_delay_first_pdu_timeout)176 void 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 *******************************************************************************/
LLCP_GetDiscoveryConfig(uint8_t * p_wt,uint8_t * p_gen_bytes,uint8_t * p_gen_bytes_len)227 void 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 *******************************************************************************/
LLCP_ActivateLink(tLLCP_ACTIVATE_CONFIG config,tLLCP_LINK_CBACK * p_link_cback)304 tLLCP_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 *******************************************************************************/
LLCP_DeactivateLink(void)330 tLLCP_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 *******************************************************************************/
LLCP_RegisterServer(uint8_t reg_sap,uint8_t link_type,std::string p_service_name,tLLCP_APP_CBACK * p_app_cback)360 uint8_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 
366   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
367       "SAP:0x%x, link_type:0x%x, ServiceName:<%s>", reg_sap, link_type,
368       ((p_service_name.empty()) ? "" : p_service_name.c_str()));
369 
370   if (!p_app_cback) {
371     LOG(ERROR) << StringPrintf("Callback must be provided");
372     return LLCP_INVALID_SAP;
373   } else if (((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00) &&
374              ((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)) {
375     LOG(ERROR) << StringPrintf("link type (0x%x) must be specified", link_type);
376     return LLCP_INVALID_SAP;
377   }
378 
379   if (reg_sap == LLCP_INVALID_SAP) {
380     /* allocate a SAP between 0x10 and 0x1F */
381     for (sap = 0; sap < LLCP_MAX_SERVER; sap++) {
382       if (llcp_cb.server_cb[sap].p_app_cback == nullptr) {
383         reg_sap = LLCP_LOWER_BOUND_SDP_SAP + sap;
384         break;
385       }
386     }
387 
388     if (reg_sap == LLCP_INVALID_SAP) {
389       LOG(ERROR) << StringPrintf("out of resource");
390       return LLCP_INVALID_SAP;
391     }
392   } else if (reg_sap == LLCP_SAP_LM) {
393     LOG(ERROR) << StringPrintf("SAP (0x%x) is for link manager", reg_sap);
394     return LLCP_INVALID_SAP;
395   } else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP) {
396     if (reg_sap >= LLCP_MAX_WKS) {
397       LOG(ERROR) << StringPrintf("out of resource for SAP (0x%x)", reg_sap);
398       return LLCP_INVALID_SAP;
399     } else if (llcp_cb.wks_cb[reg_sap].p_app_cback) {
400       LOG(ERROR) << StringPrintf("SAP (0x%x) is already registered", reg_sap);
401       return LLCP_INVALID_SAP;
402     }
403   } else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP) {
404     if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER) {
405       LOG(ERROR) << StringPrintf("out of resource for SAP (0x%x)", reg_sap);
406       return LLCP_INVALID_SAP;
407     } else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP]
408                    .p_app_cback) {
409       LOG(ERROR) << StringPrintf("SAP (0x%x) is already registered", reg_sap);
410       return LLCP_INVALID_SAP;
411     }
412   } else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP) {
413     LOG(ERROR) << StringPrintf("SAP (0x%x) must be less than 0x%x", reg_sap,
414                                LLCP_LOWER_BOUND_LOCAL_SAP);
415     return LLCP_INVALID_SAP;
416   }
417 
418   if (!p_service_name.empty()) {
419     length = p_service_name.length();
420     if (length > LLCP_MAX_SN_LEN) {
421       LOG(ERROR) << StringPrintf("Service Name (%d bytes) is too long", length);
422       return LLCP_INVALID_SAP;
423     }
424   }
425 
426   if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP) {
427     llcp_cb.lcb.wks |= (1 << reg_sap);
428   }
429 
430   DLOG_IF(INFO, nfc_debug_enabled)
431       << StringPrintf("Registered SAP = 0x%02X", reg_sap);
432 
433   if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) {
434     llcp_cb.num_logical_data_link++;
435     llcp_util_adjust_ll_congestion();
436   }
437 
438   return reg_sap;
439 }
440 
441 /*******************************************************************************
442 **
443 ** Function         LLCP_RegisterClient
444 **
445 ** Description      Register client and callback function
446 **
447 **                  link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK
448 **                              and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION
449 **
450 ** Returns          SAP between 0x20 and 0x3F, if success
451 **                  LLCP_INVALID_SAP, otherwise
452 **
453 *******************************************************************************/
LLCP_RegisterClient(uint8_t link_type,tLLCP_APP_CBACK * p_app_cback)454 uint8_t LLCP_RegisterClient(uint8_t link_type, tLLCP_APP_CBACK* p_app_cback) {
455   uint8_t reg_sap = LLCP_INVALID_SAP;
456   uint8_t sap;
457   tLLCP_APP_CB* p_app_cb;
458 
459   DLOG_IF(INFO, nfc_debug_enabled)
460       << StringPrintf("link_type = 0x%x", link_type);
461 
462   if (!p_app_cback) {
463     LOG(ERROR) << StringPrintf("Callback must be provided");
464     return LLCP_INVALID_SAP;
465   } else if (((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00) &&
466              ((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)) {
467     LOG(ERROR) << StringPrintf("link type (0x%x) must be specified", link_type);
468     return LLCP_INVALID_SAP;
469   }
470 
471   /* allocate a SAP between 0x20 and 0x3F */
472   for (sap = 0; sap < LLCP_MAX_CLIENT; sap++) {
473     if (llcp_cb.client_cb[sap].p_app_cback == nullptr) {
474       p_app_cb = &llcp_cb.client_cb[sap];
475       memset(p_app_cb, 0x00, sizeof(tLLCP_APP_CB));
476       reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap;
477       break;
478     }
479   }
480 
481   if (reg_sap == LLCP_INVALID_SAP) {
482     LOG(ERROR) << StringPrintf("out of resource");
483     return LLCP_INVALID_SAP;
484   }
485 
486   p_app_cb->p_app_cback = p_app_cback;
487   p_app_cb->p_service_name = nullptr;
488   p_app_cb->link_type = link_type;
489 
490   DLOG_IF(INFO, nfc_debug_enabled)
491       << StringPrintf("Registered SAP = 0x%02X", reg_sap);
492 
493   if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) {
494     llcp_cb.num_logical_data_link++;
495     llcp_util_adjust_ll_congestion();
496   }
497 
498   return reg_sap;
499 }
500 
501 /*******************************************************************************
502 **
503 ** Function         LLCP_Deregister
504 **
505 ** Description      Deregister server or client
506 **
507 **
508 ** Returns          LLCP_STATUS_SUCCESS if success
509 **
510 *******************************************************************************/
LLCP_Deregister(uint8_t local_sap)511 tLLCP_STATUS LLCP_Deregister(uint8_t local_sap) {
512   uint8_t idx;
513   tLLCP_APP_CB* p_app_cb;
514 
515   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("SAP:0x%x", local_sap);
516 
517   p_app_cb = llcp_util_get_app_cb(local_sap);
518 
519   if ((!p_app_cb) || (p_app_cb->p_app_cback == nullptr)) {
520     LOG(ERROR) << StringPrintf("SAP (0x%x) is not registered", local_sap);
521     return LLCP_STATUS_FAIL;
522   }
523 
524   if (p_app_cb->p_service_name) GKI_freebuf(p_app_cb->p_service_name);
525 
526   /* update WKS bit map */
527   if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) {
528     llcp_cb.lcb.wks &= ~(1 << local_sap);
529   }
530 
531   /* discard any received UI PDU on this SAP */
532   LLCP_FlushLogicalLinkRxData(local_sap);
533   llcp_cb.total_rx_ui_pdu = 0;
534 
535   /* deallocate any data link connection on this SAP */
536   for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
537     if ((llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) &&
538         (llcp_cb.dlcb[idx].local_sap == local_sap)) {
539       llcp_util_deallocate_data_link(&llcp_cb.dlcb[idx]);
540     }
541   }
542 
543   p_app_cb->p_app_cback = nullptr;
544 
545   /* discard any pending tx UI PDU from this SAP */
546   while (p_app_cb->ui_xmit_q.p_first) {
547     GKI_freebuf(GKI_dequeue(&p_app_cb->ui_xmit_q));
548     llcp_cb.total_tx_ui_pdu--;
549   }
550 
551   if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) {
552     llcp_cb.num_logical_data_link--;
553     llcp_util_adjust_ll_congestion();
554   }
555 
556   /* check rx congestion status */
557   llcp_util_check_rx_congested_status();
558 
559   return LLCP_STATUS_SUCCESS;
560 }
561 
562 /*******************************************************************************
563 **
564 ** Function         LLCP_IsLogicalLinkCongested
565 **
566 ** Description      Check if logical link is congested
567 **
568 **
569 ** Returns          TRUE if congested
570 **
571 *******************************************************************************/
LLCP_IsLogicalLinkCongested(uint8_t local_sap,uint8_t num_pending_ui_pdu,uint8_t total_pending_ui_pdu,uint8_t total_pending_i_pdu)572 bool LLCP_IsLogicalLinkCongested(uint8_t local_sap, uint8_t num_pending_ui_pdu,
573                                  uint8_t total_pending_ui_pdu,
574                                  uint8_t total_pending_i_pdu) {
575   tLLCP_APP_CB* p_app_cb;
576 
577   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
578       "Local SAP:0x%x, pending = (%d, %d, %d)", local_sap, num_pending_ui_pdu,
579       total_pending_ui_pdu, total_pending_i_pdu);
580 
581   p_app_cb = llcp_util_get_app_cb(local_sap);
582 
583   if ((llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) ||
584       (p_app_cb == nullptr) || (p_app_cb->p_app_cback == nullptr) ||
585       ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0) ||
586       (p_app_cb->is_ui_tx_congested)) {
587     return true;
588   } else if ((num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >=
589               llcp_cb.ll_tx_congest_start) ||
590              (total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >=
591               llcp_cb.max_num_ll_tx_buff) ||
592              (total_pending_ui_pdu + total_pending_i_pdu +
593                   llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
594               llcp_cb.max_num_tx_buff)) {
595     /* set flag so LLCP can notify uncongested status later */
596     p_app_cb->is_ui_tx_congested = true;
597 
598     return true;
599   }
600   return false;
601 }
602 
603 /*******************************************************************************
604 **
605 ** Function         LLCP_SendUI
606 **
607 ** Description      Send connnectionless data to DSAP
608 **
609 **
610 ** Returns          LLCP_STATUS_SUCCESS if success
611 **                  LLCP_STATUS_CONGESTED if logical link is congested
612 **                  LLCP_STATUS_FAIL, otherwise
613 **
614 *******************************************************************************/
LLCP_SendUI(uint8_t ssap,uint8_t dsap,NFC_HDR * p_buf)615 tLLCP_STATUS LLCP_SendUI(uint8_t ssap, uint8_t dsap, NFC_HDR* p_buf) {
616   tLLCP_STATUS status = LLCP_STATUS_FAIL;
617   tLLCP_APP_CB* p_app_cb;
618 
619   DLOG_IF(INFO, nfc_debug_enabled)
620       << StringPrintf("SSAP=0x%x, DSAP=0x%x", ssap, dsap);
621 
622   p_app_cb = llcp_util_get_app_cb(ssap);
623 
624   if ((p_app_cb == nullptr) || (p_app_cb->p_app_cback == nullptr)) {
625     LOG(ERROR) << StringPrintf("SSAP (0x%x) is not registered", ssap);
626   } else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0) {
627     LOG(ERROR) << StringPrintf("Logical link on SSAP (0x%x) is not enabled",
628                                ssap);
629   } else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) {
630     LOG(ERROR) << StringPrintf("LLCP link is not activated");
631   } else if ((llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN) ||
632              (llcp_cb.lcb.peer_opt & LLCP_LSC_1)) {
633     if (p_buf->len <= llcp_cb.lcb.peer_miu) {
634       if (p_buf->offset >= LLCP_MIN_OFFSET) {
635         status = llcp_util_send_ui(ssap, dsap, p_app_cb, p_buf);
636       } else {
637         LOG(ERROR) << StringPrintf("offset (%d) must be %d at least",
638                                    p_buf->offset, LLCP_MIN_OFFSET);
639       }
640     } else {
641       LOG(ERROR) << StringPrintf(
642           "Data length shall not be bigger than peer's link "
643           "MIU");
644     }
645   } else {
646     LOG(ERROR) << StringPrintf("Peer doesn't support connectionless link");
647   }
648 
649   if (status == LLCP_STATUS_FAIL) {
650     GKI_freebuf(p_buf);
651   }
652 
653   return status;
654 }
655 
656 /*******************************************************************************
657 **
658 ** Function         LLCP_ReadLogicalLinkData
659 **
660 ** Description      Read information of UI PDU for local SAP
661 **
662 **                  - Remote SAP who sent UI PDU is returned.
663 **                  - Information of UI PDU up to max_data_len is copied into
664 **                    p_data.
665 **                  - Information of next UI PDU is not concatenated.
666 **                  - Recommended max_data_len is link MIU of local device
667 **
668 ** Returns          TRUE if more information of UI PDU or more UI PDU in queue
669 **
670 *******************************************************************************/
LLCP_ReadLogicalLinkData(uint8_t local_sap,uint32_t max_data_len,uint8_t * p_remote_sap,uint32_t * p_data_len,uint8_t * p_data)671 bool LLCP_ReadLogicalLinkData(uint8_t local_sap, uint32_t max_data_len,
672                               uint8_t* p_remote_sap, uint32_t* p_data_len,
673                               uint8_t* p_data) {
674   tLLCP_APP_CB* p_app_cb;
675   NFC_HDR* p_buf;
676   uint8_t* p_ui_pdu;
677   uint16_t pdu_hdr, ui_pdu_length;
678 
679   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Local SAP:0x%x", local_sap);
680 
681   *p_data_len = 0;
682 
683   p_app_cb = llcp_util_get_app_cb(local_sap);
684 
685   /* if application is registered */
686   if ((p_app_cb) && (p_app_cb->p_app_cback)) {
687     /* if any UI PDU in rx queue */
688     if (p_app_cb->ui_rx_q.p_first) {
689       p_buf = (NFC_HDR*)p_app_cb->ui_rx_q.p_first;
690       p_ui_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
691 
692       /* get length of UI PDU */
693       BE_STREAM_TO_UINT16(ui_pdu_length, p_ui_pdu);
694 
695       /* get remote SAP from LLCP header */
696       BE_STREAM_TO_UINT16(pdu_hdr, p_ui_pdu);
697       *p_remote_sap = LLCP_GET_SSAP(pdu_hdr);
698 
699       /* layer_specific has the offset to read within UI PDU */
700       p_ui_pdu += p_buf->layer_specific;
701 
702       /* copy data up to max_data_len */
703       if (max_data_len >= (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE -
704                                      p_buf->layer_specific)) {
705         /* copy information without LLCP header */
706         *p_data_len = (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE -
707                                  p_buf->layer_specific);
708 
709         /* move to next UI PDU if any */
710         p_buf->layer_specific =
711             0; /* reset offset to read from the first byte of next UI PDU */
712         p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
713         p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
714       } else {
715         *p_data_len = max_data_len;
716 
717         /* update offset to read from remaining UI PDU next time */
718         p_buf->layer_specific += max_data_len;
719       }
720 
721       memcpy(p_data, p_ui_pdu, *p_data_len);
722 
723       /* if read all of UI PDU */
724       if (p_buf->len == 0) {
725         GKI_dequeue(&p_app_cb->ui_rx_q);
726         GKI_freebuf(p_buf);
727 
728         /* decrease number of received UI PDU in in all of ui_rx_q and check rx
729          * congestion status */
730         llcp_cb.total_rx_ui_pdu--;
731         llcp_util_check_rx_congested_status();
732       }
733     }
734 
735     /* if there is more UI PDU in rx queue */
736     if (p_app_cb->ui_rx_q.p_first) {
737       return true;
738     } else {
739       return false;
740     }
741   } else {
742     LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", local_sap);
743 
744     return false;
745   }
746 }
747 
748 /*******************************************************************************
749 **
750 ** Function         LLCP_FlushLogicalLinkRxData
751 **
752 ** Description      Discard received data in logical data link of local SAP
753 **
754 **
755 ** Returns          length of data flushed
756 **
757 *******************************************************************************/
LLCP_FlushLogicalLinkRxData(uint8_t local_sap)758 uint32_t LLCP_FlushLogicalLinkRxData(uint8_t local_sap) {
759   NFC_HDR* p_buf;
760   uint32_t flushed_length = 0;
761   tLLCP_APP_CB* p_app_cb;
762   uint8_t* p_ui_pdu;
763   uint16_t ui_pdu_length;
764 
765   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Local SAP:0x%x", local_sap);
766 
767   p_app_cb = llcp_util_get_app_cb(local_sap);
768 
769   /* if application is registered */
770   if ((p_app_cb) && (p_app_cb->p_app_cback)) {
771     /* if any UI PDU in rx queue */
772     while (p_app_cb->ui_rx_q.p_first) {
773       p_buf = (NFC_HDR*)p_app_cb->ui_rx_q.p_first;
774       p_ui_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
775 
776       /* get length of UI PDU */
777       BE_STREAM_TO_UINT16(ui_pdu_length, p_ui_pdu);
778 
779       flushed_length += (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE -
780                                    p_buf->layer_specific);
781 
782       /* move to next UI PDU if any */
783       p_buf->layer_specific = 0; /* offset */
784       p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
785       p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
786 
787       /* if read all of UI PDU */
788       if (p_buf->len == 0) {
789         GKI_dequeue(&p_app_cb->ui_rx_q);
790         GKI_freebuf(p_buf);
791         llcp_cb.total_rx_ui_pdu--;
792       }
793     }
794 
795     /* number of received UI PDU is decreased so check rx congestion status */
796     llcp_util_check_rx_congested_status();
797   } else {
798     LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", local_sap);
799   }
800 
801   return (flushed_length);
802 }
803 
804 /*******************************************************************************
805 **
806 ** Function         LLCP_ConnectReq
807 **
808 ** Description      Create data link connection between registered SAP and DSAP
809 **                  in peer LLCP,
810 **
811 **
812 ** Returns          LLCP_STATUS_SUCCESS if success
813 **                  LLCP_STATUS_FAIL, otherwise
814 **
815 *******************************************************************************/
LLCP_ConnectReq(uint8_t reg_sap,uint8_t dsap,tLLCP_CONNECTION_PARAMS * p_params)816 tLLCP_STATUS LLCP_ConnectReq(uint8_t reg_sap, uint8_t dsap,
817                              tLLCP_CONNECTION_PARAMS* p_params) {
818   tLLCP_DLCB* p_dlcb;
819   tLLCP_STATUS status;
820   tLLCP_APP_CB* p_app_cb;
821   tLLCP_CONNECTION_PARAMS params;
822 
823   DLOG_IF(INFO, nfc_debug_enabled)
824       << StringPrintf("reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap);
825 
826   if ((llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN) &&
827       ((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)) {
828     LOG(ERROR) << StringPrintf("Peer doesn't support connection-oriented link");
829     return LLCP_STATUS_FAIL;
830   }
831 
832   if (!p_params) {
833     params.miu = LLCP_DEFAULT_MIU;
834     params.rw = LLCP_DEFAULT_RW;
835     params.sn[0] = 0;
836     p_params = ¶ms;
837   }
838 
839   p_app_cb = llcp_util_get_app_cb(reg_sap);
840 
841   /* if application is registered */
842   if ((p_app_cb == nullptr) || (p_app_cb->p_app_cback == nullptr)) {
843     LOG(ERROR) << StringPrintf("SSAP (0x%x) is not registered", reg_sap);
844     return LLCP_STATUS_FAIL;
845   }
846 
847   if (dsap == LLCP_SAP_LM) {
848     LOG(ERROR) << StringPrintf("DSAP (0x%x) must not be link manager SAP",
849                                dsap);
850     return LLCP_STATUS_FAIL;
851   }
852 
853   if (dsap == LLCP_SAP_SDP) {
854     if (strlen(p_params->sn) > LLCP_MAX_SN_LEN) {
855       LOG(ERROR) << StringPrintf("Service Name (%zu bytes) is too long",
856                                  strlen(p_params->sn));
857       return LLCP_STATUS_FAIL;
858     }
859   }
860 
861   if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu)) {
862     LOG(ERROR) << StringPrintf(
863         "Data link MIU shall not be bigger than local link "
864         "MIU");
865     return LLCP_STATUS_FAIL;
866   }
867 
868   /* check if any pending connection request on this reg_sap */
869   p_dlcb = llcp_dlc_find_dlcb_by_sap(reg_sap, LLCP_INVALID_SAP);
870   if (p_dlcb) {
871     /*
872     ** Accepting LLCP may change SAP in CC, so we cannot find right data
873     ** link connection if there is multiple pending connection request on
874     ** the same local SAP.
875     */
876     LOG(ERROR) << StringPrintf(
877         "There is pending connect request on this reg_sap");
878     return LLCP_STATUS_FAIL;
879   }
880 
881   p_dlcb = llcp_util_allocate_data_link(reg_sap, dsap);
882 
883   if (p_dlcb) {
884     status =
885         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params);
886     if (status != LLCP_STATUS_SUCCESS) {
887       LOG(ERROR) << StringPrintf("Error in state machine");
888       llcp_util_deallocate_data_link(p_dlcb);
889       return LLCP_STATUS_FAIL;
890     }
891   } else {
892     return LLCP_STATUS_FAIL;
893   }
894 
895   return LLCP_STATUS_SUCCESS;
896 }
897 
898 /*******************************************************************************
899 **
900 ** Function         LLCP_ConnectCfm
901 **
902 ** Description      Accept connection request from peer LLCP
903 **
904 **
905 ** Returns          LLCP_STATUS_SUCCESS if success
906 **                  LLCP_STATUS_FAIL, otherwise
907 **
908 *******************************************************************************/
LLCP_ConnectCfm(uint8_t local_sap,uint8_t remote_sap,tLLCP_CONNECTION_PARAMS * p_params)909 tLLCP_STATUS LLCP_ConnectCfm(uint8_t local_sap, uint8_t remote_sap,
910                              tLLCP_CONNECTION_PARAMS* p_params) {
911   tLLCP_STATUS status;
912   tLLCP_DLCB* p_dlcb;
913   tLLCP_CONNECTION_PARAMS params;
914 
915   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
916       "Local SAP:0x%x, Remote SAP:0x%x)", local_sap, remote_sap);
917 
918   if (!p_params) {
919     params.miu = LLCP_DEFAULT_MIU;
920     params.rw = LLCP_DEFAULT_RW;
921     params.sn[0] = 0;
922     p_params = ¶ms;
923   }
924   if (p_params->miu > llcp_cb.lcb.local_link_miu) {
925     LOG(ERROR) << StringPrintf(
926         "Data link MIU shall not be bigger than local link "
927         "MIU");
928     return LLCP_STATUS_FAIL;
929   }
930 
931   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
932 
933   if (p_dlcb) {
934     status =
935         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params);
936   } else {
937     LOG(ERROR) << StringPrintf("No data link");
938     status = LLCP_STATUS_FAIL;
939   }
940 
941   return status;
942 }
943 
944 /*******************************************************************************
945 **
946 ** Function         LLCP_ConnectReject
947 **
948 ** Description      Reject connection request from peer LLCP
949 **
950 **                  reason : LLCP_SAP_DM_REASON_APP_REJECTED
951 **                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS
952 **                           LLCP_SAP_DM_REASON_PERM_REJECT_ANY
953 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_THIS
954 **                           LLCP_SAP_DM_REASON_TEMP_REJECT_ANY
955 **
956 ** Returns          LLCP_STATUS_SUCCESS if success
957 **                  LLCP_STATUS_FAIL, otherwise
958 **
959 *******************************************************************************/
LLCP_ConnectReject(uint8_t local_sap,uint8_t remote_sap,uint8_t reason)960 tLLCP_STATUS LLCP_ConnectReject(uint8_t local_sap, uint8_t remote_sap,
961                                 uint8_t reason) {
962   tLLCP_STATUS status;
963   tLLCP_DLCB* p_dlcb;
964 
965   DLOG_IF(INFO, nfc_debug_enabled)
966       << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x", local_sap,
967                       remote_sap, reason);
968 
969   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
970 
971   if (p_dlcb) {
972     status =
973         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason);
974     llcp_util_deallocate_data_link(p_dlcb);
975   } else {
976     LOG(ERROR) << StringPrintf("No data link");
977     status = LLCP_STATUS_FAIL;
978   }
979 
980   return status;
981 }
982 
983 /*******************************************************************************
984 **
985 ** Function         LLCP_IsDataLinkCongested
986 **
987 ** Description      Check if data link connection is congested
988 **
989 **
990 ** Returns          TRUE if congested
991 **
992 *******************************************************************************/
LLCP_IsDataLinkCongested(uint8_t local_sap,uint8_t remote_sap,uint8_t num_pending_i_pdu,uint8_t total_pending_ui_pdu,uint8_t total_pending_i_pdu)993 bool LLCP_IsDataLinkCongested(uint8_t local_sap, uint8_t remote_sap,
994                               uint8_t num_pending_i_pdu,
995                               uint8_t total_pending_ui_pdu,
996                               uint8_t total_pending_i_pdu) {
997   tLLCP_DLCB* p_dlcb;
998 
999   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1000       "Local SAP:0x%x, Remote SAP:0x%x, pending = "
1001       "(%d, %d, %d)",
1002       local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu,
1003       total_pending_i_pdu);
1004 
1005   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1006 
1007   if (p_dlcb) {
1008     if ((p_dlcb->is_tx_congested) || (p_dlcb->remote_busy)) {
1009       return true;
1010     } else if ((num_pending_i_pdu + p_dlcb->i_xmit_q.count >=
1011                 p_dlcb->remote_rw) ||
1012                (total_pending_ui_pdu + total_pending_i_pdu +
1013                     llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
1014                 llcp_cb.max_num_tx_buff)) {
1015       /* set flag so LLCP can notify uncongested status later */
1016       p_dlcb->is_tx_congested = true;
1017       return true;
1018     }
1019     return false;
1020   }
1021   return true;
1022 }
1023 
1024 /*******************************************************************************
1025 **
1026 ** Function         LLCP_SendData
1027 **
1028 ** Description      Send connection-oriented data
1029 **
1030 **
1031 ** Returns          LLCP_STATUS_SUCCESS if success
1032 **                  LLCP_STATUS_CONGESTED if data link is congested
1033 **
1034 *******************************************************************************/
LLCP_SendData(uint8_t local_sap,uint8_t remote_sap,NFC_HDR * p_buf)1035 tLLCP_STATUS LLCP_SendData(uint8_t local_sap, uint8_t remote_sap,
1036                            NFC_HDR* p_buf) {
1037   tLLCP_STATUS status = LLCP_STATUS_FAIL;
1038   tLLCP_DLCB* p_dlcb;
1039 
1040   DLOG_IF(INFO, nfc_debug_enabled)
1041       << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
1042 
1043   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1044 
1045   if (p_dlcb) {
1046     if (p_dlcb->remote_miu >= p_buf->len) {
1047       if (p_buf->offset >= LLCP_MIN_OFFSET) {
1048         status = llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf);
1049       } else {
1050         LOG(ERROR) << StringPrintf("offset (%d) must be %d at least",
1051                                    p_buf->offset, LLCP_MIN_OFFSET);
1052       }
1053     } else {
1054       LOG(ERROR) << StringPrintf(
1055           "Information (%d bytes) cannot be more than peer "
1056           "MIU (%d bytes)",
1057           p_buf->len, p_dlcb->remote_miu);
1058     }
1059   } else {
1060     LOG(ERROR) << StringPrintf("No data link");
1061   }
1062 
1063   if (status == LLCP_STATUS_FAIL) {
1064     GKI_freebuf(p_buf);
1065   }
1066 
1067   return status;
1068 }
1069 
1070 /*******************************************************************************
1071 **
1072 ** Function         LLCP_ReadDataLinkData
1073 **
1074 ** Description      Read information of I PDU for data link connection
1075 **
1076 **                  - Information of I PDU up to max_data_len is copied into
1077 **                    p_data.
1078 **                  - Information of next I PDU is not concatenated.
1079 **                  - Recommended max_data_len is data link connection MIU of
1080 **                    local end point
1081 **
1082 ** Returns          TRUE if more data in queue
1083 **
1084 *******************************************************************************/
LLCP_ReadDataLinkData(uint8_t local_sap,uint8_t remote_sap,uint32_t max_data_len,uint32_t * p_data_len,uint8_t * p_data)1085 bool LLCP_ReadDataLinkData(uint8_t local_sap, uint8_t remote_sap,
1086                            uint32_t max_data_len, uint32_t* p_data_len,
1087                            uint8_t* p_data) {
1088   tLLCP_DLCB* p_dlcb;
1089   NFC_HDR* p_buf;
1090   uint8_t* p_i_pdu;
1091   uint16_t i_pdu_length;
1092 
1093   DLOG_IF(INFO, nfc_debug_enabled)
1094       << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
1095 
1096   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1097 
1098   *p_data_len = 0;
1099   if (p_dlcb) {
1100     /* if any I PDU in rx queue */
1101     if (p_dlcb->i_rx_q.p_first) {
1102       p_buf = (NFC_HDR*)p_dlcb->i_rx_q.p_first;
1103       p_i_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
1104 
1105       /* get length of I PDU */
1106       BE_STREAM_TO_UINT16(i_pdu_length, p_i_pdu);
1107 
1108       /* layer_specific has the offset to read within I PDU */
1109       p_i_pdu += p_buf->layer_specific;
1110 
1111       /* copy data up to max_data_len */
1112       if (max_data_len >= (uint32_t)(i_pdu_length - p_buf->layer_specific)) {
1113         /* copy information */
1114         *p_data_len = (uint32_t)(i_pdu_length - p_buf->layer_specific);
1115 
1116         /* move to next I PDU if any */
1117         p_buf->layer_specific =
1118             0; /* reset offset to read from the first byte of next I PDU */
1119         p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1120         p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1121       } else {
1122         *p_data_len = max_data_len;
1123 
1124         /* update offset to read from remaining I PDU next time */
1125         p_buf->layer_specific += max_data_len;
1126       }
1127 
1128       memcpy(p_data, p_i_pdu, *p_data_len);
1129 
1130       if (p_buf->layer_specific == 0) {
1131         p_dlcb->num_rx_i_pdu--;
1132       }
1133 
1134       /* if read all of I PDU */
1135       if (p_buf->len == 0) {
1136         GKI_dequeue(&p_dlcb->i_rx_q);
1137         GKI_freebuf(p_buf);
1138 
1139         /* decrease number of received I PDU in in all of ui_rx_q and check rx
1140          * congestion status */
1141         llcp_cb.total_rx_i_pdu--;
1142         llcp_util_check_rx_congested_status();
1143       }
1144     }
1145 
1146     /* if getting out of rx congestion */
1147     if ((!p_dlcb->local_busy) && (p_dlcb->is_rx_congested) &&
1148         (p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)) {
1149       /* send RR */
1150       p_dlcb->is_rx_congested = false;
1151       p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1152     }
1153 
1154     /* if there is more I PDU in rx queue */
1155     if (p_dlcb->i_rx_q.p_first) {
1156       return true;
1157     } else {
1158       return false;
1159     }
1160   } else {
1161     LOG(ERROR) << StringPrintf("No data link connection");
1162 
1163     return false;
1164   }
1165 }
1166 
1167 /*******************************************************************************
1168 **
1169 ** Function         LLCP_FlushDataLinkRxData
1170 **
1171 ** Description      Discard received data in data link connection
1172 **
1173 **
1174 ** Returns          length of rx data flushed
1175 **
1176 *******************************************************************************/
LLCP_FlushDataLinkRxData(uint8_t local_sap,uint8_t remote_sap)1177 uint32_t LLCP_FlushDataLinkRxData(uint8_t local_sap, uint8_t remote_sap) {
1178   tLLCP_DLCB* p_dlcb;
1179   NFC_HDR* p_buf;
1180   uint32_t flushed_length = 0;
1181   uint8_t* p_i_pdu;
1182   uint16_t i_pdu_length;
1183 
1184   DLOG_IF(INFO, nfc_debug_enabled)
1185       << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
1186 
1187   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1188 
1189   if (p_dlcb) {
1190     /* if any I PDU in rx queue */
1191     while (p_dlcb->i_rx_q.p_first) {
1192       p_buf = (NFC_HDR*)p_dlcb->i_rx_q.p_first;
1193       p_i_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset;
1194 
1195       /* get length of I PDU */
1196       BE_STREAM_TO_UINT16(i_pdu_length, p_i_pdu);
1197 
1198       flushed_length += (uint32_t)(i_pdu_length - p_buf->layer_specific);
1199 
1200       /* move to next I PDU if any */
1201       p_buf->layer_specific = 0; /* offset */
1202       p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1203       p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length;
1204 
1205       /* if read all of I PDU */
1206       if (p_buf->len == 0) {
1207         GKI_dequeue(&p_dlcb->i_rx_q);
1208         GKI_freebuf(p_buf);
1209         llcp_cb.total_rx_i_pdu--;
1210       }
1211     }
1212 
1213     p_dlcb->num_rx_i_pdu = 0;
1214 
1215     /* if getting out of rx congestion */
1216     if ((!p_dlcb->local_busy) && (p_dlcb->is_rx_congested)) {
1217       /* send RR */
1218       p_dlcb->is_rx_congested = false;
1219       p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1220     }
1221 
1222     /* number of received I PDU is decreased so check rx congestion status */
1223     llcp_util_check_rx_congested_status();
1224   } else {
1225     LOG(ERROR) << StringPrintf("No data link connection");
1226   }
1227 
1228   return (flushed_length);
1229 }
1230 
1231 /*******************************************************************************
1232 **
1233 ** Function         LLCP_DisconnectReq
1234 **
1235 ** Description      Disconnect data link
1236 **                  discard any pending data if flush is set to TRUE
1237 **
1238 ** Returns          LLCP_STATUS_SUCCESS if success
1239 **
1240 *******************************************************************************/
LLCP_DisconnectReq(uint8_t local_sap,uint8_t remote_sap,bool flush)1241 tLLCP_STATUS LLCP_DisconnectReq(uint8_t local_sap, uint8_t remote_sap,
1242                                 bool flush) {
1243   tLLCP_STATUS status;
1244   tLLCP_DLCB* p_dlcb;
1245 
1246   DLOG_IF(INFO, nfc_debug_enabled)
1247       << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x, flush=%d", local_sap,
1248                       remote_sap, flush);
1249 
1250   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1251 
1252   if (p_dlcb) {
1253     status =
1254         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1255   } else {
1256     LOG(ERROR) << StringPrintf("No data link");
1257     status = LLCP_STATUS_FAIL;
1258   }
1259 
1260   return status;
1261 }
1262 
1263 /*******************************************************************************
1264 **
1265 ** Function         LLCP_SetTxCompleteNtf
1266 **
1267 ** Description      This function is called to get LLCP_SERVICE_TX_COMPLETE
1268 **                  when Tx queue is empty and all PDU is acked.
1269 **                  This is one time event, so upper layer shall call this
1270 **                  function again to get next LLCP_SERVICE_TX_COMPLETE.
1271 **
1272 ** Returns          LLCP_STATUS_SUCCESS if success
1273 **
1274 *******************************************************************************/
LLCP_SetTxCompleteNtf(uint8_t local_sap,uint8_t remote_sap)1275 tLLCP_STATUS LLCP_SetTxCompleteNtf(uint8_t local_sap, uint8_t remote_sap) {
1276   tLLCP_STATUS status;
1277   tLLCP_DLCB* p_dlcb;
1278 
1279   DLOG_IF(INFO, nfc_debug_enabled)
1280       << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
1281 
1282   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1283 
1284   if (p_dlcb) {
1285     /* set flag to notify upper later when tx complete */
1286     p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1287     status = LLCP_STATUS_SUCCESS;
1288   } else {
1289     LOG(ERROR) << StringPrintf("No data link");
1290     status = LLCP_STATUS_FAIL;
1291   }
1292 
1293   return status;
1294 }
1295 
1296 /*******************************************************************************
1297 **
1298 ** Function         LLCP_SetLocalBusyStatus
1299 **
1300 ** Description      Set local busy status
1301 **
1302 **
1303 ** Returns          LLCP_STATUS_SUCCESS if success
1304 **
1305 *******************************************************************************/
LLCP_SetLocalBusyStatus(uint8_t local_sap,uint8_t remote_sap,bool is_busy)1306 tLLCP_STATUS LLCP_SetLocalBusyStatus(uint8_t local_sap, uint8_t remote_sap,
1307                                      bool is_busy) {
1308   tLLCP_STATUS status;
1309   tLLCP_DLCB* p_dlcb;
1310 
1311   DLOG_IF(INFO, nfc_debug_enabled)
1312       << StringPrintf("Local SAP:0x%x, is_busy=%d", local_sap, is_busy);
1313 
1314   p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
1315 
1316   if (p_dlcb) {
1317     if (p_dlcb->local_busy != is_busy) {
1318       p_dlcb->local_busy = is_busy;
1319 
1320       /* send RR or RNR with valid sequence */
1321       p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1322 
1323       if (is_busy == false) {
1324         if (p_dlcb->i_rx_q.count) {
1325           llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, nullptr);
1326         }
1327       }
1328     }
1329     status = LLCP_STATUS_SUCCESS;
1330   } else {
1331     LOG(ERROR) << StringPrintf("No data link");
1332     status = LLCP_STATUS_FAIL;
1333   }
1334 
1335   return status;
1336 }
1337 
1338 /*******************************************************************************
1339 **
1340 ** Function         LLCP_GetRemoteWKS
1341 **
1342 ** Description      Return well-known service bitmap of connected device
1343 **
1344 **
1345 ** Returns          WKS bitmap if success
1346 **
1347 *******************************************************************************/
LLCP_GetRemoteWKS(void)1348 uint16_t LLCP_GetRemoteWKS(void) {
1349   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1350       "WKS:0x%04x", (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1351                         ? llcp_cb.lcb.peer_wks
1352                         : 0);
1353 
1354   if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1355     return (llcp_cb.lcb.peer_wks);
1356   else
1357     return (0);
1358 }
1359 
1360 /*******************************************************************************
1361 **
1362 ** Function         LLCP_GetRemoteLSC
1363 **
1364 ** Description      Return link service class of connected device
1365 **
1366 **
1367 ** Returns          link service class
1368 **
1369 *******************************************************************************/
LLCP_GetRemoteLSC(void)1370 uint8_t LLCP_GetRemoteLSC(void) {
1371   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1372       "LSC:0x%x", (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1373                       ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2)
1374                       : 0);
1375 
1376   if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1377     return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2));
1378   else
1379     return (LLCP_LSC_UNKNOWN);
1380 }
1381 
1382 /*******************************************************************************
1383 **
1384 ** Function         LLCP_GetRemoteVersion
1385 **
1386 ** Description      Return LLCP version of connected device
1387 **
1388 **
1389 ** Returns          LLCP version
1390 **
1391 *******************************************************************************/
LLCP_GetRemoteVersion(void)1392 uint8_t LLCP_GetRemoteVersion(void) {
1393   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1394       "Version: 0x%x", (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1395                            ? llcp_cb.lcb.peer_version
1396                            : 0);
1397 
1398   if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED)
1399     return (llcp_cb.lcb.peer_version);
1400   else
1401     return 0;
1402 }
1403 
1404 /*******************************************************************************
1405 **
1406 ** Function         LLCP_GetLinkMIU
1407 **
1408 ** Description      Return local and remote link MIU
1409 **
1410 **
1411 ** Returns          None
1412 **
1413 *******************************************************************************/
LLCP_GetLinkMIU(uint16_t * p_local_link_miu,uint16_t * p_remote_link_miu)1414 void LLCP_GetLinkMIU(uint16_t* p_local_link_miu, uint16_t* p_remote_link_miu) {
1415   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1416 
1417   if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
1418     *p_local_link_miu = llcp_cb.lcb.local_link_miu;
1419     *p_remote_link_miu = llcp_cb.lcb.effective_miu;
1420   } else {
1421     *p_local_link_miu = 0;
1422     *p_remote_link_miu = 0;
1423   }
1424 
1425   DLOG_IF(INFO, nfc_debug_enabled)
1426       << StringPrintf("local_link_miu = %d, remote_link_miu = %d",
1427                       *p_local_link_miu, *p_remote_link_miu);
1428 }
1429 
1430 /*******************************************************************************
1431 **
1432 ** Function         LLCP_DiscoverService
1433 **
1434 ** Description      Return SAP of service name in connected device through
1435 **                  callback
1436 **
1437 **
1438 ** Returns          LLCP_STATUS_SUCCESS if success
1439 **
1440 *******************************************************************************/
LLCP_DiscoverService(char * p_name,tLLCP_SDP_CBACK * p_cback,uint8_t * p_tid)1441 tLLCP_STATUS LLCP_DiscoverService(char* p_name, tLLCP_SDP_CBACK* p_cback,
1442                                   uint8_t* p_tid) {
1443   tLLCP_STATUS status;
1444   uint8_t i;
1445 
1446   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Service Name:%s", p_name);
1447 
1448   if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) {
1449     LOG(ERROR) << StringPrintf("Link is not activated");
1450     return LLCP_STATUS_FAIL;
1451   }
1452 
1453   if (!p_cback) {
1454     LOG(ERROR) << StringPrintf("Callback must be provided.");
1455     return LLCP_STATUS_FAIL;
1456   }
1457 
1458   /* if peer version is less than V1.1 then SNL is not supported */
1459   if ((llcp_cb.lcb.agreed_major_version == 0x01) &&
1460       (llcp_cb.lcb.agreed_minor_version < 0x01)) {
1461     LOG(ERROR) << StringPrintf("Peer doesn't support SNL");
1462     return LLCP_STATUS_FAIL;
1463   }
1464 
1465   for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++) {
1466     if (!llcp_cb.sdp_cb.transac[i].p_cback) {
1467       llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid;
1468       llcp_cb.sdp_cb.next_tid++;
1469       llcp_cb.sdp_cb.transac[i].p_cback = p_cback;
1470 
1471       status = llcp_sdp_send_sdreq(llcp_cb.sdp_cb.transac[i].tid, p_name);
1472 
1473       if (status == LLCP_STATUS_FAIL) {
1474         llcp_cb.sdp_cb.transac[i].p_cback = nullptr;
1475       }
1476 
1477       *p_tid = llcp_cb.sdp_cb.transac[i].tid;
1478       return (status);
1479     }
1480   }
1481 
1482   LOG(ERROR) << StringPrintf("Out of resource");
1483 
1484   return LLCP_STATUS_FAIL;
1485 }
1486