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