1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Communicate with a peer using NFC-DEP, LLCP, SNEP. 19 */ 20 #pragma once 21 #include <utils/RefBase.h> 22 #include <utils/StrongPointer.h> 23 #include "SyncEvent.h" 24 #include "NfcJniUtil.h" 25 #include <string> 26 extern "C" 27 { 28 #include "nfa_p2p_api.h" 29 } 30 31 class P2pServer; 32 class P2pClient; 33 class NfaConn; 34 #define MAX_NFA_CONNS_PER_SERVER 5 35 36 /***************************************************************************** 37 ** 38 ** Name: PeerToPeer 39 ** 40 ** Description: Communicate with a peer using NFC-DEP, LLCP, SNEP. 41 ** 42 *****************************************************************************/ 43 class PeerToPeer 44 { 45 public: 46 typedef unsigned int tJNI_HANDLE; 47 48 /******************************************************************************* 49 ** 50 ** Function: PeerToPeer 51 ** 52 ** Description: Initialize member variables. 53 ** 54 ** Returns: None 55 ** 56 *******************************************************************************/ 57 PeerToPeer (); 58 59 60 /******************************************************************************* 61 ** 62 ** Function: ~PeerToPeer 63 ** 64 ** Description: Free all resources. 65 ** 66 ** Returns: None 67 ** 68 *******************************************************************************/ 69 ~PeerToPeer (); 70 71 72 /******************************************************************************* 73 ** 74 ** Function: getInstance 75 ** 76 ** Description: Get the singleton PeerToPeer object. 77 ** 78 ** Returns: Singleton PeerToPeer object. 79 ** 80 *******************************************************************************/ 81 static PeerToPeer& getInstance(); 82 83 84 /******************************************************************************* 85 ** 86 ** Function: initialize 87 ** 88 ** Description: Initialize member variables. 89 ** 90 ** Returns: None 91 ** 92 *******************************************************************************/ 93 void initialize (); 94 95 96 /******************************************************************************* 97 ** 98 ** Function: llcpActivatedHandler 99 ** 100 ** Description: Receive LLLCP-activated event from stack. 101 ** nat: JVM-related data. 102 ** activated: Event data. 103 ** 104 ** Returns: None 105 ** 106 *******************************************************************************/ 107 void llcpActivatedHandler (nfc_jni_native_data* nativeData, tNFA_LLCP_ACTIVATED& activated); 108 109 110 /******************************************************************************* 111 ** 112 ** Function: llcpDeactivatedHandler 113 ** 114 ** Description: Receive LLLCP-deactivated event from stack. 115 ** nat: JVM-related data. 116 ** deactivated: Event data. 117 ** 118 ** Returns: None 119 ** 120 *******************************************************************************/ 121 void llcpDeactivatedHandler (nfc_jni_native_data* nativeData, tNFA_LLCP_DEACTIVATED& deactivated); 122 123 void llcpFirstPacketHandler(nfc_jni_native_data* nativeData); 124 125 /******************************************************************************* 126 ** 127 ** Function: connectionEventHandler 128 ** 129 ** Description: Receive events from the stack. 130 ** event: Event code. 131 ** eventData: Event data. 132 ** 133 ** Returns: None 134 ** 135 *******************************************************************************/ 136 void connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* eventData); 137 138 139 /******************************************************************************* 140 ** 141 ** Function: registerServer 142 ** 143 ** Description: Let a server start listening for peer's connection request. 144 ** jniHandle: Connection handle. 145 ** serviceName: Server's service name. 146 ** 147 ** Returns: True if ok. 148 ** 149 *******************************************************************************/ 150 bool registerServer (tJNI_HANDLE jniHandle, const char* serviceName); 151 152 153 /******************************************************************************* 154 ** 155 ** Function: deregisterServer 156 ** 157 ** Description: Stop a P2pServer from listening for peer. 158 ** 159 ** Returns: True if ok. 160 ** 161 *******************************************************************************/ 162 bool deregisterServer (tJNI_HANDLE jniHandle); 163 164 165 /******************************************************************************* 166 ** 167 ** Function: accept 168 ** 169 ** Description: Accept a peer's request to connect. 170 ** serverJniHandle: Server's handle. 171 ** connJniHandle: Connection handle. 172 ** maxInfoUnit: Maximum information unit. 173 ** recvWindow: Receive window size. 174 ** 175 ** Returns: True if ok. 176 ** 177 *******************************************************************************/ 178 bool accept (tJNI_HANDLE serverJniHandle, tJNI_HANDLE connJniHandle, int maxInfoUnit, int recvWindow); 179 180 181 /******************************************************************************* 182 ** 183 ** Function: createClient 184 ** 185 ** Description: Create a P2pClient object for a new out-bound connection. 186 ** jniHandle: Connection handle. 187 ** miu: Maximum information unit. 188 ** rw: Receive window size. 189 ** 190 ** Returns: True if ok. 191 ** 192 *******************************************************************************/ 193 bool createClient (tJNI_HANDLE jniHandle, UINT16 miu, UINT8 rw); 194 195 196 /******************************************************************************* 197 ** 198 ** Function: connectConnOriented 199 ** 200 ** Description: Estabish a connection-oriented connection to a peer. 201 ** jniHandle: Connection handle. 202 ** serviceName: Peer's service name. 203 ** 204 ** Returns: True if ok. 205 ** 206 *******************************************************************************/ 207 bool connectConnOriented (tJNI_HANDLE jniHandle, const char* serviceName); 208 209 210 /******************************************************************************* 211 ** 212 ** Function: connectConnOriented 213 ** 214 ** Description: Estabish a connection-oriented connection to a peer. 215 ** jniHandle: Connection handle. 216 ** destinationSap: Peer's service access point. 217 ** 218 ** Returns: True if ok. 219 ** 220 *******************************************************************************/ 221 bool connectConnOriented (tJNI_HANDLE jniHandle, UINT8 destinationSap); 222 223 224 /******************************************************************************* 225 ** 226 ** Function: send 227 ** 228 ** Description: Send data to peer. 229 ** jniHandle: Handle of connection. 230 ** buffer: Buffer of data. 231 ** bufferLen: Length of data. 232 ** 233 ** Returns: True if ok. 234 ** 235 *******************************************************************************/ 236 bool send (tJNI_HANDLE jniHandle, UINT8* buffer, UINT16 bufferLen); 237 238 239 /******************************************************************************* 240 ** 241 ** Function: receive 242 ** 243 ** Description: Receive data from peer. 244 ** jniHandle: Handle of connection. 245 ** buffer: Buffer to store data. 246 ** bufferLen: Max length of buffer. 247 ** actualLen: Actual length received. 248 ** 249 ** Returns: True if ok. 250 ** 251 *******************************************************************************/ 252 bool receive (tJNI_HANDLE jniHandle, UINT8* buffer, UINT16 bufferLen, UINT16& actualLen); 253 254 255 /******************************************************************************* 256 ** 257 ** Function: disconnectConnOriented 258 ** 259 ** Description: Disconnect a connection-oriented connection with peer. 260 ** jniHandle: Handle of connection. 261 ** 262 ** Returns: True if ok. 263 ** 264 *******************************************************************************/ 265 bool disconnectConnOriented (tJNI_HANDLE jniHandle); 266 267 268 /******************************************************************************* 269 ** 270 ** Function: getRemoteMaxInfoUnit 271 ** 272 ** Description: Get peer's max information unit. 273 ** jniHandle: Handle of the connection. 274 ** 275 ** Returns: Peer's max information unit. 276 ** 277 *******************************************************************************/ 278 UINT16 getRemoteMaxInfoUnit (tJNI_HANDLE jniHandle); 279 280 281 /******************************************************************************* 282 ** 283 ** Function: getRemoteRecvWindow 284 ** 285 ** Description: Get peer's receive window size. 286 ** jniHandle: Handle of the connection. 287 ** 288 ** Returns: Peer's receive window size. 289 ** 290 *******************************************************************************/ 291 UINT8 getRemoteRecvWindow (tJNI_HANDLE jniHandle); 292 293 294 /******************************************************************************* 295 ** 296 ** Function: setP2pListenMask 297 ** 298 ** Description: Sets the p2p listen technology mask. 299 ** p2pListenMask: the p2p listen mask to be set? 300 ** 301 ** Returns: None 302 ** 303 *******************************************************************************/ 304 void setP2pListenMask (tNFA_TECHNOLOGY_MASK p2pListenMask); 305 306 /******************************************************************************* 307 ** 308 ** Function: enableP2pListening 309 ** 310 ** Description: Start/stop polling/listening to peer that supports P2P. 311 ** isEnable: Is enable polling/listening? 312 ** 313 ** Returns: None 314 ** 315 *******************************************************************************/ 316 void enableP2pListening (bool isEnable); 317 318 319 /******************************************************************************* 320 ** 321 ** Function: handleNfcOnOff 322 ** 323 ** Description: Handle events related to turning NFC on/off by the user. 324 ** isOn: Is NFC turning on? 325 ** 326 ** Returns: None 327 ** 328 *******************************************************************************/ 329 void handleNfcOnOff (bool isOn); 330 331 332 /******************************************************************************* 333 ** 334 ** Function: getNextJniHandle 335 ** 336 ** Description: Get a new JNI handle. 337 ** 338 ** Returns: A new JNI handle. 339 ** 340 *******************************************************************************/ 341 tJNI_HANDLE getNewJniHandle (); 342 343 /******************************************************************************* 344 ** 345 ** Function: nfaServerCallback 346 ** 347 ** Description: Receive LLCP-related events from the stack. 348 ** p2pEvent: Event code. 349 ** eventData: Event data. 350 ** 351 ** Returns: None 352 ** 353 *******************************************************************************/ 354 static void nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData); 355 356 357 /******************************************************************************* 358 ** 359 ** Function: nfaClientCallback 360 ** 361 ** Description: Receive LLCP-related events from the stack. 362 ** p2pEvent: Event code. 363 ** eventData: Event data. 364 ** 365 ** Returns: None 366 ** 367 *******************************************************************************/ 368 static void nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData); 369 370 private: 371 static const int sMax = 10; 372 static PeerToPeer sP2p; 373 374 // Variables below only accessed from a single thread 375 UINT16 mRemoteWKS; // Peer's well known services 376 bool mIsP2pListening; // If P2P listening is enabled or not 377 tNFA_TECHNOLOGY_MASK mP2pListenTechMask; // P2P Listen mask 378 379 // Variable below is protected by mNewJniHandleMutex 380 tJNI_HANDLE mNextJniHandle; 381 382 // Variables below protected by mMutex 383 // A note on locking order: mMutex in PeerToPeer is *ALWAYS* 384 // locked before any locks / guards in P2pServer / P2pClient 385 Mutex mMutex; 386 android::sp<P2pServer> mServers [sMax]; 387 android::sp<P2pClient> mClients [sMax]; 388 389 // Synchronization variables 390 SyncEvent mSetTechEvent; // completion event for NFA_SetP2pListenTech() 391 SyncEvent mSnepDefaultServerStartStopEvent; // completion event for NFA_SnepStartDefaultServer(), NFA_SnepStopDefaultServer() 392 SyncEvent mSnepRegisterEvent; // completion event for NFA_SnepRegisterClient() 393 Mutex mDisconnectMutex; // synchronize the disconnect operation 394 Mutex mNewJniHandleMutex; // synchronize the creation of a new JNI handle 395 396 397 /******************************************************************************* 398 ** 399 ** Function: ndefTypeCallback 400 ** 401 ** Description: Receive NDEF-related events from the stack. 402 ** ndefEvent: Event code. 403 ** eventData: Event data. 404 ** 405 ** Returns: None 406 ** 407 *******************************************************************************/ 408 static void ndefTypeCallback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *evetnData); 409 410 411 /******************************************************************************* 412 ** 413 ** Function: findServer 414 ** 415 ** Description: Find a PeerToPeer object by connection handle. 416 ** nfaP2pServerHandle: Connectin handle. 417 ** 418 ** Returns: PeerToPeer object. 419 ** 420 *******************************************************************************/ 421 android::sp<P2pServer> findServerLocked (tNFA_HANDLE nfaP2pServerHandle); 422 423 424 /******************************************************************************* 425 ** 426 ** Function: findServer 427 ** 428 ** Description: Find a PeerToPeer object by connection handle. 429 ** serviceName: service name. 430 ** 431 ** Returns: PeerToPeer object. 432 ** 433 *******************************************************************************/ 434 android::sp<P2pServer> findServerLocked (tJNI_HANDLE jniHandle); 435 436 437 /******************************************************************************* 438 ** 439 ** Function: findServer 440 ** 441 ** Description: Find a PeerToPeer object by service name 442 ** serviceName: service name. 443 ** 444 ** Returns: PeerToPeer object. 445 ** 446 *******************************************************************************/ 447 android::sp<P2pServer> findServerLocked (const char *serviceName); 448 449 450 /******************************************************************************* 451 ** 452 ** Function: removeServer 453 ** 454 ** Description: Free resources related to a server. 455 ** jniHandle: Connection handle. 456 ** 457 ** Returns: None 458 ** 459 *******************************************************************************/ 460 void removeServer (tJNI_HANDLE jniHandle); 461 462 463 /******************************************************************************* 464 ** 465 ** Function: removeConn 466 ** 467 ** Description: Free resources related to a connection. 468 ** jniHandle: Connection handle. 469 ** 470 ** Returns: None 471 ** 472 *******************************************************************************/ 473 void removeConn (tJNI_HANDLE jniHandle); 474 475 476 /******************************************************************************* 477 ** 478 ** Function: createDataLinkConn 479 ** 480 ** Description: Establish a connection-oriented connection to a peer. 481 ** jniHandle: Connection handle. 482 ** serviceName: Peer's service name. 483 ** destinationSap: Peer's service access point. 484 ** 485 ** Returns: True if ok. 486 ** 487 *******************************************************************************/ 488 bool createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceName, UINT8 destinationSap); 489 490 491 /******************************************************************************* 492 ** 493 ** Function: findClient 494 ** 495 ** Description: Find a PeerToPeer object with a client connection handle. 496 ** nfaConnHandle: Connection handle. 497 ** 498 ** Returns: PeerToPeer object. 499 ** 500 *******************************************************************************/ 501 android::sp<P2pClient> findClient (tNFA_HANDLE nfaConnHandle); 502 503 504 /******************************************************************************* 505 ** 506 ** Function: findClient 507 ** 508 ** Description: Find a PeerToPeer object with a client connection handle. 509 ** jniHandle: Connection handle. 510 ** 511 ** Returns: PeerToPeer object. 512 ** 513 *******************************************************************************/ 514 android::sp<P2pClient> findClient (tJNI_HANDLE jniHandle); 515 516 517 /******************************************************************************* 518 ** 519 ** Function: findClientCon 520 ** 521 ** Description: Find a PeerToPeer object with a client connection handle. 522 ** nfaConnHandle: Connection handle. 523 ** 524 ** Returns: PeerToPeer object. 525 ** 526 *******************************************************************************/ 527 android::sp<P2pClient> findClientCon (tNFA_HANDLE nfaConnHandle); 528 529 530 /******************************************************************************* 531 ** 532 ** Function: findConnection 533 ** 534 ** Description: Find a PeerToPeer object with a connection handle. 535 ** nfaConnHandle: Connection handle. 536 ** 537 ** Returns: PeerToPeer object. 538 ** 539 *******************************************************************************/ 540 android::sp<NfaConn> findConnection (tNFA_HANDLE nfaConnHandle); 541 542 543 /******************************************************************************* 544 ** 545 ** Function: findConnection 546 ** 547 ** Description: Find a PeerToPeer object with a connection handle. 548 ** jniHandle: Connection handle. 549 ** 550 ** Returns: PeerToPeer object. 551 ** 552 *******************************************************************************/ 553 android::sp<NfaConn> findConnection (tJNI_HANDLE jniHandle); 554 }; 555 556 557 /***************************************************************************** 558 ** 559 ** Name: NfaConn 560 ** 561 ** Description: Store information about a connection related to a peer. 562 ** 563 *****************************************************************************/ 564 class NfaConn : public android::RefBase 565 { 566 public: 567 tNFA_HANDLE mNfaConnHandle; // NFA handle of the P2P connection 568 PeerToPeer::tJNI_HANDLE mJniHandle; // JNI handle of the P2P connection 569 UINT16 mMaxInfoUnit; 570 UINT8 mRecvWindow; 571 UINT16 mRemoteMaxInfoUnit; 572 UINT8 mRemoteRecvWindow; 573 SyncEvent mReadEvent; // event for reading 574 SyncEvent mCongEvent; // event for congestion 575 SyncEvent mDisconnectingEvent; // event for disconnecting 576 577 578 /******************************************************************************* 579 ** 580 ** Function: NfaConn 581 ** 582 ** Description: Initialize member variables. 583 ** 584 ** Returns: None 585 ** 586 *******************************************************************************/ 587 NfaConn(); 588 }; 589 590 591 /***************************************************************************** 592 ** 593 ** Name: P2pServer 594 ** 595 ** Description: Store information about an in-bound connection from a peer. 596 ** 597 *****************************************************************************/ 598 class P2pServer : public android::RefBase 599 { 600 public: 601 static const std::string sSnepServiceName; 602 603 tNFA_HANDLE mNfaP2pServerHandle; // NFA p2p handle of local server 604 PeerToPeer::tJNI_HANDLE mJniHandle; // JNI Handle 605 SyncEvent mRegServerEvent; // for NFA_P2pRegisterServer() 606 SyncEvent mConnRequestEvent; // for accept() 607 std::string mServiceName; 608 609 /******************************************************************************* 610 ** 611 ** Function: P2pServer 612 ** 613 ** Description: Initialize member variables. 614 ** 615 ** Returns: None 616 ** 617 *******************************************************************************/ 618 P2pServer (PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName); 619 620 /******************************************************************************* 621 ** 622 ** Function: registerWithStack 623 ** 624 ** Description: Register this server with the stack. 625 ** 626 ** Returns: True if ok. 627 ** 628 *******************************************************************************/ 629 bool registerWithStack(); 630 631 /******************************************************************************* 632 ** 633 ** Function: accept 634 ** 635 ** Description: Accept a peer's request to connect. 636 ** serverJniHandle: Server's handle. 637 ** connJniHandle: Connection handle. 638 ** maxInfoUnit: Maximum information unit. 639 ** recvWindow: Receive window size. 640 ** 641 ** Returns: True if ok. 642 ** 643 *******************************************************************************/ 644 bool accept (PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle, 645 int maxInfoUnit, int recvWindow); 646 647 /******************************************************************************* 648 ** 649 ** Function: unblockAll 650 ** 651 ** Description: Unblocks all server connections 652 ** 653 ** Returns: True if ok. 654 ** 655 *******************************************************************************/ 656 void unblockAll(); 657 658 /******************************************************************************* 659 ** 660 ** Function: findServerConnection 661 ** 662 ** Description: Find a P2pServer that has the handle. 663 ** nfaConnHandle: NFA connection handle. 664 ** 665 ** Returns: P2pServer object. 666 ** 667 *******************************************************************************/ 668 android::sp<NfaConn> findServerConnection (tNFA_HANDLE nfaConnHandle); 669 670 /******************************************************************************* 671 ** 672 ** Function: findServerConnection 673 ** 674 ** Description: Find a P2pServer that has the handle. 675 ** jniHandle: JNI connection handle. 676 ** 677 ** Returns: P2pServer object. 678 ** 679 *******************************************************************************/ 680 android::sp<NfaConn> findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle); 681 682 /******************************************************************************* 683 ** 684 ** Function: removeServerConnection 685 ** 686 ** Description: Remove a server connection with the provided handle. 687 ** jniHandle: JNI connection handle. 688 ** 689 ** Returns: True if connection found and removed. 690 ** 691 *******************************************************************************/ 692 bool removeServerConnection(PeerToPeer::tJNI_HANDLE jniHandle); 693 694 private: 695 Mutex mMutex; 696 // mServerConn is protected by mMutex 697 android::sp<NfaConn> mServerConn[MAX_NFA_CONNS_PER_SERVER]; 698 699 /******************************************************************************* 700 ** 701 ** Function: allocateConnection 702 ** 703 ** Description: Allocate a new connection to accept on 704 ** jniHandle: JNI connection handle. 705 ** 706 ** Returns: Allocated connection object 707 ** NULL if the maximum number of connections was reached 708 ** 709 *******************************************************************************/ 710 android::sp<NfaConn> allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle); 711 }; 712 713 714 /***************************************************************************** 715 ** 716 ** Name: P2pClient 717 ** 718 ** Description: Store information about an out-bound connection to a peer. 719 ** 720 *****************************************************************************/ 721 class P2pClient : public android::RefBase 722 { 723 public: 724 tNFA_HANDLE mNfaP2pClientHandle; // NFA p2p handle of client 725 bool mIsConnecting; // Set true while connecting 726 android::sp<NfaConn> mClientConn; 727 SyncEvent mRegisteringEvent; // For client registration 728 SyncEvent mConnectingEvent; // for NFA_P2pConnectByName or Sap() 729 SyncEvent mSnepEvent; // To wait for SNEP completion 730 731 /******************************************************************************* 732 ** 733 ** Function: P2pClient 734 ** 735 ** Description: Initialize member variables. 736 ** 737 ** Returns: None 738 ** 739 *******************************************************************************/ 740 P2pClient (); 741 742 743 /******************************************************************************* 744 ** 745 ** Function: ~P2pClient 746 ** 747 ** Description: Free all resources. 748 ** 749 ** Returns: None 750 ** 751 *******************************************************************************/ 752 ~P2pClient (); 753 754 755 /******************************************************************************* 756 ** 757 ** Function: unblock 758 ** 759 ** Description: Unblocks any threads that are locked on this connection 760 ** 761 ** Returns: None 762 ** 763 *******************************************************************************/ 764 void unblock(); 765 }; 766 767