• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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>
26 
27 #include <android-base/stringprintf.h>
28 #include <base/logging.h>
29 #include <log/log.h>
30 #include "bt_types.h"
31 #include "gki.h"
32 #include "llcp_defs.h"
33 #include "llcp_int.h"
34 #include "nfc_int.h"
35 
36 using android::base::StringPrintf;
37 
38 static tLLCP_STATUS llcp_dlsm_idle(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
39                                    void* p_data);
40 static tLLCP_STATUS llcp_dlsm_w4_remote_resp(tLLCP_DLCB* p_dlcb,
41                                              tLLCP_DLC_EVENT event,
42                                              void* p_data);
43 static tLLCP_STATUS llcp_dlsm_w4_local_resp(tLLCP_DLCB* p_dlcb,
44                                             tLLCP_DLC_EVENT event,
45                                             void* p_data);
46 static tLLCP_STATUS llcp_dlsm_connected(tLLCP_DLCB* p_dlcb,
47                                         tLLCP_DLC_EVENT event, void* p_data);
48 static tLLCP_STATUS llcp_dlsm_w4_remote_dm(tLLCP_DLCB* p_dlcb,
49                                            tLLCP_DLC_EVENT event);
50 static std::string llcp_dlsm_get_state_name(tLLCP_DLC_STATE state);
51 static std::string llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event);
52 
53 extern bool nfc_debug_enabled;
54 extern unsigned char appl_dta_mode_flag;
55 
56 /*******************************************************************************
57 **
58 ** Function         llcp_dlsm_execute
59 **
60 ** Description      This function executes the state machine for data link
61 **                  connection.
62 **
63 ** Returns          tLLCP_STATUS
64 **
65 *******************************************************************************/
llcp_dlsm_execute(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)66 tLLCP_STATUS llcp_dlsm_execute(tLLCP_DLCB* p_dlcb, tLLCP_DLC_EVENT event,
67                                void* p_data) {
68   tLLCP_STATUS status;
69 
70   DLOG_IF(INFO, nfc_debug_enabled)
71       << StringPrintf("DLC (0x%02X) - state: %s, evt: %s", p_dlcb->local_sap,
72                       llcp_dlsm_get_state_name(p_dlcb->state).c_str(),
73                       llcp_dlsm_get_event_name(event).c_str());
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);
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 *******************************************************************************/
llcp_dlsm_idle(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)113 static 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         LOG(WARNING) << StringPrintf(
148             "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       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
165           "Remote MIU:%d, RW:%d", 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       LOG(ERROR) << StringPrintf("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 *******************************************************************************/
llcp_dlsm_w4_remote_resp(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)198 static 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         LOG(WARNING) << StringPrintf(
216             "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       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
225           "Remote MIU:%d, RW:%d", 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       LOG(ERROR) << StringPrintf("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 *******************************************************************************/
llcp_dlsm_w4_local_resp(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)292 static 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       LOG(ERROR) << StringPrintf("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 *******************************************************************************/
llcp_dlsm_connected(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event,void * p_data)379 static 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           DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
448               "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         LOG(ERROR) << StringPrintf("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       LOG(ERROR) << StringPrintf("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 *******************************************************************************/
llcp_dlsm_w4_remote_dm(tLLCP_DLCB * p_dlcb,tLLCP_DLC_EVENT event)508 static tLLCP_STATUS llcp_dlsm_w4_remote_dm(tLLCP_DLCB* p_dlcb,
509                                            tLLCP_DLC_EVENT event) {
510   tLLCP_STATUS status = LLCP_STATUS_SUCCESS;
511   tLLCP_SAP_CBACK_DATA data;
512 
513   switch (event) {
514     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
515     case LLCP_DLC_EVENT_TIMEOUT:
516 
517       /* peer device sends disconnect response or didn't responde */
518       data.disconnect_resp.event = LLCP_SAP_EVT_DISCONNECT_RESP;
519       data.disconnect_resp.local_sap = p_dlcb->local_sap;
520       data.disconnect_resp.remote_sap = p_dlcb->remote_sap;
521       data.disconnect_resp.reason = LLCP_SAP_DM_REASON_RESP_DISC;
522       (*p_dlcb->p_app_cb->p_app_cback)(&data);
523 
524       llcp_util_deallocate_data_link(p_dlcb);
525       llcp_util_adjust_dl_rx_congestion();
526       break;
527 
528     case LLCP_DLC_EVENT_FRAME_ERROR:
529     case LLCP_DLC_EVENT_LINK_ERROR:
530 
531       /* received bad frame or link is deactivated */
532       data.disconnect_ind.event = LLCP_SAP_EVT_DISCONNECT_IND;
533       data.disconnect_ind.local_sap = p_dlcb->local_sap;
534       data.disconnect_ind.remote_sap = p_dlcb->remote_sap;
535       (*p_dlcb->p_app_cb->p_app_cback)(&data);
536 
537       llcp_util_deallocate_data_link(p_dlcb);
538       llcp_util_adjust_dl_rx_congestion();
539       break;
540 
541     case LLCP_DLC_EVENT_PEER_DATA_IND:
542       break;
543 
544     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
545       /* it's race condition, send disconnect response and wait for DM */
546       llcp_util_send_dm(p_dlcb->remote_sap, p_dlcb->local_sap,
547                         LLCP_SAP_DM_REASON_RESP_DISC);
548       break;
549 
550     default:
551       LOG(ERROR) << StringPrintf("Unexpected event");
552       status = LLCP_STATUS_FAIL;
553       break;
554   }
555 
556   return status;
557 }
558 
559 /*******************************************************************************
560 **
561 ** Function         llcp_dlc_find_dlcb_by_local_sap
562 **
563 ** Description      Find tLLCP_DLCB by local SAP and remote SAP
564 **                  if remote_sap is LLCP_INVALID_SAP, it will return a DLCB
565 **                  which is waiting for CC from peer.
566 **
567 ** Returns          tLLCP_DLCB *
568 **
569 *******************************************************************************/
llcp_dlc_find_dlcb_by_sap(uint8_t local_sap,uint8_t remote_sap)570 tLLCP_DLCB* llcp_dlc_find_dlcb_by_sap(uint8_t local_sap, uint8_t remote_sap) {
571   int i;
572 
573   for (i = 0; i < LLCP_MAX_DATA_LINK; i++) {
574     if ((llcp_cb.dlcb[i].state != LLCP_DLC_STATE_IDLE) &&
575         (llcp_cb.dlcb[i].local_sap == local_sap)) {
576       if ((remote_sap == LLCP_INVALID_SAP) &&
577           (llcp_cb.dlcb[i].state == LLCP_DLC_STATE_W4_REMOTE_RESP)) {
578         /* Remote SAP has not been finalized because we are watiing for CC */
579         return (&llcp_cb.dlcb[i]);
580       } else if (llcp_cb.dlcb[i].remote_sap == remote_sap) {
581         return (&llcp_cb.dlcb[i]);
582       }
583     }
584   }
585   return nullptr;
586 }
587 
588 /*******************************************************************************
589 **
590 ** Function         llcp_dlc_flush_q
591 **
592 ** Description      Free buffers in tx and rx queue in data link
593 **
594 ** Returns          void
595 **
596 *******************************************************************************/
llcp_dlc_flush_q(tLLCP_DLCB * p_dlcb)597 void llcp_dlc_flush_q(tLLCP_DLCB* p_dlcb) {
598   if (p_dlcb) {
599     DLOG_IF(INFO, nfc_debug_enabled)
600         << StringPrintf("local SAP:0x%02X", p_dlcb->local_sap);
601 
602     /* Release any held buffers */
603     while (p_dlcb->i_xmit_q.p_first) {
604       GKI_freebuf(GKI_dequeue(&p_dlcb->i_xmit_q));
605       llcp_cb.total_tx_i_pdu--;
606     }
607 
608     /* discard any received I PDU on data link  including in AGF */
609     LLCP_FlushDataLinkRxData(p_dlcb->local_sap, p_dlcb->remote_sap);
610   } else {
611     LOG(ERROR) << StringPrintf("p_dlcb is NULL");
612   }
613 }
614 
615 /*******************************************************************************
616 **
617 ** Function         llcp_dlc_proc_connect_pdu
618 **
619 ** Description      Process CONNECT PDU
620 **
621 ** Returns          void
622 **
623 *******************************************************************************/
llcp_dlc_proc_connect_pdu(uint8_t dsap,uint8_t ssap,uint16_t length,uint8_t * p_data)624 static void llcp_dlc_proc_connect_pdu(uint8_t dsap, uint8_t ssap,
625                                       uint16_t length, uint8_t* p_data) {
626   tLLCP_DLCB* p_dlcb;
627   tLLCP_STATUS status;
628   tLLCP_APP_CB* p_app_cb;
629 
630   tLLCP_CONNECTION_PARAMS params;
631 
632   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
633 
634   p_app_cb = llcp_util_get_app_cb(dsap);
635 
636   if ((p_app_cb == nullptr) || (p_app_cb->p_app_cback == nullptr) ||
637       ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
638     LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", dsap);
639     llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
640     return;
641   }
642 
643   /* parse CONNECT PDU and get connection parameters */
644   if (llcp_util_parse_connect(p_data, length, &params) != LLCP_STATUS_SUCCESS) {
645     LOG(ERROR) << StringPrintf("Bad format CONNECT");
646     /* fix to pass TC_CTO_TAR_BI_02_x (x=5) test case
647      * As per the LLCP test specification v1.2.00 by receiving erroneous SNL PDU
648      * i'e with improper length and service name "urn:nfc:sn:dta-co-echo-in",
649      * the IUT should not send any PDU except SYMM PDU */
650 
651     llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
652     return;
653   }
654 
655   /* if this is connection by service name */
656   if (dsap == LLCP_SAP_SDP) {
657     /* find registered SAP with service name */
658     if (strlen(params.sn))
659       dsap = llcp_sdp_get_sap_by_name(params.sn, (uint8_t)strlen(params.sn));
660     else {
661       /* if SN type is included without SN */
662       if (params.sn[1] == LLCP_SN_TYPE) {
663         llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
664       } else {
665         /* SDP doesn't accept connection */
666         llcp_util_send_dm(ssap, LLCP_SAP_SDP,
667                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
668       }
669       return;
670     }
671 
672     if (dsap == LLCP_SAP_SDP) {
673       LOG(ERROR) << StringPrintf("SDP doesn't accept connection");
674 
675       llcp_util_send_dm(ssap, LLCP_SAP_SDP,
676                         LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
677       return;
678     } else if (dsap == 0) {
679       LOG(ERROR) << StringPrintf("Unregistered Service:%s", params.sn);
680 
681       llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
682       return;
683     } else {
684       /* check if this application can support connection-oriented transport */
685       p_app_cb = llcp_util_get_app_cb(dsap);
686 
687       if ((p_app_cb == nullptr) || (p_app_cb->p_app_cback == nullptr) ||
688           ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
689         LOG(ERROR) << StringPrintf(
690             "SAP(0x%x) doesn't support "
691             "connection-oriented",
692             dsap);
693         llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
694         return;
695       }
696     }
697   }
698 
699   /* check if any data link */
700   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
701   if (p_dlcb) {
702     LOG(ERROR) << StringPrintf("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         LOG(ERROR) << StringPrintf("Error in state machine");
714         llcp_util_deallocate_data_link(p_dlcb);
715       }
716     } else {
717       LOG(ERROR) << StringPrintf("Out of resource");
718       llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY);
719     }
720   }
721 }
722 
723 /*******************************************************************************
724 **
725 ** Function         llcp_dlc_proc_disc_pdu
726 **
727 ** Description      Process DISC PDU
728 **
729 ** Returns          void
730 **
731 *******************************************************************************/
llcp_dlc_proc_disc_pdu(uint8_t dsap,uint8_t ssap,uint16_t length)732 static void llcp_dlc_proc_disc_pdu(uint8_t dsap, uint8_t ssap,
733                                    uint16_t length) {
734   tLLCP_DLCB* p_dlcb;
735 
736   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
737 
738   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
739   if (p_dlcb) {
740     if (length > 0) {
741       LOG(ERROR) << StringPrintf(
742           "Received extra data (%d bytes) in DISC "
743           "PDU",
744           length);
745 
746       llcp_util_send_frmr(p_dlcb,
747                           LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
748                           LLCP_PDU_DISC_TYPE, 0);
749       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
750     } else {
751       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, nullptr);
752     }
753   } else {
754     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
755   }
756 }
757 
758 /*******************************************************************************
759 **
760 ** Function         llcp_dlc_proc_cc_pdu
761 **
762 ** Description      Process CC PDU
763 **
764 ** Returns          void
765 **
766 *******************************************************************************/
llcp_dlc_proc_cc_pdu(uint8_t dsap,uint8_t ssap,uint16_t length,uint8_t * p_data)767 static void llcp_dlc_proc_cc_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
768                                  uint8_t* p_data) {
769   tLLCP_DLCB* p_dlcb;
770   tLLCP_CONNECTION_PARAMS params;
771   tLLCP_STATUS status;
772 
773   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
774 
775   /* find a DLCB waiting for CC on this local SAP */
776   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
777   if (p_dlcb) {
778     /* The CC may contain a SSAP that is different from the DSAP in the CONNECT
779      */
780     p_dlcb->remote_sap = ssap;
781 
782     if (llcp_util_parse_cc(p_data, length, &(params.miu), &(params.rw)) ==
783         LLCP_STATUS_SUCCESS) {
784       status =
785           llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
786       if (status != LLCP_STATUS_SUCCESS) {
787         LOG(ERROR) << StringPrintf("Error in state machine");
788         llcp_util_deallocate_data_link(p_dlcb);
789       }
790     } else {
791       llcp_util_send_frmr(p_dlcb,
792                           LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
793                           LLCP_PDU_DISC_TYPE, 0);
794       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
795     }
796   } else {
797     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
798   }
799 }
800 
801 /*******************************************************************************
802 **
803 ** Function         llcp_dlc_proc_dm_pdu
804 **
805 ** Description      Process DM PDU
806 **
807 ** Returns          void
808 **
809 *******************************************************************************/
llcp_dlc_proc_dm_pdu(uint8_t dsap,uint8_t ssap,uint16_t length,uint8_t * p_data)810 static void llcp_dlc_proc_dm_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
811                                  uint8_t* p_data) {
812   tLLCP_DLCB* p_dlcb;
813 
814   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
815 
816   if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE) {
817     LOG(ERROR) << StringPrintf("Received invalid DM PDU");
818   } else {
819     if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC) {
820       /* local device initiated disconnecting */
821       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
822     } else {
823       /* peer device rejected connection with any reason */
824       /* find a DLCB waiting for CC on this local SAP    */
825       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
826     }
827 
828     if (p_dlcb) {
829       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP,
830                         p_data); /* passing reason */
831     } else {
832       LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap,
833                                  ssap);
834     }
835   }
836 }
837 
838 /*******************************************************************************
839 **
840 ** Function         llcp_dlc_proc_i_pdu
841 **
842 ** Description      Process I PDU
843 **
844 ** Returns          void
845 **
846 *******************************************************************************/
llcp_dlc_proc_i_pdu(uint8_t dsap,uint8_t ssap,uint16_t i_pdu_length,uint8_t * p_i_pdu,NFC_HDR * p_msg)847 void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length,
848                          uint8_t* p_i_pdu, NFC_HDR* p_msg) {
849   uint8_t *p, *p_dst, send_seq, rcv_seq, error_flags;
850   uint16_t info_len, available_bytes;
851   tLLCP_DLCB* p_dlcb;
852   bool appended;
853   NFC_HDR* p_last_buf;
854 
855   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
856 
857   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
858 
859   if ((p_dlcb) && (p_dlcb->state == LLCP_DLC_STATE_CONNECTED)) {
860     error_flags = 0;
861 
862     if (p_msg) {
863       i_pdu_length = p_msg->len;
864       p_i_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
865     }
866 
867     if (i_pdu_length < LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE) {
868       android_errorWriteLog(0x534e4554, "116722267");
869       LOG(ERROR) << StringPrintf("Insufficient I PDU length %d", i_pdu_length);
870       if (p_msg) {
871         GKI_freebuf(p_msg);
872       }
873       return;
874     }
875 
876     info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
877 
878     if (info_len > p_dlcb->local_miu) {
879       LOG(ERROR) << StringPrintf(
880           "exceeding local MIU (%d bytes): got %d "
881           "bytes SDU",
882           p_dlcb->local_miu, info_len);
883 
884       error_flags |= LLCP_FRMR_I_ERROR_FLAG;
885     }
886 
887     /* get sequence numbers */
888     p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
889 
890     send_seq = LLCP_GET_NS(*p);
891     rcv_seq = LLCP_GET_NR(*p);
892 
893     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
894         "LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
895         rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
896         p_dlcb->sent_ack_seq);
897 
898     /* if send sequence number, N(S) is not expected one, V(R) */
899     if (p_dlcb->next_rx_seq != send_seq) {
900       LOG(ERROR) << StringPrintf("Bad N(S) got:%d, expected:%d", send_seq,
901                                  p_dlcb->next_rx_seq);
902 
903       error_flags |= LLCP_FRMR_S_ERROR_FLAG;
904     } else {
905       /* if peer device sends more than our receiving window size */
906       if ((uint8_t)(send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >=
907           p_dlcb->local_rw) {
908         LOG(ERROR) << StringPrintf("Bad N(S):%d >= V(RA):%d + RW(L):%d",
909                                    send_seq, p_dlcb->sent_ack_seq,
910                                    p_dlcb->local_rw);
911 
912         error_flags |= LLCP_FRMR_S_ERROR_FLAG;
913       }
914     }
915 
916     /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
917     if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
918             (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
919         (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
920             LLCP_SEQ_MODULO) {
921       error_flags |= LLCP_FRMR_R_ERROR_FLAG;
922       LOG(ERROR) << StringPrintf("Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
923                                  rcv_seq, p_dlcb->rcvd_ack_seq,
924                                  p_dlcb->next_tx_seq);
925     }
926 
927     /* if any error is found */
928     if (error_flags) {
929       llcp_util_send_frmr(p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
930       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
931     } else {
932       /* update local sequence variables */
933       p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
934       p_dlcb->rcvd_ack_seq = rcv_seq;
935 
936       appended = false;
937 
938       /* get last buffer in rx queue */
939       p_last_buf = (NFC_HDR*)GKI_getlast(&p_dlcb->i_rx_q);
940 
941       if (p_last_buf) {
942         /* get max length to append at the end of buffer */
943         available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
944                           p_last_buf->offset - p_last_buf->len;
945 
946         /* if new UI PDU with length can be attached at the end of buffer */
947         if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len) {
948           p_dst =
949               (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
950 
951           /* add length of information in I PDU */
952           UINT16_TO_BE_STREAM(p_dst, info_len);
953 
954           /* copy information of I PDU */
955           p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
956 
957           memcpy(p_dst, p, info_len);
958 
959           p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
960 
961           if (p_msg) {
962             GKI_freebuf(p_msg);
963             p_msg = nullptr;
964           }
965 
966           appended = true;
967         }
968       }
969 
970       /* if it is not available to append */
971       if (!appended) {
972         /* if it's not from AGF PDU */
973         if (p_msg) {
974           /* add length of information in front of information */
975           p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE -
976               LLCP_PDU_AGF_LEN_SIZE;
977           UINT16_TO_BE_STREAM(p, info_len);
978 
979           p_msg->offset +=
980               LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
981           p_msg->len -=
982               LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
983           p_msg->layer_specific = 0;
984         } else {
985           p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
986 
987           if (p_msg) {
988             p_dst = (uint8_t*)(p_msg + 1);
989 
990             /* add length of information in front of information */
991             UINT16_TO_BE_STREAM(p_dst, info_len);
992 
993             p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
994             memcpy(p_dst, p, info_len);
995 
996             p_msg->offset = 0;
997             p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
998             p_msg->layer_specific = 0;
999           } else {
1000             LOG(ERROR) << StringPrintf("out of buffer");
1001           }
1002         }
1003 
1004         /* insert I PDU in rx queue */
1005         if (p_msg) {
1006           GKI_enqueue(&p_dlcb->i_rx_q, p_msg);
1007           p_msg = nullptr;
1008           llcp_cb.total_rx_i_pdu++;
1009 
1010           llcp_util_check_rx_congested_status();
1011         }
1012       }
1013 
1014       p_dlcb->num_rx_i_pdu++;
1015 
1016       if ((!p_dlcb->local_busy) && (p_dlcb->num_rx_i_pdu == 1)) {
1017         /* notify rx data is available so upper layer reads data until queue is
1018          * empty */
1019         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, nullptr);
1020       }
1021 
1022       if ((!p_dlcb->is_rx_congested) &&
1023           (p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)) {
1024         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1025             "congested num_rx_i_pdu=%d, "
1026             "rx_congest_threshold=%d",
1027             p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
1028 
1029         /* send RNR */
1030         p_dlcb->is_rx_congested = true;
1031         p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1032       }
1033     }
1034   } else {
1035     LOG(ERROR) << StringPrintf("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 *******************************************************************************/
llcp_dlc_proc_rr_rnr_pdu(uint8_t dsap,uint8_t ptype,uint8_t ssap,uint16_t length,uint8_t * p_data)1053 static 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   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1062 
1063   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1064   if (p_dlcb != nullptr) {
1065     error_flags = 0;
1066 
1067     if (length == 0) {
1068       android_errorWriteLog(0x534e4554, "116788646");
1069       return;
1070     }
1071     rcv_seq = LLCP_GET_NR(*p_data);
1072 
1073     if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE) {
1074       error_flags |= LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG;
1075     }
1076 
1077     /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1078     if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
1079             (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
1080         (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
1081             LLCP_SEQ_MODULO) {
1082       error_flags |= LLCP_FRMR_R_ERROR_FLAG;
1083       LOG(ERROR) << StringPrintf(
1084           "Bad N(R):%d valid range [V(SA):%d, "
1085           "V(S):%d]",
1086           rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1087     }
1088 
1089     if (error_flags) {
1090       llcp_util_send_frmr(p_dlcb, error_flags, ptype, *p_data);
1091       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
1092     } else {
1093       p_dlcb->rcvd_ack_seq = rcv_seq;
1094 
1095       DLOG_IF(INFO, nfc_debug_enabled)
1096           << StringPrintf("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1097                           rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1098                           p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1099       old_remote_busy = p_dlcb->remote_busy;
1100       if (ptype == LLCP_PDU_RNR_TYPE) {
1101         p_dlcb->remote_busy = true;
1102         /* if upper layer hasn't get congestion started notification */
1103         if ((!old_remote_busy) && (!p_dlcb->is_tx_congested)) {
1104           LOG(WARNING) << StringPrintf(
1105               "Data link (SSAP:DSAP=0x%X:0x%X) "
1106               "congestion start: i_xmit_q.count=%d",
1107               p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
1108 
1109           cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1110           cback_data.congest.local_sap = p_dlcb->local_sap;
1111           cback_data.congest.remote_sap = p_dlcb->remote_sap;
1112           cback_data.congest.is_congested = true;
1113           cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1114 
1115           (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
1116         }
1117       } else {
1118         p_dlcb->remote_busy = false;
1119         /* if upper layer hasn't get congestion ended notification and data link
1120          * is not congested */
1121         if ((old_remote_busy) && (!p_dlcb->is_tx_congested)) {
1122           LOG(WARNING) << StringPrintf(
1123               "Data link (SSAP:DSAP=0x%X:0x%X) "
1124               "congestion end: i_xmit_q.count=%d",
1125               p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
1126 
1127           cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1128           cback_data.congest.local_sap = p_dlcb->local_sap;
1129           cback_data.congest.remote_sap = p_dlcb->remote_sap;
1130           cback_data.congest.is_congested = false;
1131           cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1132 
1133           (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
1134         }
1135       }
1136 
1137       /* check flag to send DISC when tx queue is empty */
1138       if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1139         /* if no pending data and all PDU is acked */
1140         if ((p_dlcb->i_xmit_q.count == 0) &&
1141             (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
1142             (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
1143           p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1144           llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1145         }
1146       }
1147     }
1148   } else {
1149     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
1150   }
1151 }
1152 
1153 /*******************************************************************************
1154 **
1155 ** Function         llcp_dlc_proc_rx_pdu
1156 **
1157 ** Description      Process PDU for data link
1158 **
1159 ** Returns          void
1160 **
1161 *******************************************************************************/
llcp_dlc_proc_rx_pdu(uint8_t dsap,uint8_t ptype,uint8_t ssap,uint16_t length,uint8_t * p_data)1162 void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1163                           uint16_t length, uint8_t* p_data) {
1164   tLLCP_DLCB* p_dlcb;
1165 
1166   DLOG_IF(INFO, nfc_debug_enabled)
1167       << StringPrintf("DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x", dsap, ptype, ssap);
1168 
1169   if (dsap == LLCP_SAP_LM) {
1170     LOG(ERROR) << StringPrintf("Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
1171     return;
1172   }
1173 
1174   switch (ptype) {
1175     case LLCP_PDU_CONNECT_TYPE:
1176       llcp_dlc_proc_connect_pdu(dsap, ssap, length, p_data);
1177       break;
1178 
1179     case LLCP_PDU_DISC_TYPE:
1180       llcp_dlc_proc_disc_pdu(dsap, ssap, length);
1181       break;
1182 
1183     case LLCP_PDU_CC_TYPE:
1184       llcp_dlc_proc_cc_pdu(dsap, ssap, length, p_data);
1185       break;
1186 
1187     case LLCP_PDU_DM_TYPE:
1188       llcp_dlc_proc_dm_pdu(dsap, ssap, length, p_data);
1189       break;
1190 
1191     case LLCP_PDU_FRMR_TYPE:
1192       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1193       if (p_dlcb) {
1194         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
1195       }
1196       break;
1197 
1198     case LLCP_PDU_RR_TYPE:
1199     case LLCP_PDU_RNR_TYPE:
1200       llcp_dlc_proc_rr_rnr_pdu(dsap, ptype, ssap, length, p_data);
1201       break;
1202 
1203     default:
1204       LOG(ERROR) << StringPrintf("Unexpected PDU type (0x%x)", ptype);
1205 
1206       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1207       if (p_dlcb) {
1208         llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1209         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
1210       }
1211       break;
1212   }
1213 }
1214 
1215 /*******************************************************************************
1216 **
1217 ** Function         llcp_dlc_check_to_send_rr_rnr
1218 **
1219 ** Description      Send RR or RNR if necessary
1220 **
1221 ** Returns          void
1222 **
1223 *******************************************************************************/
llcp_dlc_check_to_send_rr_rnr(void)1224 void llcp_dlc_check_to_send_rr_rnr(void) {
1225   uint8_t idx;
1226   bool flush = true;
1227 
1228   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1229 
1230   /*
1231   ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs
1232   ** can be aggregated in a received AGF PDU. In this case, this is post
1233   ** processing of AGF PDU to send single RR or RNR after processing all I
1234   ** PDUs in received AGF if there was no I-PDU to carry N(R).
1235   **
1236   ** Send RR or RNR if any change of local busy condition or rx congestion
1237   ** status, or V(RA) is not V(R).
1238   */
1239   for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
1240     if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
1241       llcp_util_send_rr_rnr(&(llcp_cb.dlcb[idx]));
1242 
1243       /* check flag to send DISC when tx queue is empty */
1244       if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1245         /* if no pending data and all PDU is acked */
1246         if ((llcp_cb.dlcb[idx].i_xmit_q.count == 0) &&
1247             (llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq) &&
1248             (llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)) {
1249           llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1250           llcp_dlsm_execute(&(llcp_cb.dlcb[idx]),
1251                             LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1252         }
1253       }
1254     }
1255   }
1256 }
1257 
1258 /*******************************************************************************
1259 **
1260 ** Function         llcp_dlc_is_rw_open
1261 **
1262 ** Description      check if receive window is open in remote
1263 **
1264 ** Returns          TRUE if remote can receive more data
1265 **
1266 *******************************************************************************/
llcp_dlc_is_rw_open(tLLCP_DLCB * p_dlcb)1267 bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb) {
1268   if ((uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO <
1269       p_dlcb->remote_rw) {
1270     return true;
1271   } else {
1272     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1273         "Flow Off, V(S):%d, V(SA):%d, RW(R):%d", p_dlcb->next_tx_seq,
1274         p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
1275     return false;
1276   }
1277 }
1278 
1279 /*******************************************************************************
1280 **
1281 ** Function         llcp_dlc_get_next_pdu
1282 **
1283 ** Description      Get a PDU from tx queue of data link
1284 **
1285 ** Returns          NFC_HDR*
1286 **
1287 *******************************************************************************/
llcp_dlc_get_next_pdu(tLLCP_DLCB * p_dlcb)1288 NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb) {
1289   NFC_HDR* p_msg = nullptr;
1290   bool flush = true;
1291   tLLCP_SAP_CBACK_DATA data;
1292 
1293   uint8_t send_seq = p_dlcb->next_tx_seq;
1294 
1295   /* if there is data to send and remote device can receive it */
1296   if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
1297       (llcp_dlc_is_rw_open(p_dlcb))) {
1298     p_msg = (NFC_HDR*)GKI_dequeue(&p_dlcb->i_xmit_q);
1299     llcp_cb.total_tx_i_pdu--;
1300 
1301     if (p_msg->offset >= LLCP_MIN_OFFSET) {
1302       /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq,
1303        * V(RA) */
1304       llcp_util_build_info_pdu(p_dlcb, p_msg);
1305 
1306       p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
1307 
1308       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1309           "LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
1310           p_dlcb->next_rx_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1311           p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1312     } else {
1313       LOG(ERROR) << StringPrintf("offset (%d) must be %d at least",
1314                                  p_msg->offset, LLCP_MIN_OFFSET);
1315       GKI_freebuf(p_msg);
1316       p_msg = nullptr;
1317     }
1318   }
1319 
1320   /* if tx queue is empty and all PDU is acknowledged */
1321   if ((p_dlcb->i_xmit_q.count == 0) &&
1322       (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
1323       (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
1324     /* check flag to send DISC */
1325     if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1326       p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1327       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1328     }
1329 
1330     /* check flag to notify upper layer */
1331     if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE) {
1332       p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1333 
1334       data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
1335       data.tx_complete.local_sap = p_dlcb->local_sap;
1336       data.tx_complete.remote_sap = p_dlcb->remote_sap;
1337 
1338       (*p_dlcb->p_app_cb->p_app_cback)(&data);
1339     }
1340   }
1341 
1342   return p_msg;
1343 }
1344 
1345 /*******************************************************************************
1346 **
1347 ** Function         llcp_dlc_get_next_pdu_length
1348 **
1349 ** Description      return length of PDU which is top in tx queue of data link
1350 **
1351 ** Returns          length of PDU
1352 **
1353 *******************************************************************************/
llcp_dlc_get_next_pdu_length(tLLCP_DLCB * p_dlcb)1354 uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb) {
1355   NFC_HDR* p_msg;
1356 
1357   /* if there is data to send and remote device can receive it */
1358   if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
1359       (llcp_dlc_is_rw_open(p_dlcb))) {
1360     p_msg = (NFC_HDR*)p_dlcb->i_xmit_q.p_first;
1361 
1362     return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1363   }
1364   return 0;
1365 }
1366 
1367 /*******************************************************************************
1368 **
1369 ** Function         llcp_dlsm_get_state_name
1370 **
1371 ** Description      This function returns the state name.
1372 **
1373 ** Returns          pointer to the name
1374 **
1375 *******************************************************************************/
llcp_dlsm_get_state_name(tLLCP_DLC_STATE state)1376 static std::string llcp_dlsm_get_state_name(tLLCP_DLC_STATE state) {
1377   switch (state) {
1378     case LLCP_DLC_STATE_IDLE:
1379       return "IDLE";
1380     case LLCP_DLC_STATE_W4_REMOTE_RESP:
1381       return "W4_REMOTE_RESP";
1382     case LLCP_DLC_STATE_W4_LOCAL_RESP:
1383       return "W4_LOCAL_RESP";
1384     case LLCP_DLC_STATE_CONNECTED:
1385       return "CONNECTED";
1386     case LLCP_DLC_STATE_W4_REMOTE_DM:
1387       return "W4_REMOTE_DM";
1388     default:
1389       return "???? UNKNOWN STATE";
1390   }
1391 }
1392 
1393 /*******************************************************************************
1394 **
1395 ** Function         llcp_dlsm_get_event_name
1396 **
1397 ** Description      This function returns the event name.
1398 **
1399 ** Returns          pointer to the name
1400 **
1401 *******************************************************************************/
llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event)1402 static std::string llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event) {
1403   switch (event) {
1404     case LLCP_DLC_EVENT_API_CONNECT_REQ:
1405       return "API_CONNECT_REQ";
1406     case LLCP_DLC_EVENT_API_CONNECT_CFM:
1407       return "API_CONNECT_CFM";
1408     case LLCP_DLC_EVENT_API_CONNECT_REJECT:
1409       return "API_CONNECT_REJECT";
1410     case LLCP_DLC_EVENT_PEER_CONNECT_IND:
1411       return "PEER_CONNECT_IND";
1412     case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
1413       return "PEER_CONNECT_CFM";
1414     case LLCP_DLC_EVENT_API_DATA_REQ:
1415       return "API_DATA_REQ";
1416     case LLCP_DLC_EVENT_PEER_DATA_IND:
1417       return "PEER_DATA_IND";
1418     case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
1419       return "API_DISCONNECT_REQ";
1420     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
1421       return "PEER_DISCONNECT_IND";
1422     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
1423       return "PEER_DISCONNECT_RESP";
1424     case LLCP_DLC_EVENT_FRAME_ERROR:
1425       return "FRAME_ERROR";
1426     case LLCP_DLC_EVENT_LINK_ERROR:
1427       return "LINK_ERROR";
1428     case LLCP_DLC_EVENT_TIMEOUT:
1429       return "TIMEOUT";
1430     default:
1431       return "???? UNKNOWN EVENT";
1432   }
1433 }
1434