llcp_link.c revision e9df6ba5a8fcccf306a80b1670b423be8fe7746a
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 Link Management 22 * 23 ******************************************************************************/ 24 25#include <string.h> 26#include "gki.h" 27#include "nfc_target.h" 28#include "bt_types.h" 29#include "trace_api.h" 30#include "llcp_int.h" 31#include "llcp_defs.h" 32#include "nfc_int.h" 33 34const UINT16 llcp_link_rwt[15] = /* RWT = (302us)*2**WT; 302us = 256*16/fc; fc = 13.56MHz */ 35{ 36 1, /* WT=0, 302us */ 37 1, /* WT=1, 604us */ 38 2, /* WT=2, 1208us */ 39 3, /* WT=3, 2.4ms */ 40 5, /* WT=4, 4.8ms */ 41 10, /* WT=5, 9.7ms */ 42 20, /* WT=6, 19.3ms */ 43 39, /* WT=7, 38.7ms */ 44 78, /* WT=8, 77.3ms */ 45 155, /* WT=9, 154.6ms */ 46 310, /* WT=10, 309.2ms */ 47 619, /* WT=11, 618.5ms */ 48 1237, /* WT=12, 1237.0ms */ 49 2474, /* WT=13, 2474.0ms */ 50 4948, /* WT=14, 4948.0ms */ 51}; 52 53static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes); 54static BOOLEAN llcp_link_version_agreement (void); 55 56static void llcp_link_send_SYMM (void); 57static void llcp_link_update_status (BOOLEAN is_activated); 58static void llcp_link_check_congestion (void); 59static void llcp_link_check_uncongested (void); 60static void llcp_link_proc_ui_pdu (UINT8 local_sap, UINT8 remote_sap, UINT16 ui_pdu_length, UINT8 *p_ui_pdu, BT_HDR *p_msg); 61static void llcp_link_proc_agf_pdu (BT_HDR *p_msg); 62static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg); 63static void llcp_link_proc_rx_data (BT_HDR *p_msg); 64 65static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length); 66static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_agf); 67static void llcp_link_send_to_lower (BT_HDR *p_msg); 68 69#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */ 70extern tLLCP_TEST_PARAMS llcp_test_params; 71#endif 72 73/* debug functions type */ 74#if (BT_TRACE_VERBOSE == TRUE) 75static char *llcp_pdu_type (UINT8 ptype); 76#endif 77 78/******************************************************************************* 79** 80** Function llcp_link_start_inactivity_timer 81** 82** Description This function start LLCP link inactivity timer. 83** 84** Returns void 85** 86*******************************************************************************/ 87static void llcp_link_start_inactivity_timer (void) 88{ 89 if ( (llcp_cb.lcb.inact_timer.in_use == FALSE) 90 &&(llcp_cb.lcb.inact_timeout > 0) ) 91 { 92 LLCP_TRACE_DEBUG1 ("Start inactivity_timer: %d ms", llcp_cb.lcb.inact_timeout); 93 94 nfc_start_quick_timer (&llcp_cb.lcb.inact_timer, NFC_TTYPE_LLCP_LINK_INACT, 95 ((UINT32) llcp_cb.lcb.inact_timeout) * QUICK_TIMER_TICKS_PER_SEC / 1000); 96 } 97} 98 99/******************************************************************************* 100** 101** Function llcp_link_stop_inactivity_timer 102** 103** Description This function stop LLCP link inactivity timer. 104** 105** Returns void 106** 107*******************************************************************************/ 108static void llcp_link_stop_inactivity_timer (void) 109{ 110 if (llcp_cb.lcb.inact_timer.in_use) 111 { 112 LLCP_TRACE_DEBUG0 ("Stop inactivity_timer"); 113 114 nfc_stop_quick_timer (&llcp_cb.lcb.inact_timer); 115 } 116} 117 118/******************************************************************************* 119** 120** Function llcp_link_start_link_timer 121** 122** Description This function starts LLCP link timer (LTO or delay response). 123** 124** Returns void 125** 126*******************************************************************************/ 127static void llcp_link_start_link_timer (void) 128{ 129 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) 130 { 131 /* wait for application layer sending data */ 132 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER, 133 (((UINT32) llcp_cb.lcb.symm_delay) * QUICK_TIMER_TICKS_PER_SEC) / 1000); 134 } 135 else 136 { 137 /* wait for data to receive from remote */ 138 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER, 139 ((UINT32) llcp_cb.lcb.peer_lto) * QUICK_TIMER_TICKS_PER_SEC / 1000); 140 } 141} 142 143/******************************************************************************* 144** 145** Function llcp_link_stop_link_timer 146** 147** Description This function stop LLCP link timer (LTO or delay response). 148** 149** Returns void 150** 151*******************************************************************************/ 152static void llcp_link_stop_link_timer (void) 153{ 154 nfc_stop_quick_timer (&llcp_cb.lcb.timer); 155} 156 157/******************************************************************************* 158** 159** Function llcp_link_activate 160** 161** Description Activate LLCP link 162** 163** Returns tLLCP_STATUS 164** 165*******************************************************************************/ 166tLLCP_STATUS llcp_link_activate (tLLCP_ACTIVATE_CONFIG *p_config) 167{ 168 LLCP_TRACE_DEBUG0 ("llcp_link_activate ()"); 169 170 /* At this point, MAC link activation procedure has been successfully completed */ 171 172 /* The Length Reduction values LRi and LRt MUST be 11b. (254bytes) */ 173 if (p_config->max_payload_size != LLCP_NCI_MAX_PAYL_SIZE) 174 { 175 LLCP_TRACE_WARNING2 ("llcp_link_activate (): max payload size (%d) must be %d bytes", 176 p_config->max_payload_size, LLCP_NCI_MAX_PAYL_SIZE); 177 } 178 179 /* Processing the parametes that have been received with the MAC link activation */ 180 if (llcp_link_parse_gen_bytes (p_config->gen_bytes_len, 181 p_config->p_gen_bytes ) == FALSE) 182 { 183 LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to parse general bytes"); 184 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_BAD_GEN_BYTES); 185 return LLCP_STATUS_FAIL; 186 } 187 188 /* 189 ** For the Target device, the scaled value of RWT MUST be less than or equal to the 190 ** scaled value of the LLC Link Timeout (LTO). 191 */ 192 if ((p_config->is_initiator) && (llcp_link_rwt[p_config->waiting_time] > llcp_cb.lcb.peer_lto)) 193 { 194 LLCP_TRACE_WARNING3 ("llcp_link_activate (): WT (%d, %dms) must be less than or equal to LTO (%dms)", 195 p_config->waiting_time, 196 llcp_link_rwt[p_config->waiting_time], 197 llcp_cb.lcb.peer_lto); 198 } 199 200 /* extend LTO as much as internally required processing time and propagation delays */ 201 llcp_cb.lcb.peer_lto += LLCP_INTERNAL_TX_DELAY + LLCP_INTERNAL_RX_DELAY; 202 203 /* LLCP version number agreement */ 204 if (llcp_link_version_agreement () == FALSE) 205 { 206 LLCP_TRACE_ERROR0 ("llcp_link_activate (): Failed to agree version"); 207 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_FAILED_EVT, LLCP_LINK_VERSION_FAILED); 208 return LLCP_STATUS_FAIL; 209 } 210 211 llcp_cb.lcb.is_initiator = p_config->is_initiator; 212 213 /* set tx MIU to MIN (MIU of local LLCP, MIU of peer LLCP) */ 214 215 if (llcp_cb.lcb.local_link_miu >= llcp_cb.lcb.peer_miu) 216 llcp_cb.lcb.effective_miu = llcp_cb.lcb.peer_miu; 217 else 218 llcp_cb.lcb.effective_miu = llcp_cb.lcb.local_link_miu; 219 220 /* 221 ** When entering the normal operation phase, LLCP shall initialize the symmetry 222 ** procedure. 223 */ 224 if (llcp_cb.lcb.is_initiator) 225 { 226 LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Initiator"); 227 228 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_init; 229 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT; 230 231 if (llcp_cb.lcb.delay_first_pdu_timeout > 0) 232 { 233 /* give a chance to upper layer to send PDU if need */ 234 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_DELAY_FIRST_PDU, 235 (((UINT32) llcp_cb.lcb.delay_first_pdu_timeout) * QUICK_TIMER_TICKS_PER_SEC) / 1000); 236 } 237 else 238 { 239 llcp_link_send_SYMM (); 240 } 241 } 242 else 243 { 244 LLCP_TRACE_DEBUG0 ("llcp_link_activate (): Connected as Target"); 245 llcp_cb.lcb.inact_timeout = llcp_cb.lcb.inact_timeout_target; 246 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT; 247 248 /* wait for data to receive from remote */ 249 llcp_link_start_link_timer (); 250 } 251 252 253 /* 254 ** Set state to LLCP_LINK_STATE_ACTIVATED and notify activation before set data callback 255 ** because LLCP PDU could be in NCI queue. 256 */ 257 llcp_cb.lcb.link_state = LLCP_LINK_STATE_ACTIVATED; 258 259 /* LLCP Link Activation completed */ 260 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_ACTIVATION_COMPLETE_EVT, LLCP_LINK_SUCCESS); 261 262 /* Update link status to service layer */ 263 llcp_link_update_status (TRUE); 264 265 NFC_SetStaticRfCback (llcp_link_connection_cback); 266 267 return (LLCP_STATUS_SUCCESS); 268} 269 270/******************************************************************************* 271** 272** Function llcp_deactivate_cleanup 273** 274** Description Clean up for link deactivation 275** 276** Returns void 277** 278*******************************************************************************/ 279static void llcp_deactivate_cleanup (UINT8 reason) 280{ 281 /* report SDP failure for any pending request */ 282 llcp_sdp_proc_deactivation (); 283 284 /* Update link status to service layer */ 285 llcp_link_update_status (FALSE); 286 287 /* We had sent out DISC */ 288 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATED; 289 290 llcp_link_stop_link_timer (); 291 292 /* stop inactivity timer */ 293 llcp_link_stop_inactivity_timer (); 294 295 /* Let upper layer deactivate local link */ 296 (*llcp_cb.lcb.p_link_cback) (LLCP_LINK_DEACTIVATED_EVT, reason); 297} 298 299/******************************************************************************* 300** 301** Function llcp_link_process_link_timeout 302** 303** Description Process timeout events for LTO, SYMM and deactivating 304** 305** Returns void 306** 307*******************************************************************************/ 308void llcp_link_process_link_timeout (void) 309{ 310 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 311 { 312 if ((llcp_cb.lcb.symm_delay > 0) && (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT)) 313 { 314 /* upper layer doesn't have anything to send */ 315 LLCP_TRACE_DEBUG0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT"); 316 llcp_link_send_SYMM (); 317 318 /* wait for data to receive from remote */ 319 llcp_link_start_link_timer (); 320 321 /* start inactivity timer */ 322 if (llcp_cb.num_data_link_connection == 0) 323 { 324 llcp_link_start_inactivity_timer (); 325 } 326 } 327 else 328 { 329 LLCP_TRACE_ERROR0 ("llcp_link_process_link_timeout (): LEVT_TIMEOUT in state of LLCP_LINK_SYMM_REMOTE_XMIT_NEXT"); 330 llcp_link_deactivate (LLCP_LINK_TIMEOUT); 331 } 332 } 333 else if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) 334 { 335 llcp_deactivate_cleanup (llcp_cb.lcb.link_deact_reason); 336 337 NFC_SetStaticRfCback (NULL); 338 } 339} 340 341/******************************************************************************* 342** 343** Function llcp_link_deactivate 344** 345** Description Deactivate LLCP link 346** 347** Returns void 348** 349*******************************************************************************/ 350void llcp_link_deactivate (UINT8 reason) 351{ 352 UINT8 local_sap, idx; 353 tLLCP_DLCB *p_dlcb; 354 tLLCP_APP_CB *p_app_cb; 355 356 LLCP_TRACE_DEBUG1 ("llcp_link_deactivate () reason = 0x%x", reason); 357 358 /* Release any held buffers in signaling PDU queue */ 359 while (llcp_cb.lcb.sig_xmit_q.p_first) 360 GKI_freebuf (GKI_dequeue (&llcp_cb.lcb.sig_xmit_q)); 361 362 /* Release any held buffers in UI PDU queue */ 363 for (local_sap = LLCP_SAP_SDP + 1; local_sap < LLCP_NUM_SAPS; local_sap++) 364 { 365 p_app_cb = llcp_util_get_app_cb (local_sap); 366 367 if ( (p_app_cb) 368 &&(p_app_cb->p_app_cback) ) 369 { 370 while (p_app_cb->ui_xmit_q.p_first) 371 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_xmit_q)); 372 373 p_app_cb->is_ui_tx_congested = FALSE; 374 375 while (p_app_cb->ui_rx_q.p_first) 376 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q)); 377 } 378 } 379 380 llcp_cb.total_tx_ui_pdu = 0; 381 llcp_cb.total_rx_ui_pdu = 0; 382 383 /* Notify all of data link */ 384 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) 385 { 386 if (llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) 387 { 388 p_dlcb = &(llcp_cb.dlcb[idx]); 389 390 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_LINK_ERROR, NULL); 391 } 392 } 393 llcp_cb.total_tx_i_pdu = 0; 394 llcp_cb.total_rx_i_pdu = 0; 395 396 llcp_cb.overall_tx_congested = FALSE; 397 llcp_cb.overall_rx_congested = FALSE; 398 399 if ( (reason == LLCP_LINK_FRAME_ERROR) 400 ||(reason == LLCP_LINK_LOCAL_INITIATED) ) 401 { 402 /* get rid of the data pending in NFC tx queue, so DISC PDU can be sent ASAP */ 403 NFC_FlushData (NFC_RF_CONN_ID); 404 405 llcp_util_send_disc (LLCP_SAP_LM, LLCP_SAP_LM); 406 407 /* Wait until DISC is sent to peer */ 408 LLCP_TRACE_DEBUG0 ("llcp_link_deactivate (): Wait until DISC is sent to peer"); 409 410 llcp_cb.lcb.link_state = LLCP_LINK_STATE_DEACTIVATING; 411 412 if (llcp_cb.lcb.sig_xmit_q.count == 0) 413 { 414 /* if DISC is sent to NFCC, wait for short period for NFCC to send it to peer */ 415 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER, 416 ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000); 417 } 418 419 llcp_cb.lcb.link_deact_reason = reason; 420 return; 421 } 422 else if ( (reason == LLCP_LINK_REMOTE_INITIATED) 423 &&(!llcp_cb.lcb.is_initiator) ) 424 { 425 /* if received DISC to deactivate LLCP link as target role, send SYMM PDU */ 426 llcp_link_send_SYMM (); 427 } 428 else /* for link timeout and interface error */ 429 { 430 NFC_FlushData (NFC_RF_CONN_ID); 431 } 432 433 llcp_deactivate_cleanup (reason); 434} 435 436/******************************************************************************* 437** 438** Function llcp_link_parse_gen_bytes 439** 440** Description Check LLCP magic number and get parameters in general bytes 441** 442** Returns TRUE if success 443** 444*******************************************************************************/ 445static BOOLEAN llcp_link_parse_gen_bytes (UINT8 gen_bytes_len, UINT8 *p_gen_bytes) 446{ 447 UINT8 *p = p_gen_bytes + LLCP_MAGIC_NUMBER_LEN; 448 UINT8 length = gen_bytes_len - LLCP_MAGIC_NUMBER_LEN; 449 450 if ( (gen_bytes_len >= LLCP_MAGIC_NUMBER_LEN) 451 &&(*(p_gen_bytes) == LLCP_MAGIC_NUMBER_BYTE0) 452 &&(*(p_gen_bytes + 1) == LLCP_MAGIC_NUMBER_BYTE1) 453 &&(*(p_gen_bytes + 2) == LLCP_MAGIC_NUMBER_BYTE2) ) 454 { 455 /* in case peer didn't include these */ 456 llcp_cb.lcb.peer_miu = LLCP_DEFAULT_MIU; 457 llcp_cb.lcb.peer_lto = LLCP_DEFAULT_LTO_IN_MS; 458 459 return (llcp_util_parse_link_params (length, p)); 460 } 461 else /* if this is not LLCP */ 462 { 463 return (FALSE); 464 } 465 466 return (TRUE); 467} 468 469/******************************************************************************* 470** 471** Function llcp_link_version_agreement 472** 473** Description LLCP version number agreement 474** 475** Returns TRUE if success 476** 477*******************************************************************************/ 478static BOOLEAN llcp_link_version_agreement (void) 479{ 480 UINT8 peer_major_version, peer_minor_version; 481 482 peer_major_version = LLCP_GET_MAJOR_VERSION (llcp_cb.lcb.peer_version); 483 peer_minor_version = LLCP_GET_MINOR_VERSION (llcp_cb.lcb.peer_version); 484 485 if (peer_major_version < LLCP_MIN_MAJOR_VERSION) 486 { 487 LLCP_TRACE_ERROR1("llcp_link_version_agreement(): unsupported peer version number. Peer Major Version:%d", peer_major_version); 488 return FALSE; 489 } 490 else 491 { 492 if (peer_major_version == LLCP_VERSION_MAJOR) 493 { 494 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR; 495 if (peer_minor_version >= LLCP_VERSION_MINOR) 496 { 497 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR; 498 } 499 else 500 { 501 llcp_cb.lcb.agreed_minor_version = peer_minor_version; 502 } 503 } 504 else if (peer_major_version < LLCP_VERSION_MAJOR) 505 { 506 /* so far we can support backward compatibility */ 507 llcp_cb.lcb.agreed_major_version = peer_major_version; 508 llcp_cb.lcb.agreed_minor_version = peer_minor_version; 509 } 510 else 511 { 512 /* let peer (higher major version) decide it */ 513 llcp_cb.lcb.agreed_major_version = LLCP_VERSION_MAJOR; 514 llcp_cb.lcb.agreed_minor_version = LLCP_VERSION_MINOR; 515 } 516 517 LLCP_TRACE_DEBUG6 ("local version:%d.%d, remote version:%d.%d, agreed version:%d.%d", 518 LLCP_VERSION_MAJOR, LLCP_VERSION_MINOR, 519 peer_major_version, peer_minor_version, 520 llcp_cb.lcb.agreed_major_version, llcp_cb.lcb.agreed_minor_version); 521 522 return (TRUE); 523 } 524} 525 526/******************************************************************************* 527** 528** Function llcp_link_update_status 529** 530** Description Notify all of service layer client link status change 531** 532** Returns void 533** 534*******************************************************************************/ 535static void llcp_link_update_status (BOOLEAN is_activated) 536{ 537 tLLCP_SAP_CBACK_DATA data; 538 tLLCP_APP_CB *p_app_cb; 539 UINT8 sap; 540 541 data.link_status.event = LLCP_SAP_EVT_LINK_STATUS; 542 data.link_status.is_activated = is_activated; 543 data.link_status.is_initiator = llcp_cb.lcb.is_initiator; 544 545 /* notify all SAP so they can create connection while link is activated */ 546 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) 547 { 548 p_app_cb = llcp_util_get_app_cb (sap); 549 550 if ( (p_app_cb) 551 &&(p_app_cb->p_app_cback) ) 552 { 553 data.link_status.local_sap = sap; 554 p_app_cb->p_app_cback (&data); 555 } 556 } 557} 558 559/******************************************************************************* 560** 561** Function llcp_link_check_congestion 562** 563** Description Check overall congestion status 564** Notify to all of upper layer if congested 565** 566** Returns void 567** 568*******************************************************************************/ 569static void llcp_link_check_congestion (void) 570{ 571 tLLCP_SAP_CBACK_DATA data; 572 tLLCP_APP_CB *p_app_cb; 573 UINT8 sap, idx; 574 575 if (llcp_cb.overall_tx_congested) 576 { 577 /* already congested so no need to check again */ 578 return; 579 } 580 581 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= llcp_cb.max_num_tx_buff) 582 { 583 /* overall buffer usage is high */ 584 llcp_cb.overall_tx_congested = TRUE; 585 586 LLCP_TRACE_WARNING2 ("overall tx congestion start: total_tx_ui_pdu=%d, total_tx_i_pdu=%d", 587 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu); 588 589 data.congest.event = LLCP_SAP_EVT_CONGEST; 590 data.congest.is_congested = TRUE; 591 592 /* notify logical data link congestion status */ 593 data.congest.remote_sap = LLCP_INVALID_SAP; 594 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK; 595 596 for (sap = LLCP_SAP_SDP + 1; sap < LLCP_NUM_SAPS; sap++) 597 { 598 p_app_cb = llcp_util_get_app_cb (sap); 599 600 if ( (p_app_cb) 601 &&(p_app_cb->p_app_cback) 602 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) ) 603 { 604 /* if already congested then no need to notify again */ 605 if (!p_app_cb->is_ui_tx_congested) 606 { 607 p_app_cb->is_ui_tx_congested = TRUE; 608 609 LLCP_TRACE_WARNING2 ("Logical link (SAP=0x%X) congestion start: count=%d", 610 sap, p_app_cb->ui_xmit_q.count); 611 612 data.congest.local_sap = sap; 613 p_app_cb->p_app_cback (&data); 614 } 615 } 616 } 617 618 /* notify data link connection congestion status */ 619 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION; 620 621 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++ ) 622 { 623 if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) 624 &&(llcp_cb.dlcb[idx].remote_busy == FALSE) 625 &&(llcp_cb.dlcb[idx].is_tx_congested == FALSE) ) 626 { 627 llcp_cb.dlcb[idx].is_tx_congested = TRUE; 628 629 LLCP_TRACE_WARNING3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion start: count=%d", 630 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap, 631 llcp_cb.dlcb[idx].i_xmit_q.count); 632 633 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap; 634 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap; 635 636 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data); 637 } 638 } 639 } 640} 641 642/******************************************************************************* 643** 644** Function llcp_link_check_uncongested 645** 646** Description Check overall congestion status, logical data link and 647** data link connection congestion status 648** Notify to each upper layer if uncongested 649** 650** Returns void 651** 652*******************************************************************************/ 653static void llcp_link_check_uncongested (void) 654{ 655 tLLCP_SAP_CBACK_DATA data; 656 tLLCP_APP_CB *p_app_cb; 657 UINT8 xx, sap, idx; 658 659 if (llcp_cb.overall_tx_congested) 660 { 661 if (llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu <= llcp_cb.max_num_tx_buff / 2) 662 { 663 /* overall congestion is cleared */ 664 llcp_cb.overall_tx_congested = FALSE; 665 666 LLCP_TRACE_WARNING2 ("overall tx congestion end: total_tx_ui_pdu=%d, total_tx_i_pdu=%d", 667 llcp_cb.total_tx_ui_pdu, llcp_cb.total_tx_i_pdu); 668 } 669 else 670 { 671 /* wait until more data packets are sent out */ 672 return; 673 } 674 } 675 676 data.congest.event = LLCP_SAP_EVT_CONGEST; 677 data.congest.is_congested = FALSE; 678 679 /* if total number of UI PDU is below threshold */ 680 if (llcp_cb.total_tx_ui_pdu < llcp_cb.max_num_ll_tx_buff) 681 { 682 /* check and notify logical data link congestion status */ 683 data.congest.remote_sap = LLCP_INVALID_SAP; 684 data.congest.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK; 685 686 /* 687 ** start point of uncongested status notification is in round robin 688 ** so each logical data link has equal chance of transmitting. 689 */ 690 sap = llcp_cb.ll_tx_uncongest_ntf_start_sap; 691 692 for (xx = LLCP_SAP_SDP + 1; xx < LLCP_NUM_SAPS; xx++) 693 { 694 /* no logical data link on LM and SDP */ 695 if (sap > LLCP_SAP_SDP) 696 { 697 p_app_cb = llcp_util_get_app_cb (sap); 698 699 if ( (p_app_cb) 700 &&(p_app_cb->p_app_cback) 701 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) 702 &&(p_app_cb->is_ui_tx_congested) 703 &&(p_app_cb->ui_xmit_q.count <= llcp_cb.ll_tx_congest_end) ) 704 { 705 /* if it was congested but now tx queue count is below threshold */ 706 p_app_cb->is_ui_tx_congested = FALSE; 707 708 LLCP_TRACE_DEBUG2 ("Logical link (SAP=0x%X) congestion end: count=%d", 709 sap, p_app_cb->ui_xmit_q.count); 710 711 data.congest.local_sap = sap; 712 p_app_cb->p_app_cback (&data); 713 } 714 } 715 716 sap = (sap + 1) % LLCP_NUM_SAPS; 717 } 718 719 /* move start point for next logical data link */ 720 for (xx = 0; xx < LLCP_NUM_SAPS; xx++) 721 { 722 sap = (llcp_cb.ll_tx_uncongest_ntf_start_sap + 1) % LLCP_NUM_SAPS; 723 724 if (sap > LLCP_SAP_SDP) 725 { 726 p_app_cb = llcp_util_get_app_cb (sap); 727 728 if ( (p_app_cb) 729 &&(p_app_cb->p_app_cback) 730 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) ) 731 { 732 llcp_cb.ll_tx_uncongest_ntf_start_sap = sap; 733 break; 734 } 735 } 736 } 737 } 738 739 /* notify data link connection congestion status */ 740 data.congest.link_type = LLCP_LINK_TYPE_DATA_LINK_CONNECTION; 741 742 /* 743 ** start point of uncongested status notification is in round robin 744 ** so each data link connection has equal chance of transmitting. 745 */ 746 idx = llcp_cb.dl_tx_uncongest_ntf_start_idx; 747 748 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ ) 749 { 750 /* if it was congested but now tx queue is below threshold (receiving window) */ 751 if ( (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) 752 &&(llcp_cb.dlcb[idx].is_tx_congested) 753 &&(llcp_cb.dlcb[idx].i_xmit_q.count <= llcp_cb.dlcb[idx].remote_rw / 2) ) 754 { 755 llcp_cb.dlcb[idx].is_tx_congested = FALSE; 756 757 if (llcp_cb.dlcb[idx].remote_busy == FALSE) 758 { 759 LLCP_TRACE_DEBUG3 ("Data link (SSAP:DSAP=0x%X:0x%X) congestion end: count=%d", 760 llcp_cb.dlcb[idx].local_sap, llcp_cb.dlcb[idx].remote_sap, 761 llcp_cb.dlcb[idx].i_xmit_q.count); 762 763 data.congest.local_sap = llcp_cb.dlcb[idx].local_sap; 764 data.congest.remote_sap = llcp_cb.dlcb[idx].remote_sap; 765 766 (*llcp_cb.dlcb[idx].p_app_cb->p_app_cback) (&data); 767 } 768 } 769 idx = (idx + 1) % LLCP_MAX_DATA_LINK; 770 } 771 772 /* move start point for next data link connection */ 773 for (xx = 0; xx < LLCP_MAX_DATA_LINK; xx++ ) 774 { 775 idx = (llcp_cb.dl_tx_uncongest_ntf_start_idx + 1) % LLCP_MAX_DATA_LINK; 776 if (llcp_cb.dlcb[idx].state == LLCP_DLC_STATE_CONNECTED) 777 { 778 llcp_cb.dl_tx_uncongest_ntf_start_idx = idx; 779 break; 780 } 781 } 782} 783 784/******************************************************************************* 785** 786** Function llcp_link_send_SYMM 787** 788** Description Send SYMM PDU 789** 790** Returns void 791** 792*******************************************************************************/ 793static void llcp_link_send_SYMM (void) 794{ 795 BT_HDR *p_msg; 796 UINT8 *p; 797 798 p_msg = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); 799 800 if (p_msg) 801 { 802 p_msg->len = LLCP_PDU_SYMM_SIZE; 803 p_msg->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 804 805 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 806 UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_SYMM_TYPE, LLCP_SAP_LM )); 807 808 llcp_link_send_to_lower (p_msg); 809 } 810} 811 812/******************************************************************************* 813** 814** Function llcp_link_check_send_data 815** 816** Description Send PDU to peer 817** 818** Returns void 819** 820*******************************************************************************/ 821void llcp_link_check_send_data (void) 822{ 823 BT_HDR *p_pdu; 824 825 /* don't re-enter while processing to prevent out of sequence */ 826 if (llcp_cb.lcb.is_sending_data) 827 return; 828 else 829 llcp_cb.lcb.is_sending_data = TRUE; 830 831 /* 832 ** check overall congestion due to high usage of buffer pool 833 ** if congested then notify all of upper layers not to send any more data 834 */ 835 llcp_link_check_congestion (); 836 837 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_LOCAL_XMIT_NEXT) 838 { 839 LLCP_TRACE_DEBUG0 ("llcp_link_check_send_data () in state of LLCP_LINK_SYMM_LOCAL_XMIT_NEXT"); 840 841 p_pdu = llcp_link_build_next_pdu (NULL); 842 843 /* 844 ** For data link connection, 845 ** V(RA) was updated and N(R) was set to V(RA), if I PDU was added in this transmission. 846 ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's not congested, 847 ** then RR PDU will be sent. 848 ** If there was no I PDU to carry V(RA) and V(RA) is not V(R) and it's congested, 849 ** then RNR PDU will be sent. 850 ** If local busy state has been changed then RR or RNR PDU may be sent. 851 */ 852 llcp_dlc_check_to_send_rr_rnr (); 853 854 /* add RR/RNR PDU to be sent if any */ 855 p_pdu = llcp_link_build_next_pdu (p_pdu); 856 857 if (p_pdu != NULL) 858 { 859 llcp_link_send_to_lower (p_pdu); 860 861 /* stop inactivity timer */ 862 llcp_link_stop_inactivity_timer (); 863 864 /* check congestion status after sending out some data */ 865 llcp_link_check_uncongested (); 866 } 867 else 868 { 869 /* There is no data to send, so send SYMM */ 870 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 871 { 872 if (llcp_cb.lcb.symm_delay > 0) 873 { 874 /* wait for application layer sending data */ 875 llcp_link_start_link_timer (); 876 llcp_cb.lcb.is_sending_data = FALSE; 877 return; 878 } 879 else 880 { 881 llcp_link_send_SYMM (); 882 883 /* start inactivity timer */ 884 if (llcp_cb.num_data_link_connection == 0) 885 { 886 llcp_link_start_inactivity_timer (); 887 } 888 } 889 } 890 else 891 { 892 llcp_cb.lcb.is_sending_data = FALSE; 893 return; 894 } 895 } 896 897 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) 898 { 899 /* wait for short period for NFCC to send DISC */ 900 nfc_start_quick_timer (&llcp_cb.lcb.timer, NFC_TTYPE_LLCP_LINK_MANAGER, 901 ((UINT32) 50) * QUICK_TIMER_TICKS_PER_SEC / 1000); 902 } 903 else 904 { 905 /* wait for data to receive from remote */ 906 llcp_link_start_link_timer (); 907 } 908 } 909 910 llcp_cb.lcb.is_sending_data = FALSE; 911} 912 913/******************************************************************************* 914** 915** Function llcp_link_proc_ui_pdu 916** 917** Description Process UI PDU from peer device 918** 919** Returns None 920** 921*******************************************************************************/ 922static void llcp_link_proc_ui_pdu (UINT8 local_sap, 923 UINT8 remote_sap, 924 UINT16 ui_pdu_length, 925 UINT8 *p_ui_pdu, 926 BT_HDR *p_msg) 927{ 928 BOOLEAN appended; 929 BT_HDR *p_last_buf; 930 UINT16 available_bytes; 931 UINT8 *p_dst; 932 tLLCP_APP_CB *p_app_cb; 933 tLLCP_SAP_CBACK_DATA data; 934 tLLCP_DLCB *p_dlcb; 935 936 p_app_cb = llcp_util_get_app_cb (local_sap); 937 /*if UI PDU sent to SAP with data link connection*/ 938 if ((p_dlcb = llcp_dlc_find_dlcb_by_sap (local_sap, remote_sap))) 939 { 940 llcp_util_send_frmr (p_dlcb, LLCP_FRMR_W_ERROR_FLAG, LLCP_PDU_UI_TYPE, 0); 941 llcp_dlsm_execute (p_dlcb, LLCP_DLC_EVENT_FRAME_ERROR, NULL); 942 if (p_msg) 943 { 944 GKI_freebuf (p_msg); 945 } 946 return; 947 } 948 949 /* if application is registered and expecting UI PDU on logical data link */ 950 if ( (p_app_cb) 951 &&(p_app_cb->p_app_cback) 952 &&(p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) ) 953 { 954 LLCP_TRACE_DEBUG2 ("llcp_link_proc_ui_pdu () Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap); 955 956 /* if this is not from AGF PDU */ 957 if (p_msg) 958 { 959 ui_pdu_length = p_msg->len; /* including LLCP header */ 960 p_ui_pdu = (UINT8*) (p_msg + 1) + p_msg->offset; 961 } 962 963 appended = FALSE; 964 965 /* get last buffer in rx queue */ 966 p_last_buf = (BT_HDR *) GKI_getlast (&p_app_cb->ui_rx_q); 967 968 if (p_last_buf) 969 { 970 /* get max length to append at the end of buffer */ 971 available_bytes = GKI_get_buf_size (p_last_buf) - BT_HDR_SIZE - p_last_buf->offset - p_last_buf->len; 972 973 /* if new UI PDU with length can be attached at the end of buffer */ 974 if (available_bytes >= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length) 975 { 976 p_dst = (UINT8*) (p_last_buf + 1) + p_last_buf->offset + p_last_buf->len; 977 978 /* add length of UI PDU */ 979 UINT16_TO_BE_STREAM (p_dst, ui_pdu_length); 980 981 /* copy UI PDU with LLCP header */ 982 memcpy (p_dst, p_ui_pdu, ui_pdu_length); 983 984 p_last_buf->len += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length; 985 986 if (p_msg) 987 GKI_freebuf (p_msg); 988 989 appended = TRUE; 990 } 991 } 992 993 /* if it is not available to append */ 994 if (!appended) 995 { 996 /* if it's not from AGF PDU */ 997 if (p_msg) 998 { 999 /* add length of PDU in front of UI PDU (reuse room for NCI header) */ 1000 p_ui_pdu -= LLCP_PDU_AGF_LEN_SIZE; 1001 UINT16_TO_BE_STREAM (p_ui_pdu, ui_pdu_length); 1002 1003 p_msg->offset -= LLCP_PDU_AGF_LEN_SIZE; 1004 p_msg->len += LLCP_PDU_AGF_LEN_SIZE; 1005 p_msg->layer_specific = 0; 1006 } 1007 else 1008 { 1009 p_msg = (BT_HDR *) GKI_getpoolbuf (LLCP_POOL_ID); 1010 1011 if (p_msg) 1012 { 1013 p_dst = (UINT8*) (p_msg + 1); 1014 1015 /* add length of PDU in front of UI PDU */ 1016 UINT16_TO_BE_STREAM (p_dst, ui_pdu_length); 1017 1018 memcpy (p_dst, p_ui_pdu, ui_pdu_length); 1019 1020 p_msg->offset = 0; 1021 p_msg->len = LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length; 1022 p_msg->layer_specific = 0; 1023 } 1024 else 1025 { 1026 LLCP_TRACE_ERROR0 ("llcp_link_proc_ui_pdu (): out of buffer"); 1027 } 1028 } 1029 1030 /* insert UI PDU in rx queue */ 1031 if (p_msg) 1032 { 1033 GKI_enqueue (&p_app_cb->ui_rx_q, p_msg); 1034 llcp_cb.total_rx_ui_pdu++; 1035 } 1036 } 1037 1038 if (p_app_cb->ui_rx_q.count > llcp_cb.ll_rx_congest_start) 1039 { 1040 LLCP_TRACE_WARNING2 ("llcp_link_proc_ui_pdu (): SAP:0x%x, rx link is congested (%d), discard oldest UI PDU", 1041 local_sap, p_app_cb->ui_rx_q.count); 1042 1043 GKI_freebuf (GKI_dequeue (&p_app_cb->ui_rx_q)); 1044 llcp_cb.total_rx_ui_pdu--; 1045 } 1046 1047 if ((p_app_cb->ui_rx_q.count == 1) && (appended == FALSE)) 1048 { 1049 data.data_ind.event = LLCP_SAP_EVT_DATA_IND; 1050 data.data_ind.local_sap = local_sap; 1051 data.data_ind.remote_sap = remote_sap; 1052 data.data_ind.link_type = LLCP_LINK_TYPE_LOGICAL_DATA_LINK; 1053 (*p_app_cb->p_app_cback) (&data); 1054 } 1055 } 1056 else 1057 { 1058 LLCP_TRACE_ERROR1 ("llcp_link_proc_ui_pdu (): Unregistered SAP:0x%x", local_sap); 1059 1060 if (p_msg) 1061 { 1062 GKI_freebuf (p_msg); 1063 } 1064 } 1065} 1066 1067/******************************************************************************* 1068** 1069** Function llcp_link_proc_agf_pdu 1070** 1071** Description Process AGF PDU from peer device 1072** 1073** Returns void 1074** 1075*******************************************************************************/ 1076static void llcp_link_proc_agf_pdu (BT_HDR *p_agf) 1077{ 1078 UINT16 agf_length; 1079 UINT8 *p, *p_info, *p_pdu_length; 1080 UINT16 pdu_hdr, pdu_length; 1081 UINT8 dsap, ptype, ssap; 1082 1083 p_agf->len -= LLCP_PDU_HEADER_SIZE; 1084 p_agf->offset += LLCP_PDU_HEADER_SIZE; 1085 1086 /* 1087 ** check integrity of AGF PDU and get number of PDUs in AGF PDU 1088 */ 1089 agf_length = p_agf->len; 1090 p = (UINT8 *) (p_agf + 1) + p_agf->offset; 1091 1092 while (agf_length > 0) 1093 { 1094 if (agf_length > LLCP_PDU_AGF_LEN_SIZE) 1095 { 1096 BE_STREAM_TO_UINT16 (pdu_length, p); 1097 agf_length -= LLCP_PDU_AGF_LEN_SIZE; 1098 } 1099 else 1100 { 1101 break; 1102 } 1103 1104 if (pdu_length <= agf_length) 1105 { 1106 p += pdu_length; 1107 agf_length -= pdu_length; 1108 } 1109 else 1110 { 1111 break; 1112 } 1113 } 1114 1115 if (agf_length != 0) 1116 { 1117 LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): Received invalid AGF PDU"); 1118 GKI_freebuf (p_agf); 1119 return; 1120 } 1121 1122 /* 1123 ** Process PDUs in AGF 1124 */ 1125 agf_length = p_agf->len; 1126 p = (UINT8 *) (p_agf + 1) + p_agf->offset; 1127 1128 while (agf_length > 0) 1129 { 1130 /* get length of PDU */ 1131 p_pdu_length = p; 1132 BE_STREAM_TO_UINT16 (pdu_length, p); 1133 agf_length -= LLCP_PDU_AGF_LEN_SIZE; 1134 1135 /* get DSAP/PTYPE/SSAP */ 1136 p_info = p; 1137 BE_STREAM_TO_UINT16 (pdu_hdr, p_info ); 1138 1139 dsap = LLCP_GET_DSAP (pdu_hdr); 1140 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr)); 1141 ssap = LLCP_GET_SSAP (pdu_hdr); 1142 1143#if (BT_TRACE_VERBOSE == TRUE) 1144 LLCP_TRACE_DEBUG4 ("llcp_link_proc_agf_pdu (): Rx DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x in AGF", 1145 dsap, llcp_pdu_type (ptype), ptype, ssap); 1146#endif 1147 1148 if ( (ptype == LLCP_PDU_DISC_TYPE) 1149 &&(dsap == LLCP_SAP_LM) 1150 &&(ssap == LLCP_SAP_LM) ) 1151 { 1152 GKI_freebuf (p_agf); 1153 llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED); 1154 return; 1155 } 1156 else if (ptype == LLCP_PDU_SYMM_TYPE) 1157 { 1158 LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): SYMM PDU exchange shall not be in AGF"); 1159 } 1160 else if (ptype == LLCP_PDU_PAX_TYPE) 1161 { 1162 LLCP_TRACE_ERROR0 ("llcp_link_proc_agf_pdu (): PAX PDU exchange shall not be used"); 1163 } 1164 else if (ptype == LLCP_PDU_SNL_TYPE) 1165 { 1166 llcp_sdp_proc_snl ((UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info); 1167 } 1168 else if ((ptype == LLCP_PDU_UI_TYPE) && (pdu_length > LLCP_PDU_HEADER_SIZE)) 1169 { 1170 llcp_link_proc_ui_pdu (dsap, ssap, pdu_length, p, NULL); 1171 } 1172 else if (ptype == LLCP_PDU_I_TYPE) 1173 { 1174 llcp_dlc_proc_i_pdu (dsap, ssap, pdu_length, p, NULL); 1175 } 1176 else /* let data link connection handle PDU */ 1177 { 1178 llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (pdu_length - LLCP_PDU_HEADER_SIZE), p_info); 1179 } 1180 1181 p += pdu_length; 1182 agf_length -= pdu_length; 1183 } 1184 1185 GKI_freebuf (p_agf); 1186} 1187 1188/******************************************************************************* 1189** 1190** Function llcp_link_proc_rx_pdu 1191** 1192** Description Process received PDU from peer device 1193** 1194** Returns void 1195** 1196*******************************************************************************/ 1197static void llcp_link_proc_rx_pdu (UINT8 dsap, UINT8 ptype, UINT8 ssap, BT_HDR *p_msg) 1198{ 1199 BOOLEAN free_buffer = TRUE; 1200 UINT8 *p_data; 1201 1202 switch (ptype) 1203 { 1204 case LLCP_PDU_PAX_TYPE: 1205 LLCP_TRACE_ERROR0 ("llcp_link_proc_rx_pdu (); PAX PDU exchange shall not be used"); 1206 break; 1207 1208 case LLCP_PDU_DISC_TYPE: 1209 if ((dsap == LLCP_SAP_LM) && (ssap == LLCP_SAP_LM)) 1210 { 1211 llcp_link_deactivate (LLCP_LINK_REMOTE_INITIATED); 1212 } 1213 else 1214 { 1215 p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE; 1216 llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data); 1217 } 1218 break; 1219 1220 case LLCP_PDU_SNL_TYPE: 1221 p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE; 1222 llcp_sdp_proc_snl ((UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data); 1223 break; 1224 1225 case LLCP_PDU_AGF_TYPE: 1226 llcp_link_proc_agf_pdu (p_msg); 1227 free_buffer = FALSE; 1228 break; 1229 1230 case LLCP_PDU_UI_TYPE: 1231 llcp_link_proc_ui_pdu (dsap, ssap, 0, NULL, p_msg); 1232 free_buffer = FALSE; 1233 break; 1234 1235 case LLCP_PDU_I_TYPE: 1236 llcp_dlc_proc_i_pdu (dsap, ssap, 0, NULL, p_msg); 1237 free_buffer = FALSE; 1238 break; 1239 1240 default: 1241 p_data = (UINT8 *) (p_msg + 1) + p_msg->offset + LLCP_PDU_HEADER_SIZE; 1242 llcp_dlc_proc_rx_pdu (dsap, ptype, ssap, (UINT16) (p_msg->len - LLCP_PDU_HEADER_SIZE), p_data); 1243 break; 1244 } 1245 1246 if (free_buffer) 1247 GKI_freebuf (p_msg); 1248} 1249 1250/******************************************************************************* 1251** 1252** Function llcp_link_proc_rx_data 1253** 1254** Description Process received data from NFCC and maintain symmetry state 1255** 1256** Returns void 1257** 1258*******************************************************************************/ 1259static void llcp_link_proc_rx_data (BT_HDR *p_msg) 1260{ 1261 UINT8 *p; 1262 UINT16 pdu_hdr, info_length = 0; 1263 UINT8 dsap, ptype, ssap; 1264 BOOLEAN free_buffer = TRUE; 1265 BOOLEAN frame_error = FALSE; 1266 1267 if (llcp_cb.lcb.symm_state == LLCP_LINK_SYMM_REMOTE_XMIT_NEXT) 1268 { 1269 llcp_link_stop_link_timer (); 1270 1271 if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) 1272 &&(llcp_cb.lcb.sig_xmit_q.count == 0) ) 1273 { 1274 /* this indicates that DISC PDU had been sent out to peer */ 1275 /* initiator may wait for SYMM PDU */ 1276 llcp_link_process_link_timeout (); 1277 } 1278 else 1279 { 1280 if (p_msg->len < LLCP_PDU_HEADER_SIZE) 1281 { 1282 LLCP_TRACE_ERROR1 ("Received too small PDU: got %d bytes", p_msg->len); 1283 frame_error = TRUE; 1284 } 1285 else 1286 { 1287 p = (UINT8 *) (p_msg + 1) + p_msg->offset; 1288 BE_STREAM_TO_UINT16 (pdu_hdr, p ); 1289 1290 dsap = LLCP_GET_DSAP (pdu_hdr); 1291 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr)); 1292 ssap = LLCP_GET_SSAP (pdu_hdr); 1293 1294 /* get length of information per PDU type */ 1295 if ( (ptype == LLCP_PDU_I_TYPE) 1296 ||(ptype == LLCP_PDU_RR_TYPE) 1297 ||(ptype == LLCP_PDU_RNR_TYPE) ) 1298 { 1299 if (p_msg->len >= LLCP_PDU_HEADER_SIZE + LLCP_SEQUENCE_SIZE) 1300 { 1301 info_length = p_msg->len - LLCP_PDU_HEADER_SIZE - LLCP_SEQUENCE_SIZE; 1302 } 1303 else 1304 { 1305 LLCP_TRACE_ERROR0 ("Received I/RR/RNR PDU without sequence"); 1306 frame_error = TRUE; 1307 } 1308 } 1309 else 1310 { 1311 info_length = p_msg->len - LLCP_PDU_HEADER_SIZE; 1312 } 1313 1314 /* check if length of information is bigger than link MIU */ 1315 if ((!frame_error) && (info_length > llcp_cb.lcb.local_link_miu)) 1316 { 1317 LLCP_TRACE_ERROR2 ("Received exceeding MIU (%d): got %d bytes SDU", 1318 llcp_cb.lcb.local_link_miu, info_length); 1319 1320 frame_error = TRUE; 1321 } 1322 else 1323 { 1324#if (BT_TRACE_VERBOSE == TRUE) 1325 LLCP_TRACE_DEBUG4 ("llcp_link_proc_rx_data (): DSAP:0x%x, PTYPE:%s (0x%x), SSAP:0x%x", 1326 dsap, llcp_pdu_type (ptype), ptype, ssap); 1327#endif 1328 1329 if (ptype == LLCP_PDU_SYMM_TYPE) 1330 { 1331 if (info_length > 0) 1332 { 1333 LLCP_TRACE_ERROR1 ("Received extra data (%d bytes) in SYMM PDU", info_length); 1334 frame_error = TRUE; 1335 } 1336 } 1337 else 1338 { 1339 /* received other than SYMM */ 1340 llcp_link_stop_inactivity_timer (); 1341 1342 llcp_link_proc_rx_pdu (dsap, ptype, ssap, p_msg); 1343 free_buffer = FALSE; 1344 } 1345 } 1346 } 1347 1348 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_LOCAL_XMIT_NEXT; 1349 1350 /* check if any pending packet */ 1351 llcp_link_check_send_data (); 1352 } 1353 } 1354 else 1355 { 1356 LLCP_TRACE_ERROR0 ("Received PDU in state of SYMM_MUST_XMIT_NEXT"); 1357 } 1358 1359 if (free_buffer) 1360 GKI_freebuf (p_msg); 1361} 1362 1363/******************************************************************************* 1364** 1365** Function llcp_link_get_next_pdu 1366** 1367** Description Get next PDU from link manager or data links w/wo dequeue 1368** 1369** Returns pointer of a PDU to send if length_only is FALSE 1370** NULL otherwise 1371** 1372*******************************************************************************/ 1373static BT_HDR *llcp_link_get_next_pdu (BOOLEAN length_only, UINT16 *p_next_pdu_length) 1374{ 1375 BT_HDR *p_msg; 1376 int count, xx; 1377 tLLCP_APP_CB *p_app_cb; 1378 1379 /* processing signalling PDU first */ 1380 if (llcp_cb.lcb.sig_xmit_q.p_first) 1381 { 1382 if (length_only) 1383 { 1384 p_msg = (BT_HDR*) llcp_cb.lcb.sig_xmit_q.p_first; 1385 *p_next_pdu_length = p_msg->len; 1386 return NULL; 1387 } 1388 else 1389 p_msg = (BT_HDR*) GKI_dequeue (&llcp_cb.lcb.sig_xmit_q); 1390 1391 return p_msg; 1392 } 1393 else 1394 { 1395 /* transmitting logical data link and data link connection equaly */ 1396 for (xx = 0; xx < 2; xx++) 1397 { 1398 if (!llcp_cb.lcb.ll_served) 1399 { 1400 /* Get one from logical link connection */ 1401 for (count = 0; count < LLCP_NUM_SAPS; count++) 1402 { 1403 /* round robin schedule without priority */ 1404 p_app_cb = llcp_util_get_app_cb (llcp_cb.lcb.ll_idx); 1405 1406 if ( (p_app_cb) 1407 &&(p_app_cb->p_app_cback) 1408 &&(p_app_cb->ui_xmit_q.count) ) 1409 { 1410 if (length_only) 1411 { 1412 /* don't alternate next data link to return the same length of PDU */ 1413 p_msg = (BT_HDR *) p_app_cb->ui_xmit_q.p_first; 1414 *p_next_pdu_length = p_msg->len; 1415 return NULL; 1416 } 1417 else 1418 { 1419 /* check data link connection first in next time */ 1420 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served; 1421 1422 p_msg = (BT_HDR*) GKI_dequeue (&p_app_cb->ui_xmit_q); 1423 llcp_cb.total_tx_ui_pdu--; 1424 1425 /* this logical link has been served, so start from next logical link next time */ 1426 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS; 1427 1428 return p_msg; 1429 } 1430 } 1431 else 1432 { 1433 /* check next logical link connection */ 1434 llcp_cb.lcb.ll_idx = (llcp_cb.lcb.ll_idx + 1) % LLCP_NUM_SAPS; 1435 } 1436 } 1437 1438 /* no data, so check data link connection if not checked yet */ 1439 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served; 1440 } 1441 else 1442 { 1443 /* Get one from data link connection */ 1444 for (count = 0; count < LLCP_MAX_DATA_LINK; count++) 1445 { 1446 /* round robin schedule without priority */ 1447 if (llcp_cb.dlcb[llcp_cb.lcb.dl_idx].state != LLCP_DLC_STATE_IDLE) 1448 { 1449 if (length_only) 1450 { 1451 *p_next_pdu_length = llcp_dlc_get_next_pdu_length (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]); 1452 1453 if (*p_next_pdu_length > 0 ) 1454 { 1455 /* don't change data link connection to return the same length of PDU */ 1456 return NULL; 1457 } 1458 else 1459 { 1460 /* no data, so check next data link connection */ 1461 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK; 1462 } 1463 } 1464 else 1465 { 1466 p_msg = llcp_dlc_get_next_pdu (&llcp_cb.dlcb[llcp_cb.lcb.dl_idx]); 1467 1468 /* this data link has been served, so start from next data link next time */ 1469 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK; 1470 1471 if (p_msg) 1472 { 1473 /* serve logical data link next time */ 1474 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served; 1475 return p_msg; 1476 } 1477 } 1478 } 1479 else 1480 { 1481 /* check next data link connection */ 1482 llcp_cb.lcb.dl_idx = (llcp_cb.lcb.dl_idx + 1) % LLCP_MAX_DATA_LINK; 1483 } 1484 } 1485 1486 /* if all of data link connection doesn't have data to send */ 1487 if (count >= LLCP_MAX_DATA_LINK) 1488 { 1489 llcp_cb.lcb.ll_served = !llcp_cb.lcb.ll_served; 1490 } 1491 } 1492 } 1493 } 1494 1495 /* nothing to send */ 1496 *p_next_pdu_length = 0; 1497 return NULL; 1498} 1499 1500/******************************************************************************* 1501** 1502** Function llcp_link_build_next_pdu 1503** 1504** Description Build a PDU from Link Manager and Data Link 1505** Perform aggregation procedure if necessary 1506** 1507** Returns BT_HDR* if sent any PDU 1508** 1509*******************************************************************************/ 1510static BT_HDR *llcp_link_build_next_pdu (BT_HDR *p_pdu) 1511{ 1512 BT_HDR *p_agf = NULL, *p_msg = NULL, *p_next_pdu; 1513 UINT8 *p, ptype; 1514 UINT16 next_pdu_length, pdu_hdr; 1515 1516 LLCP_TRACE_DEBUG0 ("llcp_link_build_next_pdu ()"); 1517 1518 /* add any pending SNL PDU into sig_xmit_q for transmitting */ 1519 llcp_sdp_check_send_snl (); 1520 1521 if (p_pdu) 1522 { 1523 /* get PDU type */ 1524 p = (UINT8 *) (p_pdu + 1) + p_pdu->offset; 1525 BE_STREAM_TO_UINT16 (pdu_hdr, p); 1526 1527 ptype = (UINT8) (LLCP_GET_PTYPE (pdu_hdr)); 1528 1529 if (ptype == LLCP_PDU_AGF_TYPE) 1530 { 1531 /* add more PDU into this AGF PDU */ 1532 p_agf = p_pdu; 1533 } 1534 else 1535 { 1536 p_msg = p_pdu; 1537 } 1538 } 1539 else 1540 { 1541 /* Get a PDU from link manager or data links */ 1542 p_msg = llcp_link_get_next_pdu (FALSE, &next_pdu_length); 1543 1544 if (!p_msg) 1545 { 1546 return NULL; 1547 } 1548 } 1549 1550 /* Get length of next PDU from link manager or data links without dequeue */ 1551 llcp_link_get_next_pdu (TRUE, &next_pdu_length); 1552 while (next_pdu_length > 0) 1553 { 1554 /* if it's first visit */ 1555 if (!p_agf) 1556 { 1557 /* if next PDU fits into MIU, allocate AGF PDU and copy the first PDU */ 1558 if (2 + p_msg->len + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu) 1559 { 1560 p_agf = (BT_HDR*) GKI_getpoolbuf (LLCP_POOL_ID); 1561 if (p_agf) 1562 { 1563 p_agf->offset = NCI_MSG_OFFSET_SIZE + NCI_DATA_HDR_SIZE; 1564 1565 p = (UINT8 *) (p_agf + 1) + p_agf->offset; 1566 1567 UINT16_TO_BE_STREAM (p, LLCP_GET_PDU_HEADER (LLCP_SAP_LM, LLCP_PDU_AGF_TYPE, LLCP_SAP_LM )); 1568 UINT16_TO_BE_STREAM (p, p_msg->len); 1569 memcpy(p, (UINT8 *) (p_msg + 1) + p_msg->offset, p_msg->len); 1570 1571 p_agf->len = LLCP_PDU_HEADER_SIZE + 2 + p_msg->len; 1572 1573 GKI_freebuf (p_msg); 1574 p_msg = p_agf; 1575 } 1576 else 1577 { 1578 LLCP_TRACE_ERROR0 ("llcp_link_build_next_pdu (): Out of buffer"); 1579 return p_msg; 1580 } 1581 } 1582 else 1583 { 1584 break; 1585 } 1586 } 1587 1588 /* if next PDU fits into MIU, copy the next PDU into AGF */ 1589 if (p_agf->len - LLCP_PDU_HEADER_SIZE + 2 + next_pdu_length <= llcp_cb.lcb.effective_miu) 1590 { 1591 /* Get a next PDU from link manager or data links */ 1592 p_next_pdu = llcp_link_get_next_pdu (FALSE, &next_pdu_length); 1593 1594 p = (UINT8 *) (p_agf + 1) + p_agf->offset + p_agf->len; 1595 1596 UINT16_TO_BE_STREAM (p, p_next_pdu->len); 1597 memcpy (p, (UINT8 *) (p_next_pdu + 1) + p_next_pdu->offset, p_next_pdu->len); 1598 1599 p_agf->len += 2 + p_next_pdu->len; 1600 1601 GKI_freebuf (p_next_pdu); 1602 1603 /* Get next PDU length from link manager or data links without dequeue */ 1604 llcp_link_get_next_pdu (TRUE, &next_pdu_length); 1605 } 1606 else 1607 { 1608 break; 1609 } 1610 } 1611 1612 if (p_agf) 1613 return p_agf; 1614 else 1615 return p_msg; 1616} 1617 1618/******************************************************************************* 1619** 1620** Function llcp_link_send_to_lower 1621** 1622** Description Send PDU to lower layer 1623** 1624** Returns void 1625** 1626*******************************************************************************/ 1627static void llcp_link_send_to_lower (BT_HDR *p_pdu) 1628{ 1629#if (BT_TRACE_PROTOCOL == TRUE) 1630 DispLLCP (p_pdu, FALSE); 1631#endif 1632 1633 llcp_cb.lcb.symm_state = LLCP_LINK_SYMM_REMOTE_XMIT_NEXT; 1634 1635 NFC_SendData (NFC_RF_CONN_ID, p_pdu); 1636} 1637 1638/******************************************************************************* 1639** 1640** Function llcp_link_connection_cback 1641** 1642** Description processing incoming data 1643** 1644** Returns void 1645** 1646*******************************************************************************/ 1647void llcp_link_connection_cback (UINT8 conn_id, tNFC_CONN_EVT event, tNFC_CONN *p_data) 1648{ 1649 if (event == NFC_DATA_CEVT) 1650 { 1651#if (BT_TRACE_PROTOCOL == TRUE) 1652 DispLLCP ((BT_HDR *)p_data->data.p_data, TRUE); 1653#endif 1654 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED) 1655 { 1656 /* respoding SYMM while LLCP is deactivated but RF link is not deactivated yet */ 1657 llcp_link_send_SYMM (); 1658 GKI_freebuf ((BT_HDR *) p_data->data.p_data); 1659 } 1660 else 1661 { 1662 llcp_link_proc_rx_data ((BT_HDR *) p_data->data.p_data); 1663 } 1664 } 1665 else if (event == NFC_ERROR_CEVT) 1666 { 1667 /* RF interface specific status code */ 1668 llcp_link_deactivate (*(UINT8*) p_data); 1669 } 1670 else if (event == NFC_DEACTIVATE_CEVT) 1671 { 1672 if ( (llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATING) 1673 &&(!llcp_cb.lcb.is_initiator) ) 1674 { 1675 /* peer initiates NFC link deactivation before timeout */ 1676 llcp_link_stop_link_timer (); 1677 llcp_link_process_link_timeout (); 1678 } 1679 else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED) 1680 { 1681 llcp_link_deactivate (LLCP_LINK_RF_LINK_LOSS_ERR); 1682 } 1683 NFC_SetStaticRfCback (NULL); 1684 } 1685 1686 /* LLCP ignores the following events 1687 1688 NFC_CONN_CREATE_CEVT 1689 NFC_CONN_CLOSE_CEVT 1690 */ 1691} 1692 1693#if (BT_TRACE_VERBOSE == TRUE) 1694/******************************************************************************* 1695** 1696** Function llcp_pdu_type 1697** 1698** Description 1699** 1700** Returns string of PDU type 1701** 1702*******************************************************************************/ 1703static char *llcp_pdu_type (UINT8 ptype) 1704{ 1705 switch(ptype) 1706 { 1707 case LLCP_PDU_SYMM_TYPE: 1708 return "SYMM"; 1709 case LLCP_PDU_PAX_TYPE: 1710 return "PAX"; 1711 case LLCP_PDU_AGF_TYPE: 1712 return "AGF"; 1713 case LLCP_PDU_UI_TYPE: 1714 return "UI"; 1715 case LLCP_PDU_CONNECT_TYPE: 1716 return "CONNECT"; 1717 case LLCP_PDU_DISC_TYPE: 1718 return "DISC"; 1719 case LLCP_PDU_CC_TYPE: 1720 return "CC"; 1721 case LLCP_PDU_DM_TYPE: 1722 return "DM"; 1723 case LLCP_PDU_FRMR_TYPE: 1724 return "FRMR"; 1725 case LLCP_PDU_SNL_TYPE: 1726 return "SNL"; 1727 case LLCP_PDU_I_TYPE: 1728 return "I"; 1729 case LLCP_PDU_RR_TYPE: 1730 return "RR"; 1731 case LLCP_PDU_RNR_TYPE: 1732 return "RNR"; 1733 1734 default: 1735 return "RESERVED"; 1736 } 1737} 1738 1739#endif 1740 1741