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