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