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