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, ¶ms) != 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, ¶ms);
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, ¶ms);
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