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