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