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