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