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 *******************************************************************************/ 62 tNFA_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 *******************************************************************************/ 123 tNFA_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 *******************************************************************************/ 169 tNFA_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 *******************************************************************************/ 210 tNFA_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 *******************************************************************************/ 263 tNFA_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 *******************************************************************************/ 315 tNFA_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 *******************************************************************************/ 365 tNFA_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 *******************************************************************************/ 423 tNFA_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 *******************************************************************************/ 480 tNFA_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 *******************************************************************************/ 569 tNFA_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 *******************************************************************************/ 606 tNFA_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 *******************************************************************************/ 644 tNFA_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 *******************************************************************************/ 738 tNFA_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 *******************************************************************************/ 778 tNFA_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 *******************************************************************************/ 816 tNFA_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 *******************************************************************************/ 865 tNFA_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 *******************************************************************************/ 911 tNFA_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 *******************************************************************************/ 974 tNFA_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 *******************************************************************************/ 1040 void 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 *******************************************************************************/ 1072 uint8_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