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