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_t 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_t miu, uint8_t rw); 194 195 196 /******************************************************************************* 197 ** 198 ** Function: connectConnOriented 199 ** 200 ** Description: Establish 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: Establish 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_t 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_t* buffer, uint16_t 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_t* buffer, uint16_t bufferLen, uint16_t& 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_t 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_t 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 ** 309 ** Function: getP2pListenMask 310 ** 311 ** Description: Get the set of technologies that P2P is listening. 312 ** 313 ** Returns: Set of technologies. 314 ** 315 *******************************************************************************/ 316 tNFA_TECHNOLOGY_MASK getP2pListenMask (); 317 318 319 /******************************************************************************* 320 ** 321 ** Function: resetP2pListenMask 322 ** 323 ** Description: Reset the p2p listen technology mask to initial value. 324 ** 325 ** Returns: None. 326 ** 327 *******************************************************************************/ 328 void resetP2pListenMask (); 329 330 /******************************************************************************* 331 ** 332 ** Function: enableP2pListening 333 ** 334 ** Description: Start/stop polling/listening to peer that supports P2P. 335 ** isEnable: Is enable polling/listening? 336 ** 337 ** Returns: None 338 ** 339 *******************************************************************************/ 340 void enableP2pListening (bool isEnable); 341 342 343 /******************************************************************************* 344 ** 345 ** Function: handleNfcOnOff 346 ** 347 ** Description: Handle events related to turning NFC on/off by the user. 348 ** isOn: Is NFC turning on? 349 ** 350 ** Returns: None 351 ** 352 *******************************************************************************/ 353 void handleNfcOnOff (bool isOn); 354 355 356 /******************************************************************************* 357 ** 358 ** Function: getNextJniHandle 359 ** 360 ** Description: Get a new JNI handle. 361 ** 362 ** Returns: A new JNI handle. 363 ** 364 *******************************************************************************/ 365 tJNI_HANDLE getNewJniHandle (); 366 367 /******************************************************************************* 368 ** 369 ** Function: nfaServerCallback 370 ** 371 ** Description: Receive LLCP-related events from the stack. 372 ** p2pEvent: Event code. 373 ** eventData: Event data. 374 ** 375 ** Returns: None 376 ** 377 *******************************************************************************/ 378 static void nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData); 379 380 381 /******************************************************************************* 382 ** 383 ** Function: nfaClientCallback 384 ** 385 ** Description: Receive LLCP-related events from the stack. 386 ** p2pEvent: Event code. 387 ** eventData: Event data. 388 ** 389 ** Returns: None 390 ** 391 *******************************************************************************/ 392 static void nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData); 393 394 private: 395 static const int sMax = 10; 396 static PeerToPeer sP2p; 397 398 // Variables below only accessed from a single thread 399 uint16_t mRemoteWKS; // Peer's well known services 400 bool mIsP2pListening; // If P2P listening is enabled or not 401 tNFA_TECHNOLOGY_MASK mP2pListenTechMask; // P2P Listen mask 402 403 // Variable below is protected by mNewJniHandleMutex 404 tJNI_HANDLE mNextJniHandle; 405 406 // Variables below protected by mMutex 407 // A note on locking order: mMutex in PeerToPeer is *ALWAYS* 408 // locked before any locks / guards in P2pServer / P2pClient 409 Mutex mMutex; 410 android::sp<P2pServer> mServers [sMax]; 411 android::sp<P2pClient> mClients [sMax]; 412 413 // Synchronization variables 414 SyncEvent mSetTechEvent; // completion event for NFA_SetP2pListenTech() 415 SyncEvent mSnepDefaultServerStartStopEvent; // completion event for NFA_SnepStartDefaultServer(), NFA_SnepStopDefaultServer() 416 SyncEvent mSnepRegisterEvent; // completion event for NFA_SnepRegisterClient() 417 Mutex mDisconnectMutex; // synchronize the disconnect operation 418 Mutex mNewJniHandleMutex; // synchronize the creation of a new JNI handle 419 420 421 /******************************************************************************* 422 ** 423 ** Function: ndefTypeCallback 424 ** 425 ** Description: Receive NDEF-related events from the stack. 426 ** ndefEvent: Event code. 427 ** eventData: Event data. 428 ** 429 ** Returns: None 430 ** 431 *******************************************************************************/ 432 static void ndefTypeCallback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *evetnData); 433 434 435 /******************************************************************************* 436 ** 437 ** Function: findServer 438 ** 439 ** Description: Find a PeerToPeer object by connection handle. 440 ** nfaP2pServerHandle: Connectin handle. 441 ** 442 ** Returns: PeerToPeer object. 443 ** 444 *******************************************************************************/ 445 android::sp<P2pServer> findServerLocked (tNFA_HANDLE nfaP2pServerHandle); 446 447 448 /******************************************************************************* 449 ** 450 ** Function: findServer 451 ** 452 ** Description: Find a PeerToPeer object by connection handle. 453 ** serviceName: service name. 454 ** 455 ** Returns: PeerToPeer object. 456 ** 457 *******************************************************************************/ 458 android::sp<P2pServer> findServerLocked (tJNI_HANDLE jniHandle); 459 460 461 /******************************************************************************* 462 ** 463 ** Function: findServer 464 ** 465 ** Description: Find a PeerToPeer object by service name 466 ** serviceName: service name. 467 ** 468 ** Returns: PeerToPeer object. 469 ** 470 *******************************************************************************/ 471 android::sp<P2pServer> findServerLocked (const char *serviceName); 472 473 474 /******************************************************************************* 475 ** 476 ** Function: removeServer 477 ** 478 ** Description: Free resources related to a server. 479 ** jniHandle: Connection handle. 480 ** 481 ** Returns: None 482 ** 483 *******************************************************************************/ 484 void removeServer (tJNI_HANDLE jniHandle); 485 486 487 /******************************************************************************* 488 ** 489 ** Function: removeConn 490 ** 491 ** Description: Free resources related to a connection. 492 ** jniHandle: Connection handle. 493 ** 494 ** Returns: None 495 ** 496 *******************************************************************************/ 497 void removeConn (tJNI_HANDLE jniHandle); 498 499 500 /******************************************************************************* 501 ** 502 ** Function: createDataLinkConn 503 ** 504 ** Description: Establish a connection-oriented connection to a peer. 505 ** jniHandle: Connection handle. 506 ** serviceName: Peer's service name. 507 ** destinationSap: Peer's service access point. 508 ** 509 ** Returns: True if ok. 510 ** 511 *******************************************************************************/ 512 bool createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceName, uint8_t destinationSap); 513 514 515 /******************************************************************************* 516 ** 517 ** Function: findClient 518 ** 519 ** Description: Find a PeerToPeer object with a client connection handle. 520 ** nfaConnHandle: Connection handle. 521 ** 522 ** Returns: PeerToPeer object. 523 ** 524 *******************************************************************************/ 525 android::sp<P2pClient> findClient (tNFA_HANDLE nfaConnHandle); 526 527 528 /******************************************************************************* 529 ** 530 ** Function: findClient 531 ** 532 ** Description: Find a PeerToPeer object with a client connection handle. 533 ** jniHandle: Connection handle. 534 ** 535 ** Returns: PeerToPeer object. 536 ** 537 *******************************************************************************/ 538 android::sp<P2pClient> findClient (tJNI_HANDLE jniHandle); 539 540 541 /******************************************************************************* 542 ** 543 ** Function: findClientCon 544 ** 545 ** Description: Find a PeerToPeer object with a client connection handle. 546 ** nfaConnHandle: Connection handle. 547 ** 548 ** Returns: PeerToPeer object. 549 ** 550 *******************************************************************************/ 551 android::sp<P2pClient> findClientCon (tNFA_HANDLE nfaConnHandle); 552 553 554 /******************************************************************************* 555 ** 556 ** Function: findConnection 557 ** 558 ** Description: Find a PeerToPeer object with a connection handle. 559 ** nfaConnHandle: Connection handle. 560 ** 561 ** Returns: PeerToPeer object. 562 ** 563 *******************************************************************************/ 564 android::sp<NfaConn> findConnection (tNFA_HANDLE nfaConnHandle); 565 566 567 /******************************************************************************* 568 ** 569 ** Function: findConnection 570 ** 571 ** Description: Find a PeerToPeer object with a connection handle. 572 ** jniHandle: Connection handle. 573 ** 574 ** Returns: PeerToPeer object. 575 ** 576 *******************************************************************************/ 577 android::sp<NfaConn> findConnection (tJNI_HANDLE jniHandle); 578 }; 579 580 581 /***************************************************************************** 582 ** 583 ** Name: NfaConn 584 ** 585 ** Description: Store information about a connection related to a peer. 586 ** 587 *****************************************************************************/ 588 class NfaConn : public android::RefBase 589 { 590 public: 591 tNFA_HANDLE mNfaConnHandle; // NFA handle of the P2P connection 592 PeerToPeer::tJNI_HANDLE mJniHandle; // JNI handle of the P2P connection 593 uint16_t mMaxInfoUnit; 594 uint8_t mRecvWindow; 595 uint16_t mRemoteMaxInfoUnit; 596 uint8_t mRemoteRecvWindow; 597 SyncEvent mReadEvent; // event for reading 598 SyncEvent mCongEvent; // event for congestion 599 SyncEvent mDisconnectingEvent; // event for disconnecting 600 601 602 /******************************************************************************* 603 ** 604 ** Function: NfaConn 605 ** 606 ** Description: Initialize member variables. 607 ** 608 ** Returns: None 609 ** 610 *******************************************************************************/ 611 NfaConn(); 612 }; 613 614 615 /***************************************************************************** 616 ** 617 ** Name: P2pServer 618 ** 619 ** Description: Store information about an in-bound connection from a peer. 620 ** 621 *****************************************************************************/ 622 class P2pServer : public android::RefBase 623 { 624 public: 625 static const std::string sSnepServiceName; 626 627 tNFA_HANDLE mNfaP2pServerHandle; // NFA p2p handle of local server 628 PeerToPeer::tJNI_HANDLE mJniHandle; // JNI Handle 629 SyncEvent mRegServerEvent; // for NFA_P2pRegisterServer() 630 SyncEvent mConnRequestEvent; // for accept() 631 std::string mServiceName; 632 633 /******************************************************************************* 634 ** 635 ** Function: P2pServer 636 ** 637 ** Description: Initialize member variables. 638 ** 639 ** Returns: None 640 ** 641 *******************************************************************************/ 642 P2pServer (PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName); 643 644 /******************************************************************************* 645 ** 646 ** Function: registerWithStack 647 ** 648 ** Description: Register this server with the stack. 649 ** 650 ** Returns: True if ok. 651 ** 652 *******************************************************************************/ 653 bool registerWithStack(); 654 655 /******************************************************************************* 656 ** 657 ** Function: accept 658 ** 659 ** Description: Accept a peer's request to connect. 660 ** serverJniHandle: Server's handle. 661 ** connJniHandle: Connection handle. 662 ** maxInfoUnit: Maximum information unit. 663 ** recvWindow: Receive window size. 664 ** 665 ** Returns: True if ok. 666 ** 667 *******************************************************************************/ 668 bool accept (PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle, 669 int maxInfoUnit, int recvWindow); 670 671 /******************************************************************************* 672 ** 673 ** Function: unblockAll 674 ** 675 ** Description: Unblocks all server connections 676 ** 677 ** Returns: True if ok. 678 ** 679 *******************************************************************************/ 680 void unblockAll(); 681 682 /******************************************************************************* 683 ** 684 ** Function: findServerConnection 685 ** 686 ** Description: Find a P2pServer that has the handle. 687 ** nfaConnHandle: NFA connection handle. 688 ** 689 ** Returns: P2pServer object. 690 ** 691 *******************************************************************************/ 692 android::sp<NfaConn> findServerConnection (tNFA_HANDLE nfaConnHandle); 693 694 /******************************************************************************* 695 ** 696 ** Function: findServerConnection 697 ** 698 ** Description: Find a P2pServer that has the handle. 699 ** jniHandle: JNI connection handle. 700 ** 701 ** Returns: P2pServer object. 702 ** 703 *******************************************************************************/ 704 android::sp<NfaConn> findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle); 705 706 /******************************************************************************* 707 ** 708 ** Function: removeServerConnection 709 ** 710 ** Description: Remove a server connection with the provided handle. 711 ** jniHandle: JNI connection handle. 712 ** 713 ** Returns: True if connection found and removed. 714 ** 715 *******************************************************************************/ 716 bool removeServerConnection(PeerToPeer::tJNI_HANDLE jniHandle); 717 718 private: 719 Mutex mMutex; 720 // mServerConn is protected by mMutex 721 android::sp<NfaConn> mServerConn[MAX_NFA_CONNS_PER_SERVER]; 722 723 /******************************************************************************* 724 ** 725 ** Function: allocateConnection 726 ** 727 ** Description: Allocate a new connection to accept on 728 ** jniHandle: JNI connection handle. 729 ** 730 ** Returns: Allocated connection object 731 ** NULL if the maximum number of connections was reached 732 ** 733 *******************************************************************************/ 734 android::sp<NfaConn> allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle); 735 }; 736 737 738 /***************************************************************************** 739 ** 740 ** Name: P2pClient 741 ** 742 ** Description: Store information about an out-bound connection to a peer. 743 ** 744 *****************************************************************************/ 745 class P2pClient : public android::RefBase 746 { 747 public: 748 tNFA_HANDLE mNfaP2pClientHandle; // NFA p2p handle of client 749 bool mIsConnecting; // Set true while connecting 750 android::sp<NfaConn> mClientConn; 751 SyncEvent mRegisteringEvent; // For client registration 752 SyncEvent mConnectingEvent; // for NFA_P2pConnectByName or Sap() 753 SyncEvent mSnepEvent; // To wait for SNEP completion 754 755 /******************************************************************************* 756 ** 757 ** Function: P2pClient 758 ** 759 ** Description: Initialize member variables. 760 ** 761 ** Returns: None 762 ** 763 *******************************************************************************/ 764 P2pClient (); 765 766 767 /******************************************************************************* 768 ** 769 ** Function: ~P2pClient 770 ** 771 ** Description: Free all resources. 772 ** 773 ** Returns: None 774 ** 775 *******************************************************************************/ 776 ~P2pClient (); 777 778 779 /******************************************************************************* 780 ** 781 ** Function: unblock 782 ** 783 ** Description: Unblocks any threads that are locked on this connection 784 ** 785 ** Returns: None 786 ** 787 *******************************************************************************/ 788 void unblock(); 789 }; 790 791