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