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