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