• 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     if (appl_dta_mode_flag == 1 &&
652         p_data[1] == strlen((const char*)&p_data[2])) {
653       DLOG_IF(INFO, nfc_debug_enabled)
654           << StringPrintf("%s: Strings are not equal", __func__);
655       llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
656     } else {
657       llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
658     }
659     return;
660   }
661 
662   /* if this is connection by service name */
663   if (dsap == LLCP_SAP_SDP) {
664     /* find registered SAP with service name */
665     if (strlen(params.sn))
666       dsap = llcp_sdp_get_sap_by_name(params.sn, (uint8_t)strlen(params.sn));
667     else {
668       /* if SN type is included without SN */
669       if (params.sn[1] == LLCP_SN_TYPE) {
670         llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
671       } else {
672         /* SDP doesn't accept connection */
673         llcp_util_send_dm(ssap, LLCP_SAP_SDP,
674                           LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
675       }
676       return;
677     }
678 
679     if (dsap == LLCP_SAP_SDP) {
680       LOG(ERROR) << StringPrintf("SDP doesn't accept connection");
681 
682       llcp_util_send_dm(ssap, LLCP_SAP_SDP,
683                         LLCP_SAP_DM_REASON_PERM_REJECT_THIS);
684       return;
685     } else if (dsap == 0) {
686       LOG(ERROR) << StringPrintf("Unregistered Service:%s", params.sn);
687 
688       llcp_util_send_dm(ssap, LLCP_SAP_SDP, LLCP_SAP_DM_REASON_NO_SERVICE);
689       return;
690     } else {
691       /* check if this application can support connection-oriented transport */
692       p_app_cb = llcp_util_get_app_cb(dsap);
693 
694       if ((p_app_cb == nullptr) || (p_app_cb->p_app_cback == nullptr) ||
695           ((p_app_cb->link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0)) {
696         LOG(ERROR) << StringPrintf(
697             "SAP(0x%x) doesn't support "
698             "connection-oriented",
699             dsap);
700         llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_SERVICE);
701         return;
702       }
703     }
704   }
705 
706   /* check if any data link */
707   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
708   if (p_dlcb) {
709     LOG(ERROR) << StringPrintf("Data link is aleady established");
710     llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_THIS);
711   } else {
712     /* allocate data link connection control block and notify upper layer
713      * through state machine */
714     p_dlcb = llcp_util_allocate_data_link(dsap, ssap);
715 
716     if (p_dlcb) {
717       status =
718           llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_IND, &params);
719       if (status != LLCP_STATUS_SUCCESS) {
720         LOG(ERROR) << StringPrintf("Error in state machine");
721         llcp_util_deallocate_data_link(p_dlcb);
722       }
723     } else {
724       LOG(ERROR) << StringPrintf("Out of resource");
725       llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_TEMP_REJECT_ANY);
726     }
727   }
728 }
729 
730 /*******************************************************************************
731 **
732 ** Function         llcp_dlc_proc_disc_pdu
733 **
734 ** Description      Process DISC PDU
735 **
736 ** Returns          void
737 **
738 *******************************************************************************/
llcp_dlc_proc_disc_pdu(uint8_t dsap,uint8_t ssap,uint16_t length)739 static void llcp_dlc_proc_disc_pdu(uint8_t dsap, uint8_t ssap,
740                                    uint16_t length) {
741   tLLCP_DLCB* p_dlcb;
742 
743   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
744 
745   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
746   if (p_dlcb) {
747     if (length > 0) {
748       LOG(ERROR) << StringPrintf(
749           "Received extra data (%d bytes) in DISC "
750           "PDU",
751           length);
752 
753       llcp_util_send_frmr(p_dlcb,
754                           LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
755                           LLCP_PDU_DISC_TYPE, 0);
756       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
757     } else {
758       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_IND, nullptr);
759     }
760   } else {
761     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
762   }
763 }
764 
765 /*******************************************************************************
766 **
767 ** Function         llcp_dlc_proc_cc_pdu
768 **
769 ** Description      Process CC PDU
770 **
771 ** Returns          void
772 **
773 *******************************************************************************/
llcp_dlc_proc_cc_pdu(uint8_t dsap,uint8_t ssap,uint16_t length,uint8_t * p_data)774 static void llcp_dlc_proc_cc_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
775                                  uint8_t* p_data) {
776   tLLCP_DLCB* p_dlcb;
777   tLLCP_CONNECTION_PARAMS params;
778   tLLCP_STATUS status;
779 
780   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
781 
782   /* find a DLCB waiting for CC on this local SAP */
783   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
784   if (p_dlcb) {
785     /* The CC may contain a SSAP that is different from the DSAP in the CONNECT
786      */
787     p_dlcb->remote_sap = ssap;
788 
789     if (llcp_util_parse_cc(p_data, length, &(params.miu), &(params.rw)) ==
790         LLCP_STATUS_SUCCESS) {
791       status =
792           llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_CONNECT_CFM, &params);
793       if (status != LLCP_STATUS_SUCCESS) {
794         LOG(ERROR) << StringPrintf("Error in state machine");
795         llcp_util_deallocate_data_link(p_dlcb);
796       }
797     } else {
798       llcp_util_send_frmr(p_dlcb,
799                           LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG,
800                           LLCP_PDU_DISC_TYPE, 0);
801       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
802     }
803   } else {
804     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
805   }
806 }
807 
808 /*******************************************************************************
809 **
810 ** Function         llcp_dlc_proc_dm_pdu
811 **
812 ** Description      Process DM PDU
813 **
814 ** Returns          void
815 **
816 *******************************************************************************/
llcp_dlc_proc_dm_pdu(uint8_t dsap,uint8_t ssap,uint16_t length,uint8_t * p_data)817 static void llcp_dlc_proc_dm_pdu(uint8_t dsap, uint8_t ssap, uint16_t length,
818                                  uint8_t* p_data) {
819   tLLCP_DLCB* p_dlcb;
820 
821   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
822 
823   if (length != LLCP_PDU_DM_SIZE - LLCP_PDU_HEADER_SIZE) {
824     LOG(ERROR) << StringPrintf("Received invalid DM PDU");
825   } else {
826     if (*p_data == LLCP_SAP_DM_REASON_RESP_DISC) {
827       /* local device initiated disconnecting */
828       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
829     } else {
830       /* peer device rejected connection with any reason */
831       /* find a DLCB waiting for CC on this local SAP    */
832       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, LLCP_INVALID_SAP);
833     }
834 
835     if (p_dlcb) {
836       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DISCONNECT_RESP,
837                         p_data); /* passing reason */
838     } else {
839       LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap,
840                                  ssap);
841     }
842   }
843 }
844 
845 /*******************************************************************************
846 **
847 ** Function         llcp_dlc_proc_i_pdu
848 **
849 ** Description      Process I PDU
850 **
851 ** Returns          void
852 **
853 *******************************************************************************/
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)854 void llcp_dlc_proc_i_pdu(uint8_t dsap, uint8_t ssap, uint16_t i_pdu_length,
855                          uint8_t* p_i_pdu, NFC_HDR* p_msg) {
856   uint8_t *p, *p_dst, send_seq, rcv_seq, error_flags;
857   uint16_t info_len, available_bytes;
858   tLLCP_DLCB* p_dlcb;
859   bool appended;
860   NFC_HDR* p_last_buf;
861 
862   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
863 
864   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
865 
866   if ((p_dlcb) && (p_dlcb->state == LLCP_DLC_STATE_CONNECTED)) {
867     error_flags = 0;
868 
869     if (p_msg) {
870       i_pdu_length = p_msg->len;
871       p_i_pdu = (uint8_t*)(p_msg + 1) + p_msg->offset;
872     }
873 
874     if (i_pdu_length < LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE) {
875       android_errorWriteLog(0x534e4554, "116722267");
876       LOG(ERROR) << StringPrintf("Insufficient I PDU length %d", i_pdu_length);
877       if (p_msg) {
878         GKI_freebuf(p_msg);
879       }
880       return;
881     }
882 
883     info_len = i_pdu_length - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE;
884 
885     if (info_len > p_dlcb->local_miu) {
886       LOG(ERROR) << StringPrintf(
887           "exceeding local MIU (%d bytes): got %d "
888           "bytes SDU",
889           p_dlcb->local_miu, info_len);
890 
891       error_flags |= LLCP_FRMR_I_ERROR_FLAG;
892     }
893 
894     /* get sequence numbers */
895     p = p_i_pdu + LLCP_PDU_HEADER_SIZE;
896 
897     send_seq = LLCP_GET_NS(*p);
898     rcv_seq = LLCP_GET_NR(*p);
899 
900     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
901         "LLCP RX I PDU - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
902         rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_rx_seq,
903         p_dlcb->sent_ack_seq);
904 
905     /* if send sequence number, N(S) is not expected one, V(R) */
906     if (p_dlcb->next_rx_seq != send_seq) {
907       LOG(ERROR) << StringPrintf("Bad N(S) got:%d, expected:%d", send_seq,
908                                  p_dlcb->next_rx_seq);
909 
910       error_flags |= LLCP_FRMR_S_ERROR_FLAG;
911     } else {
912       /* if peer device sends more than our receiving window size */
913       if ((uint8_t)(send_seq - p_dlcb->sent_ack_seq) % LLCP_SEQ_MODULO >=
914           p_dlcb->local_rw) {
915         LOG(ERROR) << StringPrintf("Bad N(S):%d >= V(RA):%d + RW(L):%d",
916                                    send_seq, p_dlcb->sent_ack_seq,
917                                    p_dlcb->local_rw);
918 
919         error_flags |= LLCP_FRMR_S_ERROR_FLAG;
920       }
921     }
922 
923     /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
924     if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
925             (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
926         (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
927             LLCP_SEQ_MODULO) {
928       error_flags |= LLCP_FRMR_R_ERROR_FLAG;
929       LOG(ERROR) << StringPrintf("Bad N(R):%d valid range [V(SA):%d, V(S):%d]",
930                                  rcv_seq, p_dlcb->rcvd_ack_seq,
931                                  p_dlcb->next_tx_seq);
932     }
933 
934     /* if any error is found */
935     if (error_flags) {
936       llcp_util_send_frmr(p_dlcb, error_flags, LLCP_PDU_I_TYPE, *p);
937       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
938     } else {
939       /* update local sequence variables */
940       p_dlcb->next_rx_seq = (p_dlcb->next_rx_seq + 1) % LLCP_SEQ_MODULO;
941       p_dlcb->rcvd_ack_seq = rcv_seq;
942 
943       appended = false;
944 
945       /* get last buffer in rx queue */
946       p_last_buf = (NFC_HDR*)GKI_getlast(&p_dlcb->i_rx_q);
947 
948       if (p_last_buf) {
949         /* get max length to append at the end of buffer */
950         available_bytes = GKI_get_buf_size(p_last_buf) - NFC_HDR_SIZE -
951                           p_last_buf->offset - p_last_buf->len;
952 
953         /* if new UI PDU with length can be attached at the end of buffer */
954         if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + info_len) {
955           p_dst =
956               (uint8_t*)(p_last_buf + 1) + p_last_buf->offset + p_last_buf->len;
957 
958           /* add length of information in I PDU */
959           UINT16_TO_BE_STREAM(p_dst, info_len);
960 
961           /* copy information of I PDU */
962           p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
963 
964           memcpy(p_dst, p, info_len);
965 
966           p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + info_len;
967 
968           if (p_msg) {
969             GKI_freebuf(p_msg);
970             p_msg = nullptr;
971           }
972 
973           appended = true;
974         }
975       }
976 
977       /* if it is not available to append */
978       if (!appended) {
979         /* if it's not from AGF PDU */
980         if (p_msg) {
981           /* add length of information in front of information */
982           p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE -
983               LLCP_PDU_AGF_LEN_SIZE;
984           UINT16_TO_BE_STREAM(p, info_len);
985 
986           p_msg->offset +=
987               LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
988           p_msg->len -=
989               LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE - LLCP_PDU_AGF_LEN_SIZE;
990           p_msg->layer_specific = 0;
991         } else {
992           p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID);
993 
994           if (p_msg) {
995             p_dst = (uint8_t*)(p_msg + 1);
996 
997             /* add length of information in front of information */
998             UINT16_TO_BE_STREAM(p_dst, info_len);
999 
1000             p = p_i_pdu + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE;
1001             memcpy(p_dst, p, info_len);
1002 
1003             p_msg->offset = 0;
1004             p_msg->len = LLCP_PDU_AGF_LEN_SIZE + info_len;
1005             p_msg->layer_specific = 0;
1006           } else {
1007             LOG(ERROR) << StringPrintf("out of buffer");
1008           }
1009         }
1010 
1011         /* insert I PDU in rx queue */
1012         if (p_msg) {
1013           GKI_enqueue(&p_dlcb->i_rx_q, p_msg);
1014           p_msg = nullptr;
1015           llcp_cb.total_rx_i_pdu++;
1016 
1017           llcp_util_check_rx_congested_status();
1018         }
1019       }
1020 
1021       p_dlcb->num_rx_i_pdu++;
1022 
1023       if ((!p_dlcb->local_busy) && (p_dlcb->num_rx_i_pdu == 1)) {
1024         /* notify rx data is available so upper layer reads data until queue is
1025          * empty */
1026         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, nullptr);
1027       }
1028 
1029       if ((!p_dlcb->is_rx_congested) &&
1030           (p_dlcb->num_rx_i_pdu >= p_dlcb->rx_congest_threshold)) {
1031         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1032             "congested num_rx_i_pdu=%d, "
1033             "rx_congest_threshold=%d",
1034             p_dlcb->num_rx_i_pdu, p_dlcb->rx_congest_threshold);
1035 
1036         /* send RNR */
1037         p_dlcb->is_rx_congested = true;
1038         p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR;
1039       }
1040     }
1041   } else {
1042     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
1043     llcp_util_send_dm(ssap, dsap, LLCP_SAP_DM_REASON_NO_ACTIVE_CONNECTION);
1044   }
1045 
1046   if (p_msg) {
1047     GKI_freebuf(p_msg);
1048   }
1049 }
1050 
1051 /*******************************************************************************
1052 **
1053 ** Function         llcp_dlc_proc_rr_rnr_pdu
1054 **
1055 ** Description      Process RR or RNR PDU
1056 **
1057 ** Returns          void
1058 **
1059 *******************************************************************************/
llcp_dlc_proc_rr_rnr_pdu(uint8_t dsap,uint8_t ptype,uint8_t ssap,uint16_t length,uint8_t * p_data)1060 static void llcp_dlc_proc_rr_rnr_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1061                                      uint16_t length, uint8_t* p_data) {
1062   uint8_t rcv_seq, error_flags;
1063   tLLCP_DLCB* p_dlcb;
1064   bool flush = true;
1065   tLLCP_SAP_CBACK_DATA cback_data;
1066   bool old_remote_busy;
1067 
1068   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1069 
1070   p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1071   if (p_dlcb != nullptr) {
1072     error_flags = 0;
1073 
1074     if (length == 0) {
1075       android_errorWriteLog(0x534e4554, "116788646");
1076       return;
1077     }
1078     rcv_seq = LLCP_GET_NR(*p_data);
1079 
1080     if (length != LLCP_PDU_RR_SIZE - LLCP_PDU_HEADER_SIZE) {
1081       error_flags |= LLCP_FRMR_W_ERROR_FLAG | LLCP_FRMR_I_ERROR_FLAG;
1082     }
1083 
1084     /* check N(R) is in valid range; V(SA) <= N(R) <= V(S) */
1085     if ((uint8_t)(rcv_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO +
1086             (uint8_t)(p_dlcb->next_tx_seq - rcv_seq) % LLCP_SEQ_MODULO !=
1087         (uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) %
1088             LLCP_SEQ_MODULO) {
1089       error_flags |= LLCP_FRMR_R_ERROR_FLAG;
1090       LOG(ERROR) << StringPrintf(
1091           "Bad N(R):%d valid range [V(SA):%d, "
1092           "V(S):%d]",
1093           rcv_seq, p_dlcb->rcvd_ack_seq, p_dlcb->next_tx_seq);
1094     }
1095 
1096     if (error_flags) {
1097       llcp_util_send_frmr(p_dlcb, error_flags, ptype, *p_data);
1098       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
1099     } else {
1100       p_dlcb->rcvd_ack_seq = rcv_seq;
1101 
1102       DLOG_IF(INFO, nfc_debug_enabled)
1103           << StringPrintf("LLCP RX - N(S,R):(NA,%d) V(S,SA,R,RA):(%d,%d,%d,%d)",
1104                           rcv_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1105                           p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1106       old_remote_busy = p_dlcb->remote_busy;
1107       if (ptype == LLCP_PDU_RNR_TYPE) {
1108         p_dlcb->remote_busy = true;
1109         /* if upper layer hasn't get congestion started notification */
1110         if ((!old_remote_busy) && (!p_dlcb->is_tx_congested)) {
1111           LOG(WARNING) << StringPrintf(
1112               "Data link (SSAP:DSAP=0x%X:0x%X) "
1113               "congestion start: i_xmit_q.count=%d",
1114               p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
1115 
1116           cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1117           cback_data.congest.local_sap = p_dlcb->local_sap;
1118           cback_data.congest.remote_sap = p_dlcb->remote_sap;
1119           cback_data.congest.is_congested = true;
1120           cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1121 
1122           (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
1123         }
1124       } else {
1125         p_dlcb->remote_busy = false;
1126         /* if upper layer hasn't get congestion ended notification and data link
1127          * is not congested */
1128         if ((old_remote_busy) && (!p_dlcb->is_tx_congested)) {
1129           LOG(WARNING) << StringPrintf(
1130               "Data link (SSAP:DSAP=0x%X:0x%X) "
1131               "congestion end: i_xmit_q.count=%d",
1132               p_dlcb->local_sap, p_dlcb->remote_sap, p_dlcb->i_xmit_q.count);
1133 
1134           cback_data.congest.event = LLCP_SAP_EVT_CONGEST;
1135           cback_data.congest.local_sap = p_dlcb->local_sap;
1136           cback_data.congest.remote_sap = p_dlcb->remote_sap;
1137           cback_data.congest.is_congested = false;
1138           cback_data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION;
1139 
1140           (*p_dlcb->p_app_cb->p_app_cback)(&cback_data);
1141         }
1142       }
1143 
1144       /* check flag to send DISC when tx queue is empty */
1145       if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1146         /* if no pending data and all PDU is acked */
1147         if ((p_dlcb->i_xmit_q.count == 0) &&
1148             (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
1149             (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
1150           p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1151           llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1152         }
1153       }
1154     }
1155   } else {
1156     LOG(ERROR) << StringPrintf("No data link for SAP (0x%x,0x%x)", dsap, ssap);
1157   }
1158 }
1159 
1160 /*******************************************************************************
1161 **
1162 ** Function         llcp_dlc_proc_rx_pdu
1163 **
1164 ** Description      Process PDU for data link
1165 **
1166 ** Returns          void
1167 **
1168 *******************************************************************************/
llcp_dlc_proc_rx_pdu(uint8_t dsap,uint8_t ptype,uint8_t ssap,uint16_t length,uint8_t * p_data)1169 void llcp_dlc_proc_rx_pdu(uint8_t dsap, uint8_t ptype, uint8_t ssap,
1170                           uint16_t length, uint8_t* p_data) {
1171   tLLCP_DLCB* p_dlcb;
1172 
1173   DLOG_IF(INFO, nfc_debug_enabled)
1174       << StringPrintf("DSAP:0x%x, PTYPE:0x%x, SSAP:0x%x", dsap, ptype, ssap);
1175 
1176   if (dsap == LLCP_SAP_LM) {
1177     LOG(ERROR) << StringPrintf("Invalid SAP:0x%x for PTYPE:0x%x", dsap, ptype);
1178     return;
1179   }
1180 
1181   switch (ptype) {
1182     case LLCP_PDU_CONNECT_TYPE:
1183       llcp_dlc_proc_connect_pdu(dsap, ssap, length, p_data);
1184       break;
1185 
1186     case LLCP_PDU_DISC_TYPE:
1187       llcp_dlc_proc_disc_pdu(dsap, ssap, length);
1188       break;
1189 
1190     case LLCP_PDU_CC_TYPE:
1191       llcp_dlc_proc_cc_pdu(dsap, ssap, length, p_data);
1192       break;
1193 
1194     case LLCP_PDU_DM_TYPE:
1195       llcp_dlc_proc_dm_pdu(dsap, ssap, length, p_data);
1196       break;
1197 
1198     case LLCP_PDU_FRMR_TYPE:
1199       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1200       if (p_dlcb) {
1201         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
1202       }
1203       break;
1204 
1205     case LLCP_PDU_RR_TYPE:
1206     case LLCP_PDU_RNR_TYPE:
1207       llcp_dlc_proc_rr_rnr_pdu(dsap, ptype, ssap, length, p_data);
1208       break;
1209 
1210     default:
1211       LOG(ERROR) << StringPrintf("Unexpected PDU type (0x%x)", ptype);
1212 
1213       p_dlcb = llcp_dlc_find_dlcb_by_sap(dsap, ssap);
1214       if (p_dlcb) {
1215         llcp_util_send_frmr(p_dlcb, LLCP_FRMR_W_ERROR_FLAG, ptype, 0);
1216         llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, nullptr);
1217       }
1218       break;
1219   }
1220 }
1221 
1222 /*******************************************************************************
1223 **
1224 ** Function         llcp_dlc_check_to_send_rr_rnr
1225 **
1226 ** Description      Send RR or RNR if necessary
1227 **
1228 ** Returns          void
1229 **
1230 *******************************************************************************/
llcp_dlc_check_to_send_rr_rnr(void)1231 void llcp_dlc_check_to_send_rr_rnr(void) {
1232   uint8_t idx;
1233   bool flush = true;
1234 
1235   DLOG_IF(INFO, nfc_debug_enabled) << __func__;
1236 
1237   /*
1238   ** DLC doesn't send RR PDU for each received I PDU because multiple I PDUs
1239   ** can be aggregated in a received AGF PDU. In this case, this is post
1240   ** processing of AGF PDU to send single RR or RNR after processing all I
1241   ** PDUs in received AGF if there was no I-PDU to carry N(R).
1242   **
1243   ** Send RR or RNR if any change of local busy condition or rx congestion
1244   ** status, or V(RA) is not V(R).
1245   */
1246   for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) {
1247     if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) {
1248       llcp_util_send_rr_rnr(&(llcp_cb.dlcb[idx]));
1249 
1250       /* check flag to send DISC when tx queue is empty */
1251       if (llcp_cb.dlcb[idx].flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1252         /* if no pending data and all PDU is acked */
1253         if ((llcp_cb.dlcb[idx].i_xmit_q.count == 0) &&
1254             (llcp_cb.dlcb[idx].next_rx_seq == llcp_cb.dlcb[idx].sent_ack_seq) &&
1255             (llcp_cb.dlcb[idx].next_tx_seq == llcp_cb.dlcb[idx].rcvd_ack_seq)) {
1256           llcp_cb.dlcb[idx].flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1257           llcp_dlsm_execute(&(llcp_cb.dlcb[idx]),
1258                             LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1259         }
1260       }
1261     }
1262   }
1263 }
1264 
1265 /*******************************************************************************
1266 **
1267 ** Function         llcp_dlc_is_rw_open
1268 **
1269 ** Description      check if receive window is open in remote
1270 **
1271 ** Returns          TRUE if remote can receive more data
1272 **
1273 *******************************************************************************/
llcp_dlc_is_rw_open(tLLCP_DLCB * p_dlcb)1274 bool llcp_dlc_is_rw_open(tLLCP_DLCB* p_dlcb) {
1275   if ((uint8_t)(p_dlcb->next_tx_seq - p_dlcb->rcvd_ack_seq) % LLCP_SEQ_MODULO <
1276       p_dlcb->remote_rw) {
1277     return true;
1278   } else {
1279     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1280         "Flow Off, V(S):%d, V(SA):%d, RW(R):%d", p_dlcb->next_tx_seq,
1281         p_dlcb->rcvd_ack_seq, p_dlcb->remote_rw);
1282     return false;
1283   }
1284 }
1285 
1286 /*******************************************************************************
1287 **
1288 ** Function         llcp_dlc_get_next_pdu
1289 **
1290 ** Description      Get a PDU from tx queue of data link
1291 **
1292 ** Returns          NFC_HDR*
1293 **
1294 *******************************************************************************/
llcp_dlc_get_next_pdu(tLLCP_DLCB * p_dlcb)1295 NFC_HDR* llcp_dlc_get_next_pdu(tLLCP_DLCB* p_dlcb) {
1296   NFC_HDR* p_msg = nullptr;
1297   bool flush = true;
1298   tLLCP_SAP_CBACK_DATA data;
1299 
1300   uint8_t send_seq = p_dlcb->next_tx_seq;
1301 
1302   /* if there is data to send and remote device can receive it */
1303   if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
1304       (llcp_dlc_is_rw_open(p_dlcb))) {
1305     p_msg = (NFC_HDR*)GKI_dequeue(&p_dlcb->i_xmit_q);
1306     llcp_cb.total_tx_i_pdu--;
1307 
1308     if (p_msg->offset >= LLCP_MIN_OFFSET) {
1309       /* add LLCP header, DSAP, PTYPE, SSAP, N(S), N(R) and update sent_ack_seq,
1310        * V(RA) */
1311       llcp_util_build_info_pdu(p_dlcb, p_msg);
1312 
1313       p_dlcb->next_tx_seq = (p_dlcb->next_tx_seq + 1) % LLCP_SEQ_MODULO;
1314 
1315       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1316           "LLCP TX - N(S,R):(%d,%d) V(S,SA,R,RA):(%d,%d,%d,%d)", send_seq,
1317           p_dlcb->next_rx_seq, p_dlcb->next_tx_seq, p_dlcb->rcvd_ack_seq,
1318           p_dlcb->next_rx_seq, p_dlcb->sent_ack_seq);
1319     } else {
1320       LOG(ERROR) << StringPrintf("offset (%d) must be %d at least",
1321                                  p_msg->offset, LLCP_MIN_OFFSET);
1322       GKI_freebuf(p_msg);
1323       p_msg = nullptr;
1324     }
1325   }
1326 
1327   /* if tx queue is empty and all PDU is acknowledged */
1328   if ((p_dlcb->i_xmit_q.count == 0) &&
1329       (p_dlcb->next_rx_seq == p_dlcb->sent_ack_seq) &&
1330       (p_dlcb->next_tx_seq == p_dlcb->rcvd_ack_seq)) {
1331     /* check flag to send DISC */
1332     if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_PENDING_DISC) {
1333       p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_PENDING_DISC;
1334       llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush);
1335     }
1336 
1337     /* check flag to notify upper layer */
1338     if (p_dlcb->flags & LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE) {
1339       p_dlcb->flags &= ~LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE;
1340 
1341       data.tx_complete.event = LLCP_SAP_EVT_TX_COMPLETE;
1342       data.tx_complete.local_sap = p_dlcb->local_sap;
1343       data.tx_complete.remote_sap = p_dlcb->remote_sap;
1344 
1345       (*p_dlcb->p_app_cb->p_app_cback)(&data);
1346     }
1347   }
1348 
1349   return p_msg;
1350 }
1351 
1352 /*******************************************************************************
1353 **
1354 ** Function         llcp_dlc_get_next_pdu_length
1355 **
1356 ** Description      return length of PDU which is top in tx queue of data link
1357 **
1358 ** Returns          length of PDU
1359 **
1360 *******************************************************************************/
llcp_dlc_get_next_pdu_length(tLLCP_DLCB * p_dlcb)1361 uint16_t llcp_dlc_get_next_pdu_length(tLLCP_DLCB* p_dlcb) {
1362   NFC_HDR* p_msg;
1363 
1364   /* if there is data to send and remote device can receive it */
1365   if ((p_dlcb->i_xmit_q.count) && (!p_dlcb->remote_busy) &&
1366       (llcp_dlc_is_rw_open(p_dlcb))) {
1367     p_msg = (NFC_HDR*)p_dlcb->i_xmit_q.p_first;
1368 
1369     return (p_msg->len + LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE);
1370   }
1371   return 0;
1372 }
1373 
1374 /*******************************************************************************
1375 **
1376 ** Function         llcp_dlsm_get_state_name
1377 **
1378 ** Description      This function returns the state name.
1379 **
1380 ** Returns          pointer to the name
1381 **
1382 *******************************************************************************/
llcp_dlsm_get_state_name(tLLCP_DLC_STATE state)1383 static std::string llcp_dlsm_get_state_name(tLLCP_DLC_STATE state) {
1384   switch (state) {
1385     case LLCP_DLC_STATE_IDLE:
1386       return "IDLE";
1387     case LLCP_DLC_STATE_W4_REMOTE_RESP:
1388       return "W4_REMOTE_RESP";
1389     case LLCP_DLC_STATE_W4_LOCAL_RESP:
1390       return "W4_LOCAL_RESP";
1391     case LLCP_DLC_STATE_CONNECTED:
1392       return "CONNECTED";
1393     case LLCP_DLC_STATE_W4_REMOTE_DM:
1394       return "W4_REMOTE_DM";
1395     default:
1396       return "???? UNKNOWN STATE";
1397   }
1398 }
1399 
1400 /*******************************************************************************
1401 **
1402 ** Function         llcp_dlsm_get_event_name
1403 **
1404 ** Description      This function returns the event name.
1405 **
1406 ** Returns          pointer to the name
1407 **
1408 *******************************************************************************/
llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event)1409 static std::string llcp_dlsm_get_event_name(tLLCP_DLC_EVENT event) {
1410   switch (event) {
1411     case LLCP_DLC_EVENT_API_CONNECT_REQ:
1412       return "API_CONNECT_REQ";
1413     case LLCP_DLC_EVENT_API_CONNECT_CFM:
1414       return "API_CONNECT_CFM";
1415     case LLCP_DLC_EVENT_API_CONNECT_REJECT:
1416       return "API_CONNECT_REJECT";
1417     case LLCP_DLC_EVENT_PEER_CONNECT_IND:
1418       return "PEER_CONNECT_IND";
1419     case LLCP_DLC_EVENT_PEER_CONNECT_CFM:
1420       return "PEER_CONNECT_CFM";
1421     case LLCP_DLC_EVENT_API_DATA_REQ:
1422       return "API_DATA_REQ";
1423     case LLCP_DLC_EVENT_PEER_DATA_IND:
1424       return "PEER_DATA_IND";
1425     case LLCP_DLC_EVENT_API_DISCONNECT_REQ:
1426       return "API_DISCONNECT_REQ";
1427     case LLCP_DLC_EVENT_PEER_DISCONNECT_IND:
1428       return "PEER_DISCONNECT_IND";
1429     case LLCP_DLC_EVENT_PEER_DISCONNECT_RESP:
1430       return "PEER_DISCONNECT_RESP";
1431     case LLCP_DLC_EVENT_FRAME_ERROR:
1432       return "FRAME_ERROR";
1433     case LLCP_DLC_EVENT_LINK_ERROR:
1434       return "LINK_ERROR";
1435     case LLCP_DLC_EVENT_TIMEOUT:
1436       return "TIMEOUT";
1437     default:
1438       return "???? UNKNOWN EVENT";
1439   }
1440 }
1441