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 * NFA interface to LLCP 22 * 23 ******************************************************************************/ 24 #include <android-base/stringprintf.h> 25 #include <base/logging.h> 26 27 #include "nfa_p2p_api.h" 28 #include "nfa_p2p_int.h" 29 30 using android::base::StringPrintf; 31 32 extern bool nfc_debug_enabled; 33 34 /***************************************************************************** 35 ** Constants 36 *****************************************************************************/ 37 38 /******************************************************************************* 39 ** 40 ** Function NFA_P2pRegisterServer 41 ** 42 ** Description This function is called to listen to a SAP as server on 43 ** LLCP. 44 ** 45 ** NFA_P2P_REG_SERVER_EVT will be returned with status and 46 ** handle. 47 ** 48 ** If server_sap is set to NFA_P2P_ANY_SAP, then NFA will 49 ** allocate a SAP between LLCP_LOWER_BOUND_SDP_SAP and 50 ** LLCP_UPPER_BOUND_SDP_SAP Otherwise, server_sap must be 51 ** between (LLCP_SDP_SAP + 1) and LLCP_UPPER_BOUND_SDP_SAP 52 ** 53 ** link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE 54 ** 55 ** Note: If RF discovery is started, 56 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 57 ** happen before calling this function 58 ** 59 ** Returns NFA_STATUS_OK if successfully initiated 60 ** NFA_STATUS_FAILED otherwise 61 ** 62 *******************************************************************************/ 63 tNFA_STATUS NFA_P2pRegisterServer(uint8_t server_sap, 64 tNFA_P2P_LINK_TYPE link_type, 65 char* p_service_name, 66 tNFA_P2P_CBACK* p_cback) { 67 tNFA_P2P_API_REG_SERVER* p_msg; 68 69 DLOG_IF(INFO, nfc_debug_enabled) 70 << StringPrintf("server_sap:0x%02x, link_type:0x%x, SN:<%s>", server_sap, 71 link_type, p_service_name); 72 73 if ((server_sap != NFA_P2P_ANY_SAP) && 74 ((server_sap <= LLCP_SAP_SDP) || 75 (server_sap > LLCP_UPPER_BOUND_SDP_SAP))) { 76 LOG(ERROR) << StringPrintf("server_sap must be between %d and %d", 77 LLCP_SAP_SDP + 1, LLCP_UPPER_BOUND_SDP_SAP); 78 return (NFA_STATUS_FAILED); 79 } else if (((link_type & NFA_P2P_LLINK_TYPE) == 0x00) && 80 ((link_type & NFA_P2P_DLINK_TYPE) == 0x00)) { 81 LOG(ERROR) << StringPrintf("link type (0x%x) must be specified", link_type); 82 return (NFA_STATUS_FAILED); 83 } 84 85 if ((p_msg = (tNFA_P2P_API_REG_SERVER*)GKI_getbuf( 86 sizeof(tNFA_P2P_API_REG_SERVER))) != NULL) { 87 p_msg->hdr.event = NFA_P2P_API_REG_SERVER_EVT; 88 89 p_msg->server_sap = server_sap; 90 p_msg->link_type = link_type; 91 92 strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN); 93 p_msg->service_name[LLCP_MAX_SN_LEN] = 0; 94 95 p_msg->p_cback = p_cback; 96 97 nfa_sys_sendmsg(p_msg); 98 99 return (NFA_STATUS_OK); 100 } 101 102 return (NFA_STATUS_FAILED); 103 } 104 105 /******************************************************************************* 106 ** 107 ** Function NFA_P2pRegisterClient 108 ** 109 ** Description This function is called to register a client service on 110 ** LLCP. 111 ** 112 ** NFA_P2P_REG_CLIENT_EVT will be returned with status and 113 ** handle. 114 ** 115 ** link_type : NFA_P2P_LLINK_TYPE and/or NFA_P2P_DLINK_TYPE 116 ** 117 ** Returns NFA_STATUS_OK if successfully initiated 118 ** NFA_STATUS_FAILED otherwise 119 ** 120 *******************************************************************************/ 121 tNFA_STATUS NFA_P2pRegisterClient(tNFA_P2P_LINK_TYPE link_type, 122 tNFA_P2P_CBACK* p_cback) { 123 tNFA_P2P_API_REG_CLIENT* p_msg; 124 125 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("link_type:0x%x", link_type); 126 127 if (((link_type & NFA_P2P_LLINK_TYPE) == 0x00) && 128 ((link_type & NFA_P2P_DLINK_TYPE) == 0x00)) { 129 LOG(ERROR) << StringPrintf("link type (0x%x) must be specified", link_type); 130 return (NFA_STATUS_FAILED); 131 } 132 133 if ((p_msg = (tNFA_P2P_API_REG_CLIENT*)GKI_getbuf( 134 sizeof(tNFA_P2P_API_REG_CLIENT))) != NULL) { 135 p_msg->hdr.event = NFA_P2P_API_REG_CLIENT_EVT; 136 137 p_msg->p_cback = p_cback; 138 p_msg->link_type = link_type; 139 140 nfa_sys_sendmsg(p_msg); 141 142 return (NFA_STATUS_OK); 143 } 144 145 return (NFA_STATUS_FAILED); 146 } 147 148 /******************************************************************************* 149 ** 150 ** Function NFA_P2pDeregister 151 ** 152 ** Description This function is called to stop listening to a SAP as server 153 ** or stop client service on LLCP. 154 ** 155 ** Note: If this function is called to de-register a server and RF 156 ** discovery is started, 157 ** NFA_StopRfDiscovery()/NFA_RF_DISCOVERY_STOPPED_EVT should 158 ** happen before calling this function 159 ** 160 ** Returns NFA_STATUS_OK if successfully initiated 161 ** NFA_STATUS_BAD_HANDLE if handle is not valid 162 ** NFA_STATUS_FAILED otherwise 163 ** 164 *******************************************************************************/ 165 tNFA_STATUS NFA_P2pDeregister(tNFA_HANDLE handle) { 166 tNFA_P2P_API_DEREG* p_msg; 167 tNFA_HANDLE xx; 168 169 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%02X", handle); 170 171 xx = handle & NFA_HANDLE_MASK; 172 173 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 174 LOG(ERROR) << StringPrintf("Handle is invalid or not registered"); 175 return (NFA_STATUS_BAD_HANDLE); 176 } 177 178 if ((p_msg = (tNFA_P2P_API_DEREG*)GKI_getbuf(sizeof(tNFA_P2P_API_DEREG))) != 179 NULL) { 180 p_msg->hdr.event = NFA_P2P_API_DEREG_EVT; 181 182 p_msg->handle = handle; 183 184 nfa_sys_sendmsg(p_msg); 185 186 return (NFA_STATUS_OK); 187 } 188 189 return (NFA_STATUS_FAILED); 190 } 191 192 /******************************************************************************* 193 ** 194 ** Function NFA_P2pAcceptConn 195 ** 196 ** Description This function is called to accept a request of data link 197 ** connection to a listening SAP on LLCP after receiving 198 ** NFA_P2P_CONN_REQ_EVT. 199 ** 200 ** Returns NFA_STATUS_OK if successfully initiated 201 ** NFA_STATUS_BAD_HANDLE if handle is not valid 202 ** NFA_STATUS_FAILED otherwise 203 ** 204 *******************************************************************************/ 205 tNFA_STATUS NFA_P2pAcceptConn(tNFA_HANDLE handle, uint16_t miu, uint8_t rw) { 206 tNFA_P2P_API_ACCEPT_CONN* p_msg; 207 tNFA_HANDLE xx; 208 209 DLOG_IF(INFO, nfc_debug_enabled) 210 << StringPrintf("handle:0x%02X, MIU:%d, RW:%d", handle, miu, rw); 211 212 xx = handle & NFA_HANDLE_MASK; 213 214 if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) { 215 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 216 return (NFA_STATUS_BAD_HANDLE); 217 } else { 218 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 219 } 220 221 if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 222 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 223 return (NFA_STATUS_BAD_HANDLE); 224 } 225 226 if ((miu < LLCP_DEFAULT_MIU) || (nfa_p2p_cb.local_link_miu < miu)) { 227 LOG(ERROR) << StringPrintf("MIU(%d) must be between %d and %d", miu, 228 LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu); 229 } else if ((p_msg = (tNFA_P2P_API_ACCEPT_CONN*)GKI_getbuf( 230 sizeof(tNFA_P2P_API_ACCEPT_CONN))) != NULL) { 231 p_msg->hdr.event = NFA_P2P_API_ACCEPT_CONN_EVT; 232 233 p_msg->conn_handle = handle; 234 p_msg->miu = miu; 235 p_msg->rw = rw; 236 237 nfa_sys_sendmsg(p_msg); 238 239 return (NFA_STATUS_OK); 240 } 241 242 return (NFA_STATUS_FAILED); 243 } 244 245 /******************************************************************************* 246 ** 247 ** Function NFA_P2pRejectConn 248 ** 249 ** Description This function is called to reject a request of data link 250 ** connection to a listening SAP on LLCP after receiving 251 ** NFA_P2P_CONN_REQ_EVT. 252 ** 253 ** Returns NFA_STATUS_OK if successfully initiated 254 ** NFA_STATUS_BAD_HANDLE if handle is not valid 255 ** NFA_STATUS_FAILED otherwise 256 ** 257 *******************************************************************************/ 258 tNFA_STATUS NFA_P2pRejectConn(tNFA_HANDLE handle) { 259 tNFA_P2P_API_REJECT_CONN* p_msg; 260 tNFA_HANDLE xx; 261 262 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%02X", handle); 263 264 xx = handle & NFA_HANDLE_MASK; 265 266 if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) { 267 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 268 return (NFA_STATUS_BAD_HANDLE); 269 } else { 270 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 271 } 272 273 if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 274 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 275 return (NFA_STATUS_BAD_HANDLE); 276 } 277 278 if ((p_msg = (tNFA_P2P_API_REJECT_CONN*)GKI_getbuf( 279 sizeof(tNFA_P2P_API_REJECT_CONN))) != NULL) { 280 p_msg->hdr.event = NFA_P2P_API_REJECT_CONN_EVT; 281 282 p_msg->conn_handle = handle; 283 284 nfa_sys_sendmsg(p_msg); 285 286 return (NFA_STATUS_OK); 287 } 288 289 return (NFA_STATUS_FAILED); 290 } 291 292 /******************************************************************************* 293 ** 294 ** Function NFA_P2pDisconnect 295 ** 296 ** Description This function is called to disconnect an existing or 297 ** connecting data link connection. 298 ** 299 ** discard any pending data on data link connection if flush is 300 ** set to TRUE 301 ** 302 ** NFA_P2P_DISC_EVT will be returned after data link connection 303 ** is disconnected 304 ** 305 ** Returns NFA_STATUS_OK if successfully initiated 306 ** NFA_STATUS_BAD_HANDLE if handle is not valid 307 ** NFA_STATUS_FAILED otherwise 308 ** 309 *******************************************************************************/ 310 tNFA_STATUS NFA_P2pDisconnect(tNFA_HANDLE handle, bool flush) { 311 tNFA_P2P_API_DISCONNECT* p_msg; 312 tNFA_HANDLE xx; 313 314 DLOG_IF(INFO, nfc_debug_enabled) 315 << StringPrintf("handle:0x%02X, flush=%d", handle, flush); 316 317 xx = handle & NFA_HANDLE_MASK; 318 319 if (xx & NFA_P2P_HANDLE_FLAG_CONN) { 320 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 321 322 if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 323 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 324 return (NFA_STATUS_BAD_HANDLE); 325 } 326 } else { 327 LOG(ERROR) << StringPrintf("Handle is not valid"); 328 return (NFA_STATUS_BAD_HANDLE); 329 } 330 331 if ((p_msg = (tNFA_P2P_API_DISCONNECT*)GKI_getbuf( 332 sizeof(tNFA_P2P_API_DISCONNECT))) != NULL) { 333 p_msg->hdr.event = NFA_P2P_API_DISCONNECT_EVT; 334 335 p_msg->conn_handle = handle; 336 p_msg->flush = flush; 337 338 nfa_sys_sendmsg(p_msg); 339 340 return (NFA_STATUS_OK); 341 } 342 343 return (NFA_STATUS_FAILED); 344 } 345 346 /******************************************************************************* 347 ** 348 ** Function NFA_P2pConnectByName 349 ** 350 ** Description This function is called to create a connection-oriented 351 ** transport by a service name. 352 ** NFA_P2P_CONNECTED_EVT if success 353 ** NFA_P2P_DISC_EVT if failed 354 ** 355 ** Returns NFA_STATUS_OK if successfully initiated 356 ** NFA_STATUS_BAD_HANDLE if client is not registered 357 ** NFA_STATUS_FAILED otherwise 358 ** 359 *******************************************************************************/ 360 tNFA_STATUS NFA_P2pConnectByName(tNFA_HANDLE client_handle, 361 char* p_service_name, uint16_t miu, 362 uint8_t rw) { 363 tNFA_P2P_API_CONNECT* p_msg; 364 tNFA_HANDLE xx; 365 366 DLOG_IF(INFO, nfc_debug_enabled) 367 << StringPrintf("client_handle:0x%x, SN:<%s>, MIU:%d, RW:%d", 368 client_handle, p_service_name, miu, rw); 369 370 xx = client_handle & NFA_HANDLE_MASK; 371 372 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 373 LOG(ERROR) << StringPrintf("Client Handle is not valid"); 374 return (NFA_STATUS_BAD_HANDLE); 375 } 376 377 if ((miu < LLCP_DEFAULT_MIU) || 378 (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) || 379 (nfa_p2p_cb.local_link_miu < miu)) { 380 LOG(ERROR) << StringPrintf( 381 "MIU(%d) must be between %d and %d or LLCP " 382 "link is not activated", 383 miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu); 384 } else if ((p_msg = (tNFA_P2P_API_CONNECT*)GKI_getbuf( 385 sizeof(tNFA_P2P_API_CONNECT))) != NULL) { 386 p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT; 387 388 strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN); 389 p_msg->service_name[LLCP_MAX_SN_LEN] = 0; 390 391 p_msg->dsap = LLCP_INVALID_SAP; 392 p_msg->miu = miu; 393 p_msg->rw = rw; 394 p_msg->client_handle = client_handle; 395 396 nfa_sys_sendmsg(p_msg); 397 398 return (NFA_STATUS_OK); 399 } 400 401 return (NFA_STATUS_FAILED); 402 } 403 404 /******************************************************************************* 405 ** 406 ** Function NFA_P2pConnectBySap 407 ** 408 ** Description This function is called to create a connection-oriented 409 ** transport by a SAP. 410 ** NFA_P2P_CONNECTED_EVT if success 411 ** NFA_P2P_DISC_EVT if failed 412 ** 413 ** Returns NFA_STATUS_OK if successfully initiated 414 ** NFA_STATUS_BAD_HANDLE if client is not registered 415 ** NFA_STATUS_FAILED otherwise 416 ** 417 *******************************************************************************/ 418 tNFA_STATUS NFA_P2pConnectBySap(tNFA_HANDLE client_handle, uint8_t dsap, 419 uint16_t miu, uint8_t rw) { 420 tNFA_P2P_API_CONNECT* p_msg; 421 tNFA_HANDLE xx; 422 423 DLOG_IF(INFO, nfc_debug_enabled) 424 << StringPrintf("client_handle:0x%x, DSAP:0x%02X, MIU:%d, RW:%d", 425 client_handle, dsap, miu, rw); 426 427 xx = client_handle & NFA_HANDLE_MASK; 428 429 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 430 LOG(ERROR) << StringPrintf("Client Handle is not valid"); 431 return (NFA_STATUS_BAD_HANDLE); 432 } 433 434 if ((miu < LLCP_DEFAULT_MIU) || 435 (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) || 436 (nfa_p2p_cb.local_link_miu < miu)) { 437 LOG(ERROR) << StringPrintf( 438 "MIU(%d) must be between %d and %d, or LLCP " 439 "link is not activated", 440 miu, LLCP_DEFAULT_MIU, nfa_p2p_cb.local_link_miu); 441 } else if ((p_msg = (tNFA_P2P_API_CONNECT*)GKI_getbuf( 442 sizeof(tNFA_P2P_API_CONNECT))) != NULL) { 443 p_msg->hdr.event = NFA_P2P_API_CONNECT_EVT; 444 445 p_msg->service_name[LLCP_MAX_SN_LEN] = 0; 446 447 p_msg->dsap = dsap; 448 p_msg->miu = miu; 449 p_msg->rw = rw; 450 p_msg->client_handle = client_handle; 451 452 nfa_sys_sendmsg(p_msg); 453 454 return (NFA_STATUS_OK); 455 } 456 457 return (NFA_STATUS_FAILED); 458 } 459 460 /******************************************************************************* 461 ** 462 ** Function NFA_P2pSendUI 463 ** 464 ** Description This function is called to send data on connectionless 465 ** transport. 466 ** 467 ** Returns NFA_STATUS_OK if successfully initiated 468 ** NFA_STATUS_BAD_HANDLE if handle is not valid 469 ** NFA_STATUS_BAD_LENGTH if data length is more than remote 470 ** link MIU 471 ** NFA_STATUS_CONGESTED if congested 472 ** NFA_STATUS_FAILED otherwise 473 ** 474 *******************************************************************************/ 475 tNFA_STATUS NFA_P2pSendUI(tNFA_HANDLE handle, uint8_t dsap, uint16_t length, 476 uint8_t* p_data) { 477 tNFA_P2P_API_SEND_UI* p_msg; 478 tNFA_STATUS ret_status = NFA_STATUS_FAILED; 479 tNFA_HANDLE xx; 480 481 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 482 "handle:0x%X, DSAP:0x%02X, length:%d", handle, dsap, length); 483 484 GKI_sched_lock(); 485 486 xx = handle & NFA_HANDLE_MASK; 487 488 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 489 LOG(ERROR) << StringPrintf("Handle (0x%X) is not valid", handle); 490 ret_status = NFA_STATUS_BAD_HANDLE; 491 } else if (length > nfa_p2p_cb.remote_link_miu) { 492 LOG(ERROR) << StringPrintf( 493 "handle:0x%X, length(%d) must be less than remote " 494 "link MIU(%d)", 495 handle, length, nfa_p2p_cb.remote_link_miu); 496 ret_status = NFA_STATUS_BAD_LENGTH; 497 } else if (nfa_p2p_cb.sap_cb[xx].flags & NFA_P2P_SAP_FLAG_LLINK_CONGESTED) { 498 LOG(WARNING) << StringPrintf( 499 "handle:0x%X, logical data link is already congested", handle); 500 ret_status = NFA_STATUS_CONGESTED; 501 } else if (LLCP_IsLogicalLinkCongested( 502 (uint8_t)xx, nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu, 503 nfa_p2p_cb.total_pending_ui_pdu, 504 nfa_p2p_cb.total_pending_i_pdu)) { 505 nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED; 506 507 LOG(WARNING) << StringPrintf("handle:0x%X, logical data link is congested", 508 handle); 509 ret_status = NFA_STATUS_CONGESTED; 510 } else if ((p_msg = (tNFA_P2P_API_SEND_UI*)GKI_getbuf( 511 sizeof(tNFA_P2P_API_SEND_UI))) != NULL) { 512 p_msg->hdr.event = NFA_P2P_API_SEND_UI_EVT; 513 514 p_msg->handle = handle; 515 p_msg->dsap = dsap; 516 517 p_msg->p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID); 518 if (p_msg->p_msg != NULL) { 519 p_msg->p_msg->len = length; 520 p_msg->p_msg->offset = LLCP_MIN_OFFSET; 521 memcpy(((uint8_t*)(p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data, 522 length); 523 524 /* increase number of tx UI PDU which is not processed by NFA for 525 * congestion control */ 526 nfa_p2p_cb.sap_cb[xx].num_pending_ui_pdu++; 527 nfa_p2p_cb.total_pending_ui_pdu++; 528 nfa_sys_sendmsg(p_msg); 529 530 ret_status = NFA_STATUS_OK; 531 } else { 532 GKI_freebuf(p_msg); 533 534 nfa_p2p_cb.sap_cb[xx].flags |= NFA_P2P_SAP_FLAG_LLINK_CONGESTED; 535 ret_status = NFA_STATUS_CONGESTED; 536 } 537 } 538 539 GKI_sched_unlock(); 540 541 return (ret_status); 542 } 543 544 /******************************************************************************* 545 ** 546 ** Function NFA_P2pReadUI 547 ** 548 ** Description This function is called to read data on connectionless 549 ** transport when receiving NFA_P2P_DATA_EVT with 550 ** NFA_P2P_LLINK_TYPE. 551 ** 552 ** - Remote SAP who sent UI PDU is returned. 553 ** - Information of UI PDU up to max_data_len is copied into 554 ** p_data. 555 ** - If more information of UI PDU or more UI PDU in queue then 556 ** more is returned to TRUE. 557 ** - Information of next UI PDU is not concatenated. 558 ** 559 ** Returns NFA_STATUS_OK if successfully initiated 560 ** NFA_STATUS_BAD_HANDLE if handle is not valid 561 ** 562 *******************************************************************************/ 563 tNFA_STATUS NFA_P2pReadUI(tNFA_HANDLE handle, uint32_t max_data_len, 564 uint8_t* p_remote_sap, uint32_t* p_data_len, 565 uint8_t* p_data, bool* p_more) { 566 tNFA_STATUS ret_status; 567 tNFA_HANDLE xx; 568 569 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%X", handle); 570 571 GKI_sched_lock(); 572 573 xx = handle & NFA_HANDLE_MASK; 574 575 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 576 LOG(ERROR) << StringPrintf("Handle (0x%X) is not valid", handle); 577 ret_status = NFA_STATUS_BAD_HANDLE; 578 } else { 579 *p_more = LLCP_ReadLogicalLinkData((uint8_t)xx, max_data_len, p_remote_sap, 580 p_data_len, p_data); 581 ret_status = NFA_STATUS_OK; 582 } 583 584 GKI_sched_unlock(); 585 586 return (ret_status); 587 } 588 589 /******************************************************************************* 590 ** 591 ** Function NFA_P2pFlushUI 592 ** 593 ** Description This function is called to flush data on connectionless 594 ** transport. 595 ** 596 ** Returns NFA_STATUS_OK if successfully initiated 597 ** NFA_STATUS_BAD_HANDLE if handle is not valid 598 ** 599 *******************************************************************************/ 600 tNFA_STATUS NFA_P2pFlushUI(tNFA_HANDLE handle, uint32_t* p_length) { 601 tNFA_STATUS ret_status; 602 tNFA_HANDLE xx; 603 604 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%X", handle); 605 606 GKI_sched_lock(); 607 608 xx = handle & NFA_HANDLE_MASK; 609 610 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 611 LOG(ERROR) << StringPrintf("Handle (0x%X) is not valid", handle); 612 ret_status = NFA_STATUS_BAD_HANDLE; 613 *p_length = 0; 614 } else { 615 *p_length = LLCP_FlushLogicalLinkRxData((uint8_t)xx); 616 ret_status = NFA_STATUS_OK; 617 } 618 619 GKI_sched_unlock(); 620 621 return (ret_status); 622 } 623 624 /******************************************************************************* 625 ** 626 ** Function NFA_P2pSendData 627 ** 628 ** Description This function is called to send data on connection-oriented 629 ** transport. 630 ** 631 ** Returns NFA_STATUS_OK if successfully initiated 632 ** NFA_STATUS_BAD_HANDLE if handle is not valid 633 ** NFA_STATUS_BAD_LENGTH if data length is more than remote MIU 634 ** NFA_STATUS_CONGESTED if congested 635 ** NFA_STATUS_FAILED otherwise 636 ** 637 *******************************************************************************/ 638 tNFA_STATUS NFA_P2pSendData(tNFA_HANDLE handle, uint16_t length, 639 uint8_t* p_data) { 640 tNFA_P2P_API_SEND_DATA* p_msg; 641 tNFA_STATUS ret_status = NFA_STATUS_FAILED; 642 tNFA_HANDLE xx; 643 644 DLOG_IF(INFO, nfc_debug_enabled) 645 << StringPrintf("handle:0x%X, length:%d", handle, length); 646 647 GKI_sched_lock(); 648 649 xx = handle & NFA_HANDLE_MASK; 650 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 651 652 if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) || 653 (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 654 LOG(ERROR) << StringPrintf("Handle(0x%X) is not valid", handle); 655 ret_status = NFA_STATUS_BAD_HANDLE; 656 } else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_REMOTE_RW_ZERO) { 657 LOG(ERROR) << StringPrintf("handle:0x%X, Remote set RW to 0 (flow off)", 658 handle); 659 ret_status = NFA_STATUS_FAILED; 660 } else if (nfa_p2p_cb.conn_cb[xx].remote_miu < length) { 661 LOG(ERROR) << StringPrintf("handle:0x%X, Data more than remote MIU(%d)", 662 handle, nfa_p2p_cb.conn_cb[xx].remote_miu); 663 ret_status = NFA_STATUS_BAD_LENGTH; 664 } else if (nfa_p2p_cb.conn_cb[xx].flags & NFA_P2P_CONN_FLAG_CONGESTED) { 665 LOG(WARNING) << StringPrintf( 666 "handle:0x%X, data link connection is already " 667 "congested", 668 handle); 669 ret_status = NFA_STATUS_CONGESTED; 670 } else if (LLCP_IsDataLinkCongested(nfa_p2p_cb.conn_cb[xx].local_sap, 671 nfa_p2p_cb.conn_cb[xx].remote_sap, 672 nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu, 673 nfa_p2p_cb.total_pending_ui_pdu, 674 nfa_p2p_cb.total_pending_i_pdu)) { 675 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED; 676 677 LOG(WARNING) << StringPrintf( 678 "handle:0x%X, data link connection is congested", handle); 679 ret_status = NFA_STATUS_CONGESTED; 680 } else if ((p_msg = (tNFA_P2P_API_SEND_DATA*)GKI_getbuf( 681 sizeof(tNFA_P2P_API_SEND_DATA))) != NULL) { 682 p_msg->hdr.event = NFA_P2P_API_SEND_DATA_EVT; 683 684 p_msg->conn_handle = handle; 685 686 p_msg->p_msg = (NFC_HDR*)GKI_getpoolbuf(LLCP_POOL_ID); 687 if (p_msg->p_msg != NULL) { 688 p_msg->p_msg->len = length; 689 p_msg->p_msg->offset = LLCP_MIN_OFFSET; 690 memcpy(((uint8_t*)(p_msg->p_msg + 1) + p_msg->p_msg->offset), p_data, 691 length); 692 693 /* increase number of tx I PDU which is not processed by NFA for 694 * congestion control */ 695 nfa_p2p_cb.conn_cb[xx].num_pending_i_pdu++; 696 nfa_p2p_cb.total_pending_i_pdu++; 697 nfa_sys_sendmsg(p_msg); 698 699 ret_status = NFA_STATUS_OK; 700 } else { 701 GKI_freebuf(p_msg); 702 nfa_p2p_cb.conn_cb[xx].flags |= NFA_P2P_CONN_FLAG_CONGESTED; 703 ret_status = NFA_STATUS_CONGESTED; 704 } 705 } 706 707 GKI_sched_unlock(); 708 709 return (ret_status); 710 } 711 712 /******************************************************************************* 713 ** 714 ** Function NFA_P2pReadData 715 ** 716 ** Description This function is called to read data on connection-oriented 717 ** transport when receiving NFA_P2P_DATA_EVT with 718 ** NFA_P2P_DLINK_TYPE. 719 ** 720 ** - Information of I PDU is copied into p_data up to 721 ** max_data_len. 722 ** - If more information of I PDU or more I PDU in queue, then 723 ** more is returned to TRUE. 724 ** - Information of next I PDU is not concatenated. 725 ** 726 ** Returns NFA_STATUS_OK if successfully initiated 727 ** NFA_STATUS_BAD_HANDLE if handle is not valid 728 ** 729 *******************************************************************************/ 730 tNFA_STATUS NFA_P2pReadData(tNFA_HANDLE handle, uint32_t max_data_len, 731 uint32_t* p_data_len, uint8_t* p_data, 732 bool* p_more) { 733 tNFA_STATUS ret_status; 734 tNFA_HANDLE xx; 735 736 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%X", handle); 737 738 GKI_sched_lock(); 739 740 xx = handle & NFA_HANDLE_MASK; 741 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 742 743 if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) || 744 (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 745 LOG(ERROR) << StringPrintf("Handle(0x%X) is not valid", handle); 746 ret_status = NFA_STATUS_BAD_HANDLE; 747 } else { 748 *p_more = LLCP_ReadDataLinkData(nfa_p2p_cb.conn_cb[xx].local_sap, 749 nfa_p2p_cb.conn_cb[xx].remote_sap, 750 max_data_len, p_data_len, p_data); 751 ret_status = NFA_STATUS_OK; 752 } 753 754 GKI_sched_unlock(); 755 756 return (ret_status); 757 } 758 759 /******************************************************************************* 760 ** 761 ** Function NFA_P2pFlushData 762 ** 763 ** Description This function is called to flush data on connection-oriented 764 ** transport. 765 ** 766 ** Returns NFA_STATUS_OK if successfully initiated 767 ** NFA_STATUS_BAD_HANDLE if handle is not valid 768 ** 769 *******************************************************************************/ 770 tNFA_STATUS NFA_P2pFlushData(tNFA_HANDLE handle, uint32_t* p_length) { 771 tNFA_STATUS ret_status; 772 tNFA_HANDLE xx; 773 774 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%X", handle); 775 776 GKI_sched_lock(); 777 778 xx = handle & NFA_HANDLE_MASK; 779 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 780 781 if ((!(handle & NFA_P2P_HANDLE_FLAG_CONN)) || (xx >= LLCP_MAX_DATA_LINK) || 782 (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 783 LOG(ERROR) << StringPrintf("Handle(0x%X) is not valid", handle); 784 ret_status = NFA_STATUS_BAD_HANDLE; 785 } else { 786 *p_length = LLCP_FlushDataLinkRxData(nfa_p2p_cb.conn_cb[xx].local_sap, 787 nfa_p2p_cb.conn_cb[xx].remote_sap); 788 ret_status = NFA_STATUS_OK; 789 } 790 791 GKI_sched_unlock(); 792 793 return (ret_status); 794 } 795 796 /******************************************************************************* 797 ** 798 ** Function NFA_P2pSetLocalBusy 799 ** 800 ** Description This function is called to stop or resume incoming data on 801 ** connection-oriented transport. 802 ** 803 ** Returns NFA_STATUS_OK if successfully initiated 804 ** NFA_STATUS_BAD_HANDLE if handle is not valid 805 ** NFA_STATUS_FAILED otherwise 806 ** 807 *******************************************************************************/ 808 tNFA_STATUS NFA_P2pSetLocalBusy(tNFA_HANDLE conn_handle, bool is_busy) { 809 tNFA_P2P_API_SET_LOCAL_BUSY* p_msg; 810 tNFA_HANDLE xx; 811 812 DLOG_IF(INFO, nfc_debug_enabled) 813 << StringPrintf("conn_handle:0x%02X, is_busy:%d", conn_handle, is_busy); 814 815 xx = conn_handle & NFA_HANDLE_MASK; 816 817 if (!(xx & NFA_P2P_HANDLE_FLAG_CONN)) { 818 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 819 return (NFA_STATUS_BAD_HANDLE); 820 } else { 821 xx &= ~NFA_P2P_HANDLE_FLAG_CONN; 822 } 823 824 if ((xx >= LLCP_MAX_DATA_LINK) || (nfa_p2p_cb.conn_cb[xx].flags == 0)) { 825 LOG(ERROR) << StringPrintf("Connection Handle is not valid"); 826 return (NFA_STATUS_BAD_HANDLE); 827 } 828 829 if ((p_msg = (tNFA_P2P_API_SET_LOCAL_BUSY*)GKI_getbuf( 830 sizeof(tNFA_P2P_API_SET_LOCAL_BUSY))) != NULL) { 831 p_msg->hdr.event = NFA_P2P_API_SET_LOCAL_BUSY_EVT; 832 833 p_msg->conn_handle = conn_handle; 834 p_msg->is_busy = is_busy; 835 836 nfa_sys_sendmsg(p_msg); 837 838 return (NFA_STATUS_OK); 839 } 840 841 return (NFA_STATUS_FAILED); 842 } 843 844 /******************************************************************************* 845 ** 846 ** Function NFA_P2pGetLinkInfo 847 ** 848 ** Description This function is called to get local/remote link MIU and 849 ** Well-Known Service list encoded as a 16-bit field of 850 ** connected LLCP. NFA_P2P_LINK_INFO_EVT will be returned. 851 ** 852 ** Returns NFA_STATUS_OK if successfully initiated 853 ** NFA_STATUS_BAD_HANDLE if server or client is not registered 854 ** NFA_STATUS_FAILED otherwise 855 ** 856 *******************************************************************************/ 857 tNFA_STATUS NFA_P2pGetLinkInfo(tNFA_HANDLE handle) { 858 tNFA_P2P_API_GET_LINK_INFO* p_msg; 859 tNFA_HANDLE xx; 860 861 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("handle:0x%x", handle); 862 863 if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) { 864 LOG(ERROR) << StringPrintf("LLCP link is not activated"); 865 return (NFA_STATUS_FAILED); 866 } 867 868 xx = handle & NFA_HANDLE_MASK; 869 870 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 871 LOG(ERROR) << StringPrintf("Handle is invalid or not registered"); 872 return (NFA_STATUS_BAD_HANDLE); 873 } 874 875 if ((p_msg = (tNFA_P2P_API_GET_LINK_INFO*)GKI_getbuf( 876 sizeof(tNFA_P2P_API_GET_LINK_INFO))) != NULL) { 877 p_msg->hdr.event = NFA_P2P_API_GET_LINK_INFO_EVT; 878 879 p_msg->handle = handle; 880 881 nfa_sys_sendmsg(p_msg); 882 883 return (NFA_STATUS_OK); 884 } 885 886 return (NFA_STATUS_FAILED); 887 } 888 889 /******************************************************************************* 890 ** 891 ** Function NFA_P2pGetRemoteSap 892 ** 893 ** Description This function is called to get SAP associated by service 894 ** name on connected remote LLCP. 895 ** NFA_P2P_SDP_EVT will be returned. 896 ** 897 ** Returns NFA_STATUS_OK if successfully initiated 898 ** NFA_STATUS_BAD_HANDLE if server or client is not registered 899 ** NFA_STATUS_FAILED otherwise 900 ** 901 *******************************************************************************/ 902 tNFA_STATUS NFA_P2pGetRemoteSap(tNFA_HANDLE handle, char* p_service_name) { 903 tNFA_P2P_API_GET_REMOTE_SAP* p_msg; 904 tNFA_HANDLE xx; 905 906 DLOG_IF(INFO, nfc_debug_enabled) 907 << StringPrintf("handle:0x%x, SN:<%s>", handle, p_service_name); 908 909 if (nfa_p2p_cb.llcp_state != NFA_P2P_LLCP_STATE_ACTIVATED) { 910 LOG(ERROR) << StringPrintf("LLCP link is not activated"); 911 return (NFA_STATUS_FAILED); 912 } 913 914 xx = handle & NFA_HANDLE_MASK; 915 916 if ((xx >= NFA_P2P_NUM_SAP) || (nfa_p2p_cb.sap_cb[xx].p_cback == NULL)) { 917 LOG(ERROR) << StringPrintf("Handle is invalid or not registered"); 918 return (NFA_STATUS_BAD_HANDLE); 919 } 920 921 if ((p_msg = (tNFA_P2P_API_GET_REMOTE_SAP*)GKI_getbuf( 922 sizeof(tNFA_P2P_API_GET_REMOTE_SAP))) != NULL) { 923 p_msg->hdr.event = NFA_P2P_API_GET_REMOTE_SAP_EVT; 924 925 p_msg->handle = handle; 926 927 strncpy(p_msg->service_name, p_service_name, LLCP_MAX_SN_LEN); 928 p_msg->service_name[LLCP_MAX_SN_LEN] = 0; 929 930 nfa_sys_sendmsg(p_msg); 931 932 return (NFA_STATUS_OK); 933 } 934 935 return (NFA_STATUS_FAILED); 936 } 937 938 /******************************************************************************* 939 ** 940 ** Function NFA_P2pSetLLCPConfig 941 ** 942 ** Description This function is called to change LLCP config parameters. 943 ** Application must call while LLCP is not activated. 944 ** 945 ** Parameters descriptions (default value) 946 ** - Local Link MIU (LLCP_MIU) 947 ** - Option parameter (LLCP_OPT_VALUE) 948 ** - Response Waiting Time Index (LLCP_WAITING_TIME) 949 ** - Local Link Timeout (LLCP_LTO_VALUE) 950 ** - Inactivity Timeout as initiator role 951 ** (LLCP_INIT_INACTIVITY_TIMEOUT) 952 ** - Inactivity Timeout as target role 953 ** (LLCP_TARGET_INACTIVITY_TIMEOUT) 954 ** - Delay SYMM response (LLCP_DELAY_RESP_TIME) 955 ** - Data link connection timeout 956 ** (LLCP_DATA_LINK_CONNECTION_TOUT) 957 ** - Delay timeout to send first PDU as initiator 958 ** (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU) 959 ** 960 ** Returns NFA_STATUS_OK if successfully initiated 961 ** NFA_STATUS_FAILED otherwise 962 ** 963 *******************************************************************************/ 964 tNFA_STATUS NFA_P2pSetLLCPConfig(uint16_t link_miu, uint8_t opt, uint8_t wt, 965 uint16_t link_timeout, 966 uint16_t inact_timeout_init, 967 uint16_t inact_timeout_target, 968 uint16_t symm_delay, 969 uint16_t data_link_timeout, 970 uint16_t delay_first_pdu_timeout) { 971 tNFA_P2P_API_SET_LLCP_CFG* p_msg; 972 973 DLOG_IF(INFO, nfc_debug_enabled) 974 << StringPrintf("link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d", 975 link_miu, opt, wt, link_timeout); 976 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 977 " inact_timeout(init:%d, target:%d), " 978 "symm_delay:%d, data_link_timeout:%d", 979 inact_timeout_init, inact_timeout_target, symm_delay, data_link_timeout); 980 DLOG_IF(INFO, nfc_debug_enabled) 981 << StringPrintf(" delay_first_pdu_timeout:%d", 982 delay_first_pdu_timeout); 983 984 if (nfa_p2p_cb.llcp_state == NFA_P2P_LLCP_STATE_ACTIVATED) { 985 LOG(ERROR) << StringPrintf("LLCP link is activated"); 986 return (NFA_STATUS_FAILED); 987 } 988 989 if ((p_msg = (tNFA_P2P_API_SET_LLCP_CFG*)GKI_getbuf( 990 sizeof(tNFA_P2P_API_SET_LLCP_CFG))) != NULL) { 991 p_msg->hdr.event = NFA_P2P_API_SET_LLCP_CFG_EVT; 992 993 p_msg->link_miu = link_miu; 994 p_msg->opt = opt; 995 p_msg->wt = wt; 996 p_msg->link_timeout = link_timeout; 997 p_msg->inact_timeout_init = inact_timeout_init; 998 p_msg->inact_timeout_target = inact_timeout_target; 999 p_msg->symm_delay = symm_delay; 1000 p_msg->data_link_timeout = data_link_timeout; 1001 p_msg->delay_first_pdu_timeout = delay_first_pdu_timeout; 1002 1003 nfa_sys_sendmsg(p_msg); 1004 1005 return (NFA_STATUS_OK); 1006 } 1007 1008 return (NFA_STATUS_FAILED); 1009 } 1010 1011 /******************************************************************************* 1012 ** 1013 ** Function NFA_P2pGetLLCPConfig 1014 ** 1015 ** Description This function is called to read LLCP config parameters. 1016 ** 1017 ** Parameters descriptions 1018 ** - Local Link MIU 1019 ** - Option parameter 1020 ** - Response Waiting Time Index 1021 ** - Local Link Timeout 1022 ** - Inactivity Timeout as initiator role 1023 ** - Inactivity Timeout as target role 1024 ** - Delay SYMM response 1025 ** - Data link connection timeout 1026 ** - Delay timeout to send first PDU as initiator 1027 ** 1028 ** Returns None 1029 ** 1030 *******************************************************************************/ 1031 void NFA_P2pGetLLCPConfig(uint16_t* p_link_miu, uint8_t* p_opt, uint8_t* p_wt, 1032 uint16_t* p_link_timeout, 1033 uint16_t* p_inact_timeout_init, 1034 uint16_t* p_inact_timeout_target, 1035 uint16_t* p_symm_delay, uint16_t* p_data_link_timeout, 1036 uint16_t* p_delay_first_pdu_timeout) { 1037 LLCP_GetConfig(p_link_miu, p_opt, p_wt, p_link_timeout, p_inact_timeout_init, 1038 p_inact_timeout_target, p_symm_delay, p_data_link_timeout, 1039 p_delay_first_pdu_timeout); 1040 1041 DLOG_IF(INFO, nfc_debug_enabled) 1042 << StringPrintf("link_miu:%d, opt:0x%02X, wt:%d, link_timeout:%d", 1043 *p_link_miu, *p_opt, *p_wt, *p_link_timeout); 1044 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf( 1045 " inact_timeout(init:%d, target:%d), " 1046 "symm_delay:%d, data_link_timeout:%d", 1047 *p_inact_timeout_init, *p_inact_timeout_target, *p_symm_delay, 1048 *p_data_link_timeout); 1049 DLOG_IF(INFO, nfc_debug_enabled) 1050 << StringPrintf(" delay_first_pdu_timeout:%d", 1051 *p_delay_first_pdu_timeout); 1052 } 1053