• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2010-2014 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains the LLCP 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