llcp_link.c revision 26620e3108f6a0f32f5f0a0725e28e5ae66017d6
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)
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_PAX_TYPE)
1117        {
1118            LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu(): PAX PDU exchange shall not be used");
1119        }
1120        else if (ptype == LLCP_PDU_SNL_TYPE)
1121        {
1122            if (llcp_sdp_proc_snl ((UINT16)(pdu_length - LLCP_PDU_HEADER_SIZE), p_info) != LLCP_STATUS_SUCCESS)
1123            {
1124                GKI_freebuf (p_agf);
1125                llcp_link_deactivate (LLCP_LINK_FRAME_ERROR);
1126                return;
1127            }
1128        }
1129        else if ((ptype == LLCP_PDU_UI_TYPE) && (pdu_length > LLCP_PDU_HEADER_SIZE))
1130        {
1131            llcp_link_proc_ui_pdu (dsap, ssap, pdu_length, p, NULL);
1132        }
1133        else if (ptype == LLCP_PDU_I_TYPE)
1134        {
1135            llcp_dlc_proc_i_pdu (dsap, ssap, pdu_length, p, NULL);
1136        }
1137        else /* let data link connection handle PDU */
1138        {
1139            llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16)(pdu_length - LLCP_PDU_HEADER_SIZE), p_info);
1140        }
1141
1142        p += pdu_length;
1143        agf_length -= pdu_length;
1144    }
1145
1146    GKI_freebuf (p_agf);
1147}
1148
1149/*******************************************************************************
1150**
1151** Function         llcp_link_proc_rx_pdu
1152**
1153** Description      Process received PDU from peer device
1154**
1155** Returns          void
1156**
1157*******************************************************************************/
1158static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg)
1159{
1160    BOOLEAN free_buffer = TRUE;
1161    UINT8   *p_data;
1162
1163    switch(ptype)
1164    {
1165    case LLCP_PDU_PAX_TYPE:
1166        LLCP_TRACE_ERROR0 ("llcp_link_proc_rx_pdu(); PAX PDU exchange shall not be used");
1167        break;
1168
1169    case LLCP_PDU_DISC_TYPE:
1170        if ((dsap == LLCP_SAP_LM)&&(ssap == LLCP_SAP_LM))
1171        {
1172            llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED);
1173        }
1174        else
1175        {
1176            p_data = (UINT8 *)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1177            llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16)(p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1178        }
1179        break;
1180
1181    case LLCP_PDU_SNL_TYPE:
1182        p_data = (UINT8 *)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1183        if (llcp_sdp_proc_snl ((UINT16)(p_msg->len - LLCP_PDU_HEADER_SIZE), p_data) != LLCP_STATUS_SUCCESS)
1184        {
1185            llcp_link_deactivate (LLCP_LINK_FRAME_ERROR);
1186        }
1187        break;
1188
1189    case LLCP_PDU_AGF_TYPE:
1190        llcp_link_proc_agf_pdu (p_msg);
1191        free_buffer = FALSE;
1192        break;
1193
1194    case LLCP_PDU_UI_TYPE:
1195        llcp_link_proc_ui_pdu (dsap, ssap, 0, NULL, p_msg);
1196        free_buffer = FALSE;
1197        break;
1198
1199    case LLCP_PDU_I_TYPE:
1200        llcp_dlc_proc_i_pdu (dsap, ssap, 0, NULL, p_msg);
1201        free_buffer = FALSE;
1202        break;
1203
1204    default:
1205        p_data = (UINT8 *)(p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE;
1206        llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16)(p_msg->len - LLCP_PDU_HEADER_SIZE), p_data);
1207        break;
1208    }
1209
1210    if (free_buffer)
1211        GKI_freebuf(p_msg);
1212}
1213
1214/*******************************************************************************
1215**
1216** Function         llcp_link_proc_rx_data
1217**
1218** Description      Process received data from NFCC and maintain symmetry state
1219**
1220** Returns          void
1221**
1222*******************************************************************************/
1223static void llcp_link_proc_rx_data (BT_HDR *p_msg)
1224{
1225    UINT8  *p;
1226    UINT16  pdu_hdr, info_length = 0;
1227    UINT8   dsap, ptype, ssap;
1228    BOOLEAN free_buffer = TRUE;
1229    BOOLEAN frame_error = FALSE;
1230
1231    if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT)
1232    {
1233        llcp_link_stop_link_timer ();
1234
1235        if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
1236          &&(llcp_cb.lcb.sig_xmit_q.count == 0))
1237        {
1238            /* this indicates that DISC PDU had been sent out to peer */
1239            /* initiator may wait for SYMM PDU */
1240            llcp_link_process_link_timeout ();
1241        }
1242        else
1243        {
1244            if (p_msg->len < LLCP_PDU_HEADER_SIZE)
1245            {
1246                LLCP_TRACE_ERROR1 ("Received too small PDU: got %d bytes", p_msg->len);
1247                frame_error = TRUE;
1248            }
1249            else
1250            {
1251                p = (UINT8 *)(p_msg + 1) + p_msg->offset;
1252                BE_STREAM_TO_UINT16 ( pdu_hdr, p );
1253
1254                dsap  = LLCP_GET_DSAP(pdu_hdr);
1255                ptype = (UINT8)(LLCP_GET_PTYPE(pdu_hdr));
1256                ssap  = LLCP_GET_SSAP(pdu_hdr);
1257
1258                /* get length of information per PDU type */
1259                if ((ptype == LLCP_PDU_I_TYPE)
1260                  ||(ptype == LLCP_PDU_RR_TYPE)
1261                  ||(ptype == LLCP_PDU_RNR_TYPE))
1262                {
1263                    if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE)
1264                    {
1265                        info_length = p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
1266                    }
1267                    else
1268                    {
1269                        LLCP_TRACE_ERROR0 ("Received I/RR/RNR PDU without sequence");
1270                        frame_error = TRUE;
1271                    }
1272                }
1273                else
1274                {
1275                    info_length = p_msg->len - LLCP_PDU_HEADER_SIZE;
1276                }
1277
1278                /* check if length of information is bigger than link MIU */
1279                if ((!frame_error)&&(info_length > llcp_cb.lcb.local_link_miu))
1280                {
1281                    LLCP_TRACE_ERROR2 ("Received exceeding MIU(%d): got %d bytes SDU",
1282                                       llcp_cb.lcb.local_link_miu, info_length);
1283
1284                    frame_error = TRUE;
1285                }
1286                else
1287                {
1288#if (BT_TRACE_VERBOSE == TRUE)
1289                    LLCP_TRACE_DEBUG4 ("llcp_link_proc_rx_data(): DSAP:0x%x, PTYPE:%s(0x%x), SSAP:0x%x",
1290                                       dsap, llcp_pdu_type (ptype), ptype, ssap);
1291#endif
1292
1293                    if (ptype == LLCP_PDU_SYMM_TYPE)
1294                    {
1295                        if (info_length > 0)
1296                        {
1297                            LLCP_TRACE_ERROR1 ("Received extra data(%d bytes) in SYMM PDU", info_length);
1298                            frame_error = TRUE;
1299                        }
1300                    }
1301                    else
1302                    {
1303                        /* received other than SYMM */
1304                        llcp_link_stop_inactivity_timer ();
1305
1306                        llcp_link_proc_rx_pdu (dsap, ptype, ssap, p_msg);
1307                        free_buffer = FALSE;
1308                    }
1309                }
1310            }
1311
1312            llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT;
1313
1314            if (!frame_error)
1315            {
1316                /* check if any pending packet */
1317                llcp_link_check_send_data ();
1318            }
1319        }
1320    }
1321    else
1322    {
1323        LLCP_TRACE_ERROR0 ("Received PDU in state of SYMM_MUST_XMIT_NEXT");
1324    }
1325
1326    if (frame_error)
1327        llcp_link_deactivate (LLCP_LINK_FRAME_ERROR);
1328
1329    if (free_buffer)
1330        GKI_freebuf(p_msg);
1331}
1332
1333/*******************************************************************************
1334**
1335** Function         llcp_link_get_next_pdu
1336**
1337** Description      Get next PDU from link manager or data links w/wo dequeue
1338**
1339** Returns          pointer of a PDU to send if length_only is FALSE
1340**                  NULL otherwise
1341**
1342*******************************************************************************/
1343static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length)
1344{
1345    BT_HDR *p_msg;
1346    int     count, xx;
1347    tLLCP_APP_CB *p_app_cb;
1348
1349    /* processing signalling PDU first */
1350    if (llcp_cb.lcb.sig_xmit_q.p_first)
1351    {
1352        if (length_only)
1353        {
1354            p_msg = (BT_HDR*)llcp_cb.lcb.sig_xmit_q.p_first;
1355            *p_next_pdu_length = p_msg->len;
1356            return NULL;
1357        }
1358        else
1359            p_msg = (BT_HDR*)GKI_dequeue (&llcp_cb.lcb.sig_xmit_q);
1360
1361        return p_msg;
1362    }
1363    else
1364    {
1365        /* transmitting logical data link and data link connection equaly */
1366        for (xx = 0; xx < 2; xx++)
1367        {
1368            if (!llcp_cb.lcb.ll_served)
1369            {
1370                /* Get one from logical link connection */
1371                for (count = 0; count < LLCP_NUM_SAPS; count++)
1372                {
1373                    /* round robin schedule without priority  */
1374                    p_app_cb = llcp_util_get_app_cb (llcp_cb.lcb.ll_idx);
1375
1376                    if ((p_app_cb)
1377                      &&(p_app_cb->p_app_cback)
1378                      &&(p_app_cb->ui_xmit_q.count))
1379                    {
1380                        if (length_only)
1381                        {
1382                            /* don't alternate next data link to return the same length of PDU */
1383                            p_msg = (BT_HDR *)p_app_cb->ui_xmit_q.p_first;
1384                            *p_next_pdu_length = p_msg->len;
1385                            return NULL;
1386                        }
1387                        else
1388                        {
1389                            /* check data link connection first in next time */
1390                            llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1391
1392                            p_msg = (BT_HDR*)GKI_dequeue (&p_app_cb->ui_xmit_q);
1393                            llcp_cb.total_tx_ui_pdu--;
1394
1395                            /* this logical link has been served, so start from next logical link next time */
1396                            llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1397
1398                            return p_msg;
1399                        }
1400                    }
1401                    else
1402                    {
1403                        /* check next logical link connection */
1404                        llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS;
1405                    }
1406                }
1407
1408                /* no data, so check data link connection if not checked yet */
1409                llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1410            }
1411            else
1412            {
1413                /* Get one from data link connection */
1414                for (count = 0; count < LLCP_MAX_DATA_LINK; count++)
1415                {
1416                    /* round robin schedule without priority  */
1417                    if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE)
1418                    {
1419                        if (length_only)
1420                        {
1421                            *p_next_pdu_length = llcp_dlc_get_next_pdu_length (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
1422
1423                            if (*p_next_pdu_length > 0 )
1424                            {
1425                                /* don't change data link connection to return the same length of PDU */
1426                                return NULL;
1427                            }
1428                            else
1429                            {
1430                                /* no data, so check next data link connection */
1431                                llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1432                            }
1433                        }
1434                        else
1435                        {
1436                            p_msg = llcp_dlc_get_next_pdu (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]);
1437
1438                            /* this data link has been served, so start from next data link next time */
1439                            llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1440
1441                            if (p_msg)
1442                            {
1443                                /* serve logical data link next time */
1444                                llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1445                                return p_msg;
1446                            }
1447                        }
1448                    }
1449                    else
1450                    {
1451                        /* check next data link connection */
1452                        llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK;
1453                    }
1454                }
1455
1456                /* if all of data link connection doesn't have data to send */
1457                if (count >= LLCP_MAX_DATA_LINK)
1458                {
1459                    llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served;
1460                }
1461            }
1462        }
1463    }
1464
1465    /* nothing to send */
1466    *p_next_pdu_length = 0;
1467    return NULL;
1468}
1469
1470/*******************************************************************************
1471**
1472** Function         llcp_link_build_next_pdu
1473**
1474** Description      Build a PDU from Link Manager and Data Link
1475**                  Perform aggregation procedure if necessary
1476**
1477** Returns          BT_HDR* if sent any PDU
1478**
1479*******************************************************************************/
1480static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_pdu)
1481{
1482    BT_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu;
1483    UINT8  *p, ptype;
1484    UINT16  next_pdu_length, pdu_hdr;
1485
1486    LLCP_TRACE_DEBUG0 ("llcp_link_build_next_pdu()");
1487
1488    /* add any pending SNL PDU into sig_xmit_q for transmitting */
1489    llcp_sdp_check_send_snl ();
1490
1491    if (p_pdu)
1492    {
1493        /* get PDU type */
1494        p = (UINT8 *)(p_pdu + 1) + p_pdu->offset;
1495        BE_STREAM_TO_UINT16 (pdu_hdr, p);
1496
1497        ptype = (UINT8)(LLCP_GET_PTYPE(pdu_hdr));
1498
1499        if (ptype == LLCP_PDU_AGF_TYPE)
1500        {
1501            /* add more PDU into this AGF PDU */
1502            p_agf = p_pdu;
1503        }
1504        else
1505        {
1506            p_msg = p_pdu;
1507        }
1508    }
1509    else
1510    {
1511        /* Get a PDU from link manager or data links */
1512        p_msg = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
1513
1514        if (!p_msg)
1515        {
1516            return NULL;
1517        }
1518    }
1519
1520    /* Get length of next PDU from link manager or data links without dequeue */
1521    llcp_link_get_next_pdu (TRUE, &next_pdu_length);
1522    while (next_pdu_length > 0)
1523    {
1524        /* if it's first visit */
1525        if (!p_agf)
1526        {
1527            /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */
1528            if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
1529            {
1530                p_agf = (BT_HDR*)GKI_getpoolbuf (LLCP_POOL_ID);
1531                if (p_agf)
1532                {
1533                    p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE;
1534
1535                    p = (UINT8 *)(p_agf + 1) + p_agf->offset;
1536
1537                    UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER( LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM ));
1538                    UINT16_TO_BE_STREAM (p, p_msg->len);
1539                    memcpy(p, (UINT8 *)(p_msg + 1) + p_msg->offset, p_msg->len);
1540
1541                    p_agf->len      = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len;
1542
1543                    GKI_freebuf (p_msg);
1544                    p_msg = p_agf;
1545                }
1546                else
1547                {
1548                    LLCP_TRACE_ERROR0 ("llcp_link_build_next_pdu(): Out of buffer");
1549                    return p_msg;
1550                }
1551            }
1552            else
1553            {
1554                break;
1555            }
1556        }
1557
1558        /* if next PDU fits into MIU, copy the next PDU into AGF */
1559        if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu)
1560        {
1561            /* Get a next PDU from link manager or data links */
1562            p_next_pdu = llcp_link_get_next_pdu (FALSE, &next_pdu_length);
1563
1564            p = (UINT8 *)(p_agf + 1) + p_agf->offset + p_agf->len;
1565
1566            UINT16_TO_BE_STREAM (p, p_next_pdu->len);
1567            memcpy (p, (UINT8 *)(p_next_pdu + 1) + p_next_pdu->offset, p_next_pdu->len);
1568
1569            p_agf->len += 2 + p_next_pdu->len;
1570
1571            GKI_freebuf (p_next_pdu);
1572
1573            /* Get next PDU length from link manager or data links without dequeue */
1574            llcp_link_get_next_pdu (TRUE, &next_pdu_length);
1575        }
1576        else
1577        {
1578            break;
1579        }
1580    }
1581
1582    if (p_agf)
1583        return p_agf;
1584    else
1585        return p_msg;
1586}
1587
1588/*******************************************************************************
1589**
1590** Function         llcp_link_send_to_lower
1591**
1592** Description      Send PDU to lower layer
1593**
1594** Returns          void
1595**
1596*******************************************************************************/
1597static void llcp_link_send_to_lower (BT_HDR *p_pdu)
1598{
1599#if (BT_TRACE_PROTOCOL == TRUE)
1600    DispLLCP(p_pdu, FALSE);
1601#endif
1602
1603    llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT;
1604
1605    NFC_SendData (NFC_RF_CONN_ID, p_pdu);
1606}
1607
1608/*******************************************************************************
1609**
1610** Function         llcp_link_connection_cback
1611**
1612** Description      processing incoming data
1613**
1614** Returns          void
1615**
1616*******************************************************************************/
1617void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data)
1618{
1619    if (event == NFC_DATA_CEVT)
1620    {
1621#if (BT_TRACE_PROTOCOL == TRUE)
1622        DispLLCP((BT_HDR *)p_data->data.p_data, TRUE);
1623#endif
1624        llcp_link_proc_rx_data ((BT_HDR *)p_data->data.p_data);
1625    }
1626    else if (event == NFC_ERROR_CEVT)
1627    {
1628        /* RF interface specific status code */
1629        llcp_link_deactivate (*(UINT8*)p_data);
1630    }
1631    else if (event == NFC_DEACTIVATE_CEVT)
1632    {
1633        if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING)
1634          &&(!llcp_cb.lcb.is_initiator))
1635        {
1636            /* peer initiates NFC link deactivation before timeout */
1637            llcp_link_stop_link_timer ();
1638            llcp_link_process_link_timeout ();
1639        }
1640        else
1641        {
1642            llcp_link_deactivate (LLCP_LINK_RF_LINK_LOSS_ERR);
1643        }
1644    }
1645
1646    /* LLCP ignores the following events
1647
1648        NFC_CONN_CREATE_CEVT
1649        NFC_CONN_CLOSE_CEVT
1650    */
1651}
1652
1653#if (BT_TRACE_VERBOSE == TRUE)
1654/*******************************************************************************
1655**
1656** Function         llcp_pdu_type
1657**
1658** Description
1659**
1660** Returns          string of PDU type
1661**
1662*******************************************************************************/
1663static char *llcp_pdu_type (UINT8 ptype)
1664{
1665    switch(ptype)
1666    {
1667    case LLCP_PDU_SYMM_TYPE:
1668        return "SYMM";
1669    case LLCP_PDU_PAX_TYPE:
1670        return "PAX";
1671    case LLCP_PDU_AGF_TYPE:
1672        return "AGF";
1673    case LLCP_PDU_UI_TYPE:
1674        return "UI";
1675    case LLCP_PDU_CONNECT_TYPE:
1676        return "CONNECT";
1677    case LLCP_PDU_DISC_TYPE:
1678        return "DISC";
1679    case LLCP_PDU_CC_TYPE:
1680        return "CC";
1681    case LLCP_PDU_DM_TYPE:
1682        return "DM";
1683    case LLCP_PDU_FRMR_TYPE:
1684        return "FRMR";
1685    case LLCP_PDU_SNL_TYPE:
1686        return "SNL";
1687    case LLCP_PDU_I_TYPE:
1688        return "I";
1689    case LLCP_PDU_RR_TYPE:
1690        return "RR";
1691    case LLCP_PDU_RNR_TYPE:
1692        return "RNR";
1693
1694    default:
1695        return "RESERVED";
1696    }
1697}
1698
1699#endif
1700
1701