• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 = &params;
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 = &params;
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