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