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