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