llcp_api.cc revision 9343bf46e1ffabdd10973a3b71baa503567e319d
1/****************************************************************************** 2 * 3 * Copyright (C) 2010-2014 Broadcom Corporation 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at: 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 ******************************************************************************/ 18 19/****************************************************************************** 20 * 21 * This file contains the LLCP API code 22 * 23 ******************************************************************************/ 24 25#include "llcp_api.h" 26#include "gki.h" 27#include "llcp_int.h" 28 29#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */ 30 31tLLCP_TEST_PARAMS llcp_test_params = { 32 LLCP_VERSION_VALUE, 0, /* not override */ 33}; 34 35/******************************************************************************* 36** 37** Function LLCP_SetTestParams 38** 39** Description Set test parameters for LLCP 40** 41** 42** Returns void 43** 44*******************************************************************************/ 45void LLCP_SetTestParams(uint8_t version, uint16_t wks) { 46 DLOG_IF(INFO, nfc_debug_enabled) 47 << StringPrintf("version:0x%02X, wks:0x%04X", version, wks); 48 49 if (version != 0xFF) llcp_test_params.version = version; 50 51 if (wks != 0xFFFF) llcp_test_params.wks = wks; 52} 53#endif 54 55/******************************************************************************* 56** 57** Function LLCP_RegisterDtaCback 58** 59** Description Register callback function for LLCP DTA testing 60** 61** 62** Returns void 63** 64*******************************************************************************/ 65void LLCP_RegisterDtaCback(tLLCP_DTA_CBACK* p_dta_cback) { 66 DLOG_IF(INFO, nfc_debug_enabled) << __func__; 67 68 llcp_cb.p_dta_cback = p_dta_cback; 69} 70 71/******************************************************************************* 72** 73** Function LLCP_SetConfig 74** 75** Description Set configuration parameters for LLCP 76** - Local Link MIU 77** - Option parameter 78** - Response Waiting Time Index 79** - Local Link Timeout 80** - Inactivity Timeout as initiator role 81** - Inactivity Timeout as target role 82** - Delay SYMM response 83** - Data link connection timeout 84** - Delay timeout to send first PDU as initiator 85** 86** Returns void 87** 88*******************************************************************************/ 89void LLCP_SetConfig(uint16_t link_miu, uint8_t opt, uint8_t wt, 90 uint16_t link_timeout, uint16_t inact_timeout_init, 91 uint16_t inact_timeout_target, uint16_t symm_delay, 92 uint16_t data_link_timeout, 93 uint16_t delay_first_pdu_timeout) { 94 DLOG_IF(INFO, nfc_debug_enabled) 95 << StringPrintf("link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d", 96 link_miu, opt, wt, link_timeout); 97 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 98 " inact_timeout (init:%d,target:%d), symm_delay:%d, " 99 "data_link_timeout:%d", 100 inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout); 101 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 102 " delay_first_pdu_timeout:%d", delay_first_pdu_timeout); 103 104 if (link_miu < LLCP_DEFAULT_MIU) { 105 LOG(ERROR) << StringPrintf( 106 "link_miu shall not be smaller than " 107 "LLCP_DEFAULT_MIU (%d)", 108 LLCP_DEFAULT_MIU); 109 link_miu = LLCP_DEFAULT_MIU; 110 } else if (link_miu > LLCP_MAX_MIU) { 111 LOG(ERROR) << StringPrintf( 112 "link_miu shall not be bigger than LLCP_MAX_MIU " 113 "(%d)", 114 LLCP_MAX_MIU); 115 link_miu = LLCP_MAX_MIU; 116 } 117 118 /* if Link MIU is bigger than GKI buffer */ 119 if (link_miu > LLCP_MIU) { 120 LOG(ERROR) << StringPrintf( 121 "link_miu shall not be bigger than LLCP_MIU (%zu)", LLCP_MIU); 122 llcp_cb.lcb.local_link_miu = LLCP_MIU; 123 } else 124 llcp_cb.lcb.local_link_miu = link_miu; 125 126 llcp_cb.lcb.local_opt = opt; 127 llcp_cb.lcb.local_wt = wt; 128 129 if (link_timeout < LLCP_LTO_UNIT) { 130 LOG(ERROR) << StringPrintf( 131 "link_timeout shall not be smaller than " 132 "LLCP_LTO_UNIT (%d ms)", 133 LLCP_LTO_UNIT); 134 llcp_cb.lcb.local_lto = LLCP_DEFAULT_LTO_IN_MS; 135 } else if (link_timeout > LLCP_MAX_LTO_IN_MS) { 136 LOG(ERROR) << StringPrintf( 137 "link_timeout shall not be bigger than " 138 "LLCP_MAX_LTO_IN_MS (%d ms)", 139 LLCP_MAX_LTO_IN_MS); 140 llcp_cb.lcb.local_lto = LLCP_MAX_LTO_IN_MS; 141 } else 142 llcp_cb.lcb.local_lto = link_timeout; 143 144 llcp_cb.lcb.inact_timeout_init = inact_timeout_init; 145 llcp_cb.lcb.inact_timeout_target = inact_timeout_target; 146 llcp_cb.lcb.symm_delay = symm_delay; 147 llcp_cb.lcb.data_link_timeout = data_link_timeout; 148 llcp_cb.lcb.delay_first_pdu_timeout = delay_first_pdu_timeout; 149} 150 151/******************************************************************************* 152** 153** Function LLCP_GetConfig 154** 155** Description Get configuration parameters for LLCP 156** - Local Link MIU 157** - Option parameter 158** - Response Waiting Time Index 159** - Local Link Timeout 160** - Inactivity Timeout as initiator role 161** - Inactivity Timeout as target role 162** - Delay SYMM response 163** - Data link connection timeout 164** - Delay timeout to send first PDU as initiator 165** 166** Returns void 167** 168*******************************************************************************/ 169void LLCP_GetConfig(uint16_t* p_link_miu, uint8_t* p_opt, uint8_t* p_wt, 170 uint16_t* p_link_timeout, uint16_t* p_inact_timeout_init, 171 uint16_t* p_inact_timeout_target, uint16_t* p_symm_delay, 172 uint16_t* p_data_link_timeout, 173 uint16_t* p_delay_first_pdu_timeout) { 174 *p_link_miu = llcp_cb.lcb.local_link_miu; 175 *p_opt = llcp_cb.lcb.local_opt; 176 *p_wt = llcp_cb.lcb.local_wt; 177 *p_link_timeout = llcp_cb.lcb.local_lto; 178 *p_inact_timeout_init = llcp_cb.lcb.inact_timeout_init; 179 *p_inact_timeout_target = llcp_cb.lcb.inact_timeout_target; 180 *p_symm_delay = llcp_cb.lcb.symm_delay; 181 *p_data_link_timeout = llcp_cb.lcb.data_link_timeout; 182 *p_delay_first_pdu_timeout = llcp_cb.lcb.delay_first_pdu_timeout; 183 184 DLOG_IF(INFO, nfc_debug_enabled) 185 << StringPrintf("link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d", 186 *p_link_miu, *p_opt, *p_wt, *p_link_timeout); 187 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 188 "inact_timeout (init:%d, target:%d), symm_delay:%d, data_link_timeout:%d", 189 *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, 190 *p_data_link_timeout); 191 DLOG_IF(INFO, nfc_debug_enabled) 192 << StringPrintf("delay_first_pdu_timeout:%d", *p_delay_first_pdu_timeout); 193} 194 195/******************************************************************************* 196** 197** Function LLCP_GetDiscoveryConfig 198** 199** Description Returns discovery config for ISO 18092 MAC link activation 200** This function is called to get general bytes for 201** NFC_PMID_ATR_REQ_GEN_BYTES or NFC_PMID_ATR_RES_GEN_BYTES 202** before starting discovery. 203** 204** wt:Waiting time 0 - 8, only for listen 205** p_gen_bytes: pointer to store LLCP magic number and 206** paramters 207** p_gen_bytes_len: length of buffer for gen bytes as input 208** (NOTE:it must be bigger than 209** LLCP_MIN_GEN_BYTES) actual gen bytes size 210** as output 211** 212** Restrictions on the use of ISO 18092 213** 1. The DID features shall not be used. 214** 2. the NAD features shall not be used. 215** 3. Frame waiting time extentions (WTX) shall not be used. 216** 217** Returns None 218** 219*******************************************************************************/ 220void LLCP_GetDiscoveryConfig(uint8_t* p_wt, uint8_t* p_gen_bytes, 221 uint8_t* p_gen_bytes_len) { 222 uint8_t* p = p_gen_bytes; 223 224 DLOG_IF(INFO, nfc_debug_enabled) << __func__; 225 226 if (*p_gen_bytes_len < LLCP_MIN_GEN_BYTES) { 227 LOG(ERROR) << StringPrintf( 228 "GenBytes length shall not be smaller than " 229 "LLCP_MIN_GEN_BYTES (%d)", 230 LLCP_MIN_GEN_BYTES); 231 *p_gen_bytes_len = 0; 232 return; 233 } 234 235 *p_wt = llcp_cb.lcb.local_wt; 236 237 UINT8_TO_BE_STREAM(p, LLCP_MAGIC_NUMBER_BYTE0); 238 UINT8_TO_BE_STREAM(p, LLCP_MAGIC_NUMBER_BYTE1); 239 UINT8_TO_BE_STREAM(p, LLCP_MAGIC_NUMBER_BYTE2); 240 241#if (LLCP_TEST_INCLUDED == TRUE) /* this is for LLCP testing */ 242 UINT8_TO_BE_STREAM(p, LLCP_VERSION_TYPE); 243 UINT8_TO_BE_STREAM(p, LLCP_VERSION_LEN); 244 UINT8_TO_BE_STREAM(p, llcp_test_params.version); 245 246 UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE); 247 UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN); 248 UINT16_TO_BE_STREAM(p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU)); 249 250 UINT8_TO_BE_STREAM(p, LLCP_WKS_TYPE); 251 UINT8_TO_BE_STREAM(p, LLCP_WKS_LEN); 252 if (llcp_test_params.wks == 0) /* not override */ 253 { 254 UINT16_TO_BE_STREAM(p, llcp_cb.lcb.wks); 255 } else { 256 UINT16_TO_BE_STREAM(p, llcp_test_params.wks); 257 } 258#else 259 UINT8_TO_BE_STREAM(p, LLCP_VERSION_TYPE); 260 UINT8_TO_BE_STREAM(p, LLCP_VERSION_LEN); 261 UINT8_TO_BE_STREAM(p, LLCP_VERSION_VALUE); 262 263 UINT8_TO_BE_STREAM(p, LLCP_MIUX_TYPE); 264 UINT8_TO_BE_STREAM(p, LLCP_MIUX_LEN); 265 UINT16_TO_BE_STREAM(p, (llcp_cb.lcb.local_link_miu - LLCP_DEFAULT_MIU)); 266 267 UINT8_TO_BE_STREAM(p, LLCP_WKS_TYPE); 268 UINT8_TO_BE_STREAM(p, LLCP_WKS_LEN); 269 UINT16_TO_BE_STREAM(p, llcp_cb.lcb.wks); 270#endif 271 272 UINT8_TO_BE_STREAM(p, LLCP_LTO_TYPE); 273 UINT8_TO_BE_STREAM(p, LLCP_LTO_LEN); 274 UINT8_TO_BE_STREAM(p, (llcp_cb.lcb.local_lto / LLCP_LTO_UNIT)); 275 276 UINT8_TO_BE_STREAM(p, LLCP_OPT_TYPE); 277 UINT8_TO_BE_STREAM(p, LLCP_OPT_LEN); 278 UINT8_TO_BE_STREAM(p, llcp_cb.lcb.local_opt); 279 280 *p_gen_bytes_len = (uint8_t)(p - p_gen_bytes); 281} 282 283/******************************************************************************* 284** 285** Function LLCP_ActivateLink 286** 287** Description This function will activate LLCP link with LR, WT and Gen 288** Bytes in activation NTF from NFCC. 289** 290** LLCP_LINK_ACTIVATION_COMPLETE_EVT will be returned through 291** callback function if successful. 292** Otherwise, LLCP_LINK_ACTIVATION_FAILED_EVT will be returned. 293** 294** Returns LLCP_STATUS_SUCCESS if success 295** 296*******************************************************************************/ 297tLLCP_STATUS LLCP_ActivateLink(tLLCP_ACTIVATE_CONFIG config, 298 tLLCP_LINK_CBACK* p_link_cback) { 299 DLOG_IF(INFO, nfc_debug_enabled) 300 << StringPrintf("link_state = %d", llcp_cb.lcb.link_state); 301 302 if ((llcp_cb.lcb.link_state == LLCP_LINK_STATE_DEACTIVATED) && 303 (p_link_cback)) { 304 llcp_cb.lcb.p_link_cback = p_link_cback; 305 return (llcp_link_activate(&config)); 306 } else 307 return LLCP_STATUS_FAIL; 308} 309 310/******************************************************************************* 311** 312** Function LLCP_DeactivateLink 313** 314** Description Deactivate LLCP link 315** 316** LLCP_LINK_DEACTIVATED_EVT will be returned through callback 317** when LLCP link is deactivated. Then NFC link may be 318** deactivated. 319** 320** Returns LLCP_STATUS_SUCCESS if success 321** 322*******************************************************************************/ 323tLLCP_STATUS LLCP_DeactivateLink(void) { 324 DLOG_IF(INFO, nfc_debug_enabled) 325 << StringPrintf("link_state = %d", llcp_cb.lcb.link_state); 326 327 if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_DEACTIVATED) { 328 llcp_link_deactivate(LLCP_LINK_LOCAL_INITIATED); 329 return LLCP_STATUS_SUCCESS; 330 } else 331 return LLCP_STATUS_FAIL; 332} 333 334/******************************************************************************* 335** 336** Function LLCP_RegisterServer 337** 338** Description Register server and callback function 339** 340** reg_sap : Well-Known SAP except LM and SDP (0x02 - 0x0F) 341** Advertized by SDP (0x10 - 0x1F) 342** LLCP_INVALID_SAP, LLCP will allocate between 0x10 343** and 0x1F 344** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK 345** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION 346** p_service_name : Null-terminated string up to 347** LLCP_MAX_SN_LEN 348** 349** Returns SAP between 0x02 and 0x1F, if success 350** LLCP_INVALID_SAP, otherwise 351** 352*******************************************************************************/ 353uint8_t LLCP_RegisterServer(uint8_t reg_sap, uint8_t link_type, 354 std::string p_service_name, 355 tLLCP_APP_CBACK* p_app_cback) { 356 uint8_t sap; 357 uint16_t length; 358 tLLCP_APP_CB* p_app_cb = { 359 0, 360 }; 361 362 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 363 "SAP:0x%x, link_type:0x%x, ServiceName:<%s>", reg_sap, link_type, 364 ((p_service_name.empty()) ? "" : p_service_name.c_str())); 365 366 if (!p_app_cback) { 367 LOG(ERROR) << StringPrintf("Callback must be provided"); 368 return LLCP_INVALID_SAP; 369 } else if (((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00) && 370 ((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)) { 371 LOG(ERROR) << StringPrintf("link type (0x%x) must be specified", link_type); 372 return LLCP_INVALID_SAP; 373 } 374 375 if (reg_sap == LLCP_INVALID_SAP) { 376 /* allocate a SAP between 0x10 and 0x1F */ 377 for (sap = 0; sap < LLCP_MAX_SERVER; sap++) { 378 if (llcp_cb.server_cb[sap].p_app_cback == NULL) { 379 p_app_cb = &llcp_cb.server_cb[sap]; 380 reg_sap = LLCP_LOWER_BOUND_SDP_SAP + sap; 381 break; 382 } 383 } 384 385 if (reg_sap == LLCP_INVALID_SAP) { 386 LOG(ERROR) << StringPrintf("out of resource"); 387 return LLCP_INVALID_SAP; 388 } 389 } else if (reg_sap == LLCP_SAP_LM) { 390 LOG(ERROR) << StringPrintf("SAP (0x%x) is for link manager", reg_sap); 391 return LLCP_INVALID_SAP; 392 } else if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP) { 393 if (reg_sap >= LLCP_MAX_WKS) { 394 LOG(ERROR) << StringPrintf("out of resource for SAP (0x%x)", reg_sap); 395 return LLCP_INVALID_SAP; 396 } else if (llcp_cb.wks_cb[reg_sap].p_app_cback) { 397 LOG(ERROR) << StringPrintf("SAP (0x%x) is already registered", reg_sap); 398 return LLCP_INVALID_SAP; 399 } else { 400 p_app_cb = &llcp_cb.wks_cb[reg_sap]; 401 } 402 } else if (reg_sap <= LLCP_UPPER_BOUND_SDP_SAP) { 403 if (reg_sap - LLCP_LOWER_BOUND_SDP_SAP >= LLCP_MAX_SERVER) { 404 LOG(ERROR) << StringPrintf("out of resource for SAP (0x%x)", reg_sap); 405 return LLCP_INVALID_SAP; 406 } else if (llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP] 407 .p_app_cback) { 408 LOG(ERROR) << StringPrintf("SAP (0x%x) is already registered", reg_sap); 409 return LLCP_INVALID_SAP; 410 } else { 411 p_app_cb = &llcp_cb.server_cb[reg_sap - LLCP_LOWER_BOUND_SDP_SAP]; 412 } 413 } else if (reg_sap >= LLCP_LOWER_BOUND_LOCAL_SAP) { 414 LOG(ERROR) << StringPrintf("SAP (0x%x) must be less than 0x%x", reg_sap, 415 LLCP_LOWER_BOUND_LOCAL_SAP); 416 return LLCP_INVALID_SAP; 417 } 418 419 memset(p_app_cb, 0x00, sizeof(tLLCP_APP_CB)); 420 421 if (!p_service_name.empty()) { 422 length = p_service_name.length(); 423 if (length > LLCP_MAX_SN_LEN) { 424 LOG(ERROR) << StringPrintf("Service Name (%d bytes) is too long", length); 425 return LLCP_INVALID_SAP; 426 } 427 428 p_app_cb->p_service_name = (char*)GKI_getbuf((uint16_t)(length + 1)); 429 if (p_app_cb->p_service_name == NULL) { 430 LOG(ERROR) << StringPrintf("Out of resource"); 431 return LLCP_INVALID_SAP; 432 } 433 434 strncpy(p_app_cb->p_service_name, p_service_name.c_str(), length + 1); 435 p_app_cb->p_service_name[length] = 0; 436 } else 437 p_app_cb->p_service_name = NULL; 438 439 p_app_cb->p_app_cback = p_app_cback; 440 p_app_cb->link_type = link_type; 441 442 if (reg_sap <= LLCP_UPPER_BOUND_WK_SAP) { 443 llcp_cb.lcb.wks |= (1 << reg_sap); 444 } 445 446 DLOG_IF(INFO, nfc_debug_enabled) 447 << StringPrintf("Registered SAP = 0x%02X", reg_sap); 448 449 if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) { 450 llcp_cb.num_logical_data_link++; 451 llcp_util_adjust_ll_congestion(); 452 } 453 454 return reg_sap; 455} 456 457/******************************************************************************* 458** 459** Function LLCP_RegisterClient 460** 461** Description Register client and callback function 462** 463** link_type : LLCP_LINK_TYPE_LOGICAL_DATA_LINK 464** and/or LLCP_LINK_TYPE_DATA_LINK_CONNECTION 465** 466** Returns SAP between 0x20 and 0x3F, if success 467** LLCP_INVALID_SAP, otherwise 468** 469*******************************************************************************/ 470uint8_t LLCP_RegisterClient(uint8_t link_type, tLLCP_APP_CBACK* p_app_cback) { 471 uint8_t reg_sap = LLCP_INVALID_SAP; 472 uint8_t sap; 473 tLLCP_APP_CB* p_app_cb; 474 475 DLOG_IF(INFO, nfc_debug_enabled) 476 << StringPrintf("link_type = 0x%x", link_type); 477 478 if (!p_app_cback) { 479 LOG(ERROR) << StringPrintf("Callback must be provided"); 480 return LLCP_INVALID_SAP; 481 } else if (((link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0x00) && 482 ((link_type & LLCP_LINK_TYPE_DATA_LINK_CONNECTION) == 0x00)) { 483 LOG(ERROR) << StringPrintf("link type (0x%x) must be specified", link_type); 484 return LLCP_INVALID_SAP; 485 } 486 487 /* allocate a SAP between 0x20 and 0x3F */ 488 for (sap = 0; sap < LLCP_MAX_CLIENT; sap++) { 489 if (llcp_cb.client_cb[sap].p_app_cback == NULL) { 490 p_app_cb = &llcp_cb.client_cb[sap]; 491 memset(p_app_cb, 0x00, sizeof(tLLCP_APP_CB)); 492 reg_sap = LLCP_LOWER_BOUND_LOCAL_SAP + sap; 493 break; 494 } 495 } 496 497 if (reg_sap == LLCP_INVALID_SAP) { 498 LOG(ERROR) << StringPrintf("out of resource"); 499 return LLCP_INVALID_SAP; 500 } 501 502 p_app_cb->p_app_cback = p_app_cback; 503 p_app_cb->p_service_name = NULL; 504 p_app_cb->link_type = link_type; 505 506 DLOG_IF(INFO, nfc_debug_enabled) 507 << StringPrintf("Registered SAP = 0x%02X", reg_sap); 508 509 if (link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) { 510 llcp_cb.num_logical_data_link++; 511 llcp_util_adjust_ll_congestion(); 512 } 513 514 return reg_sap; 515} 516 517/******************************************************************************* 518** 519** Function LLCP_Deregister 520** 521** Description Deregister server or client 522** 523** 524** Returns LLCP_STATUS_SUCCESS if success 525** 526*******************************************************************************/ 527tLLCP_STATUS LLCP_Deregister(uint8_t local_sap) { 528 uint8_t idx; 529 tLLCP_APP_CB* p_app_cb; 530 531 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("SAP:0x%x", local_sap); 532 533 p_app_cb = llcp_util_get_app_cb(local_sap); 534 535 if ((!p_app_cb) || (p_app_cb->p_app_cback == NULL)) { 536 LOG(ERROR) << StringPrintf("SAP (0x%x) is not registered", local_sap); 537 return LLCP_STATUS_FAIL; 538 } 539 540 if (p_app_cb->p_service_name) GKI_freebuf(p_app_cb->p_service_name); 541 542 /* update WKS bit map */ 543 if (local_sap <= LLCP_UPPER_BOUND_WK_SAP) { 544 llcp_cb.lcb.wks &= ~(1 << local_sap); 545 } 546 547 /* discard any received UI PDU on this SAP */ 548 LLCP_FlushLogicalLinkRxData(local_sap); 549 llcp_cb.total_rx_ui_pdu = 0; 550 551 /* deallocate any data link connection on this SAP */ 552 for (idx = 0; idx < LLCP_MAX_DATA_LINK; idx++) { 553 if ((llcp_cb.dlcb[idx].state != LLCP_DLC_STATE_IDLE) && 554 (llcp_cb.dlcb[idx].local_sap == local_sap)) { 555 llcp_util_deallocate_data_link(&llcp_cb.dlcb[idx]); 556 } 557 } 558 559 p_app_cb->p_app_cback = NULL; 560 561 /* discard any pending tx UI PDU from this SAP */ 562 while (p_app_cb->ui_xmit_q.p_first) { 563 GKI_freebuf(GKI_dequeue(&p_app_cb->ui_xmit_q)); 564 llcp_cb.total_tx_ui_pdu--; 565 } 566 567 if (p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) { 568 llcp_cb.num_logical_data_link--; 569 llcp_util_adjust_ll_congestion(); 570 } 571 572 /* check rx congestion status */ 573 llcp_util_check_rx_congested_status(); 574 575 return LLCP_STATUS_SUCCESS; 576} 577 578/******************************************************************************* 579** 580** Function LLCP_IsLogicalLinkCongested 581** 582** Description Check if logical link is congested 583** 584** 585** Returns TRUE if congested 586** 587*******************************************************************************/ 588bool LLCP_IsLogicalLinkCongested(uint8_t local_sap, uint8_t num_pending_ui_pdu, 589 uint8_t total_pending_ui_pdu, 590 uint8_t total_pending_i_pdu) { 591 tLLCP_APP_CB* p_app_cb; 592 593 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 594 "Local SAP:0x%x, pending = (%d, %d, %d)", local_sap, num_pending_ui_pdu, 595 total_pending_ui_pdu, total_pending_i_pdu); 596 597 p_app_cb = llcp_util_get_app_cb(local_sap); 598 599 if ((llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) || 600 (p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL) || 601 ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0) || 602 (p_app_cb->is_ui_tx_congested)) { 603 return true; 604 } else if ((num_pending_ui_pdu + p_app_cb->ui_xmit_q.count >= 605 llcp_cb.ll_tx_congest_start) || 606 (total_pending_ui_pdu + llcp_cb.total_tx_ui_pdu >= 607 llcp_cb.max_num_ll_tx_buff) || 608 (total_pending_ui_pdu + total_pending_i_pdu + 609 llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= 610 llcp_cb.max_num_tx_buff)) { 611 /* set flag so LLCP can notify uncongested status later */ 612 p_app_cb->is_ui_tx_congested = true; 613 614 return true; 615 } 616 return false; 617} 618 619/******************************************************************************* 620** 621** Function LLCP_SendUI 622** 623** Description Send connnectionless data to DSAP 624** 625** 626** Returns LLCP_STATUS_SUCCESS if success 627** LLCP_STATUS_CONGESTED if logical link is congested 628** LLCP_STATUS_FAIL, otherwise 629** 630*******************************************************************************/ 631tLLCP_STATUS LLCP_SendUI(uint8_t ssap, uint8_t dsap, NFC_HDR* p_buf) { 632 tLLCP_STATUS status = LLCP_STATUS_FAIL; 633 tLLCP_APP_CB* p_app_cb; 634 635 DLOG_IF(INFO, nfc_debug_enabled) 636 << StringPrintf("SSAP=0x%x, DSAP=0x%x", ssap, dsap); 637 638 p_app_cb = llcp_util_get_app_cb(ssap); 639 640 if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL)) { 641 LOG(ERROR) << StringPrintf("SSAP (0x%x) is not registered", ssap); 642 } else if ((p_app_cb->link_type & LLCP_LINK_TYPE_LOGICAL_DATA_LINK) == 0) { 643 LOG(ERROR) << StringPrintf("Logical link on SSAP (0x%x) is not enabled", 644 ssap); 645 } else if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) { 646 LOG(ERROR) << StringPrintf("LLCP link is not activated"); 647 } else if ((llcp_cb.lcb.peer_opt == LLCP_LSC_UNKNOWN) || 648 (llcp_cb.lcb.peer_opt & LLCP_LSC_1)) { 649 if (p_buf->len <= llcp_cb.lcb.peer_miu) { 650 if (p_buf->offset >= LLCP_MIN_OFFSET) { 651 status = llcp_util_send_ui(ssap, dsap, p_app_cb, p_buf); 652 } else { 653 LOG(ERROR) << StringPrintf("offset (%d) must be %d at least", 654 p_buf->offset, LLCP_MIN_OFFSET); 655 } 656 } else { 657 LOG(ERROR) << StringPrintf( 658 "Data length shall not be bigger than peer's link " 659 "MIU"); 660 } 661 } else { 662 LOG(ERROR) << StringPrintf("Peer doesn't support connectionless link"); 663 } 664 665 if (status == LLCP_STATUS_FAIL) { 666 GKI_freebuf(p_buf); 667 } 668 669 return status; 670} 671 672/******************************************************************************* 673** 674** Function LLCP_ReadLogicalLinkData 675** 676** Description Read information of UI PDU for local SAP 677** 678** - Remote SAP who sent UI PDU is returned. 679** - Information of UI PDU up to max_data_len is copied into 680** p_data. 681** - Information of next UI PDU is not concatenated. 682** - Recommended max_data_len is link MIU of local device 683** 684** Returns TRUE if more information of UI PDU or more UI PDU in queue 685** 686*******************************************************************************/ 687bool LLCP_ReadLogicalLinkData(uint8_t local_sap, uint32_t max_data_len, 688 uint8_t* p_remote_sap, uint32_t* p_data_len, 689 uint8_t* p_data) { 690 tLLCP_APP_CB* p_app_cb; 691 NFC_HDR* p_buf; 692 uint8_t* p_ui_pdu; 693 uint16_t pdu_hdr, ui_pdu_length; 694 695 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Local SAP:0x%x", local_sap); 696 697 *p_data_len = 0; 698 699 p_app_cb = llcp_util_get_app_cb(local_sap); 700 701 /* if application is registered */ 702 if ((p_app_cb) && (p_app_cb->p_app_cback)) { 703 /* if any UI PDU in rx queue */ 704 if (p_app_cb->ui_rx_q.p_first) { 705 p_buf = (NFC_HDR*)p_app_cb->ui_rx_q.p_first; 706 p_ui_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset; 707 708 /* get length of UI PDU */ 709 BE_STREAM_TO_UINT16(ui_pdu_length, p_ui_pdu); 710 711 /* get remote SAP from LLCP header */ 712 BE_STREAM_TO_UINT16(pdu_hdr, p_ui_pdu); 713 *p_remote_sap = LLCP_GET_SSAP(pdu_hdr); 714 715 /* layer_specific has the offset to read within UI PDU */ 716 p_ui_pdu += p_buf->layer_specific; 717 718 /* copy data up to max_data_len */ 719 if (max_data_len >= (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE - 720 p_buf->layer_specific)) { 721 /* copy information without LLCP header */ 722 *p_data_len = (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE - 723 p_buf->layer_specific); 724 725 /* move to next UI PDU if any */ 726 p_buf->layer_specific = 727 0; /* reset offset to read from the first byte of next UI PDU */ 728 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length; 729 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length; 730 } else { 731 *p_data_len = max_data_len; 732 733 /* update offset to read from remaining UI PDU next time */ 734 p_buf->layer_specific += max_data_len; 735 } 736 737 memcpy(p_data, p_ui_pdu, *p_data_len); 738 739 /* if read all of UI PDU */ 740 if (p_buf->len == 0) { 741 GKI_dequeue(&p_app_cb->ui_rx_q); 742 GKI_freebuf(p_buf); 743 744 /* decrease number of received UI PDU in in all of ui_rx_q and check rx 745 * congestion status */ 746 llcp_cb.total_rx_ui_pdu--; 747 llcp_util_check_rx_congested_status(); 748 } 749 } 750 751 /* if there is more UI PDU in rx queue */ 752 if (p_app_cb->ui_rx_q.p_first) { 753 return true; 754 } else { 755 return false; 756 } 757 } else { 758 LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", local_sap); 759 760 return false; 761 } 762} 763 764/******************************************************************************* 765** 766** Function LLCP_FlushLogicalLinkRxData 767** 768** Description Discard received data in logical data link of local SAP 769** 770** 771** Returns length of data flushed 772** 773*******************************************************************************/ 774uint32_t LLCP_FlushLogicalLinkRxData(uint8_t local_sap) { 775 NFC_HDR* p_buf; 776 uint32_t flushed_length = 0; 777 tLLCP_APP_CB* p_app_cb; 778 uint8_t* p_ui_pdu; 779 uint16_t ui_pdu_length; 780 781 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Local SAP:0x%x", local_sap); 782 783 p_app_cb = llcp_util_get_app_cb(local_sap); 784 785 /* if application is registered */ 786 if ((p_app_cb) && (p_app_cb->p_app_cback)) { 787 /* if any UI PDU in rx queue */ 788 while (p_app_cb->ui_rx_q.p_first) { 789 p_buf = (NFC_HDR*)p_app_cb->ui_rx_q.p_first; 790 p_ui_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset; 791 792 /* get length of UI PDU */ 793 BE_STREAM_TO_UINT16(ui_pdu_length, p_ui_pdu); 794 795 flushed_length += (uint32_t)(ui_pdu_length - LLCP_PDU_HEADER_SIZE - 796 p_buf->layer_specific); 797 798 /* move to next UI PDU if any */ 799 p_buf->layer_specific = 0; /* offset */ 800 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length; 801 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + ui_pdu_length; 802 803 /* if read all of UI PDU */ 804 if (p_buf->len == 0) { 805 GKI_dequeue(&p_app_cb->ui_rx_q); 806 GKI_freebuf(p_buf); 807 llcp_cb.total_rx_ui_pdu--; 808 } 809 } 810 811 /* number of received UI PDU is decreased so check rx congestion status */ 812 llcp_util_check_rx_congested_status(); 813 } else { 814 LOG(ERROR) << StringPrintf("Unregistered SAP:0x%x", local_sap); 815 } 816 817 return (flushed_length); 818} 819 820/******************************************************************************* 821** 822** Function LLCP_ConnectReq 823** 824** Description Create data link connection between registered SAP and DSAP 825** in peer LLCP, 826** 827** 828** Returns LLCP_STATUS_SUCCESS if success 829** LLCP_STATUS_FAIL, otherwise 830** 831*******************************************************************************/ 832tLLCP_STATUS LLCP_ConnectReq(uint8_t reg_sap, uint8_t dsap, 833 tLLCP_CONNECTION_PARAMS* p_params) { 834 tLLCP_DLCB* p_dlcb; 835 tLLCP_STATUS status; 836 tLLCP_APP_CB* p_app_cb; 837 tLLCP_CONNECTION_PARAMS params; 838 839 DLOG_IF(INFO, nfc_debug_enabled) 840 << StringPrintf("reg_sap=0x%x, DSAP=0x%x", reg_sap, dsap); 841 842 if ((llcp_cb.lcb.peer_opt != LLCP_LSC_UNKNOWN) && 843 ((llcp_cb.lcb.peer_opt & LLCP_LSC_2) == 0)) { 844 LOG(ERROR) << StringPrintf("Peer doesn't support connection-oriented link"); 845 return LLCP_STATUS_FAIL; 846 } 847 848 if (!p_params) { 849 params.miu = LLCP_DEFAULT_MIU; 850 params.rw = LLCP_DEFAULT_RW; 851 params.sn[0] = 0; 852 p_params = ¶ms; 853 } 854 855 p_app_cb = llcp_util_get_app_cb(reg_sap); 856 857 /* if application is registered */ 858 if ((p_app_cb == NULL) || (p_app_cb->p_app_cback == NULL)) { 859 LOG(ERROR) << StringPrintf("SSAP (0x%x) is not registered", reg_sap); 860 return LLCP_STATUS_FAIL; 861 } 862 863 if (dsap == LLCP_SAP_LM) { 864 LOG(ERROR) << StringPrintf("DSAP (0x%x) must not be link manager SAP", 865 dsap); 866 return LLCP_STATUS_FAIL; 867 } 868 869 if (dsap == LLCP_SAP_SDP) { 870 if (strlen(p_params->sn) > LLCP_MAX_SN_LEN) { 871 LOG(ERROR) << StringPrintf("Service Name (%zu bytes) is too long", 872 strlen(p_params->sn)); 873 return LLCP_STATUS_FAIL; 874 } 875 } 876 877 if ((p_params) && (p_params->miu > llcp_cb.lcb.local_link_miu)) { 878 LOG(ERROR) << StringPrintf( 879 "Data link MIU shall not be bigger than local link " 880 "MIU"); 881 return LLCP_STATUS_FAIL; 882 } 883 884 /* check if any pending connection request on this reg_sap */ 885 p_dlcb = llcp_dlc_find_dlcb_by_sap(reg_sap, LLCP_INVALID_SAP); 886 if (p_dlcb) { 887 /* 888 ** Accepting LLCP may change SAP in CC, so we cannot find right data 889 ** link connection if there is multiple pending connection request on 890 ** the same local SAP. 891 */ 892 LOG(ERROR) << StringPrintf( 893 "There is pending connect request on this reg_sap"); 894 return LLCP_STATUS_FAIL; 895 } 896 897 p_dlcb = llcp_util_allocate_data_link(reg_sap, dsap); 898 899 if (p_dlcb) { 900 status = 901 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REQ, p_params); 902 if (status != LLCP_STATUS_SUCCESS) { 903 LOG(ERROR) << StringPrintf("Error in state machine"); 904 llcp_util_deallocate_data_link(p_dlcb); 905 return LLCP_STATUS_FAIL; 906 } 907 } else { 908 return LLCP_STATUS_FAIL; 909 } 910 911 return LLCP_STATUS_SUCCESS; 912} 913 914/******************************************************************************* 915** 916** Function LLCP_ConnectCfm 917** 918** Description Accept connection request from peer LLCP 919** 920** 921** Returns LLCP_STATUS_SUCCESS if success 922** LLCP_STATUS_FAIL, otherwise 923** 924*******************************************************************************/ 925tLLCP_STATUS LLCP_ConnectCfm(uint8_t local_sap, uint8_t remote_sap, 926 tLLCP_CONNECTION_PARAMS* p_params) { 927 tLLCP_STATUS status; 928 tLLCP_DLCB* p_dlcb; 929 tLLCP_CONNECTION_PARAMS params; 930 931 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 932 "Local SAP:0x%x, Remote SAP:0x%x)", local_sap, remote_sap); 933 934 if (!p_params) { 935 params.miu = LLCP_DEFAULT_MIU; 936 params.rw = LLCP_DEFAULT_RW; 937 params.sn[0] = 0; 938 p_params = ¶ms; 939 } 940 if (p_params->miu > llcp_cb.lcb.local_link_miu) { 941 LOG(ERROR) << StringPrintf( 942 "Data link MIU shall not be bigger than local link " 943 "MIU"); 944 return LLCP_STATUS_FAIL; 945 } 946 947 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 948 949 if (p_dlcb) { 950 status = 951 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_CFM, p_params); 952 } else { 953 LOG(ERROR) << StringPrintf("No data link"); 954 status = LLCP_STATUS_FAIL; 955 } 956 957 return status; 958} 959 960/******************************************************************************* 961** 962** Function LLCP_ConnectReject 963** 964** Description Reject connection request from peer LLCP 965** 966** reason : LLCP_SAP_DM_REASON_APP_REJECTED 967** LLCP_SAP_DM_REASON_PERM_REJECT_THIS 968** LLCP_SAP_DM_REASON_PERM_REJECT_ANY 969** LLCP_SAP_DM_REASON_TEMP_REJECT_THIS 970** LLCP_SAP_DM_REASON_TEMP_REJECT_ANY 971** 972** Returns LLCP_STATUS_SUCCESS if success 973** LLCP_STATUS_FAIL, otherwise 974** 975*******************************************************************************/ 976tLLCP_STATUS LLCP_ConnectReject(uint8_t local_sap, uint8_t remote_sap, 977 uint8_t reason) { 978 tLLCP_STATUS status; 979 tLLCP_DLCB* p_dlcb; 980 981 DLOG_IF(INFO, nfc_debug_enabled) 982 << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x, reason:0x%x", local_sap, 983 remote_sap, reason); 984 985 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 986 987 if (p_dlcb) { 988 status = 989 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_CONNECT_REJECT, &reason); 990 llcp_util_deallocate_data_link(p_dlcb); 991 } else { 992 LOG(ERROR) << StringPrintf("No data link"); 993 status = LLCP_STATUS_FAIL; 994 } 995 996 return status; 997} 998 999/******************************************************************************* 1000** 1001** Function LLCP_IsDataLinkCongested 1002** 1003** Description Check if data link connection is congested 1004** 1005** 1006** Returns TRUE if congested 1007** 1008*******************************************************************************/ 1009bool LLCP_IsDataLinkCongested(uint8_t local_sap, uint8_t remote_sap, 1010 uint8_t num_pending_i_pdu, 1011 uint8_t total_pending_ui_pdu, 1012 uint8_t total_pending_i_pdu) { 1013 tLLCP_DLCB* p_dlcb; 1014 1015 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 1016 "Local SAP:0x%x, Remote SAP:0x%x, pending = " 1017 "(%d, %d, %d)", 1018 local_sap, remote_sap, num_pending_i_pdu, total_pending_ui_pdu, 1019 total_pending_i_pdu); 1020 1021 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1022 1023 if (p_dlcb) { 1024 if ((p_dlcb->is_tx_congested) || (p_dlcb->remote_busy)) { 1025 return true; 1026 } else if ((num_pending_i_pdu + p_dlcb->i_xmit_q.count >= 1027 p_dlcb->remote_rw) || 1028 (total_pending_ui_pdu + total_pending_i_pdu + 1029 llcp_cb.total_tx_ui_pdu + llcp_cb.total_tx_i_pdu >= 1030 llcp_cb.max_num_tx_buff)) { 1031 /* set flag so LLCP can notify uncongested status later */ 1032 p_dlcb->is_tx_congested = true; 1033 return true; 1034 } 1035 return false; 1036 } 1037 return true; 1038} 1039 1040/******************************************************************************* 1041** 1042** Function LLCP_SendData 1043** 1044** Description Send connection-oriented data 1045** 1046** 1047** Returns LLCP_STATUS_SUCCESS if success 1048** LLCP_STATUS_CONGESTED if data link is congested 1049** 1050*******************************************************************************/ 1051tLLCP_STATUS LLCP_SendData(uint8_t local_sap, uint8_t remote_sap, 1052 NFC_HDR* p_buf) { 1053 tLLCP_STATUS status = LLCP_STATUS_FAIL; 1054 tLLCP_DLCB* p_dlcb; 1055 1056 DLOG_IF(INFO, nfc_debug_enabled) 1057 << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap); 1058 1059 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1060 1061 if (p_dlcb) { 1062 if (p_dlcb->remote_miu >= p_buf->len) { 1063 if (p_buf->offset >= LLCP_MIN_OFFSET) { 1064 status = llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DATA_REQ, p_buf); 1065 } else { 1066 LOG(ERROR) << StringPrintf("offset (%d) must be %d at least", 1067 p_buf->offset, LLCP_MIN_OFFSET); 1068 } 1069 } else { 1070 LOG(ERROR) << StringPrintf( 1071 "Information (%d bytes) cannot be more than peer " 1072 "MIU (%d bytes)", 1073 p_buf->len, p_dlcb->remote_miu); 1074 } 1075 } else { 1076 LOG(ERROR) << StringPrintf("No data link"); 1077 } 1078 1079 if (status == LLCP_STATUS_FAIL) { 1080 GKI_freebuf(p_buf); 1081 } 1082 1083 return status; 1084} 1085 1086/******************************************************************************* 1087** 1088** Function LLCP_ReadDataLinkData 1089** 1090** Description Read information of I PDU for data link connection 1091** 1092** - Information of I PDU up to max_data_len is copied into 1093** p_data. 1094** - Information of next I PDU is not concatenated. 1095** - Recommended max_data_len is data link connection MIU of 1096** local end point 1097** 1098** Returns TRUE if more data in queue 1099** 1100*******************************************************************************/ 1101bool LLCP_ReadDataLinkData(uint8_t local_sap, uint8_t remote_sap, 1102 uint32_t max_data_len, uint32_t* p_data_len, 1103 uint8_t* p_data) { 1104 tLLCP_DLCB* p_dlcb; 1105 NFC_HDR* p_buf; 1106 uint8_t* p_i_pdu; 1107 uint16_t i_pdu_length; 1108 1109 DLOG_IF(INFO, nfc_debug_enabled) 1110 << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap); 1111 1112 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1113 1114 *p_data_len = 0; 1115 if (p_dlcb) { 1116 /* if any I PDU in rx queue */ 1117 if (p_dlcb->i_rx_q.p_first) { 1118 p_buf = (NFC_HDR*)p_dlcb->i_rx_q.p_first; 1119 p_i_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset; 1120 1121 /* get length of I PDU */ 1122 BE_STREAM_TO_UINT16(i_pdu_length, p_i_pdu); 1123 1124 /* layer_specific has the offset to read within I PDU */ 1125 p_i_pdu += p_buf->layer_specific; 1126 1127 /* copy data up to max_data_len */ 1128 if (max_data_len >= (uint32_t)(i_pdu_length - p_buf->layer_specific)) { 1129 /* copy information */ 1130 *p_data_len = (uint32_t)(i_pdu_length - p_buf->layer_specific); 1131 1132 /* move to next I PDU if any */ 1133 p_buf->layer_specific = 1134 0; /* reset offset to read from the first byte of next I PDU */ 1135 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length; 1136 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length; 1137 } else { 1138 *p_data_len = max_data_len; 1139 1140 /* update offset to read from remaining I PDU next time */ 1141 p_buf->layer_specific += max_data_len; 1142 } 1143 1144 memcpy(p_data, p_i_pdu, *p_data_len); 1145 1146 if (p_buf->layer_specific == 0) { 1147 p_dlcb->num_rx_i_pdu--; 1148 } 1149 1150 /* if read all of I PDU */ 1151 if (p_buf->len == 0) { 1152 GKI_dequeue(&p_dlcb->i_rx_q); 1153 GKI_freebuf(p_buf); 1154 1155 /* decrease number of received I PDU in in all of ui_rx_q and check rx 1156 * congestion status */ 1157 llcp_cb.total_rx_i_pdu--; 1158 llcp_util_check_rx_congested_status(); 1159 } 1160 } 1161 1162 /* if getting out of rx congestion */ 1163 if ((!p_dlcb->local_busy) && (p_dlcb->is_rx_congested) && 1164 (p_dlcb->num_rx_i_pdu <= p_dlcb->rx_congest_threshold / 2)) { 1165 /* send RR */ 1166 p_dlcb->is_rx_congested = false; 1167 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR; 1168 } 1169 1170 /* if there is more I PDU in rx queue */ 1171 if (p_dlcb->i_rx_q.p_first) { 1172 return true; 1173 } else { 1174 return false; 1175 } 1176 } else { 1177 LOG(ERROR) << StringPrintf("No data link connection"); 1178 1179 return false; 1180 } 1181} 1182 1183/******************************************************************************* 1184** 1185** Function LLCP_FlushDataLinkRxData 1186** 1187** Description Discard received data in data link connection 1188** 1189** 1190** Returns length of rx data flushed 1191** 1192*******************************************************************************/ 1193uint32_t LLCP_FlushDataLinkRxData(uint8_t local_sap, uint8_t remote_sap) { 1194 tLLCP_DLCB* p_dlcb; 1195 NFC_HDR* p_buf; 1196 uint32_t flushed_length = 0; 1197 uint8_t* p_i_pdu; 1198 uint16_t i_pdu_length; 1199 1200 DLOG_IF(INFO, nfc_debug_enabled) 1201 << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap); 1202 1203 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1204 1205 if (p_dlcb) { 1206 /* if any I PDU in rx queue */ 1207 while (p_dlcb->i_rx_q.p_first) { 1208 p_buf = (NFC_HDR*)p_dlcb->i_rx_q.p_first; 1209 p_i_pdu = (uint8_t*)(p_buf + 1) + p_buf->offset; 1210 1211 /* get length of I PDU */ 1212 BE_STREAM_TO_UINT16(i_pdu_length, p_i_pdu); 1213 1214 flushed_length += (uint32_t)(i_pdu_length - p_buf->layer_specific); 1215 1216 /* move to next I PDU if any */ 1217 p_buf->layer_specific = 0; /* offset */ 1218 p_buf->offset += LLCP_PDU_AGF_LEN_SIZE + i_pdu_length; 1219 p_buf->len -= LLCP_PDU_AGF_LEN_SIZE + i_pdu_length; 1220 1221 /* if read all of I PDU */ 1222 if (p_buf->len == 0) { 1223 GKI_dequeue(&p_dlcb->i_rx_q); 1224 GKI_freebuf(p_buf); 1225 llcp_cb.total_rx_i_pdu--; 1226 } 1227 } 1228 1229 p_dlcb->num_rx_i_pdu = 0; 1230 1231 /* if getting out of rx congestion */ 1232 if ((!p_dlcb->local_busy) && (p_dlcb->is_rx_congested)) { 1233 /* send RR */ 1234 p_dlcb->is_rx_congested = false; 1235 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR; 1236 } 1237 1238 /* number of received I PDU is decreased so check rx congestion status */ 1239 llcp_util_check_rx_congested_status(); 1240 } else { 1241 LOG(ERROR) << StringPrintf("No data link connection"); 1242 } 1243 1244 return (flushed_length); 1245} 1246 1247/******************************************************************************* 1248** 1249** Function LLCP_DisconnectReq 1250** 1251** Description Disconnect data link 1252** discard any pending data if flush is set to TRUE 1253** 1254** Returns LLCP_STATUS_SUCCESS if success 1255** 1256*******************************************************************************/ 1257tLLCP_STATUS LLCP_DisconnectReq(uint8_t local_sap, uint8_t remote_sap, 1258 bool flush) { 1259 tLLCP_STATUS status; 1260 tLLCP_DLCB* p_dlcb; 1261 1262 DLOG_IF(INFO, nfc_debug_enabled) 1263 << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x, flush=%d", local_sap, 1264 remote_sap, flush); 1265 1266 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1267 1268 if (p_dlcb) { 1269 status = 1270 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_API_DISCONNECT_REQ, &flush); 1271 } else { 1272 LOG(ERROR) << StringPrintf("No data link"); 1273 status = LLCP_STATUS_FAIL; 1274 } 1275 1276 return status; 1277} 1278 1279/******************************************************************************* 1280** 1281** Function LLCP_SetTxCompleteNtf 1282** 1283** Description This function is called to get LLCP_SERVICE_TX_COMPLETE 1284** when Tx queue is empty and all PDU is acked. 1285** This is one time event, so upper layer shall call this 1286** function again to get next LLCP_SERVICE_TX_COMPLETE. 1287** 1288** Returns LLCP_STATUS_SUCCESS if success 1289** 1290*******************************************************************************/ 1291tLLCP_STATUS LLCP_SetTxCompleteNtf(uint8_t local_sap, uint8_t remote_sap) { 1292 tLLCP_STATUS status; 1293 tLLCP_DLCB* p_dlcb; 1294 1295 DLOG_IF(INFO, nfc_debug_enabled) 1296 << StringPrintf("Local SAP:0x%x, Remote SAP:0x%x", local_sap, remote_sap); 1297 1298 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1299 1300 if (p_dlcb) { 1301 /* set flag to notify upper later when tx complete */ 1302 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_NOTIFY_TX_DONE; 1303 status = LLCP_STATUS_SUCCESS; 1304 } else { 1305 LOG(ERROR) << StringPrintf("No data link"); 1306 status = LLCP_STATUS_FAIL; 1307 } 1308 1309 return status; 1310} 1311 1312/******************************************************************************* 1313** 1314** Function LLCP_SetLocalBusyStatus 1315** 1316** Description Set local busy status 1317** 1318** 1319** Returns LLCP_STATUS_SUCCESS if success 1320** 1321*******************************************************************************/ 1322tLLCP_STATUS LLCP_SetLocalBusyStatus(uint8_t local_sap, uint8_t remote_sap, 1323 bool is_busy) { 1324 tLLCP_STATUS status; 1325 tLLCP_DLCB* p_dlcb; 1326 1327 DLOG_IF(INFO, nfc_debug_enabled) 1328 << StringPrintf("Local SAP:0x%x, is_busy=%d", local_sap, is_busy); 1329 1330 p_dlcb = llcp_dlc_find_dlcb_by_sap(local_sap, remote_sap); 1331 1332 if (p_dlcb) { 1333 if (p_dlcb->local_busy != is_busy) { 1334 p_dlcb->local_busy = is_busy; 1335 1336 /* send RR or RNR with valid sequence */ 1337 p_dlcb->flags |= LLCP_DATA_LINK_FLAG_PENDING_RR_RNR; 1338 1339 if (is_busy == false) { 1340 if (p_dlcb->i_rx_q.count) { 1341 llcp_dlsm_execute(p_dlcb, LLCP_DLC_EVENT_PEER_DATA_IND, NULL); 1342 } 1343 } 1344 } 1345 status = LLCP_STATUS_SUCCESS; 1346 } else { 1347 LOG(ERROR) << StringPrintf("No data link"); 1348 status = LLCP_STATUS_FAIL; 1349 } 1350 1351 return status; 1352} 1353 1354/******************************************************************************* 1355** 1356** Function LLCP_GetRemoteWKS 1357** 1358** Description Return well-known service bitmap of connected device 1359** 1360** 1361** Returns WKS bitmap if success 1362** 1363*******************************************************************************/ 1364uint16_t LLCP_GetRemoteWKS(void) { 1365 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 1366 "WKS:0x%04x", (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 1367 ? llcp_cb.lcb.peer_wks 1368 : 0); 1369 1370 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 1371 return (llcp_cb.lcb.peer_wks); 1372 else 1373 return (0); 1374} 1375 1376/******************************************************************************* 1377** 1378** Function LLCP_GetRemoteLSC 1379** 1380** Description Return link service class of connected device 1381** 1382** 1383** Returns link service class 1384** 1385*******************************************************************************/ 1386uint8_t LLCP_GetRemoteLSC(void) { 1387 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 1388 "LSC:0x%x", (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 1389 ? llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2) 1390 : 0); 1391 1392 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 1393 return (llcp_cb.lcb.peer_opt & (LLCP_LSC_1 | LLCP_LSC_2)); 1394 else 1395 return (LLCP_LSC_UNKNOWN); 1396} 1397 1398/******************************************************************************* 1399** 1400** Function LLCP_GetRemoteVersion 1401** 1402** Description Return LLCP version of connected device 1403** 1404** 1405** Returns LLCP version 1406** 1407*******************************************************************************/ 1408uint8_t LLCP_GetRemoteVersion(void) { 1409 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 1410 "Version: 0x%x", (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 1411 ? llcp_cb.lcb.peer_version 1412 : 0); 1413 1414 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) 1415 return (llcp_cb.lcb.peer_version); 1416 else 1417 return 0; 1418} 1419 1420/******************************************************************************* 1421** 1422** Function LLCP_GetLinkMIU 1423** 1424** Description Return local and remote link MIU 1425** 1426** 1427** Returns None 1428** 1429*******************************************************************************/ 1430void LLCP_GetLinkMIU(uint16_t* p_local_link_miu, uint16_t* p_remote_link_miu) { 1431 DLOG_IF(INFO, nfc_debug_enabled) << __func__; 1432 1433 if (llcp_cb.lcb.link_state == LLCP_LINK_STATE_ACTIVATED) { 1434 *p_local_link_miu = llcp_cb.lcb.local_link_miu; 1435 *p_remote_link_miu = llcp_cb.lcb.effective_miu; 1436 } else { 1437 *p_local_link_miu = 0; 1438 *p_remote_link_miu = 0; 1439 } 1440 1441 DLOG_IF(INFO, nfc_debug_enabled) 1442 << StringPrintf("local_link_miu = %d, remote_link_miu = %d", 1443 *p_local_link_miu, *p_remote_link_miu); 1444} 1445 1446/******************************************************************************* 1447** 1448** Function LLCP_DiscoverService 1449** 1450** Description Return SAP of service name in connected device through 1451** callback 1452** 1453** 1454** Returns LLCP_STATUS_SUCCESS if success 1455** 1456*******************************************************************************/ 1457tLLCP_STATUS LLCP_DiscoverService(char* p_name, tLLCP_SDP_CBACK* p_cback, 1458 uint8_t* p_tid) { 1459 tLLCP_STATUS status; 1460 uint8_t i; 1461 1462 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("Service Name:%s", p_name); 1463 1464 if (llcp_cb.lcb.link_state != LLCP_LINK_STATE_ACTIVATED) { 1465 LOG(ERROR) << StringPrintf("Link is not activated"); 1466 return LLCP_STATUS_FAIL; 1467 } 1468 1469 if (!p_cback) { 1470 LOG(ERROR) << StringPrintf("Callback must be provided."); 1471 return LLCP_STATUS_FAIL; 1472 } 1473 1474 /* if peer version is less than V1.1 then SNL is not supported */ 1475 if ((llcp_cb.lcb.agreed_major_version == 0x01) && 1476 (llcp_cb.lcb.agreed_minor_version < 0x01)) { 1477 LOG(ERROR) << StringPrintf("Peer doesn't support SNL"); 1478 return LLCP_STATUS_FAIL; 1479 } 1480 1481 for (i = 0; i < LLCP_MAX_SDP_TRANSAC; i++) { 1482 if (!llcp_cb.sdp_cb.transac[i].p_cback) { 1483 llcp_cb.sdp_cb.transac[i].tid = llcp_cb.sdp_cb.next_tid; 1484 llcp_cb.sdp_cb.next_tid++; 1485 llcp_cb.sdp_cb.transac[i].p_cback = p_cback; 1486 1487 status = llcp_sdp_send_sdreq(llcp_cb.sdp_cb.transac[i].tid, p_name); 1488 1489 if (status == LLCP_STATUS_FAIL) { 1490 llcp_cb.sdp_cb.transac[i].p_cback = NULL; 1491 } 1492 1493 *p_tid = llcp_cb.sdp_cb.transac[i].tid; 1494 return (status); 1495 } 1496 } 1497 1498 LOG(ERROR) << StringPrintf("Out of resource"); 1499 1500 return LLCP_STATUS_FAIL; 1501} 1502