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