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