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