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