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