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