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