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