llcp_dlc.c revision 7c69b2723b60a59df4aaa58b13985b3483b291bf
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    }
1059
1060    if (p_msg)
1061    {
1062        GKI_freebuf (p_msg);
1063    }
1064}
1065
1066/*******************************************************************************
1067**
1068** Function         llcp_dlc_proc_rr_rnr_pdu
1069**
1070** Description      Process RR or RNR PDU
1071**
1072** Returns          void
1073**
1074*******************************************************************************/
1075static void llcp_dlc_proc_rr_rnr_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1076{
1077    UINT8      rcv_seq, error_flags;
1078    tLLCP_DLCB *p_dlcb;
1079    BOOLEAN     flush = TRUE;
1080    tLLCP_SAP_CBACK_DATA cback_data;
1081
1082    LLCP_TRACE_DEBUG0 ("llcp_dlc_proc_rr_rnr_pdu ()");
1083
1084    p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1085    if (p_dlcb != NULL)
1086    {
1087        error_flags = 0;
1088
1089        rcv_seq = LLCP_GET_NR (*p_data);
1090
1091        if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE)
1092        {
1093            error_flags |= LLCP_FRMR_W_ERROR_FLAG|LLCP_FRMR_I_ERROR_FLAG;
1094        }
1095
1096        /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1097        if ((UINT8) (rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO + (UINT8) (p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO
1098            != (UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO )
1099        {
1100            error_flags |= LLCP_FRMR_R_ERROR_FLAG;
1101            LLCP_TRACE_ERROR3 ("llcp_dlc_proc_rr_rnr_pdu (): Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
1102                                rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1103        }
1104
1105        if (error_flags)
1106        {
1107            llcp_util_send_frmr (p_dlcb, error_flags, ptype, *p_data);
1108            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1109        }
1110        else
1111        {
1112            p_dlcb->rcvd_ack_seq = rcv_seq;
1113
1114#if (BT_TRACE_VERBOSE == TRUE)
1115            LLCP_TRACE_DEBUG5 ("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1116                                rcv_seq,
1117                                p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1118                                p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1119#endif
1120
1121            if (ptype == LLCP_PDU_RNR_TYPE)
1122            {
1123                /* if upper layer hasn't get congestion started notification */
1124                if (  (!p_dlcb->remote_busy)
1125                    &&(!p_dlcb->is_tx_congested)  )
1126                {
1127                    LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion start: i_xmit_q.count=%d",
1128                                          p_dlcb->local_sap, p_dlcb->remote_sap,
1129                                          p_dlcb->i_xmit_q.count);
1130
1131                    cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
1132                    cback_data.congest.local_sap    = p_dlcb->local_sap;
1133                    cback_data.congest.remote_sap   = p_dlcb->remote_sap;
1134                    cback_data.congest.is_congested = TRUE;
1135                    cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1136
1137                    (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1138                }
1139                p_dlcb->remote_busy = TRUE;
1140            }
1141            else
1142            {
1143                /* if upper layer hasn't get congestion ended notification and data link is not congested */
1144                if (  (p_dlcb->remote_busy)
1145                    &&(!p_dlcb->is_tx_congested)  )
1146                {
1147                    LLCP_TRACE_WARNING3 ("llcp_dlc_proc_rr_rnr_pdu (): Data link (SSAP:DSAP=0x%X:0x%X) congestion end: i_xmit_q.count=%d",
1148                                          p_dlcb->local_sap, p_dlcb->remote_sap,
1149                                          p_dlcb->i_xmit_q.count);
1150
1151                    cback_data.congest.event        = LLCP_SAP_EVT_CONGEST;
1152                    cback_data.congest.local_sap    = p_dlcb->local_sap;
1153                    cback_data.congest.remote_sap   = p_dlcb->remote_sap;
1154                    cback_data.congest.is_congested = FALSE;
1155                    cback_data.congest.link_type    = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1156
1157                    (*p_dlcb->p_app_cb->p_app_cback) (&cback_data);
1158                }
1159                p_dlcb->remote_busy = FALSE;
1160            }
1161
1162            /* check flag to send DISC when tx queue is empty */
1163            if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1164            {
1165                /* if no pending data and all PDU is acked */
1166                if (  (p_dlcb->i_xmit_q.count == 0)
1167                    &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1168                    &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
1169                {
1170                    p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1171                    llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1172                }
1173            }
1174        }
1175    }
1176    else
1177    {
1178        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rr_rnr_pdu (): No data link for SAP (0x%x,0x%x)", dsap, ssap);
1179    }
1180}
1181
1182/*******************************************************************************
1183**
1184** Function         llcp_dlc_proc_rx_pdu
1185**
1186** Description      Process PDU for data link
1187**
1188** Returns          void
1189**
1190*******************************************************************************/
1191void llcp_dlc_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, UINT16 length, UINT8 *p_data)
1192{
1193    tLLCP_DLCB *p_dlcb;
1194
1195    LLCP_TRACE_DEBUG3 ("llcp_dlc_proc_rx_pdu (): DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x",
1196                        dsap, ptype, ssap);
1197
1198    if (dsap == LLCP_SAP_LM)
1199    {
1200        LLCP_TRACE_ERROR2 ("llcp_dlc_proc_rx_pdu (): Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
1201        return;
1202    }
1203
1204    switch (ptype)
1205    {
1206    case LLCP_PDU_CONNECT_TYPE:
1207        llcp_dlc_proc_connect_pdu (dsap, ssap, length, p_data);
1208        break;
1209
1210    case LLCP_PDU_DISC_TYPE:
1211        llcp_dlc_proc_disc_pdu (dsap, ssap, length, p_data);
1212        break;
1213
1214    case LLCP_PDU_CC_TYPE:
1215        llcp_dlc_proc_cc_pdu (dsap, ssap, length, p_data);
1216        break;
1217
1218    case LLCP_PDU_DM_TYPE:
1219        llcp_dlc_proc_dm_pdu (dsap, ssap, length, p_data);
1220        break;
1221
1222    case LLCP_PDU_FRMR_TYPE:
1223        p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1224        if (p_dlcb)
1225        {
1226            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1227        }
1228        break;
1229
1230    case LLCP_PDU_RR_TYPE:
1231    case LLCP_PDU_RNR_TYPE:
1232        llcp_dlc_proc_rr_rnr_pdu (dsap, ptype, ssap, length, p_data);
1233        break;
1234
1235    default:
1236        LLCP_TRACE_ERROR1 ("llcp_dlc_proc_rx_pdu (): Unexpected PDU type (0x%x)", ptype);
1237
1238        p_dlcb = llcp_dlc_find_dlcb_by_sap (dsap, ssap);
1239        if (p_dlcb)
1240        {
1241            llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1242            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL);
1243        }
1244        break;
1245    }
1246}
1247
1248/*******************************************************************************
1249**
1250** Function         llcp_dlc_check_to_send_rr_rnr
1251**
1252** Description      Send RR or RNR if necessary
1253**
1254** Returns          void
1255**
1256*******************************************************************************/
1257void llcp_dlc_check_to_send_rr_rnr (void)
1258{
1259    UINT8   idx;
1260    BOOLEAN flush = TRUE;
1261
1262    LLCP_TRACE_DEBUG0 ("llcp_dlc_check_to_send_rr_rnr ()");
1263
1264    /*
1265    ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs can be aggregated
1266    ** in a received AGF PDU. In this case, this is post processing of AGF PDU to send single RR
1267    ** or RNR after processing all I PDUs in received AGF if there was no I-PDU to carry N(R).
1268    **
1269    ** Send RR or RNR if any change of local busy condition or rx congestion status, or V(RA) is not
1270    ** V(R).
1271    */
1272    for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++)
1273    {
1274        if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED)
1275        {
1276            llcp_util_send_rr_rnr (&(llcp_cb.dlcb[idx]));
1277
1278            /* check flag to send DISC when tx queue is empty */
1279            if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1280            {
1281                /* if no pending data and all PDU is acked */
1282                if (  (llcp_cb.dlcb[idx].i_xmit_q.count == 0)
1283                    &&(llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq)
1284                    &&(llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)  )
1285                {
1286                    llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1287                    llcp_dlsm_execute (&(llcp_cb.dlcb[idx]), LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1288                }
1289            }
1290        }
1291    }
1292}
1293
1294/*******************************************************************************
1295**
1296** Function         llcp_dlc_is_rw_open
1297**
1298** Description      check if receive window is open in remote
1299**
1300** Returns          TRUE if remote can receive more data
1301**
1302*******************************************************************************/
1303BOOLEAN llcp_dlc_is_rw_open (tLLCP_DLCB *p_dlcb)
1304{
1305    if ((UINT8) (p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO < p_dlcb->remote_rw)
1306    {
1307        return TRUE;
1308    }
1309    else
1310    {
1311        LLCP_TRACE_DEBUG3 ("llcp_dlc_is_rw_open ():Flow Off, V(S):%d, V(SA):%d, RW(R):%d",
1312                           p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
1313        return FALSE;
1314    }
1315}
1316
1317/*******************************************************************************
1318**
1319** Function         llcp_dlc_get_next_pdu
1320**
1321** Description      Get a PDU from tx queue of data link
1322**
1323** Returns          BT_HDR*
1324**
1325*******************************************************************************/
1326BT_HDR* llcp_dlc_get_next_pdu (tLLCP_DLCB *p_dlcb)
1327{
1328    BT_HDR *p_msg = NULL;
1329    BOOLEAN flush = TRUE;
1330    tLLCP_SAP_CBACK_DATA data;
1331
1332#if (BT_TRACE_VERBOSE == TRUE)
1333    UINT8   send_seq = p_dlcb->next_tx_seq;
1334#endif
1335
1336    /* if there is data to send and remote device can receive it */
1337    if (  (p_dlcb->i_xmit_q.count)
1338        &&(!p_dlcb->remote_busy)
1339        &&(llcp_dlc_is_rw_open (p_dlcb))  )
1340    {
1341        p_msg = (BT_HDR *) GKI_dequeue (&p_dlcb->i_xmit_q);
1342        llcp_cb.total_tx_i_pdu--;
1343
1344        if (p_msg->offset >= LLCP_MIN_OFFSET)
1345        {
1346            /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq, V(RA) */
1347            llcp_util_build_info_pdu (p_dlcb, p_msg);
1348
1349            p_dlcb->next_tx_seq  = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
1350
1351#if (BT_TRACE_VERBOSE == TRUE)
1352            LLCP_TRACE_DEBUG6 ("LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1353                                send_seq, p_dlcb->next_rx_seq,
1354                                p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1355                                p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1356#endif
1357        }
1358        else
1359        {
1360            LLCP_TRACE_ERROR2 ("LLCP - llcp_dlc_get_next_pdu (): offset (%d) must be %d at least",
1361                                p_msg->offset, LLCP_MIN_OFFSET );
1362            GKI_freebuf (p_msg);
1363            p_msg = NULL;
1364        }
1365    }
1366
1367    /* if tx queue is empty and all PDU is acknowledged */
1368    if (  (p_dlcb->i_xmit_q.count == 0)
1369        &&(p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq)
1370        &&(p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)  )
1371    {
1372        /* check flag to send DISC */
1373        if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC)
1374        {
1375            p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1376            llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1377        }
1378
1379        /* check flag to notify upper layer */
1380        if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE)
1381        {
1382            p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1383
1384            data.tx_complete.event      = LLCP_SAP_EVT_TX_COMPLETE;
1385            data.tx_complete.local_sap  = p_dlcb->local_sap;
1386            data.tx_complete.remote_sap = p_dlcb->remote_sap;
1387
1388            (*p_dlcb->p_app_cb->p_app_cback) (&data);
1389        }
1390    }
1391
1392    return p_msg;
1393}
1394
1395/*******************************************************************************
1396**
1397** Function         llcp_dlc_get_next_pdu_length
1398**
1399** Description      return length of PDU which is top in tx queue of data link
1400**
1401** Returns          length of PDU
1402**
1403*******************************************************************************/
1404UINT16 llcp_dlc_get_next_pdu_length (tLLCP_DLCB *p_dlcb)
1405{
1406    BT_HDR *p_msg;
1407
1408    /* if there is data to send and remote device can receive it */
1409    if (  (p_dlcb->i_xmit_q.count)
1410        &&(!p_dlcb->remote_busy)
1411        &&(llcp_dlc_is_rw_open (p_dlcb))  )
1412    {
1413        p_msg = (BT_HDR *) p_dlcb->i_xmit_q.p_first;
1414
1415        return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1416    }
1417    return 0;
1418}
1419
1420#if (BT_TRACE_VERBOSE == TRUE)
1421/*******************************************************************************
1422**
1423** Function         llcp_dlsm_get_state_name
1424**
1425** Description      This function returns the state name.
1426**
1427** Returns          pointer to the name
1428**
1429*******************************************************************************/
1430static char *llcp_dlsm_get_state_name (tLLCP_DLC_STATE state)
1431{
1432    switch (state)
1433    {
1434    case LLCP_DLC_STATE_IDLE:
1435        return ("IDLE");
1436    case LLCP_DLC_STATE_W4_REMOTE_RESP:
1437        return ("W4_REMOTE_RESP");
1438    case LLCP_DLC_STATE_W4_LOCAL_RESP:
1439        return ("W4_LOCAL_RESP");
1440    case LLCP_DLC_STATE_CONNECTED:
1441        return ("CONNECTED");
1442    case LLCP_DLC_STATE_W4_REMOTE_DM:
1443        return ("W4_REMOTE_DM");
1444    default:
1445        return ("???? UNKNOWN STATE");
1446    }
1447}
1448
1449/*******************************************************************************
1450**
1451** Function         llcp_dlsm_get_event_name
1452**
1453** Description      This function returns the event name.
1454**
1455** Returns          pointer to the name
1456**
1457*******************************************************************************/
1458static char *llcp_dlsm_get_event_name (tLLCP_DLC_EVENT event)
1459{
1460    switch (event)
1461    {
1462    case LLCP_DLC_EVENT_API_CONNECT_REQ:
1463        return ("API_CONNECT_REQ");
1464    case LLCP_DLC_EVENT_API_CONNECT_CFM:
1465        return ("API_CONNECT_CFM");
1466    case LLCP_DLC_EVENT_API_CONNECT_REJECT:
1467        return ("API_CONNECT_REJECT");
1468    case LLCP_DLC_EVENT_PEER_CONNECT_IND:
1469        return ("PEER_CONNECT_IND");
1470    case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
1471        return ("PEER_CONNECT_CFM");
1472
1473    case LLCP_DLC_EVENT_API_DATA_REQ:
1474        return ("API_DATA_REQ");
1475    case LLCP_DLC_EVENT_PEER_DATA_IND:
1476        return ("PEER_DATA_IND");
1477
1478    case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
1479        return ("API_DISCONNECT_REQ");
1480    case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
1481        return ("PEER_DISCONNECT_IND");
1482    case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
1483        return ("PEER_DISCONNECT_RESP");
1484
1485    case LLCP_DLC_EVENT_FRAME_ERROR:
1486        return ("FRAME_ERROR");
1487    case LLCP_DLC_EVENT_LINK_ERROR:
1488        return ("LINK_ERROR");
1489
1490    case LLCP_DLC_EVENT_TIMEOUT:
1491        return ("TIMEOUT");
1492
1493    default:
1494        return ("???? UNKNOWN EVENT");
1495    }
1496}
1497#endif /* (BT_TRACE_VERBOSE == TRUE) */
1498
1499
1500