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