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 Link Management
22 *
23 ******************************************************************************/
24
25 #include <string.h>
26
27 #include <android-base/stringprintf.h>
28 #include <base/logging.h>
29 #include <log/log.h>
30 #include "bt_types.h"
31 #include "gki.h"
32 #include "llcp_defs.h"
33 #include "llcp_int.h"
34 #include "nfa_dm_int.h"
35 #include "nfc_int.h"
36
37 using android::base::StringPrintf;
38
39 const uint16_t llcp_link_rwt
40 [15] = /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */
41 {
42 1, /* WT=0, 302us */
43 1, /* WT=1, 604us */
44 2, /* WT=2, 1208us */
45 3, /* WT=3, 2.4ms */
46 5, /* WT=4, 4.8ms */
47 10, /* WT=5, 9.7ms */
48 20, /* WT=6, 19.3ms */
49 39, /* WT=7, 38.7ms */
50 78, /* WT=8, 77.3ms */
51 155, /* WT=9, 154.6ms */
52 310, /* WT=10, 309.2ms */
53 619, /* WT=11, 618.5ms */
54 1237, /* WT=12, 1237.0ms */
55 2474, /* WT=13, 2474.0ms */
56 4948, /* WT=14, 4948.0ms */
57 };
58
59 static bool llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,
60 uint8_t* p_gen_bytes);
61 static bool llcp_link_version_agreement(void);
62
63 static void llcp_link_send_SYMM(void);
64 static void llcp_link_update_status(bool is_activated);
65 static void llcp_link_check_congestion(void);
66 static void llcp_link_check_uncongested(void);
67 static void llcp_link_proc_ui_pdu(uint8_t local_sap, uint8_t remote_sap,
68 uint16_t ui_pdu_length, uint8_t* p_ui_pdu,
69 NFC_HDR* p_msg);
70 static void llcp_link_proc_agf_pdu(NFC_HDR* p_msg);
71 static void llcp_link_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
72 NFC_HDR* p_msg);
73 static void llcp_link_proc_rx_data(NFC_HDR* p_msg);
74
75 static NFC_HDR* llcp_link_get_next_pdu(bool length_only,
76 uint16_t* p_next_pdu_length);
77 static NFC_HDR* llcp_link_build_next_pdu(NFC_HDR* p_agf);
78 static void llcp_link_send_to_lower(NFC_HDR* p_msg);
79
80 #if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */
81 extern tLLCP_TEST_PARAMS llcp_test_params;
82 #endif
83
84 extern bool nfc_debug_enabled;
85 extern unsigned char appl_dta_mode_flag;
86
87 /* debug functions type */
88 static std::string llcp_pdu_type(uint8_t ptype);
89
90 /*******************************************************************************
91 **
92 ** Function llcp_link_start_inactivity_timer
93 **
94 ** Description This function start LLCP link inactivity timer.
95 **
96 ** Returns void
97 **
98 *******************************************************************************/
llcp_link_start_inactivity_timer(void)99 static void llcp_link_start_inactivity_timer(void) {
100 if ((llcp_cb.lcb.inact_timer.in_use == false) &&
101 (llcp_cb.lcb.inact_timeout > 0)) {
102 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
103 "Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout);
104
105 nfc_start_quick_timer(&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT,
106 ((uint32_t)llcp_cb.lcb.inact_timeout) *
107 QUICK_TIMER_TICKS_PER_SEC / 1000);
108 }
109 }
110
111 /*******************************************************************************
112 **
113 ** Function llcp_link_stop_inactivity_timer
114 **
115 ** Description This function stop LLCP link inactivity timer.
116 **
117 ** Returns void
118 **
119 *******************************************************************************/
llcp_link_stop_inactivity_timer(void)120 static void llcp_link_stop_inactivity_timer(void) {
121 if (llcp_cb.lcb.inact_timer.in_use) {
122 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Stop inactivity_timer");
123
124 nfc_stop_quick_timer(&llcp_cb.lcb.inact_timer);
125 }
126 }
127
128 /*******************************************************************************
129 **
130 ** Function llcp_link_start_link_timer
131 **
132 ** Description This function starts LLCP link timer (LTO or delay response)
133 **
134 ** Returns void
135 **
136 *******************************************************************************/
llcp_link_start_link_timer(void)137 static void llcp_link_start_link_timer(void) {
138 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) {
139 /* wait for application layer sending data */
140 nfc_start_quick_timer(
141 &llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
142 (((uint32_t)llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) /
143 1000);
144 } else {
145 /* wait for data to receive from remote */
146 nfc_start_quick_timer(
147 &llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
148 ((uint32_t)llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000);
149 }
150 }
151
152 /*******************************************************************************
153 **
154 ** Function llcp_link_stop_link_timer
155 **
156 ** Description This function stop LLCP link timer (LTO or delay response).
157 **
158 ** Returns void
159 **
160 *******************************************************************************/
llcp_link_stop_link_timer(void)161 static void llcp_link_stop_link_timer(void) {
162 nfc_stop_quick_timer(&llcp_cb.lcb.timer);
163 }
164
165 /*******************************************************************************
166 **
167 ** Function llcp_link_activate
168 **
169 ** Description Activate LLCP link
170 **
171 ** Returns tLLCP_STATUS
172 **
173 *******************************************************************************/
llcp_link_activate(tLLCP_ACTIVATE_CONFIG * p_config)174 tLLCP_STATUS llcp_link_activate(tLLCP_ACTIVATE_CONFIG* p_config) {
175 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
176
177 /* At this point, MAC link activation procedure has been successfully
178 * completed */
179
180 /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */
181 if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE) {
182 LOG(WARNING) << StringPrintf("max payload size (%d) must be %d bytes",
183 p_config->max_payload_size,
184 LLCP_NCI_MAX_PAYL_SIZE);
185 }
186
187 /* Processing the parametes that have been received with the MAC link
188 * activation */
189 if (llcp_link_parse_gen_bytes(p_config->gen_bytes_len,
190 p_config->p_gen_bytes) == false) {
191 LOG(ERROR) << StringPrintf("Failed to parse general bytes");
192 /* For LLCP DTA test, In case of bad magic bytes normal p2p communication is
193 * expected,but in case of wrong magic bytes in ATR_REQ, LLC layer will be
194 * disconnected but P2P connection is expected to be in connected state
195 * and non LLC PDU is expected.
196 * As per NFC forum expectation below changes is to send PDU after
197 * disconnect of LLCP PDU.
198 * This is fix for TC_MAC_TAR_BI_01 LLCP test case */
199
200 if (appl_dta_mode_flag == 1 && p_config->is_initiator == FALSE) {
201 NFC_HDR* p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
202
203 if (p_msg) {
204 /*LLCP test scenario requires non LLC PDU to be sent in case of wrong
205 magic bytes. So sending NFC-DEP pdu with size 1 (0x00)*/
206 p_msg->len = 1;
207 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
208
209 NFC_SendData(NFC_RF_CONN_ID, p_msg);
210 }
211 }
212
213 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_FAILED_EVT,
214 LLCP_LINK_BAD_GEN_BYTES);
215
216 if (p_config->is_initiator == false) {
217 /* repond to any incoming PDU with invalid LLCP PDU */
218 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATION_FAILED;
219 NFC_SetStaticRfCback(llcp_link_connection_cback);
220 }
221 return LLCP_STATUS_FAIL;
222 }
223
224 /*
225 ** For the Target device, the scaled value of RWT MUST be less than or equal
226 ** to the scaled value of the LLC Link Timeout (LTO).
227 */
228 if ((p_config->is_initiator) &&
229 (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto)) {
230 LOG(WARNING) << StringPrintf(
231 "WT (%d, %dms) must be less than or equal to "
232 "LTO (%dms)",
233 p_config->waiting_time, llcp_link_rwt[p_config->waiting_time],
234 llcp_cb.lcb.peer_lto);
235 }
236 /* For DTA mode Peer LTO Should not include TX RX Delay, Just llcp deactivate
237 * after Peer LTO time */
238 if (!appl_dta_mode_flag) {
239 /* extend LTO as much as internally required processing time and propagation
240 * delays */
241 llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY;
242 }
243 /* LLCP version number agreement */
244 if (llcp_link_version_agreement() == false) {
245 LOG(ERROR) << StringPrintf("Failed to agree version");
246 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_FAILED_EVT,
247 LLCP_LINK_VERSION_FAILED);
248
249 if (p_config->is_initiator == false) {
250 /* repond to any incoming PDU with invalid LLCP PDU */
251 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATION_FAILED;
252 NFC_SetStaticRfCback(llcp_link_connection_cback);
253 }
254 return LLCP_STATUS_FAIL;
255 }
256
257 llcp_cb.lcb.received_first_packet = false;
258 llcp_cb.lcb.is_initiator = p_config->is_initiator;
259
260 /* reset internal flags */
261 llcp_cb.lcb.flags = 0x00;
262
263 /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */
264
265 if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu)
266 llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu;
267 else
268 llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu;
269
270 /*
271 ** When entering the normal operation phase, LLCP shall initialize the
272 ** symmetry procedure.
273 */
274 if (llcp_cb.lcb.is_initiator) {
275 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Connected as Initiator");
276
277 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init;
278 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
279
280 if (llcp_cb.lcb.delay_first_pdu_timeout > 0) {
281 /* give a chance to upper layer to send PDU if need */
282 nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU,
283 (((uint32_t)llcp_cb.lcb.delay_first_pdu_timeout) *
284 QUICK_TIMER_TICKS_PER_SEC) /
285 1000);
286 } else {
287 llcp_link_send_SYMM();
288 }
289 } else {
290 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Connected as Target");
291 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target;
292 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
293
294 /* wait for data to receive from remote */
295 llcp_link_start_link_timer();
296 }
297
298 /*
299 ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set
300 ** data callback because LLCP PDU could be in NCI queue.
301 */
302 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED;
303
304 /* LLCP Link Activation completed */
305 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_ACTIVATION_COMPLETE_EVT,
306 LLCP_LINK_SUCCESS);
307
308 /* Update link status to service layer */
309 llcp_link_update_status(true);
310
311 NFC_SetStaticRfCback(llcp_link_connection_cback);
312
313 return (LLCP_STATUS_SUCCESS);
314 }
315
316 /*******************************************************************************
317 **
318 ** Function llcp_deactivate_cleanup
319 **
320 ** Description Clean up for link deactivation
321 **
322 ** Returns void
323 **
324 *******************************************************************************/
llcp_deactivate_cleanup(uint8_t reason)325 static void llcp_deactivate_cleanup(uint8_t reason) {
326 /* report SDP failure for any pending request */
327 llcp_sdp_proc_deactivation();
328
329 /* Update link status to service layer */
330 llcp_link_update_status(false);
331
332 /* We had sent out DISC */
333 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
334
335 llcp_link_stop_link_timer();
336
337 /* stop inactivity timer */
338 llcp_link_stop_inactivity_timer();
339
340 /* Let upper layer deactivate local link */
341 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_DEACTIVATED_EVT, reason);
342 }
343
344 /*******************************************************************************
345 **
346 ** Function llcp_link_process_link_timeout
347 **
348 ** Description Process timeout events for LTO, SYMM and deactivating
349 **
350 ** Returns void
351 **
352 *******************************************************************************/
llcp_link_process_link_timeout(void)353 void llcp_link_process_link_timeout(void) {
354 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
355 if ((llcp_cb.lcb.symm_delay > 0) &&
356 (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)) {
357 /* upper layer doesn't have anything to send */
358 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
359 "LEVT_TIMEOUT in state of "
360 "LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
361 llcp_link_send_SYMM();
362
363 /* wait for data to receive from remote */
364 llcp_link_start_link_timer();
365
366 /* start inactivity timer */
367 if (llcp_cb.num_data_link_connection == 0) {
368 llcp_link_start_inactivity_timer();
369 }
370 } else {
371 LOG(ERROR) << StringPrintf(
372 "LEVT_TIMEOUT in state of "
373 "LLCP_LINK_SYMM_REMOTE_XMIT_NEXT");
374 llcp_link_deactivate(LLCP_LINK_TIMEOUT);
375 }
376 } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) {
377 llcp_deactivate_cleanup(llcp_cb.lcb.link_deact_reason);
378
379 NFC_SetStaticRfCback(nullptr);
380 }
381 }
382
383 /*******************************************************************************
384 **
385 ** Function llcp_link_deactivate
386 **
387 ** Description Deactivate LLCP link
388 **
389 ** Returns void
390 **
391 *******************************************************************************/
llcp_link_deactivate(uint8_t reason)392 void llcp_link_deactivate(uint8_t reason) {
393 uint8_t local_sap, idx;
394 tLLCP_DLCB* p_dlcb;
395 tLLCP_APP_CB* p_app_cb;
396
397 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("reason = 0x%x", reason);
398
399 /* Release any held buffers in signaling PDU queue */
400 while (llcp_cb.lcb.sig_xmit_q.p_first)
401 GKI_freebuf(GKI_dequeue(&llcp_cb.lcb.sig_xmit_q));
402
403 /* Release any held buffers in UI PDU queue */
404 for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++) {
405 p_app_cb = llcp_util_get_app_cb(local_sap);
406
407 if ((p_app_cb) && (p_app_cb->p_app_cback)) {
408 while (p_app_cb->ui_xmit_q.p_first)
409 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_xmit_q));
410
411 p_app_cb->is_ui_tx_congested = false;
412
413 while (p_app_cb->ui_rx_q.p_first)
414 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_rx_q));
415 }
416 }
417
418 llcp_cb.total_tx_ui_pdu = 0;
419 llcp_cb.total_rx_ui_pdu = 0;
420
421 /* Notify all of data link */
422 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
423 if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) {
424 p_dlcb = &(llcp_cb.dlcb[idx]);
425
426 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, nullptr);
427 }
428 }
429 llcp_cb.total_tx_i_pdu = 0;
430 llcp_cb.total_rx_i_pdu = 0;
431
432 llcp_cb.overall_tx_congested = false;
433 llcp_cb.overall_rx_congested = false;
434
435 /* As per the LLCP test specification v1.2.00 for test case TC_LLC_TAR_BV_04
436 * the receiving LLC shall commence sending an LLC PDU to the remote
437 * LLC. So, after IUT receives DISC PDU from LT(remote device), IUT shall
438 * send DISC PDU to LT. appl_dta_mode_flag condition is added to fulfil
439 * above requirement. Only in CR8, the IUT shall acknoweledge with SYMM for
440 * DISC PDU. For other CRx, send DISC PDU.
441 */
442 if ((reason == LLCP_LINK_FRAME_ERROR) ||
443 (reason == LLCP_LINK_LOCAL_INITIATED) ||
444 (appl_dta_mode_flag && reason == LLCP_LINK_REMOTE_INITIATED &&
445 llcp_cb.lcb.is_initiator == false &&
446 (nfa_dm_cb.eDtaMode & 0xF0) != NFA_DTA_CR8)) {
447 /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP
448 */
449 NFC_FlushData(NFC_RF_CONN_ID);
450
451 llcp_util_send_disc(LLCP_SAP_LM, LLCP_SAP_LM);
452
453 /* Wait until DISC is sent to peer */
454 DLOG_IF(INFO, nfc_debug_enabled)
455 << StringPrintf("Wait until DISC is sent to peer");
456
457 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING;
458
459 if (llcp_cb.lcb.sig_xmit_q.count == 0) {
460 /* if DISC is sent to NFCC, wait for short period for NFCC to send it to
461 * peer */
462 nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
463 ((uint32_t)50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
464 }
465
466 llcp_cb.lcb.link_deact_reason = reason;
467 return;
468 } else if ((reason == LLCP_LINK_REMOTE_INITIATED) &&
469 (!llcp_cb.lcb.is_initiator)) {
470 /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */
471 llcp_link_send_SYMM();
472 } else /* for link timeout and interface error */
473 {
474 /* if got RF link loss receiving no LLC PDU from peer */
475 if ((reason == LLCP_LINK_RF_LINK_LOSS_ERR) &&
476 (!(llcp_cb.lcb.flags & LLCP_LINK_FLAGS_RX_ANY_LLC_PDU))) {
477 reason = LLCP_LINK_RF_LINK_LOSS_NO_RX_LLC;
478 }
479
480 NFC_FlushData(NFC_RF_CONN_ID);
481 }
482
483 llcp_deactivate_cleanup(reason);
484 }
485
486 /*******************************************************************************
487 **
488 ** Function llcp_link_parse_gen_bytes
489 **
490 ** Description Check LLCP magic number and get parameters in general bytes
491 **
492 ** Returns TRUE if success
493 **
494 *******************************************************************************/
llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,uint8_t * p_gen_bytes)495 static bool llcp_link_parse_gen_bytes(uint8_t gen_bytes_len,
496 uint8_t* p_gen_bytes) {
497 uint8_t* p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN;
498 uint8_t length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN;
499
500 if ((gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN) &&
501 (*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0) &&
502 (*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1) &&
503 (*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2)) {
504 /* in case peer didn't include these */
505 llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU;
506 llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS;
507
508 return (llcp_util_parse_link_params(length, p));
509 } else /* if this is not LLCP */
510 {
511 return false;
512 }
513
514 return true;
515 }
516
517 /*******************************************************************************
518 **
519 ** Function llcp_link_version_agreement
520 **
521 ** Description LLCP version number agreement
522 **
523 ** Returns TRUE if success
524 **
525 *******************************************************************************/
llcp_link_version_agreement(void)526 static bool llcp_link_version_agreement(void) {
527 uint8_t peer_major_version, peer_minor_version;
528
529 peer_major_version = LLCP_GET_MAJOR_VERSION(llcp_cb.lcb.peer_version);
530 peer_minor_version = LLCP_GET_MINOR_VERSION(llcp_cb.lcb.peer_version);
531
532 if (peer_major_version < LLCP_MIN_MAJOR_VERSION) {
533 LOG(ERROR) << StringPrintf(
534 "unsupported peer version number. Peer "
535 "Major Version:%d",
536 peer_major_version);
537 return false;
538 } else {
539 if (peer_major_version == LLCP_VERSION_MAJOR) {
540 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
541 if (peer_minor_version >= LLCP_VERSION_MINOR) {
542 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
543 } else {
544 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
545 }
546 } else if (peer_major_version < LLCP_VERSION_MAJOR) {
547 /* so far we can support backward compatibility */
548 llcp_cb.lcb.agreed_major_version = peer_major_version;
549 llcp_cb.lcb.agreed_minor_version = peer_minor_version;
550 } else {
551 /* let peer (higher major version) decide it */
552 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR;
553 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR;
554 }
555
556 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
557 "local version:%d.%d, remote version:%d.%d, agreed version:%d.%d",
558 LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR, peer_major_version,
559 peer_minor_version, llcp_cb.lcb.agreed_major_version,
560 llcp_cb.lcb.agreed_minor_version);
561
562 return true;
563 }
564 }
565
566 /*******************************************************************************
567 **
568 ** Function llcp_link_update_status
569 **
570 ** Description Notify all of service layer client link status change
571 **
572 ** Returns void
573 **
574 *******************************************************************************/
llcp_link_update_status(bool is_activated)575 static void llcp_link_update_status(bool is_activated) {
576 tLLCP_SAP_CBACK_DATA data;
577 tLLCP_APP_CB* p_app_cb;
578 uint8_t sap;
579
580 data.link_status.event = LLCP_SAP_EVT_LINK_STATUS;
581 data.link_status.is_activated = is_activated;
582 data.link_status.is_initiator = llcp_cb.lcb.is_initiator;
583
584 /* notify all SAP so they can create connection while link is activated */
585 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) {
586 p_app_cb = llcp_util_get_app_cb(sap);
587
588 if ((p_app_cb) && (p_app_cb->p_app_cback)) {
589 data.link_status.local_sap = sap;
590 p_app_cb->p_app_cback(&data);
591 }
592 }
593 }
594
595 /*******************************************************************************
596 **
597 ** Function llcp_link_check_congestion
598 **
599 ** Description Check overall congestion status
600 ** Notify to all of upper layer if congested
601 **
602 ** Returns void
603 **
604 *******************************************************************************/
llcp_link_check_congestion(void)605 static void llcp_link_check_congestion(void) {
606 tLLCP_SAP_CBACK_DATA data;
607 tLLCP_APP_CB* p_app_cb;
608 uint8_t sap, idx;
609
610 if (llcp_cb.overall_tx_congested) {
611 /* already congested so no need to check again */
612 return;
613 }
614
615 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >=
616 llcp_cb.max_num_tx_buff) {
617 /* overall buffer usage is high */
618 llcp_cb.overall_tx_congested = true;
619
620 LOG(WARNING) << StringPrintf(
621 "overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
622 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
623
624 data.congest.event = LLCP_SAP_EVT_CONGEST;
625 data.congest.is_congested = true;
626
627 /* notify logical data link congestion status */
628 data.congest.remote_sap = LLCP_INVALID_SAP;
629 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
630
631 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) {
632 p_app_cb = llcp_util_get_app_cb(sap);
633
634 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
635 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
636 /* if already congested then no need to notify again */
637 if (!p_app_cb->is_ui_tx_congested) {
638 p_app_cb->is_ui_tx_congested = true;
639
640 LOG(WARNING) << StringPrintf(
641 "Logical link (SAP=0x%X) congestion start: count=%d", sap,
642 p_app_cb->ui_xmit_q.count);
643
644 data.congest.local_sap = sap;
645 p_app_cb->p_app_cback(&data);
646 }
647 }
648 }
649
650 /* notify data link connection congestion status */
651 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
652
653 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
654 if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
655 (llcp_cb.dlcb[idx].remote_busy == false) &&
656 (llcp_cb.dlcb[idx].is_tx_congested == false)) {
657 llcp_cb.dlcb[idx].is_tx_congested = true;
658
659 LOG(WARNING) << StringPrintf(
660 "Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d",
661 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
662 llcp_cb.dlcb[idx].i_xmit_q.count);
663
664 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
665 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
666
667 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback)(&data);
668 }
669 }
670 }
671 }
672
673 /*******************************************************************************
674 **
675 ** Function llcp_link_check_uncongested
676 **
677 ** Description Check overall congestion status, logical data link and
678 ** data link connection congestion status
679 ** Notify to each upper layer if uncongested
680 **
681 ** Returns void
682 **
683 *******************************************************************************/
llcp_link_check_uncongested(void)684 static void llcp_link_check_uncongested(void) {
685 tLLCP_SAP_CBACK_DATA data;
686 tLLCP_APP_CB* p_app_cb;
687 uint8_t xx, sap, idx;
688
689 if (llcp_cb.overall_tx_congested) {
690 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <=
691 llcp_cb.max_num_tx_buff / 2) {
692 /* overall congestion is cleared */
693 llcp_cb.overall_tx_congested = false;
694
695 LOG(WARNING) << StringPrintf(
696 "overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d",
697 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu);
698 } else {
699 /* wait until more data packets are sent out */
700 return;
701 }
702 }
703
704 data.congest.event = LLCP_SAP_EVT_CONGEST;
705 data.congest.is_congested = false;
706
707 /* if total number of UI PDU is below threshold */
708 if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff) {
709 /* check and notify logical data link congestion status */
710 data.congest.remote_sap = LLCP_INVALID_SAP;
711 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
712
713 /*
714 ** start point of uncongested status notification is in round robin
715 ** so each logical data link has equal chance of transmitting.
716 */
717 sap = llcp_cb.ll_tx_uncongest_ntf_start_sap;
718
719 for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++) {
720 /* no logical data link on LM and SDP */
721 if (sap > LLCP_SAP_SDP) {
722 p_app_cb = llcp_util_get_app_cb(sap);
723
724 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
725 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) &&
726 (p_app_cb->is_ui_tx_congested) &&
727 (p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end)) {
728 /* if it was congested but now tx queue count is below threshold */
729 p_app_cb->is_ui_tx_congested = false;
730
731 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
732 "Logical link (SAP=0x%X) congestion end: count=%d", sap,
733 p_app_cb->ui_xmit_q.count);
734
735 data.congest.local_sap = sap;
736 p_app_cb->p_app_cback(&data);
737 }
738 }
739
740 sap = (sap + 1) % LLCP_NUM_SAPS;
741 }
742
743 /* move start point for next logical data link */
744 for (xx = 0; xx < LLCP_NUM_SAPS; xx++) {
745 sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS;
746
747 if (sap > LLCP_SAP_SDP) {
748 p_app_cb = llcp_util_get_app_cb(sap);
749
750 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
751 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
752 llcp_cb.ll_tx_uncongest_ntf_start_sap = sap;
753 break;
754 }
755 }
756 }
757 }
758
759 /* notify data link connection congestion status */
760 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
761
762 /*
763 ** start point of uncongested status notification is in round robin
764 ** so each data link connection has equal chance of transmitting.
765 */
766 idx = llcp_cb.dl_tx_uncongest_ntf_start_idx;
767
768 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
769 /* if it was congested but now tx queue is below threshold (receiving
770 * window) */
771 if ((llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) &&
772 (llcp_cb.dlcb[idx].is_tx_congested) &&
773 (llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2)) {
774 llcp_cb.dlcb[idx].is_tx_congested = false;
775
776 if (llcp_cb.dlcb[idx].remote_busy == false) {
777 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
778 "Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d",
779 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap,
780 llcp_cb.dlcb[idx].i_xmit_q.count);
781
782 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap;
783 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap;
784
785 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback)(&data);
786 }
787 }
788 idx = (idx + 1) % LLCP_MAX_DATA_LINK;
789 }
790
791 /* move start point for next data link connection */
792 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++) {
793 idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK;
794 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
795 llcp_cb.dl_tx_uncongest_ntf_start_idx = idx;
796 break;
797 }
798 }
799 }
800
801 /*******************************************************************************
802 **
803 ** Function llcp_link_send_SYMM
804 **
805 ** Description Send SYMM PDU
806 **
807 ** Returns void
808 **
809 *******************************************************************************/
llcp_link_send_SYMM(void)810 static void llcp_link_send_SYMM(void) {
811 NFC_HDR* p_msg;
812 uint8_t* p;
813
814 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
815
816 if (p_msg) {
817 p_msg->len = LLCP_PDU_SYMM_SIZE;
818 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
819
820 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
821 UINT16_TO_BE_STREAM(
822 p, LLCP_GET_PDU_HEADER(LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM));
823
824 llcp_link_send_to_lower(p_msg);
825 }
826 }
827
828 /*******************************************************************************
829 **
830 ** Function llcp_link_send_invalid_pdu
831 **
832 ** Description Send invalid LLC PDU in LLCP_LINK_STATE_ACTIVATION_FAILED
833 **
834 ** Returns void
835 **
836 *******************************************************************************/
llcp_link_send_invalid_pdu(void)837 static void llcp_link_send_invalid_pdu(void) {
838 NFC_HDR* p_msg;
839 uint8_t* p;
840
841 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
842
843 if (p_msg) {
844 /* send one byte of 0x00 as invalid LLC PDU */
845 p_msg->len = 1;
846 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
847
848 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
849 *p = 0x00;
850
851 NFC_SendData(NFC_RF_CONN_ID, p_msg);
852 }
853 }
854
855 /*******************************************************************************
856 **
857 ** Function llcp_link_check_send_data
858 **
859 ** Description Send PDU to peer
860 **
861 ** Returns void
862 **
863 *******************************************************************************/
llcp_link_check_send_data(void)864 void llcp_link_check_send_data(void) {
865 NFC_HDR* p_pdu;
866
867 /* don't re-enter while processing to prevent out of sequence */
868 if (llcp_cb.lcb.is_sending_data)
869 return;
870 else
871 llcp_cb.lcb.is_sending_data = true;
872
873 /*
874 ** check overall congestion due to high usage of buffer pool
875 ** if congested then notify all of upper layers not to send any more data
876 */
877 llcp_link_check_congestion();
878
879 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT ||
880 (appl_dta_mode_flag &&
881 llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)) {
882 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
883 "in state of "
884 "LLCP_LINK_SYMM_LOCAL_XMIT_NEXT");
885
886 p_pdu = llcp_link_build_next_pdu(nullptr);
887
888 /*
889 ** For data link connection,
890 ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in
891 ** this transmission. If there was no I PDU to carry V(RA) and V(RA) is
892 ** not V(R) and it's not congested, then RR PDU will be sent.
893 ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's
894 ** congested, then RNR PDU will be sent.
895 ** If local busy state has been changed then RR or RNR PDU may be sent.
896 */
897 llcp_dlc_check_to_send_rr_rnr();
898
899 /* add RR/RNR PDU to be sent if any */
900 p_pdu = llcp_link_build_next_pdu(p_pdu);
901
902 if (p_pdu != nullptr) {
903 llcp_link_send_to_lower(p_pdu);
904
905 /* stop inactivity timer */
906 llcp_link_stop_inactivity_timer();
907
908 /* check congestion status after sending out some data */
909 llcp_link_check_uncongested();
910 } else {
911 /* There is no data to send, so send SYMM */
912 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) {
913 if (llcp_cb.lcb.symm_delay > 0) {
914 /* wait for application layer sending data */
915 llcp_link_start_link_timer();
916 llcp_cb.lcb.is_sending_data = false;
917 return;
918 } else {
919 llcp_link_send_SYMM();
920
921 /* start inactivity timer */
922 if (llcp_cb.num_data_link_connection == 0) {
923 llcp_link_start_inactivity_timer();
924 }
925 }
926 } else {
927 llcp_cb.lcb.is_sending_data = false;
928 return;
929 }
930 }
931
932 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) {
933 /* wait for short period for NFCC to send DISC */
934 nfc_start_quick_timer(&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER,
935 ((uint32_t)50) * QUICK_TIMER_TICKS_PER_SEC / 1000);
936 } else {
937 /* wait for data to receive from remote */
938 llcp_link_start_link_timer();
939 }
940 }
941
942 llcp_cb.lcb.is_sending_data = false;
943 }
944
945 /*******************************************************************************
946 **
947 ** Function llcp_link_proc_ui_pdu
948 **
949 ** Description Process UI PDU from peer device
950 **
951 ** Returns None
952 **
953 *******************************************************************************/
llcp_link_proc_ui_pdu(uint8_t local_sap,uint8_t remote_sap,uint16_t ui_pdu_length,uint8_t * p_ui_pdu,NFC_HDR * p_msg)954 static void llcp_link_proc_ui_pdu(uint8_t local_sap, uint8_t remote_sap,
955 uint16_t ui_pdu_length, uint8_t* p_ui_pdu,
956 NFC_HDR* p_msg) {
957 bool appended;
958 NFC_HDR* p_last_buf;
959 uint16_t available_bytes;
960 uint8_t* p_dst;
961 tLLCP_APP_CB* p_app_cb;
962 tLLCP_SAP_CBACK_DATA data;
963 tLLCP_DLCB* p_dlcb;
964
965 p_app_cb = llcp_util_get_app_cb(local_sap);
966 /*if UI PDU sent to SAP with data link connection*/
967 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap);
968 if (p_dlcb) {
969 llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0);
970 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
971 if (p_msg) {
972 GKI_freebuf(p_msg);
973 }
974 return;
975 }
976
977 /* if application is registered and expecting UI PDU on logical data link */
978 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
979 (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK)) {
980 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
981 "Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap);
982
983 /* if this is not from AGF PDU */
984 if (p_msg) {
985 ui_pdu_length = p_msg->len; /* including LLCP header */
986 p_ui_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
987 }
988
989 appended = false;
990
991 /* get last buffer in rx queue */
992 p_last_buf = (NFC_HDR*)GKI_getlast(&p_app_cb->ui_rx_q);
993
994 if (p_last_buf) {
995 /* get max length to append at the end of buffer */
996 available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
997 p_last_buf->offset - p_last_buf->len;
998
999 /* if new UI PDU with length can be attached at the end of buffer */
1000 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length) {
1001 p_dst =
1002 (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
1003
1004 /* add length of UI PDU */
1005 UINT16_TO_BE_STREAM(p_dst, ui_pdu_length);
1006
1007 /* copy UI PDU with LLCP header */
1008 memcpy(p_dst, p_ui_pdu, ui_pdu_length);
1009
1010 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
1011
1012 if (p_msg) GKI_freebuf(p_msg);
1013
1014 appended = true;
1015 }
1016 }
1017
1018 /* if it is not available to append */
1019 if (!appended) {
1020 /* if it's not from AGF PDU */
1021 if (p_msg) {
1022 /* add length of PDU in front of UI PDU (reuse room for NCI header) */
1023 p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE;
1024 UINT16_TO_BE_STREAM(p_ui_pdu, ui_pdu_length);
1025
1026 p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE;
1027 p_msg->len += LLCP_PDU_AGF_LEN_SIZE;
1028 p_msg->layer_specific = 0;
1029 } else {
1030 p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
1031
1032 if (p_msg) {
1033 p_dst = (uint8_t*)(p_msg + 1);
1034
1035 /* add length of PDU in front of UI PDU */
1036 UINT16_TO_BE_STREAM(p_dst, ui_pdu_length);
1037
1038 memcpy(p_dst, p_ui_pdu, ui_pdu_length);
1039
1040 p_msg->offset = 0;
1041 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length;
1042 p_msg->layer_specific = 0;
1043 } else {
1044 LOG(ERROR) << StringPrintf("out of buffer");
1045 }
1046 }
1047
1048 /* insert UI PDU in rx queue */
1049 if (p_msg) {
1050 GKI_enqueue(&p_app_cb->ui_rx_q, p_msg);
1051 llcp_cb.total_rx_ui_pdu++;
1052 }
1053 }
1054
1055 if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start) {
1056 LOG(WARNING) << StringPrintf(
1057 "SAP:0x%x, rx link is congested (%d), "
1058 "discard oldest UI PDU",
1059 local_sap, p_app_cb->ui_rx_q.count);
1060
1061 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_rx_q));
1062 llcp_cb.total_rx_ui_pdu--;
1063 }
1064
1065 if ((p_app_cb->ui_rx_q.count == 1) && (appended == false)) {
1066 data.data_ind.event = LLCP_SAP_EVT_DATA_IND;
1067 data.data_ind.local_sap = local_sap;
1068 data.data_ind.remote_sap = remote_sap;
1069 data.data_ind.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK;
1070 (*p_app_cb->p_app_cback)(&data);
1071 }
1072 } else {
1073 LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", local_sap);
1074
1075 if (p_msg) {
1076 GKI_freebuf(p_msg);
1077 }
1078 }
1079 }
1080
1081 /*******************************************************************************
1082 **
1083 ** Function llcp_link_proc_agf_pdu
1084 **
1085 ** Description Process AGF PDU from peer device
1086 **
1087 ** Returns void
1088 **
1089 *******************************************************************************/
llcp_link_proc_agf_pdu(NFC_HDR * p_agf)1090 static void llcp_link_proc_agf_pdu(NFC_HDR* p_agf) {
1091 uint16_t agf_length;
1092 uint8_t *p, *p_info, *p_pdu_length;
1093 uint16_t pdu_hdr, pdu_length, pdu_num;
1094 uint8_t dsap, ptype, ssap;
1095
1096 p_agf->len -= LLCP_PDU_HEADER_SIZE;
1097 p_agf->offset += LLCP_PDU_HEADER_SIZE;
1098
1099 /*
1100 ** check integrity of AGF PDU and get number of PDUs in AGF PDU
1101 */
1102 agf_length = p_agf->len;
1103 p = (uint8_t*)(p_agf + 1) + p_agf->offset;
1104 pdu_num = 0;
1105
1106 while (agf_length > 0) {
1107 if (agf_length > LLCP_PDU_AGF_LEN_SIZE) {
1108 BE_STREAM_TO_UINT16(pdu_length, p);
1109 if (pdu_length < LLCP_PDU_HEADER_SIZE) {
1110 LOG(ERROR) << StringPrintf("Received invalid encapsulated PDU");
1111 break;
1112 }
1113 agf_length -= LLCP_PDU_AGF_LEN_SIZE;
1114 } else {
1115 break;
1116 }
1117
1118 if (pdu_length <= agf_length) {
1119 p += pdu_length;
1120 agf_length -= pdu_length;
1121 pdu_num++;
1122 } else {
1123 break;
1124 }
1125 }
1126
1127 if (agf_length != 0 || pdu_num < 2) {
1128 android_errorWriteLog(0x534e4554, "116791157");
1129 LOG(ERROR) << StringPrintf("Received invalid AGF PDU");
1130 GKI_freebuf(p_agf);
1131 return;
1132 }
1133
1134 /*
1135 ** Process PDUs in AGF
1136 */
1137 agf_length = p_agf->len;
1138 p = (uint8_t*)(p_agf + 1) + p_agf->offset;
1139
1140 while (agf_length >= (LLCP_PDU_HEADER_SIZE + LLCP_PDU_AGF_LEN_SIZE)) {
1141 /* get length of PDU */
1142 p_pdu_length = p;
1143 BE_STREAM_TO_UINT16(pdu_length, p);
1144 agf_length -= LLCP_PDU_AGF_LEN_SIZE;
1145
1146 /* get DSAP/PTYPE/SSAP */
1147 p_info = p;
1148 BE_STREAM_TO_UINT16(pdu_hdr, p_info);
1149
1150 dsap = LLCP_GET_DSAP(pdu_hdr);
1151 ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
1152 ssap = LLCP_GET_SSAP(pdu_hdr);
1153
1154 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1155 "Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x "
1156 "in AGF",
1157 dsap, llcp_pdu_type(ptype).c_str(), ptype, ssap);
1158
1159 if ((ptype == LLCP_PDU_DISC_TYPE) && (dsap == LLCP_SAP_LM) &&
1160 (ssap == LLCP_SAP_LM)) {
1161 GKI_freebuf(p_agf);
1162 llcp_link_deactivate(LLCP_LINK_REMOTE_INITIATED);
1163 return;
1164 } else if (ptype == LLCP_PDU_AGF_TYPE) {
1165 LOG(ERROR) << StringPrintf("AGF PDU shall not be in AGF");
1166 } else if (ptype == LLCP_PDU_SYMM_TYPE) {
1167 LOG(ERROR) << StringPrintf("SYMM PDU exchange shall not be in AGF");
1168 } else if (ptype == LLCP_PDU_PAX_TYPE) {
1169 LOG(ERROR) << StringPrintf("PAX PDU exchange shall not be used");
1170 } else if (ptype == LLCP_PDU_SNL_TYPE) {
1171 llcp_sdp_proc_snl((uint16_t)(pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
1172 } else if ((ptype == LLCP_PDU_UI_TYPE) &&
1173 (pdu_length > LLCP_PDU_HEADER_SIZE)) {
1174 llcp_link_proc_ui_pdu(dsap, ssap, pdu_length, p, nullptr);
1175 } else if (ptype == LLCP_PDU_I_TYPE) {
1176 llcp_dlc_proc_i_pdu(dsap, ssap, pdu_length, p, nullptr);
1177 } else /* let data link connection handle PDU */
1178 {
1179 llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
1180 (uint16_t)(pdu_length - LLCP_PDU_HEADER_SIZE),
1181 p_info);
1182 }
1183
1184 p += pdu_length;
1185 agf_length -= pdu_length;
1186 }
1187
1188 GKI_freebuf(p_agf);
1189 }
1190
1191 /*******************************************************************************
1192 **
1193 ** Function llcp_link_proc_rx_pdu
1194 **
1195 ** Description Process received PDU from peer device
1196 **
1197 ** Returns void
1198 **
1199 *******************************************************************************/
llcp_link_proc_rx_pdu(uint8_t dsap,uint8_t ptype,uint8_t ssap,NFC_HDR * p_msg)1200 static void llcp_link_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1201 NFC_HDR* p_msg) {
1202 bool free_buffer = true;
1203 uint8_t* p_data;
1204
1205 switch (ptype) {
1206 case LLCP_PDU_PAX_TYPE:
1207 LOG(ERROR) << StringPrintf("; PAX PDU exchange shall not be used");
1208 break;
1209
1210 case LLCP_PDU_DISC_TYPE:
1211 if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM)) {
1212 llcp_link_deactivate(LLCP_LINK_REMOTE_INITIATED);
1213 } else {
1214 p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1215 llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
1216 (uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE),
1217 p_data);
1218 }
1219 break;
1220
1221 case LLCP_PDU_SNL_TYPE:
1222 p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1223 llcp_sdp_proc_snl((uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1224 break;
1225
1226 case LLCP_PDU_AGF_TYPE:
1227 llcp_link_proc_agf_pdu(p_msg);
1228 free_buffer = false;
1229 break;
1230
1231 case LLCP_PDU_UI_TYPE:
1232 llcp_link_proc_ui_pdu(dsap, ssap, 0, nullptr, p_msg);
1233 free_buffer = false;
1234 break;
1235
1236 case LLCP_PDU_I_TYPE:
1237 llcp_dlc_proc_i_pdu(dsap, ssap, 0, nullptr, p_msg);
1238 free_buffer = false;
1239 break;
1240
1241 default:
1242 p_data = (uint8_t*)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1243 llcp_dlc_proc_rx_pdu(dsap, ptype, ssap,
1244 (uint16_t)(p_msg->len - LLCP_PDU_HEADER_SIZE),
1245 p_data);
1246 break;
1247 }
1248
1249 if (free_buffer) GKI_freebuf(p_msg);
1250 }
1251
1252 /*******************************************************************************
1253 **
1254 ** Function llcp_link_proc_rx_data
1255 **
1256 ** Description Process received data from NFCC and maintain symmetry state
1257 **
1258 ** Returns void
1259 **
1260 *******************************************************************************/
llcp_link_proc_rx_data(NFC_HDR * p_msg)1261 static void llcp_link_proc_rx_data(NFC_HDR* p_msg) {
1262 uint8_t* p;
1263 uint16_t pdu_hdr, info_length = 0;
1264 uint8_t dsap, ptype, ssap;
1265 bool free_buffer = true;
1266 bool frame_error = false;
1267
1268 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) {
1269 llcp_link_stop_link_timer();
1270
1271 if (llcp_cb.lcb.received_first_packet == false) {
1272 llcp_cb.lcb.received_first_packet = true;
1273 (*llcp_cb.lcb.p_link_cback)(LLCP_LINK_FIRST_PACKET_RECEIVED_EVT,
1274 LLCP_LINK_SUCCESS);
1275 }
1276 if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) &&
1277 (llcp_cb.lcb.sig_xmit_q.count == 0)) {
1278 /* this indicates that DISC PDU had been sent out to peer */
1279 /* initiator may wait for SYMM PDU */
1280 if (appl_dta_mode_flag == 0x01)
1281 llcp_util_send_disc(LLCP_SAP_LM, LLCP_SAP_LM);
1282 else
1283 llcp_link_process_link_timeout();
1284 } else {
1285 if (p_msg->len < LLCP_PDU_HEADER_SIZE) {
1286 LOG(ERROR) << StringPrintf("Received too small PDU: got %d bytes",
1287 p_msg->len);
1288 frame_error = true;
1289 } else {
1290 p = (uint8_t*)(p_msg + 1) + p_msg->offset;
1291 BE_STREAM_TO_UINT16(pdu_hdr, p);
1292
1293 dsap = LLCP_GET_DSAP(pdu_hdr);
1294 ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
1295 ssap = LLCP_GET_SSAP(pdu_hdr);
1296
1297 /* get length of information per PDU type */
1298 if ((ptype == LLCP_PDU_I_TYPE) || (ptype == LLCP_PDU_RR_TYPE) ||
1299 (ptype == LLCP_PDU_RNR_TYPE)) {
1300 if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE) {
1301 info_length =
1302 p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
1303 } else {
1304 LOG(ERROR) << StringPrintf(
1305 "Received I/RR/RNR PDU without sequence");
1306 frame_error = true;
1307 }
1308 } else {
1309 info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
1310 }
1311
1312 /* check if length of information is bigger than link MIU */
1313 if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu)) {
1314 LOG(ERROR) << StringPrintf(
1315 "Received exceeding MIU (%d): got %d bytes SDU",
1316 llcp_cb.lcb.local_link_miu, info_length);
1317
1318 frame_error = true;
1319 } else {
1320 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1321 "DSAP:0x%x, PTYPE:%s (0x%x), "
1322 "SSAP:0x%x",
1323 dsap, llcp_pdu_type(ptype).c_str(), ptype, ssap);
1324
1325 if (ptype == LLCP_PDU_SYMM_TYPE) {
1326 if (info_length > 0) {
1327 LOG(ERROR) << StringPrintf(
1328 "Received extra data (%d bytes) in SYMM PDU", info_length);
1329 frame_error = true;
1330 }
1331 } else {
1332 /* received other than SYMM */
1333 llcp_link_stop_inactivity_timer();
1334
1335 llcp_link_proc_rx_pdu(dsap, ptype, ssap, p_msg);
1336 free_buffer = false;
1337 }
1338 }
1339 }
1340
1341 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
1342
1343 /* check if any pending packet */
1344 llcp_link_check_send_data();
1345 }
1346 } else {
1347 LOG(ERROR) << StringPrintf("Received PDU in state of SYMM_MUST_XMIT_NEXT");
1348 }
1349
1350 if (free_buffer) GKI_freebuf(p_msg);
1351 }
1352
1353 /*******************************************************************************
1354 **
1355 ** Function llcp_link_get_next_pdu
1356 **
1357 ** Description Get next PDU from link manager or data links w/wo dequeue
1358 **
1359 ** Returns pointer of a PDU to send if length_only is FALSE
1360 ** NULL otherwise
1361 **
1362 *******************************************************************************/
llcp_link_get_next_pdu(bool length_only,uint16_t * p_next_pdu_length)1363 static NFC_HDR* llcp_link_get_next_pdu(bool length_only,
1364 uint16_t* p_next_pdu_length) {
1365 NFC_HDR* p_msg;
1366 int count, xx;
1367 tLLCP_APP_CB* p_app_cb;
1368
1369 /* processing signalling PDU first */
1370 if (llcp_cb.lcb.sig_xmit_q.p_first) {
1371 if (length_only) {
1372 p_msg = (NFC_HDR*)llcp_cb.lcb.sig_xmit_q.p_first;
1373 *p_next_pdu_length = p_msg->len;
1374 return nullptr;
1375 } else
1376 p_msg = (NFC_HDR*)GKI_dequeue(&llcp_cb.lcb.sig_xmit_q);
1377
1378 return p_msg;
1379 } else {
1380 /* transmitting logical data link and data link connection equaly */
1381 for (xx = 0; xx < 2; xx++) {
1382 if (!llcp_cb.lcb.ll_served) {
1383 /* Get one from logical link connection */
1384 for (count = 0; count < LLCP_NUM_SAPS; count++) {
1385 /* round robin schedule without priority */
1386 p_app_cb = llcp_util_get_app_cb(llcp_cb.lcb.ll_idx);
1387
1388 if ((p_app_cb) && (p_app_cb->p_app_cback) &&
1389 (p_app_cb->ui_xmit_q.count)) {
1390 if (length_only) {
1391 /* don't alternate next data link to return the same length of PDU
1392 */
1393 p_msg = (NFC_HDR*)p_app_cb->ui_xmit_q.p_first;
1394 *p_next_pdu_length = p_msg->len;
1395 return nullptr;
1396 } else {
1397 /* check data link connection first in next time */
1398 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1399
1400 p_msg = (NFC_HDR*)GKI_dequeue(&p_app_cb->ui_xmit_q);
1401 llcp_cb.total_tx_ui_pdu--;
1402
1403 /* this logical link has been served, so start from next logical
1404 * link next time */
1405 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1406
1407 return p_msg;
1408 }
1409 } else {
1410 /* check next logical link connection */
1411 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1412 }
1413 }
1414
1415 /* no data, so check data link connection if not checked yet */
1416 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1417 } else {
1418 /* Get one from data link connection */
1419 for (count = 0; count < LLCP_MAX_DATA_LINK; count++) {
1420 /* round robin schedule without priority */
1421 if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE) {
1422 if (length_only) {
1423 *p_next_pdu_length = llcp_dlc_get_next_pdu_length(
1424 &llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
1425
1426 if (*p_next_pdu_length > 0) {
1427 /* don't change data link connection to return the same length
1428 * of PDU */
1429 return nullptr;
1430 } else {
1431 /* no data, so check next data link connection */
1432 llcp_cb.lcb.dl_idx =
1433 (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1434 }
1435 } else {
1436 p_msg = llcp_dlc_get_next_pdu(&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
1437
1438 /* this data link has been served, so start from next data link
1439 * next time */
1440 llcp_cb.lcb.dl_idx =
1441 (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1442
1443 if (p_msg) {
1444 /* serve logical data link next time */
1445 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1446 return p_msg;
1447 }
1448 }
1449 } else {
1450 /* check next data link connection */
1451 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1452 }
1453 }
1454
1455 /* if all of data link connection doesn't have data to send */
1456 if (count >= LLCP_MAX_DATA_LINK) {
1457 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1458 }
1459 }
1460 }
1461 }
1462
1463 /* nothing to send */
1464 *p_next_pdu_length = 0;
1465 return nullptr;
1466 }
1467
1468 /*******************************************************************************
1469 **
1470 ** Function llcp_link_build_next_pdu
1471 **
1472 ** Description Build a PDU from Link Manager and Data Link
1473 ** Perform aggregation procedure if necessary
1474 **
1475 ** Returns NFC_HDR* if sent any PDU
1476 **
1477 *******************************************************************************/
llcp_link_build_next_pdu(NFC_HDR * p_pdu)1478 static NFC_HDR* llcp_link_build_next_pdu(NFC_HDR* p_pdu) {
1479 NFC_HDR *p_agf = nullptr, *p_msg = nullptr, *p_next_pdu;
1480 uint8_t *p, ptype;
1481 uint16_t next_pdu_length, pdu_hdr;
1482
1483 DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1484
1485 /* add any pending SNL PDU into sig_xmit_q for transmitting */
1486 llcp_sdp_check_send_snl();
1487
1488 if (p_pdu) {
1489 /* get PDU type */
1490 p = (uint8_t*)(p_pdu + 1) + p_pdu->offset;
1491 BE_STREAM_TO_UINT16(pdu_hdr, p);
1492
1493 ptype = (uint8_t)(LLCP_GET_PTYPE(pdu_hdr));
1494
1495 if (ptype == LLCP_PDU_AGF_TYPE) {
1496 /* add more PDU into this AGF PDU */
1497 p_agf = p_pdu;
1498 } else {
1499 p_msg = p_pdu;
1500 }
1501 } else {
1502 /* Get a PDU from link manager or data links */
1503 p_msg = llcp_link_get_next_pdu(false, &next_pdu_length);
1504
1505 if (!p_msg) {
1506 return nullptr;
1507 }
1508 }
1509
1510 /* Get length of next PDU from link manager or data links without dequeue */
1511 llcp_link_get_next_pdu(true, &next_pdu_length);
1512 while (next_pdu_length > 0) {
1513 /* if it's first visit */
1514 if (!p_agf) {
1515 /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
1516 if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu) {
1517 p_agf = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
1518 if (p_agf) {
1519 p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1520
1521 p = (uint8_t*)(p_agf + 1) + p_agf->offset;
1522
1523 UINT16_TO_BE_STREAM(
1524 p,
1525 LLCP_GET_PDU_HEADER(LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM));
1526 UINT16_TO_BE_STREAM(p, p_msg->len);
1527 memcpy(p, (uint8_t*)(p_msg + 1) + p_msg->offset, p_msg->len);
1528
1529 p_agf->len = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
1530
1531 GKI_freebuf(p_msg);
1532 p_msg = p_agf;
1533 } else {
1534 LOG(ERROR) << StringPrintf("Out of buffer");
1535 return p_msg;
1536 }
1537 } else {
1538 break;
1539 }
1540 }
1541
1542 /* if next PDU fits into MIU, copy the next PDU into AGF */
1543 if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <=
1544 llcp_cb.lcb.effective_miu) {
1545 /* Get a next PDU from link manager or data links */
1546 p_next_pdu = llcp_link_get_next_pdu(false, &next_pdu_length);
1547
1548 p = (uint8_t*)(p_agf + 1) + p_agf->offset + p_agf->len;
1549
1550 UINT16_TO_BE_STREAM(p, p_next_pdu->len);
1551 memcpy(p, (uint8_t*)(p_next_pdu + 1) + p_next_pdu->offset,
1552 p_next_pdu->len);
1553
1554 p_agf->len += 2 + p_next_pdu->len;
1555
1556 GKI_freebuf(p_next_pdu);
1557
1558 /* Get next PDU length from link manager or data links without dequeue */
1559 llcp_link_get_next_pdu(true, &next_pdu_length);
1560 } else {
1561 break;
1562 }
1563 }
1564
1565 if (p_agf)
1566 return p_agf;
1567 else
1568 return p_msg;
1569 }
1570
1571 /*******************************************************************************
1572 **
1573 ** Function llcp_link_send_to_lower
1574 **
1575 ** Description Send PDU to lower layer
1576 **
1577 ** Returns void
1578 **
1579 *******************************************************************************/
llcp_link_send_to_lower(NFC_HDR * p_pdu)1580 static void llcp_link_send_to_lower(NFC_HDR* p_pdu) {
1581 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
1582 NFC_SendData(NFC_RF_CONN_ID, p_pdu);
1583 }
1584
1585 /*******************************************************************************
1586 **
1587 ** Function llcp_link_connection_cback
1588 **
1589 ** Description processing incoming data
1590 **
1591 ** Returns void
1592 **
1593 *******************************************************************************/
llcp_link_connection_cback(uint8_t conn_id,tNFC_CONN_EVT event,tNFC_CONN * p_data)1594 void llcp_link_connection_cback(__attribute__((unused)) uint8_t conn_id,
1595 tNFC_CONN_EVT event, tNFC_CONN* p_data) {
1596 if (event == NFC_DATA_CEVT) {
1597 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED) {
1598 /* respoding SYMM while LLCP is deactivated but RF link is not deactivated
1599 * yet */
1600 llcp_link_send_SYMM();
1601 GKI_freebuf((NFC_HDR*)p_data->data.p_data);
1602 } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATION_FAILED) {
1603 /* respoding with invalid LLC PDU until initiator deactivates RF link
1604 *after LLCP activation was failed,
1605 ** so that initiator knows LLCP link activation was failed.
1606 */
1607 llcp_link_send_invalid_pdu();
1608 GKI_freebuf((NFC_HDR*)p_data->data.p_data);
1609 } else {
1610 llcp_cb.lcb.flags |= LLCP_LINK_FLAGS_RX_ANY_LLC_PDU;
1611 llcp_link_proc_rx_data((NFC_HDR*)p_data->data.p_data);
1612 }
1613 } else if (event == NFC_ERROR_CEVT) {
1614 /* RF interface specific status code */
1615 llcp_link_deactivate(*(uint8_t*)p_data);
1616 } else if (event == NFC_DEACTIVATE_CEVT) {
1617 if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) &&
1618 (!llcp_cb.lcb.is_initiator)) {
1619 /* peer initiates NFC link deactivation before timeout */
1620 llcp_link_stop_link_timer();
1621 llcp_link_process_link_timeout();
1622 } else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATION_FAILED) {
1623 /* do not notify to upper layer because activation failure was already
1624 * notified */
1625 NFC_FlushData(NFC_RF_CONN_ID);
1626 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED;
1627 } else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED) {
1628 llcp_link_deactivate(LLCP_LINK_RF_LINK_LOSS_ERR);
1629 }
1630
1631 NFC_SetStaticRfCback(nullptr);
1632 } else if (event == NFC_DATA_START_CEVT) {
1633 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) {
1634 /* LLCP shall stop LTO timer when receiving the first bit of LLC PDU */
1635 llcp_link_stop_link_timer();
1636 }
1637 }
1638
1639 /* LLCP ignores the following events
1640
1641 NFC_CONN_CREATE_CEVT
1642 NFC_CONN_CLOSE_CEVT
1643 */
1644 }
1645
1646 /*******************************************************************************
1647 **
1648 ** Function llcp_pdu_type
1649 **
1650 ** Description
1651 **
1652 ** Returns string of PDU type
1653 **
1654 *******************************************************************************/
llcp_pdu_type(uint8_t ptype)1655 static std::string llcp_pdu_type(uint8_t ptype) {
1656 switch (ptype) {
1657 case LLCP_PDU_SYMM_TYPE:
1658 return "SYMM";
1659 case LLCP_PDU_PAX_TYPE:
1660 return "PAX";
1661 case LLCP_PDU_AGF_TYPE:
1662 return "AGF";
1663 case LLCP_PDU_UI_TYPE:
1664 return "UI";
1665 case LLCP_PDU_CONNECT_TYPE:
1666 return "CONNECT";
1667 case LLCP_PDU_DISC_TYPE:
1668 return "DISC";
1669 case LLCP_PDU_CC_TYPE:
1670 return "CC";
1671 case LLCP_PDU_DM_TYPE:
1672 return "DM";
1673 case LLCP_PDU_FRMR_TYPE:
1674 return "FRMR";
1675 case LLCP_PDU_SNL_TYPE:
1676 return "SNL";
1677 case LLCP_PDU_I_TYPE:
1678 return "I";
1679 case LLCP_PDU_RR_TYPE:
1680 return "RR";
1681 case LLCP_PDU_RNR_TYPE:
1682 return "RNR";
1683 default:
1684 return "RESERVED";
1685 }
1686 }
1687