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