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