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 30using android::base::StringPrintf; 31 32extern 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*******************************************************************************/ 63tNFA_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*******************************************************************************/ 121tNFA_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*******************************************************************************/ 165tNFA_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*******************************************************************************/ 205tNFA_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*******************************************************************************/ 258tNFA_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*******************************************************************************/ 310tNFA_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*******************************************************************************/ 360tNFA_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*******************************************************************************/ 418tNFA_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*******************************************************************************/ 475tNFA_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*******************************************************************************/ 563tNFA_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*******************************************************************************/ 600tNFA_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*******************************************************************************/ 638tNFA_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*******************************************************************************/ 730tNFA_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*******************************************************************************/ 770tNFA_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*******************************************************************************/ 808tNFA_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*******************************************************************************/ 857tNFA_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*******************************************************************************/ 902tNFA_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*******************************************************************************/ 964tNFA_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*******************************************************************************/ 1031void 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