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 Data Link Connection Management
23 *
24 ******************************************************************************/
25
26#include <string.h>
27#include "gki.h"
28#include "nfc_target.h"
29#include "bt_types.h"
30#include "llcp_int.h"
31#include "llcp_defs.h"
32#include "nfc_int.h"
33
34static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
35static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
36static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
37static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
38static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data);
39
40#if (BT_TRACE_VERBOSE == TRUE)
41static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state);
42static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event);
43#endif
44
45/*******************************************************************************
46**
47** Function         llcp_dlsm_execute
48**
49** Description      This function executes the state machine for data link connection.
50**
51** Returns          tLLCP_STATUS
52**
53*******************************************************************************/
54tLLCP_STATUS llcp_dlsm_execute (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
55{
56    tLLCP_STATUS status;
57
58#if (BT_TRACE_VERBOSE == TRUE)
59    LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %s, evt: %s",
60                        p_dlcb->local_sap,
61                        llcp_dlsm_get_state_name (p_dlcb->state),
62                        llcp_dlsm_get_event_name (event));
63#else
64    LLCP_TRACE_EVENT3 ("DLC (0x%02X) - state: %d, evt: %d", p_dlcb->local_sap, p_dlcb->state, event);
65#endif
66
67    switch (p_dlcb->state)
68    {
69    case LLCP_DLC_STATE_IDLE:
70        status = llcp_dlsm_idle (p_dlcb, event, p_data);
71        break;
72
73    case LLCP_DLC_STATE_W4_REMOTE_RESP:
74        status = llcp_dlsm_w4_remote_resp (p_dlcb, event, p_data);
75        break;
76
77    case LLCP_DLC_STATE_W4_LOCAL_RESP:
78        status = llcp_dlsm_w4_local_resp (p_dlcb, event, p_data);
79        break;
80
81    case LLCP_DLC_STATE_CONNECTED:
82        status = llcp_dlsm_connected (p_dlcb, event, p_data);
83        break;
84
85    case LLCP_DLC_STATE_W4_REMOTE_DM:
86        status = llcp_dlsm_w4_remote_dm (p_dlcb, event, p_data);
87        break;
88
89    default:
90        status = LLCP_STATUS_FAIL;
91        break;
92    }
93
94    return status;
95}
96
97/*******************************************************************************
98**
99** Function         llcp_dlsm_idle
100**
101** Description      Data link connection is in idle state
102**
103** Returns          tLLCP_STATUS
104**
105*******************************************************************************/
106static tLLCP_STATUS llcp_dlsm_idle (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
107{
108    tLLCP_STATUS            status = LLCP_STATUS_SUCCESS;
109    tLLCP_SAP_CBACK_DATA    data;
110    tLLCP_CONNECTION_PARAMS *p_params;
111
112    switch (event)
113    {
114    case LLCP_DLC_EVENT_API_CONNECT_REQ:
115
116        /* upper layer requests to create data link connection */
117        p_params = (tLLCP_CONNECTION_PARAMS *)p_data;
118
119        status = llcp_util_send_connect (p_dlcb, p_params);
120
121        if (status == LLCP_STATUS_SUCCESS)
122        {
123            p_dlcb->local_miu = p_params->miu;
124            p_dlcb->local_rw  = p_params->rw;
125
126            /* wait for response from peer device */
127            p_dlcb->state     = LLCP_DLC_STATE_W4_REMOTE_RESP;
128
129            nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
130                                   (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
131        }
132        break;
133
134    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
135
136        /* peer device requests to create data link connection */
137        p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
138
139        if (p_params->miu > llcp_cb.lcb.peer_miu)
140        {
141            LLCP_TRACE_WARNING0 ("llcp_dlsm_idle (): Peer sent data link MIU bigger than peer's link MIU");
142            p_params->miu = llcp_cb.lcb.peer_miu;
143        }
144
145        data.connect_ind.event          = LLCP_SAP_EVT_CONNECT_IND;
146        data.connect_ind.remote_sap     = p_dlcb->remote_sap;
147        data.connect_ind.local_sap      = p_dlcb->local_sap;
148        data.connect_ind.miu            = p_params->miu;
149        data.connect_ind.rw             = p_params->rw;
150        data.connect_ind.p_service_name = p_params->sn;
151        data.connect_ind.server_sap     = p_dlcb->local_sap;
152
153        p_dlcb->remote_miu = p_params->miu;
154        p_dlcb->remote_rw  = p_params->rw;
155
156        LLCP_TRACE_DEBUG2 ("llcp_dlsm_idle (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
157
158        /* wait for response from upper layer */
159        p_dlcb->state = LLCP_DLC_STATE_W4_LOCAL_RESP;
160
161        nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
162                               (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
163
164        (*p_dlcb->p_app_cb->p_app_cback) (&data);
165
166        break;
167
168    default:
169        LLCP_TRACE_ERROR0 ("llcp_dlsm_idle (): Unexpected event");
170        status = LLCP_STATUS_FAIL;
171        break;
172    }
173
174    return status;
175}
176
177/*******************************************************************************
178**
179** Function         llcp_dlsm_w4_remote_resp
180**
181** Description      data link connection is waiting for connection confirm from peer
182**
183** Returns          tLLCP_STATUS
184**
185*******************************************************************************/
186static tLLCP_STATUS llcp_dlsm_w4_remote_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
187{
188    tLLCP_STATUS            status = LLCP_STATUS_SUCCESS;
189    tLLCP_SAP_CBACK_DATA    data;
190    tLLCP_CONNECTION_PARAMS *p_params;
191
192    switch (event)
193    {
194    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
195
196        /* peer device accepted data link connection */
197        nfc_stop_quick_timer (&p_dlcb->timer);
198
199        p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
200
201        /* data link MIU must be up to link MIU */
202        if (p_params->miu > llcp_cb.lcb.peer_miu)
203        {
204            LLCP_TRACE_WARNING0 ("llcp_dlsm_w4_remote_resp (): Peer sent data link MIU bigger than peer's link MIU");
205            p_params->miu = llcp_cb.lcb.peer_miu;
206        }
207
208        p_dlcb->remote_miu = p_params->miu;
209        p_dlcb->remote_rw  = p_params->rw;
210
211        LLCP_TRACE_DEBUG2 ("llcp_dlsm_w4_remote_resp (): Remote MIU:%d, RW:%d", p_dlcb->remote_miu, p_dlcb->remote_rw);
212
213        p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
214        llcp_util_adjust_dl_rx_congestion ();
215
216        data.connect_resp.event          = LLCP_SAP_EVT_CONNECT_RESP;
217        data.connect_resp.remote_sap     = p_dlcb->remote_sap;
218        data.connect_resp.local_sap      = p_dlcb->local_sap;
219        data.connect_resp.miu            = p_params->miu;
220        data.connect_resp.rw             = p_params->rw;
221
222        (*p_dlcb->p_app_cb->p_app_cback) (&data);
223
224        if (llcp_cb.overall_rx_congested)
225        {
226            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
227        }
228        break;
229
230    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
231    case LLCP_DLC_EVENT_TIMEOUT:
232
233        /* peer device rejected connection or didn't respond */
234        data.disconnect_resp.event       = LLCP_SAP_EVT_DISCONNECT_RESP;
235        data.disconnect_resp.local_sap   = p_dlcb->local_sap;
236        data.disconnect_resp.remote_sap  = p_dlcb->remote_sap;
237        data.disconnect_resp.reason      = *((UINT8*) p_data);
238        (*p_dlcb->p_app_cb->p_app_cback) (&data);
239
240        /* stop timer, flush any pending data in queue and deallocate control block */
241        llcp_util_deallocate_data_link (p_dlcb);
242
243        llcp_util_adjust_dl_rx_congestion ();
244        break;
245
246    case LLCP_DLC_EVENT_FRAME_ERROR:
247    case LLCP_DLC_EVENT_LINK_ERROR:
248
249        /* received bad frame or link is deactivated */
250        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
251        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
252        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
253        (*p_dlcb->p_app_cb->p_app_cback) (&data);
254
255        llcp_util_deallocate_data_link (p_dlcb);
256        llcp_util_adjust_dl_rx_congestion ();
257        break;
258
259    default:
260        LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_resp (): Unexpected event");
261        status = LLCP_STATUS_FAIL;
262        break;
263    }
264
265    return status;
266}
267
268/*******************************************************************************
269**
270** Function         llcp_dlsm_w4_local_resp
271**
272** Description      data link connection is waiting for connection confirm from application
273**
274** Returns          tLLCP_STATUS
275**
276*******************************************************************************/
277static tLLCP_STATUS llcp_dlsm_w4_local_resp (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
278{
279    tLLCP_STATUS             status = LLCP_STATUS_SUCCESS;
280    tLLCP_CONNECTION_PARAMS *p_params;
281    tLLCP_SAP_CBACK_DATA     data;
282    UINT8                    reason;
283
284    switch (event)
285    {
286    case LLCP_DLC_EVENT_API_CONNECT_CFM:
287
288        /* upper layer accepted data link connection */
289        nfc_stop_quick_timer (&p_dlcb->timer);
290
291        p_params = (tLLCP_CONNECTION_PARAMS *) p_data;
292
293        p_dlcb->local_miu = p_params->miu;
294        p_dlcb->local_rw  = p_params->rw;
295
296        p_dlcb->state = LLCP_DLC_STATE_CONNECTED;
297
298        if (llcp_cb.overall_rx_congested)
299        {
300            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
301        }
302
303        status = llcp_util_send_cc (p_dlcb, p_params);
304
305        if (status == LLCP_STATUS_SUCCESS)
306        {
307            llcp_util_adjust_dl_rx_congestion ();
308        }
309        else
310        {
311            data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
312            data.disconnect_ind.local_sap   = p_dlcb->local_sap;
313            data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
314            (*p_dlcb->p_app_cb->p_app_cback) (&data);
315
316            llcp_util_deallocate_data_link (p_dlcb);
317        }
318        break;
319
320    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
321    case LLCP_DLC_EVENT_TIMEOUT:
322
323        if (event == LLCP_DLC_EVENT_TIMEOUT)
324            reason = LLCP_SAP_DM_REASON_TEMP_REJECT_THIS;
325        else
326            reason = *((UINT8*) p_data);
327
328        /* upper layer rejected connection or didn't respond */
329        llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, reason);
330
331        /* stop timer, flush any pending data in queue and deallocate control block */
332        llcp_util_deallocate_data_link (p_dlcb);
333        llcp_util_adjust_dl_rx_congestion ();
334        break;
335
336    case LLCP_DLC_EVENT_FRAME_ERROR:
337    case LLCP_DLC_EVENT_LINK_ERROR:
338
339        /* received bad frame or link is deactivated */
340        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
341        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
342        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
343        (*p_dlcb->p_app_cb->p_app_cback) (&data);
344
345        llcp_util_deallocate_data_link (p_dlcb);
346        llcp_util_adjust_dl_rx_congestion ();
347        break;
348
349    default:
350        LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_local_resp (): Unexpected event");
351        status = LLCP_STATUS_FAIL;
352        break;
353    }
354
355    return status;
356}
357
358/*******************************************************************************
359**
360** Function         llcp_dlsm_connected
361**
362** Description      data link connection is connected
363**
364** Returns          tLLCP_STATUS
365**
366*******************************************************************************/
367static tLLCP_STATUS llcp_dlsm_connected (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
368{
369    BOOLEAN              flush;
370    tLLCP_STATUS         status = LLCP_STATUS_SUCCESS;
371    tLLCP_SAP_CBACK_DATA data;
372
373    switch (event)
374    {
375    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
376
377        /* upper layer requests to disconnect */
378        flush = *(BOOLEAN*) (p_data);
379
380        /*
381        ** if upper layer asks to discard any pending data
382        ** or there is no pending data/ack to send and it is not waiting for ack
383        */
384        if (  (flush)
385            ||(  (p_dlcb->i_xmit_q.count == 0)
386               &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
387               &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )  )
388        {
389            /* wait for disconnect response */
390            p_dlcb->state = LLCP_DLC_STATE_W4_REMOTE_DM;
391
392            llcp_util_send_disc (p_dlcb->remote_sap, p_dlcb->local_sap );
393
394            nfc_start_quick_timer (&p_dlcb->timer, NFC_TTYPE_LLCP_DATA_LINK,
395                                   (UINT32) (llcp_cb.lcb.data_link_timeout * QUICK_TIMER_TICKS_PER_SEC) / 1000);
396        }
397        else
398        {
399            /* set flag to send DISC when tx queue is empty */
400            p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_DISC;
401        }
402        break;
403
404    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
405
406        /* peer device requests to disconnect */
407
408        /* send disconnect response and notify upper layer */
409        llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
410
411        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
412        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
413        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
414        (*p_dlcb->p_app_cb->p_app_cback) (&data);
415
416        llcp_util_deallocate_data_link (p_dlcb);
417        llcp_util_adjust_dl_rx_congestion ();
418        break;
419
420    case LLCP_DLC_EVENT_API_DATA_REQ:
421
422        /* upper layer requests to send data */
423
424        /* if peer device can receive data */
425        if (p_dlcb->remote_rw)
426        {
427            /* enqueue data and check if data can be sent */
428            GKI_enqueue (&p_dlcb->i_xmit_q, p_data);
429            llcp_cb.total_tx_i_pdu++;
430
431            llcp_link_check_send_data ();
432
433            if (  (p_dlcb->is_tx_congested)
434                ||(llcp_cb.overall_tx_congested)
435                ||(p_dlcb->remote_busy)
436                ||(p_dlcb->i_xmit_q.count >= p_dlcb->remote_rw)  ) /*if enough data to send next round */
437            {
438                LLCP_TRACE_DEBUG3 ("llcp_dlsm_connected (): Data link (SSAP:DSAP=0x%X:0x%X) congested: xmit_q.count=%d",
439                                    p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
440
441                /* set congested here so overall congestion check routine will not report event again */
442                p_dlcb->is_tx_congested = TRUE;
443                status = LLCP_STATUS_CONGESTED;
444            }
445        }
446        else
447        {
448            LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Remote RW is zero: discard data");
449            /* buffer will be freed when returned to API function */
450            status = LLCP_STATUS_FAIL;
451        }
452        break;
453
454    case LLCP_DLC_EVENT_PEER_DATA_IND:
455        /* peer device sends data so notify upper layer to read data from data link connection */
456
457        data.data_ind.event         = LLCP_SAP_EVT_DATA_IND;
458        data.data_ind.local_sap     = p_dlcb->local_sap;
459        data.data_ind.link_type     = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
460        data.data_ind.remote_sap    = p_dlcb->remote_sap;
461
462        (*p_dlcb->p_app_cb->p_app_cback) (&data);
463        break;
464
465    case LLCP_DLC_EVENT_FRAME_ERROR:
466    case LLCP_DLC_EVENT_LINK_ERROR:
467
468        /* received bad frame or link is deactivated */
469        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
470        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
471        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
472        (*p_dlcb->p_app_cb->p_app_cback) (&data);
473
474        llcp_util_deallocate_data_link (p_dlcb);
475        llcp_util_adjust_dl_rx_congestion ();
476        break;
477
478    default:
479        LLCP_TRACE_ERROR0 ("llcp_dlsm_connected (): Unexpected event");
480        status = LLCP_STATUS_FAIL;
481        break;
482    }
483
484    return status;
485}
486
487/*******************************************************************************
488**
489** Function         llcp_dlsm_w4_remote_dm
490**
491** Description      data link connection is waiting for disconnection confirm from peer
492**
493** Returns          tLLCP_STATUS
494**
495*******************************************************************************/
496static tLLCP_STATUS llcp_dlsm_w4_remote_dm (tLLCP_DLCB *p_dlcb, tLLCP_DLC_EVENT event, void *p_data)
497{
498    tLLCP_STATUS         status = LLCP_STATUS_SUCCESS;
499    tLLCP_SAP_CBACK_DATA data;
500
501    switch (event)
502    {
503    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
504    case LLCP_DLC_EVENT_TIMEOUT:
505
506        /* peer device sends disconnect response or didn't responde */
507        data.disconnect_resp.event       = LLCP_SAP_EVT_DISCONNECT_RESP;
508        data.disconnect_resp.local_sap   = p_dlcb->local_sap;
509        data.disconnect_resp.remote_sap  = p_dlcb->remote_sap;
510        data.disconnect_resp.reason      = LLCP_SAP_DM_REASON_RESP_DISC;
511        (*p_dlcb->p_app_cb->p_app_cback) (&data);
512
513        llcp_util_deallocate_data_link (p_dlcb);
514        llcp_util_adjust_dl_rx_congestion ();
515        break;
516
517    case LLCP_DLC_EVENT_FRAME_ERROR:
518    case LLCP_DLC_EVENT_LINK_ERROR:
519
520        /* received bad frame or link is deactivated */
521        data.disconnect_ind.event       = LLCP_SAP_EVT_DISCONNECT_IND;
522        data.disconnect_ind.local_sap   = p_dlcb->local_sap;
523        data.disconnect_ind.remote_sap  = p_dlcb->remote_sap;
524        (*p_dlcb->p_app_cb->p_app_cback) (&data);
525
526        llcp_util_deallocate_data_link (p_dlcb);
527        llcp_util_adjust_dl_rx_congestion ();
528        break;
529
530    case LLCP_DLC_EVENT_PEER_DATA_IND:
531        break;
532
533    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
534        /* it's race condition, send disconnect response and wait for DM */
535        llcp_util_send_dm (p_dlcb->remote_sap, p_dlcb->local_sap, LLCP_SAP_DM_REASON_RESP_DISC );
536        break;
537
538    default:
539        LLCP_TRACE_ERROR0 ("llcp_dlsm_w4_remote_dm (): Unexpected event");
540        status = LLCP_STATUS_FAIL;
541        break;
542    }
543
544    return status;
545}
546
547/*******************************************************************************
548**
549** Function         llcp_dlc_find_dlcb_by_local_sap
550**
551** Description      Find tLLCP_DLCB by local SAP and remote SAP
552**                  if remote_sap is LLCP_INVALID_SAP, it will return a DLCB which
553**                  is waiting for CC from peer.
554**
555** Returns          tLLCP_DLCB *
556**
557*******************************************************************************/
558tLLCP_DLCB *llcp_dlc_find_dlcb_by_sap (UINT8 local_sap, UINT8 remote_sap)
559{
560    int i;
561
562    for (i = 0; i < LLCP_MAX_DATA_LINK; i++)
563    {
564        if (  (llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE)
565            &&(llcp_cb.dlcb[i].local_sap == local_sap)  )
566        {
567            if ((remote_sap == LLCP_INVALID_SAP) && (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP))
568            {
569                /* Remote SAP has not been finalized because we are watiing for CC */
570                return (&llcp_cb.dlcb[i]);
571            }
572            else if (llcp_cb.dlcb[i].remote_sap == remote_sap)
573            {
574                return (&llcp_cb.dlcb[i]);
575            }
576        }
577    }
578    return NULL;
579}
580
581/*******************************************************************************
582**
583** Function         llcp_dlc_flush_q
584**
585** Description      Free buffers in tx and rx queue in data link
586**
587** Returns          void
588**
589*******************************************************************************/
590void llcp_dlc_flush_q (tLLCP_DLCB *p_dlcb)
591{
592    if (p_dlcb)
593    {
594        LLCP_TRACE_DEBUG1 ("llcp_dlc_flush_q (): local SAP:0x%02X", p_dlcb->local_sap);
595
596        /* Release any held buffers */
597        while (p_dlcb->i_xmit_q.p_first)
598        {
599            GKI_freebuf (GKI_dequeue (&p_dlcb->i_xmit_q));
600            llcp_cb.total_tx_i_pdu--;
601        }
602
603        /* discard any received I PDU on data link  including in AGF */
604        LLCP_FlushDataLinkRxData (p_dlcb->local_sap, p_dlcb->remote_sap);
605    }
606    else
607    {
608        LLCP_TRACE_ERROR0 ("llcp_dlc_flush_q (): p_dlcb is NULL");
609    }
610}
611
612/*******************************************************************************
613**
614** Function         llcp_dlc_proc_connect_pdu
615**
616** Description      Process CONNECT PDU
617**
618** Returns          void
619**
620*******************************************************************************/
621static void llcp_dlc_proc_connect_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
622{
623    tLLCP_DLCB   *p_dlcb;
624    tLLCP_STATUS  status;
625    tLLCP_APP_CB *p_app_cb;
626
627    tLLCP_CONNECTION_PARAMS  params;
628
629    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_connect_pdu ()");
630
631    p_app_cb = llcp_util_get_app_cb (dsap);
632
633    if (  (p_app_cb == NULL)
634        ||(p_app_cb->p_app_cback == NULL)
635        ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)  )
636    {
637        LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered SAP:0x%x", dsap);
638        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
639        return;
640    }
641
642    /* parse CONNECT PDU and get connection parameters */
643    if (llcp_util_parse_connect (p_data, length, &params) != LLCP_STATUS_SUCCESS)
644    {
645        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Bad format CONNECT");
646        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
647        return;
648    }
649
650    /* if this is connection by service name */
651    if (dsap == LLCP_SAP_SDP)
652    {
653        /* find registered SAP with service name */
654        if (strlen (params.sn))
655            dsap = llcp_sdp_get_sap_by_name (params.sn, (UINT8) strlen (params.sn));
656        else
657        {
658            /* if SN type is included without SN */
659            if (params.sn[1] == LLCP_SN_TYPE)
660            {
661                llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
662            }
663            else
664            {
665                /* SDP doesn't accept connection */
666                llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
667            }
668            return;
669        }
670
671        if (dsap == LLCP_SAP_SDP)
672        {
673            LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): SDP doesn't accept connection");
674
675            llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_PERM_REJECT_THIS );
676            return;
677        }
678        else if (dsap == 0)
679        {
680            LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): Unregistered Service:%s", params.sn);
681
682            llcp_util_send_dm (ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE );
683            return;
684        }
685        else
686        {
687            /* check if this application can support connection-oriented transport */
688            p_app_cb = llcp_util_get_app_cb (dsap);
689
690            if (  (p_app_cb == NULL)
691                ||(p_app_cb->p_app_cback == NULL)
692                ||((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)  )
693            {
694                LLCP_TRACE_ERROR1 ("llcp_dlc_proc_connect_pdu (): SAP(0x%x) doesn't support connection-oriented", dsap);
695                llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE );
696                return;
697            }
698        }
699    }
700
701    /* check if any data link */
702    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
703    if (p_dlcb)
704    {
705        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Data link is aleady established");
706        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS );
707    }
708    else
709    {
710        /* allocate data link connection control block and notify upper layer through state machine */
711        p_dlcb = llcp_util_allocate_data_link (dsap, ssap);
712
713        if (p_dlcb)
714        {
715            status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
716            if (status != LLCP_STATUS_SUCCESS)
717            {
718                LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Error in state machine");
719                llcp_util_deallocate_data_link (p_dlcb);
720            }
721        }
722        else
723        {
724            LLCP_TRACE_ERROR0 ("llcp_dlc_proc_connect_pdu (): Out of resource");
725            llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY );
726        }
727    }
728}
729
730/*******************************************************************************
731**
732** Function         llcp_dlc_proc_disc_pdu
733**
734** Description      Process DISC PDU
735**
736** Returns          void
737**
738*******************************************************************************/
739static void llcp_dlc_proc_disc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
740{
741    tLLCP_DLCB *p_dlcb;
742
743    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_disc_pdu ()");
744
745    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
746    if (p_dlcb)
747    {
748        if (length > 0)
749        {
750            LLCP_TRACE_ERROR1 ("llcp_dlc_proc_disc_pdu (): Received extra data (%d bytes) in DISC PDU", length);
751
752            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
753            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
754        }
755        else
756        {
757            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, NULL);
758        }
759    }
760    else
761    {
762        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_disc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
763    }
764}
765
766/*******************************************************************************
767**
768** Function         llcp_dlc_proc_cc_pdu
769**
770** Description      Process CC PDU
771**
772** Returns          void
773**
774*******************************************************************************/
775static void llcp_dlc_proc_cc_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
776{
777    tLLCP_DLCB              *p_dlcb;
778    tLLCP_CONNECTION_PARAMS  params;
779    tLLCP_STATUS             status;
780
781    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_cc_pdu ()");
782
783    /* find a DLCB waiting for CC on this local SAP */
784    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
785    if (p_dlcb)
786    {
787        /* The CC may contain a SSAP that is different from the DSAP in the CONNECT */
788        p_dlcb->remote_sap = ssap;
789
790        if (llcp_util_parse_cc (p_data, length, &(params.miu), &(params.rw)) == LLCP_STATUS_SUCCESS)
791        {
792            status = llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
793            if (status != LLCP_STATUS_SUCCESS)
794            {
795                LLCP_TRACE_ERROR0 ("llcp_dlc_proc_cc_pdu (): Error in state machine");
796                llcp_util_deallocate_data_link (p_dlcb);
797            }
798        }
799        else
800        {
801            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG, LLCP_PDU_DISC_TYPE, 0);
802            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
803        }
804    }
805    else
806    {
807        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_cc_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
808    }
809}
810
811/*******************************************************************************
812**
813** Function         llcp_dlc_proc_dm_pdu
814**
815** Description      Process DM PDU
816**
817** Returns          void
818**
819*******************************************************************************/
820static void llcp_dlc_proc_dm_pdu (UINT8 dsap, UINT8 ssap, UINT16 length, UINT8 *p_data)
821{
822    tLLCP_DLCB *p_dlcb;
823
824    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_dm_pdu ()");
825
826    if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE)
827    {
828        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_dm_pdu (): Received invalid DM PDU");
829    }
830    else
831    {
832        if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC)
833        {
834            /* local device initiated disconnecting */
835            p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
836        }
837        else
838        {
839            /* peer device rejected connection with any reason */
840            /* find a DLCB waiting for CC on this local SAP    */
841            p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, LLCP_INVALID_SAP);
842        }
843
844        if (p_dlcb)
845        {
846            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP, p_data); /* passing reason */
847        }
848        else
849        {
850            LLCP_TRACE_ERROR2 ("llcp_dlc_proc_dm_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
851        }
852    }
853}
854
855/*******************************************************************************
856**
857** Function         llcp_dlc_proc_i_pdu
858**
859** Description      Process I PDU
860**
861** Returns          void
862**
863*******************************************************************************/
864void llcp_dlc_proc_i_pdu (UINT8 dsap, UINT8 ssap, UINT16 i_pdu_length, UINT8 *p_i_pdu, BT_HDR *p_msg)
865{
866    UINT8      *p, *p_dst, send_seq, rcv_seq, error_flags;
867    UINT16      info_len, available_bytes;
868    tLLCP_DLCB *p_dlcb;
869    BOOLEAN     appended;
870    BT_HDR     *p_last_buf;
871
872    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_i_pdu ()");
873
874    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
875
876    if ((p_dlcb)&&(p_dlcb->state == LLCP_DLC_STATE_CONNECTED))
877    {
878        error_flags = 0;
879
880        if (p_msg)
881        {
882            i_pdu_length = p_msg->len;
883            p_i_pdu = (UINT8 *) (p_msg + 1) + p_msg->offset;
884        }
885
886        info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
887
888        if (info_len > p_dlcb->local_miu)
889        {
890            LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): exceeding local MIU (%d bytes): got %d bytes SDU",
891                                p_dlcb->local_miu, info_len);
892
893            error_flags |= LLCP_FRMR_I_ERROR_FLAG;
894        }
895
896        /* get sequence numbers */
897        p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
898
899        send_seq = LLCP_GET_NS (*p);
900        rcv_seq  = LLCP_GET_NR (*p);
901
902#if (BT_TRACE_VERBOSE == TRUE)
903        LLCP_TRACE_DEBUG6 ("LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
904                            send_seq, rcv_seq,
905                            p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
906                            p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
907#endif
908
909        /* if send sequence number, N(S) is not expected one, V(R) */
910        if (p_dlcb->next_rx_seq != send_seq)
911        {
912            LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): Bad N(S) got:%d, expected:%d",
913                                send_seq, p_dlcb->next_rx_seq);
914
915            error_flags |= LLCP_FRMR_S_ERROR_FLAG;
916        }
917        else
918        {
919            /* if peer device sends more than our receiving window size */
920            if ((UINT8) (send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >= p_dlcb->local_rw)
921            {
922                LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(S):%d >= V(RA):%d + RW(L):%d",
923                                    send_seq, p_dlcb->sent_ack_seq, p_dlcb->local_rw);
924
925                error_flags |= LLCP_FRMR_S_ERROR_FLAG;
926            }
927        }
928
929        /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
930        if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
931            != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO)
932        {
933            error_flags |= LLCP_FRMR_R_ERROR_FLAG;
934            LLCP_TRACE_ERROR3 ("llcp_dlc_proc_i_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
935                                rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
936        }
937
938        /* if any error is found */
939        if (error_flags)
940        {
941            llcp_util_send_frmr (p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
942            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
943        }
944        else
945        {
946            /* update local sequence variables */
947            p_dlcb->next_rx_seq  = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
948            p_dlcb->rcvd_ack_seq = rcv_seq;
949
950            appended = FALSE;
951
952            /* get last buffer in rx queue */
953            p_last_buf = (BT_HDR *) GKI_getlast (&p_dlcb->i_rx_q);
954
955            if (p_last_buf)
956            {
957                /* get max length to append at the end of buffer */
958                available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len;
959
960                /* if new UI PDU with length can be attached at the end of buffer */
961                if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len)
962                {
963                    p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
964
965                    /* add length of information in I PDU */
966                    UINT16_TO_BE_STREAM (p_dst, info_len);
967
968                    /* copy information of I PDU */
969                    p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
970
971                    memcpy (p_dst, p, info_len);
972
973                    p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
974
975                    if (p_msg)
976                    {
977                        GKI_freebuf (p_msg);
978                        p_msg = NULL;
979                    }
980
981                    appended = TRUE;
982                }
983            }
984
985            /* if it is not available to append */
986            if (!appended)
987            {
988                /* if it's not from AGF PDU */
989                if (p_msg)
990                {
991                    /* add length of information in front of information */
992                    p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
993                    UINT16_TO_BE_STREAM (p, info_len);
994
995                    p_msg->offset += LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
996                    p_msg->len    -= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
997                    p_msg->layer_specific = 0;
998                }
999                else
1000                {
1001                    p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID);
1002
1003                    if (p_msg)
1004                    {
1005                        p_dst = (UINT8*) (p_msg + 1);
1006
1007                        /* add length of information in front of information */
1008                        UINT16_TO_BE_STREAM (p_dst, info_len);
1009
1010                        p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
1011                        memcpy (p_dst, p, info_len);
1012
1013                        p_msg->offset = 0;
1014                        p_msg->len    = LLCP_PDU_AGF_LEN_SIZE + info_len;
1015                        p_msg->layer_specific = 0;
1016                    }
1017                    else
1018                    {
1019                        LLCP_TRACE_ERROR0 ("llcp_dlc_proc_i_pdu (): out of buffer");
1020                    }
1021                }
1022
1023                /* insert I PDU in rx queue */
1024                if (p_msg)
1025                {
1026                    GKI_enqueue (&p_dlcb->i_rx_q, p_msg);
1027                    p_msg = NULL;
1028                    llcp_cb.total_rx_i_pdu++;
1029
1030                    llcp_util_check_rx_congested_status ();
1031                }
1032            }
1033
1034            p_dlcb->num_rx_i_pdu++;
1035
1036            if (  (!p_dlcb->local_busy)
1037                &&(p_dlcb->num_rx_i_pdu == 1)  )
1038            {
1039                /* notify rx data is available so upper layer reads data until queue is empty */
1040                llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL);
1041            }
1042
1043            if (  (!p_dlcb->is_rx_congested)
1044                &&(p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)  )
1045            {
1046                LLCP_TRACE_DEBUG2 ("llcp_dlc_proc_i_pdu (): congested num_rx_i_pdu=%d, rx_congest_threshold=%d",
1047                                    p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
1048
1049                /* send RNR */
1050                p_dlcb->is_rx_congested = TRUE;
1051                p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1052            }
1053        }
1054    }
1055    else
1056    {
1057        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_i_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1058        llcp_util_send_dm (ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION );
1059    }
1060
1061    if (p_msg)
1062    {
1063        GKI_freebuf (p_msg);
1064    }
1065}
1066
1067/*******************************************************************************
1068**
1069** Function         llcp_dlc_proc_rr_rnr_pdu
1070**
1071** Description      Process RR or RNR PDU
1072**
1073** Returns          void
1074**
1075*******************************************************************************/
1076static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1077{
1078    UINT8      rcv_seq, error_flags;
1079    tLLCP_DLCB *p_dlcb;
1080    BOOLEAN     flush = TRUE;
1081    tLLCP_SAP_CBACK_DATA cback_data;
1082    BOOLEAN              old_remote_busy;
1083
1084    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
1085
1086    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1087    if (p_dlcb != NULL)
1088    {
1089        error_flags = 0;
1090
1091        rcv_seq = LLCP_GET_NR (*p_data);
1092
1093        if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
1094        {
1095            error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
1096        }
1097
1098        /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1099        if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
1100            != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
1101        {
1102            error_flags |= LLCP_FRMR_R_ERROR_FLAG;
1103            LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
1104                                rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1105        }
1106
1107        if (error_flags)
1108        {
1109            llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
1110            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1111        }
1112        else
1113        {
1114            p_dlcb->rcvd_ack_seq = rcv_seq;
1115
1116#if (BT_TRACE_VERBOSE == TRUE)
1117            LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1118                                rcv_seq,
1119                                p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1120                                p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1121#endif
1122            old_remote_busy = p_dlcb->remote_busy;
1123            if (ptype == LLCP_PDU_RNR_TYPE)
1124            {
1125                p_dlcb->remote_busy = TRUE;
1126                /* if upper layer hasn't get congestion started notification */
1127                if (  (!old_remote_busy)
1128                    &&(!p_dlcb->is_tx_congested)  )
1129                {
1130                    LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
1131                                          p_dlcb->local_sap, p_dlcb->remote_sap,
1132                                          p_dlcb->i_xmit_q.count);
1133
1134                    cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
1135                    cback_data.congest.local_sap    = p_dlcb->local_sap;
1136                    cback_data.congest.remote_sap   = p_dlcb->remote_sap;
1137                    cback_data.congest.is_congested = TRUE;
1138                    cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1139
1140                    (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1141                }
1142            }
1143            else
1144            {
1145                p_dlcb->remote_busy = FALSE;
1146                /* if upper layer hasn't get congestion ended notification and data link is not congested */
1147                if (  (old_remote_busy)
1148                    &&(!p_dlcb->is_tx_congested)  )
1149                {
1150                    LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
1151                                          p_dlcb->local_sap, p_dlcb->remote_sap,
1152                                          p_dlcb->i_xmit_q.count);
1153
1154                    cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
1155                    cback_data.congest.local_sap    = p_dlcb->local_sap;
1156                    cback_data.congest.remote_sap   = p_dlcb->remote_sap;
1157                    cback_data.congest.is_congested = FALSE;
1158                    cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1159
1160                    (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1161                }
1162            }
1163
1164            /* check flag to send DISC when tx queue is empty */
1165            if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1166            {
1167                /* if no pending data and all PDU is acked */
1168                if (  (p_dlcb->i_xmit_q.count == 0)
1169                    &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1170                    &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
1171                {
1172                    p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1173                    llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1174                }
1175            }
1176        }
1177    }
1178    else
1179    {
1180        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1181    }
1182}
1183
1184/*******************************************************************************
1185**
1186** Function         llcp_dlc_proc_rx_pdu
1187**
1188** Description      Process PDU for data link
1189**
1190** Returns          void
1191**
1192*******************************************************************************/
1193void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1194{
1195    tLLCP_DLCB *p_dlcb;
1196
1197    LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
1198                        dsap, ptype, ssap);
1199
1200    if (dsap == LLCP_SAP_LM)
1201    {
1202        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
1203        return;
1204    }
1205
1206    switch (ptype)
1207    {
1208    case LLCP_PDU_CONNECT_TYPE:
1209        llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
1210        break;
1211
1212    case LLCP_PDU_DISC_TYPE:
1213        llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
1214        break;
1215
1216    case LLCP_PDU_CC_TYPE:
1217        llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
1218        break;
1219
1220    case LLCP_PDU_DM_TYPE:
1221        llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
1222        break;
1223
1224    case LLCP_PDU_FRMR_TYPE:
1225        p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1226        if (p_dlcb)
1227        {
1228            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1229        }
1230        break;
1231
1232    case LLCP_PDU_RR_TYPE:
1233    case LLCP_PDU_RNR_TYPE:
1234        llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
1235        break;
1236
1237    default:
1238        LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
1239
1240        p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1241        if (p_dlcb)
1242        {
1243            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1244            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1245        }
1246        break;
1247    }
1248}
1249
1250/*******************************************************************************
1251**
1252** Function         llcp_dlc_check_to_send_rr_rnr
1253**
1254** Description      Send RR or RNR if necessary
1255**
1256** Returns          void
1257**
1258*******************************************************************************/
1259void llcp_dlc_check_to_send_rr_rnr (void)
1260{
1261    UINT8   idx;
1262    BOOLEAN flush = TRUE;
1263
1264    LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
1265
1266    /*
1267    ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
1268    ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
1269    ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
1270    **
1271    ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
1272    ** V(R).
1273    */
1274    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
1275    {
1276        if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
1277        {
1278            llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
1279
1280            /* check flag to send DISC when tx queue is empty */
1281            if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1282            {
1283                /* if no pending data and all PDU is acked */
1284                if (  (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
1285                    &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
1286                    &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)  )
1287                {
1288                    llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1289                    llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1290                }
1291            }
1292        }
1293    }
1294}
1295
1296/*******************************************************************************
1297**
1298** Function         llcp_dlc_is_rw_open
1299**
1300** Description      check if receive window is open in remote
1301**
1302** Returns          TRUE if remote can receive more data
1303**
1304*******************************************************************************/
1305BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
1306{
1307    if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
1308    {
1309        return TRUE;
1310    }
1311    else
1312    {
1313        LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
1314                           p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
1315        return FALSE;
1316    }
1317}
1318
1319/*******************************************************************************
1320**
1321** Function         llcp_dlc_get_next_pdu
1322**
1323** Description      Get a PDU from tx queue of data link
1324**
1325** Returns          BT_HDR*
1326**
1327*******************************************************************************/
1328BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
1329{
1330    BT_HDR *p_msg = NULL;
1331    BOOLEAN flush = TRUE;
1332    tLLCP_SAP_CBACK_DATA data;
1333
1334#if (BT_TRACE_VERBOSE == TRUE)
1335    UINT8   send_seq = p_dlcb->next_tx_seq;
1336#endif
1337
1338    /* if there is data to send and remote device can receive it */
1339    if (  (p_dlcb->i_xmit_q.count)
1340        &&(!p_dlcb->remote_busy)
1341        &&(llcp_dlc_is_rw_open (p_dlcb))  )
1342    {
1343        p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
1344        llcp_cb.total_tx_i_pdu--;
1345
1346        if (p_msg->offset >= LLCP_MIN_OFFSET)
1347        {
1348            /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
1349            llcp_util_build_info_pdu (p_dlcb, p_msg);
1350
1351            p_dlcb->next_tx_seq  = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
1352
1353#if (BT_TRACE_VERBOSE == TRUE)
1354            LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1355                                send_seq, p_dlcb->next_rx_seq,
1356                                p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1357                                p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1358#endif
1359        }
1360        else
1361        {
1362            LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
1363                                p_msg->offset, LLCP_MIN_OFFSET );
1364            GKI_freebuf (p_msg);
1365            p_msg = NULL;
1366        }
1367    }
1368
1369    /* if tx queue is empty and all PDU is acknowledged */
1370    if (  (p_dlcb->i_xmit_q.count == 0)
1371        &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1372        &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
1373    {
1374        /* check flag to send DISC */
1375        if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1376        {
1377            p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1378            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1379        }
1380
1381        /* check flag to notify upper layer */
1382        if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
1383        {
1384            p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1385
1386            data.tx_complete.event      = LLCP_SAP_EVT_TX_COMPLETE;
1387            data.tx_complete.local_sap  = p_dlcb->local_sap;
1388            data.tx_complete.remote_sap = p_dlcb->remote_sap;
1389
1390            (*p_dlcb->p_app_cb->p_app_cback) (&data);
1391        }
1392    }
1393
1394    return p_msg;
1395}
1396
1397/*******************************************************************************
1398**
1399** Function         llcp_dlc_get_next_pdu_length
1400**
1401** Description      return length of PDU which is top in tx queue of data link
1402**
1403** Returns          length of PDU
1404**
1405*******************************************************************************/
1406UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
1407{
1408    BT_HDR *p_msg;
1409
1410    /* if there is data to send and remote device can receive it */
1411    if (  (p_dlcb->i_xmit_q.count)
1412        &&(!p_dlcb->remote_busy)
1413        &&(llcp_dlc_is_rw_open (p_dlcb))  )
1414    {
1415        p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
1416
1417        return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1418    }
1419    return 0;
1420}
1421
1422#if (BT_TRACE_VERBOSE == TRUE)
1423/*******************************************************************************
1424**
1425** Function         llcp_dlsm_get_state_name
1426**
1427** Description      This function returns the state name.
1428**
1429** Returns          pointer to the name
1430**
1431*******************************************************************************/
1432static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
1433{
1434    switch (state)
1435    {
1436    case LLCP_DLC_STATE_IDLE:
1437        return ("IDLE");
1438    case LLCP_DLC_STATE_W4_REMOTE_RESP:
1439        return ("W4_REMOTE_RESP");
1440    case LLCP_DLC_STATE_W4_LOCAL_RESP:
1441        return ("W4_LOCAL_RESP");
1442    case LLCP_DLC_STATE_CONNECTED:
1443        return ("CONNECTED");
1444    case LLCP_DLC_STATE_W4_REMOTE_DM:
1445        return ("W4_REMOTE_DM");
1446    default:
1447        return ("???? UNKNOWN STATE");
1448    }
1449}
1450
1451/*******************************************************************************
1452**
1453** Function         llcp_dlsm_get_event_name
1454**
1455** Description      This function returns the event name.
1456**
1457** Returns          pointer to the name
1458**
1459*******************************************************************************/
1460static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
1461{
1462    switch (event)
1463    {
1464    case LLCP_DLC_EVENT_API_CONNECT_REQ:
1465        return ("API_CONNECT_REQ");
1466    case LLCP_DLC_EVENT_API_CONNECT_CFM:
1467        return ("API_CONNECT_CFM");
1468    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
1469        return ("API_CONNECT_REJECT");
1470    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
1471        return ("PEER_CONNECT_IND");
1472    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
1473        return ("PEER_CONNECT_CFM");
1474
1475    case LLCP_DLC_EVENT_API_DATA_REQ:
1476        return ("API_DATA_REQ");
1477    case LLCP_DLC_EVENT_PEER_DATA_IND:
1478        return ("PEER_DATA_IND");
1479
1480    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
1481        return ("API_DISCONNECT_REQ");
1482    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
1483        return ("PEER_DISCONNECT_IND");
1484    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
1485        return ("PEER_DISCONNECT_RESP");
1486
1487    case LLCP_DLC_EVENT_FRAME_ERROR:
1488        return ("FRAME_ERROR");
1489    case LLCP_DLC_EVENT_LINK_ERROR:
1490        return ("LINK_ERROR");
1491
1492    case LLCP_DLC_EVENT_TIMEOUT:
1493        return ("TIMEOUT");
1494
1495    default:
1496        return ("???? UNKNOWN EVENT");
1497    }
1498}
1499#endif /* (BT_TRACE_VERBOSE == TRUE) */
1500
1501
1502