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