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