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