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 #include "OverrideLog.h" 21 #include "PeerToPeer.h" 22 #include "NfcJniUtil.h" 23 #include "llcp_defs.h" 24 #include "config.h" 25 #include "JavaClassConstants.h" 26 #include <ScopedLocalRef.h> 27 28 /* Some older PN544-based solutions would only send the first SYMM back 29 * (as an initiator) after the full LTO (750ms). But our connect timer 30 * starts immediately, and hence we may timeout if the timer is set to 31 * 1000 ms. Worse, this causes us to immediately connect to the NPP 32 * socket, causing concurrency issues in that stack. Increase the default 33 * timeout to 2000 ms, giving us enough time to complete the first connect. 34 */ 35 #define LLCP_DATA_LINK_TIMEOUT 2000 36 37 using namespace android; 38 39 namespace android 40 { 41 extern void nativeNfcTag_registerNdefTypeHandler (); 42 extern void nativeNfcTag_deregisterNdefTypeHandler (); 43 } 44 45 46 PeerToPeer PeerToPeer::sP2p; 47 const std::string P2pServer::sSnepServiceName ("urn:nfc:sn:snep"); 48 49 50 /******************************************************************************* 51 ** 52 ** Function: PeerToPeer 53 ** 54 ** Description: Initialize member variables. 55 ** 56 ** Returns: None 57 ** 58 *******************************************************************************/ 59 PeerToPeer::PeerToPeer () 60 : mRemoteWKS (0), 61 mIsP2pListening (false), 62 mP2pListenTechMask (NFA_TECHNOLOGY_MASK_A 63 | NFA_TECHNOLOGY_MASK_F 64 | NFA_TECHNOLOGY_MASK_A_ACTIVE 65 | NFA_TECHNOLOGY_MASK_F_ACTIVE), 66 mNextJniHandle (1) 67 { 68 memset (mServers, 0, sizeof(mServers)); 69 memset (mClients, 0, sizeof(mClients)); 70 } 71 72 73 /******************************************************************************* 74 ** 75 ** Function: ~PeerToPeer 76 ** 77 ** Description: Free all resources. 78 ** 79 ** Returns: None 80 ** 81 *******************************************************************************/ 82 PeerToPeer::~PeerToPeer () 83 { 84 } 85 86 87 /******************************************************************************* 88 ** 89 ** Function: getInstance 90 ** 91 ** Description: Get the singleton PeerToPeer object. 92 ** 93 ** Returns: Singleton PeerToPeer object. 94 ** 95 *******************************************************************************/ 96 PeerToPeer& PeerToPeer::getInstance () 97 { 98 return sP2p; 99 } 100 101 102 /******************************************************************************* 103 ** 104 ** Function: initialize 105 ** 106 ** Description: Initialize member variables. 107 ** 108 ** Returns: None 109 ** 110 *******************************************************************************/ 111 void PeerToPeer::initialize () 112 { 113 ALOGD ("PeerToPeer::initialize"); 114 unsigned long num = 0; 115 116 if (GetNumValue ("P2P_LISTEN_TECH_MASK", &num, sizeof (num))) 117 mP2pListenTechMask = num; 118 } 119 120 121 /******************************************************************************* 122 ** 123 ** Function: findServerLocked 124 ** 125 ** Description: Find a PeerToPeer object by connection handle. 126 ** Assumes mMutex is already held 127 ** nfaP2pServerHandle: Connectin handle. 128 ** 129 ** Returns: PeerToPeer object. 130 ** 131 *******************************************************************************/ 132 sp<P2pServer> PeerToPeer::findServerLocked (tNFA_HANDLE nfaP2pServerHandle) 133 { 134 for (int i = 0; i < sMax; i++) 135 { 136 if ( (mServers[i] != NULL) 137 && (mServers[i]->mNfaP2pServerHandle == nfaP2pServerHandle) ) 138 { 139 return (mServers [i]); 140 } 141 } 142 143 // If here, not found 144 return NULL; 145 } 146 147 148 /******************************************************************************* 149 ** 150 ** Function: findServerLocked 151 ** 152 ** Description: Find a PeerToPeer object by connection handle. 153 ** Assumes mMutex is already held 154 ** serviceName: service name. 155 ** 156 ** Returns: PeerToPeer object. 157 ** 158 *******************************************************************************/ 159 sp<P2pServer> PeerToPeer::findServerLocked (tJNI_HANDLE jniHandle) 160 { 161 for (int i = 0; i < sMax; i++) 162 { 163 if ( (mServers[i] != NULL) 164 && (mServers[i]->mJniHandle == jniHandle) ) 165 { 166 return (mServers [i]); 167 } 168 } 169 170 // If here, not found 171 return NULL; 172 } 173 174 175 /******************************************************************************* 176 ** 177 ** Function: findServerLocked 178 ** 179 ** Description: Find a PeerToPeer object by service name 180 ** Assumes mMutex is already heldf 181 ** serviceName: service name. 182 ** 183 ** Returns: PeerToPeer object. 184 ** 185 *******************************************************************************/ 186 sp<P2pServer> PeerToPeer::findServerLocked (const char *serviceName) 187 { 188 for (int i = 0; i < sMax; i++) 189 { 190 if ( (mServers[i] != NULL) && (mServers[i]->mServiceName.compare(serviceName) == 0) ) 191 return (mServers [i]); 192 } 193 194 // If here, not found 195 return NULL; 196 } 197 198 199 /******************************************************************************* 200 ** 201 ** Function: registerServer 202 ** 203 ** Description: Let a server start listening for peer's connection request. 204 ** jniHandle: Connection handle. 205 ** serviceName: Server's service name. 206 ** 207 ** Returns: True if ok. 208 ** 209 *******************************************************************************/ 210 bool PeerToPeer::registerServer (tJNI_HANDLE jniHandle, const char *serviceName) 211 { 212 static const char fn [] = "PeerToPeer::registerServer"; 213 ALOGD ("%s: enter; service name: %s JNI handle: %u", fn, serviceName, jniHandle); 214 sp<P2pServer> pSrv = NULL; 215 216 mMutex.lock(); 217 // Check if already registered 218 if ((pSrv = findServerLocked(serviceName)) != NULL) 219 { 220 ALOGD ("%s: service name=%s already registered, handle: 0x%04x", fn, serviceName, pSrv->mNfaP2pServerHandle); 221 222 // Update JNI handle 223 pSrv->mJniHandle = jniHandle; 224 mMutex.unlock(); 225 return (true); 226 } 227 228 for (int ii = 0; ii < sMax; ii++) 229 { 230 if (mServers[ii] == NULL) 231 { 232 pSrv = mServers[ii] = new P2pServer(jniHandle, serviceName); 233 234 ALOGD ("%s: added new p2p server index: %d handle: %u name: %s", fn, ii, jniHandle, serviceName); 235 break; 236 } 237 } 238 mMutex.unlock(); 239 240 if (pSrv == NULL) 241 { 242 ALOGE ("%s: service name=%s no free entry", fn, serviceName); 243 return (false); 244 } 245 246 if (pSrv->registerWithStack()) { 247 ALOGD ("%s: got new p2p server h=0x%X", fn, pSrv->mNfaP2pServerHandle); 248 return (true); 249 } else { 250 ALOGE ("%s: invalid server handle", fn); 251 removeServer (jniHandle); 252 return (false); 253 } 254 } 255 256 257 /******************************************************************************* 258 ** 259 ** Function: removeServer 260 ** 261 ** Description: Free resources related to a server. 262 ** jniHandle: Connection handle. 263 ** 264 ** Returns: None 265 ** 266 *******************************************************************************/ 267 void PeerToPeer::removeServer (tJNI_HANDLE jniHandle) 268 { 269 static const char fn [] = "PeerToPeer::removeServer"; 270 271 AutoMutex mutex(mMutex); 272 273 for (int i = 0; i < sMax; i++) 274 { 275 if ( (mServers[i] != NULL) && (mServers[i]->mJniHandle == jniHandle) ) 276 { 277 ALOGD ("%s: server jni_handle: %u; nfa_handle: 0x%04x; name: %s; index=%d", 278 fn, jniHandle, mServers[i]->mNfaP2pServerHandle, mServers[i]->mServiceName.c_str(), i); 279 280 mServers [i] = NULL; 281 return; 282 } 283 } 284 ALOGE ("%s: unknown server jni handle: %u", fn, jniHandle); 285 } 286 287 288 /******************************************************************************* 289 ** 290 ** Function: llcpActivatedHandler 291 ** 292 ** Description: Receive LLLCP-activated event from stack. 293 ** nat: JVM-related data. 294 ** activated: Event data. 295 ** 296 ** Returns: None 297 ** 298 *******************************************************************************/ 299 void PeerToPeer::llcpActivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_ACTIVATED& activated) 300 { 301 static const char fn [] = "PeerToPeer::llcpActivatedHandler"; 302 ALOGD ("%s: enter", fn); 303 304 //no longer need to receive NDEF message from a tag 305 android::nativeNfcTag_deregisterNdefTypeHandler (); 306 307 mRemoteWKS = activated.remote_wks; 308 309 JNIEnv* e = NULL; 310 ScopedAttach attach(nat->vm, &e); 311 if (e == NULL) 312 { 313 ALOGE ("%s: jni env is null", fn); 314 return; 315 } 316 317 ALOGD ("%s: get object class", fn); 318 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(nat->cached_P2pDevice)); 319 if (e->ExceptionCheck()) { 320 e->ExceptionClear(); 321 ALOGE ("%s: fail get p2p device", fn); 322 return; 323 } 324 325 ALOGD ("%s: instantiate", fn); 326 /* New target instance */ 327 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V"); 328 ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor)); 329 330 /* Set P2P Target mode */ 331 jfieldID f = e->GetFieldID(tag_cls.get(), "mMode", "I"); 332 333 if (activated.is_initiator == TRUE) { 334 ALOGD ("%s: p2p initiator", fn); 335 e->SetIntField(tag.get(), f, (jint) MODE_P2P_INITIATOR); 336 } else { 337 ALOGD ("%s: p2p target", fn); 338 e->SetIntField(tag.get(), f, (jint) MODE_P2P_TARGET); 339 } 340 341 /* Set tag handle */ 342 f = e->GetFieldID(tag_cls.get(), "mHandle", "I"); 343 e->SetIntField(tag.get(), f, (jint) 0x1234); // ?? This handle is not used for anything 344 345 if (nat->tag != NULL) { 346 e->DeleteGlobalRef(nat->tag); 347 } 348 nat->tag = e->NewGlobalRef(tag.get()); 349 350 ALOGD ("%s: notify nfc service", fn); 351 352 /* Notify manager that new a P2P device was found */ 353 e->CallVoidMethod(nat->manager, android::gCachedNfcManagerNotifyLlcpLinkActivation, tag.get()); 354 if (e->ExceptionCheck()) { 355 e->ExceptionClear(); 356 ALOGE ("%s: fail notify", fn); 357 } 358 359 ALOGD ("%s: exit", fn); 360 } 361 362 363 /******************************************************************************* 364 ** 365 ** Function: llcpDeactivatedHandler 366 ** 367 ** Description: Receive LLLCP-deactivated event from stack. 368 ** nat: JVM-related data. 369 ** deactivated: Event data. 370 ** 371 ** Returns: None 372 ** 373 *******************************************************************************/ 374 void PeerToPeer::llcpDeactivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_DEACTIVATED& /*deactivated*/) 375 { 376 static const char fn [] = "PeerToPeer::llcpDeactivatedHandler"; 377 ALOGD ("%s: enter", fn); 378 379 JNIEnv* e = NULL; 380 ScopedAttach attach(nat->vm, &e); 381 if (e == NULL) 382 { 383 ALOGE ("%s: jni env is null", fn); 384 return; 385 } 386 387 ALOGD ("%s: notify nfc service", fn); 388 /* Notify manager that the LLCP is lost or deactivated */ 389 e->CallVoidMethod (nat->manager, android::gCachedNfcManagerNotifyLlcpLinkDeactivated, nat->tag); 390 if (e->ExceptionCheck()) 391 { 392 e->ExceptionClear(); 393 ALOGE ("%s: fail notify", fn); 394 } 395 396 //let the tag-reading code handle NDEF data event 397 android::nativeNfcTag_registerNdefTypeHandler (); 398 ALOGD ("%s: exit", fn); 399 } 400 401 void PeerToPeer::llcpFirstPacketHandler (nfc_jni_native_data* nat) 402 { 403 static const char fn [] = "PeerToPeer::llcpFirstPacketHandler"; 404 ALOGD ("%s: enter", fn); 405 406 JNIEnv* e = NULL; 407 ScopedAttach attach(nat->vm, &e); 408 if (e == NULL) 409 { 410 ALOGE ("%s: jni env is null", fn); 411 return; 412 } 413 414 ALOGD ("%s: notify nfc service", fn); 415 /* Notify manager that the LLCP is lost or deactivated */ 416 e->CallVoidMethod (nat->manager, android::gCachedNfcManagerNotifyLlcpFirstPacketReceived, nat->tag); 417 if (e->ExceptionCheck()) 418 { 419 e->ExceptionClear(); 420 ALOGE ("%s: fail notify", fn); 421 } 422 423 ALOGD ("%s: exit", fn); 424 425 } 426 /******************************************************************************* 427 ** 428 ** Function: accept 429 ** 430 ** Description: Accept a peer's request to connect. 431 ** serverJniHandle: Server's handle. 432 ** connJniHandle: Connection handle. 433 ** maxInfoUnit: Maximum information unit. 434 ** recvWindow: Receive window size. 435 ** 436 ** Returns: True if ok. 437 ** 438 *******************************************************************************/ 439 bool PeerToPeer::accept (tJNI_HANDLE serverJniHandle, tJNI_HANDLE connJniHandle, int maxInfoUnit, int recvWindow) 440 { 441 static const char fn [] = "PeerToPeer::accept"; 442 sp<P2pServer> pSrv = NULL; 443 444 ALOGD ("%s: enter; server jni handle: %u; conn jni handle: %u; maxInfoUnit: %d; recvWindow: %d", fn, 445 serverJniHandle, connJniHandle, maxInfoUnit, recvWindow); 446 447 mMutex.lock(); 448 if ((pSrv = findServerLocked (serverJniHandle)) == NULL) 449 { 450 ALOGE ("%s: unknown server jni handle: %u", fn, serverJniHandle); 451 mMutex.unlock(); 452 return (false); 453 } 454 mMutex.unlock(); 455 456 return pSrv->accept(serverJniHandle, connJniHandle, maxInfoUnit, recvWindow); 457 } 458 459 460 /******************************************************************************* 461 ** 462 ** Function: deregisterServer 463 ** 464 ** Description: Stop a P2pServer from listening for peer. 465 ** 466 ** Returns: True if ok. 467 ** 468 *******************************************************************************/ 469 bool PeerToPeer::deregisterServer (tJNI_HANDLE jniHandle) 470 { 471 static const char fn [] = "PeerToPeer::deregisterServer"; 472 ALOGD ("%s: enter; JNI handle: %u", fn, jniHandle); 473 tNFA_STATUS nfaStat = NFA_STATUS_FAILED; 474 sp<P2pServer> pSrv = NULL; 475 476 mMutex.lock(); 477 if ((pSrv = findServerLocked (jniHandle)) == NULL) 478 { 479 ALOGE ("%s: unknown service handle: %u", fn, jniHandle); 480 mMutex.unlock(); 481 return (false); 482 } 483 mMutex.unlock(); 484 485 { 486 // Server does not call NFA_P2pDisconnect(), so unblock the accept() 487 SyncEventGuard guard (pSrv->mConnRequestEvent); 488 pSrv->mConnRequestEvent.notifyOne(); 489 } 490 491 nfaStat = NFA_P2pDeregister (pSrv->mNfaP2pServerHandle); 492 if (nfaStat != NFA_STATUS_OK) 493 { 494 ALOGE ("%s: deregister error=0x%X", fn, nfaStat); 495 } 496 497 removeServer (jniHandle); 498 499 ALOGD ("%s: exit", fn); 500 return true; 501 } 502 503 504 /******************************************************************************* 505 ** 506 ** Function: createClient 507 ** 508 ** Description: Create a P2pClient object for a new out-bound connection. 509 ** jniHandle: Connection handle. 510 ** miu: Maximum information unit. 511 ** rw: Receive window size. 512 ** 513 ** Returns: True if ok. 514 ** 515 *******************************************************************************/ 516 bool PeerToPeer::createClient (tJNI_HANDLE jniHandle, UINT16 miu, UINT8 rw) 517 { 518 static const char fn [] = "PeerToPeer::createClient"; 519 int i = 0; 520 ALOGD ("%s: enter: jni h: %u miu: %u rw: %u", fn, jniHandle, miu, rw); 521 522 mMutex.lock(); 523 sp<P2pClient> client = NULL; 524 for (i = 0; i < sMax; i++) 525 { 526 if (mClients[i] == NULL) 527 { 528 mClients [i] = client = new P2pClient(); 529 530 mClients [i]->mClientConn->mJniHandle = jniHandle; 531 mClients [i]->mClientConn->mMaxInfoUnit = miu; 532 mClients [i]->mClientConn->mRecvWindow = rw; 533 break; 534 } 535 } 536 mMutex.unlock(); 537 538 if (client == NULL) 539 { 540 ALOGE ("%s: fail", fn); 541 return (false); 542 } 543 544 ALOGD ("%s: pClient: 0x%p assigned for client jniHandle: %u", fn, client.get(), jniHandle); 545 546 { 547 SyncEventGuard guard (mClients[i]->mRegisteringEvent); 548 NFA_P2pRegisterClient (NFA_P2P_DLINK_TYPE, nfaClientCallback); 549 mClients[i]->mRegisteringEvent.wait(); //wait for NFA_P2P_REG_CLIENT_EVT 550 } 551 552 if (mClients[i]->mNfaP2pClientHandle != NFA_HANDLE_INVALID) 553 { 554 ALOGD ("%s: exit; new client jniHandle: %u NFA Handle: 0x%04x", fn, jniHandle, client->mClientConn->mNfaConnHandle); 555 return (true); 556 } 557 else 558 { 559 ALOGE ("%s: FAILED; new client jniHandle: %u NFA Handle: 0x%04x", fn, jniHandle, client->mClientConn->mNfaConnHandle); 560 removeConn (jniHandle); 561 return (false); 562 } 563 } 564 565 566 /******************************************************************************* 567 ** 568 ** Function: removeConn 569 ** 570 ** Description: Free resources related to a connection. 571 ** jniHandle: Connection handle. 572 ** 573 ** Returns: None 574 ** 575 *******************************************************************************/ 576 void PeerToPeer::removeConn(tJNI_HANDLE jniHandle) 577 { 578 static const char fn[] = "PeerToPeer::removeConn"; 579 580 AutoMutex mutex(mMutex); 581 // If the connection is a for a client, delete the client itself 582 for (int ii = 0; ii < sMax; ii++) 583 { 584 if ((mClients[ii] != NULL) && (mClients[ii]->mClientConn->mJniHandle == jniHandle)) 585 { 586 if (mClients[ii]->mNfaP2pClientHandle != NFA_HANDLE_INVALID) 587 NFA_P2pDeregister (mClients[ii]->mNfaP2pClientHandle); 588 589 mClients[ii] = NULL; 590 ALOGD ("%s: deleted client handle: %u index: %u", fn, jniHandle, ii); 591 return; 592 } 593 } 594 595 // If the connection is for a server, just delete the connection 596 for (int ii = 0; ii < sMax; ii++) 597 { 598 if (mServers[ii] != NULL) 599 { 600 if (mServers[ii]->removeServerConnection(jniHandle)) { 601 return; 602 } 603 } 604 } 605 606 ALOGE ("%s: could not find handle: %u", fn, jniHandle); 607 } 608 609 610 /******************************************************************************* 611 ** 612 ** Function: connectConnOriented 613 ** 614 ** Description: Establish a connection-oriented connection to a peer. 615 ** jniHandle: Connection handle. 616 ** serviceName: Peer's service name. 617 ** 618 ** Returns: True if ok. 619 ** 620 *******************************************************************************/ 621 bool PeerToPeer::connectConnOriented (tJNI_HANDLE jniHandle, const char* serviceName) 622 { 623 static const char fn [] = "PeerToPeer::connectConnOriented"; 624 ALOGD ("%s: enter; h: %u service name=%s", fn, jniHandle, serviceName); 625 bool stat = createDataLinkConn (jniHandle, serviceName, 0); 626 ALOGD ("%s: exit; h: %u stat: %u", fn, jniHandle, stat); 627 return stat; 628 } 629 630 631 /******************************************************************************* 632 ** 633 ** Function: connectConnOriented 634 ** 635 ** Description: Establish a connection-oriented connection to a peer. 636 ** jniHandle: Connection handle. 637 ** destinationSap: Peer's service access point. 638 ** 639 ** Returns: True if ok. 640 ** 641 *******************************************************************************/ 642 bool PeerToPeer::connectConnOriented (tJNI_HANDLE jniHandle, UINT8 destinationSap) 643 { 644 static const char fn [] = "PeerToPeer::connectConnOriented"; 645 ALOGD ("%s: enter; h: %u dest sap: 0x%X", fn, jniHandle, destinationSap); 646 bool stat = createDataLinkConn (jniHandle, NULL, destinationSap); 647 ALOGD ("%s: exit; h: %u stat: %u", fn, jniHandle, stat); 648 return stat; 649 } 650 651 652 /******************************************************************************* 653 ** 654 ** Function: createDataLinkConn 655 ** 656 ** Description: Establish a connection-oriented connection to a peer. 657 ** jniHandle: Connection handle. 658 ** serviceName: Peer's service name. 659 ** destinationSap: Peer's service access point. 660 ** 661 ** Returns: True if ok. 662 ** 663 *******************************************************************************/ 664 bool PeerToPeer::createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceName, UINT8 destinationSap) 665 { 666 static const char fn [] = "PeerToPeer::createDataLinkConn"; 667 ALOGD ("%s: enter", fn); 668 tNFA_STATUS nfaStat = NFA_STATUS_FAILED; 669 sp<P2pClient> pClient = NULL; 670 671 if ((pClient = findClient (jniHandle)) == NULL) 672 { 673 ALOGE ("%s: can't find client, JNI handle: %u", fn, jniHandle); 674 return (false); 675 } 676 677 { 678 SyncEventGuard guard (pClient->mConnectingEvent); 679 pClient->mIsConnecting = true; 680 681 if (serviceName) 682 nfaStat = NFA_P2pConnectByName (pClient->mNfaP2pClientHandle, 683 const_cast<char*>(serviceName), pClient->mClientConn->mMaxInfoUnit, 684 pClient->mClientConn->mRecvWindow); 685 else if (destinationSap) 686 nfaStat = NFA_P2pConnectBySap (pClient->mNfaP2pClientHandle, destinationSap, 687 pClient->mClientConn->mMaxInfoUnit, pClient->mClientConn->mRecvWindow); 688 if (nfaStat == NFA_STATUS_OK) 689 { 690 ALOGD ("%s: wait for connected event mConnectingEvent: 0x%p", fn, pClient.get()); 691 pClient->mConnectingEvent.wait(); 692 } 693 } 694 695 if (nfaStat == NFA_STATUS_OK) 696 { 697 if (pClient->mClientConn->mNfaConnHandle == NFA_HANDLE_INVALID) 698 { 699 removeConn (jniHandle); 700 nfaStat = NFA_STATUS_FAILED; 701 } 702 else 703 pClient->mIsConnecting = false; 704 } 705 else 706 { 707 removeConn (jniHandle); 708 ALOGE ("%s: fail; error=0x%X", fn, nfaStat); 709 } 710 711 ALOGD ("%s: exit", fn); 712 return nfaStat == NFA_STATUS_OK; 713 } 714 715 716 /******************************************************************************* 717 ** 718 ** Function: findClient 719 ** 720 ** Description: Find a PeerToPeer object with a client connection handle. 721 ** nfaConnHandle: Connection handle. 722 ** 723 ** Returns: PeerToPeer object. 724 ** 725 *******************************************************************************/ 726 sp<P2pClient> PeerToPeer::findClient (tNFA_HANDLE nfaConnHandle) 727 { 728 AutoMutex mutex(mMutex); 729 for (int i = 0; i < sMax; i++) 730 { 731 if ((mClients[i] != NULL) && (mClients[i]->mNfaP2pClientHandle == nfaConnHandle)) 732 return (mClients[i]); 733 } 734 return (NULL); 735 } 736 737 738 /******************************************************************************* 739 ** 740 ** Function: findClient 741 ** 742 ** Description: Find a PeerToPeer object with a client connection handle. 743 ** jniHandle: Connection handle. 744 ** 745 ** Returns: PeerToPeer object. 746 ** 747 *******************************************************************************/ 748 sp<P2pClient> PeerToPeer::findClient (tJNI_HANDLE jniHandle) 749 { 750 AutoMutex mutex(mMutex); 751 for (int i = 0; i < sMax; i++) 752 { 753 if ((mClients[i] != NULL) && (mClients[i]->mClientConn->mJniHandle == jniHandle)) 754 return (mClients[i]); 755 } 756 return (NULL); 757 } 758 759 760 /******************************************************************************* 761 ** 762 ** Function: findClientCon 763 ** 764 ** Description: Find a PeerToPeer object with a client connection handle. 765 ** nfaConnHandle: Connection handle. 766 ** 767 ** Returns: PeerToPeer object. 768 ** 769 *******************************************************************************/ 770 sp<P2pClient> PeerToPeer::findClientCon (tNFA_HANDLE nfaConnHandle) 771 { 772 AutoMutex mutex(mMutex); 773 for (int i = 0; i < sMax; i++) 774 { 775 if ((mClients[i] != NULL) && (mClients[i]->mClientConn->mNfaConnHandle == nfaConnHandle)) 776 return (mClients[i]); 777 } 778 return (NULL); 779 } 780 781 782 /******************************************************************************* 783 ** 784 ** Function: findConnection 785 ** 786 ** Description: Find a PeerToPeer object with a connection handle. 787 ** nfaConnHandle: Connection handle. 788 ** 789 ** Returns: PeerToPeer object. 790 ** 791 *******************************************************************************/ 792 sp<NfaConn> PeerToPeer::findConnection (tNFA_HANDLE nfaConnHandle) 793 { 794 AutoMutex mutex(mMutex); 795 // First, look through all the client control blocks 796 for (int ii = 0; ii < sMax; ii++) 797 { 798 if ( (mClients[ii] != NULL) 799 && (mClients[ii]->mClientConn->mNfaConnHandle == nfaConnHandle) ) { 800 return mClients[ii]->mClientConn; 801 } 802 } 803 804 // Not found yet. Look through all the server control blocks 805 for (int ii = 0; ii < sMax; ii++) 806 { 807 if (mServers[ii] != NULL) 808 { 809 sp<NfaConn> conn = mServers[ii]->findServerConnection(nfaConnHandle); 810 if (conn != NULL) { 811 return conn; 812 } 813 } 814 } 815 816 // Not found... 817 return NULL; 818 } 819 820 821 /******************************************************************************* 822 ** 823 ** Function: findConnection 824 ** 825 ** Description: Find a PeerToPeer object with a connection handle. 826 ** jniHandle: Connection handle. 827 ** 828 ** Returns: PeerToPeer object. 829 ** 830 *******************************************************************************/ 831 sp<NfaConn> PeerToPeer::findConnection (tJNI_HANDLE jniHandle) 832 { 833 AutoMutex mutex(mMutex); 834 // First, look through all the client control blocks 835 for (int ii = 0; ii < sMax; ii++) 836 { 837 if ( (mClients[ii] != NULL) 838 && (mClients[ii]->mClientConn->mJniHandle == jniHandle) ) { 839 return mClients[ii]->mClientConn; 840 } 841 } 842 843 // Not found yet. Look through all the server control blocks 844 for (int ii = 0; ii < sMax; ii++) 845 { 846 if (mServers[ii] != NULL) 847 { 848 sp<NfaConn> conn = mServers[ii]->findServerConnection(jniHandle); 849 if (conn != NULL) { 850 return conn; 851 } 852 } 853 } 854 855 // Not found... 856 return NULL; 857 } 858 859 860 /******************************************************************************* 861 ** 862 ** Function: send 863 ** 864 ** Description: Send data to peer. 865 ** jniHandle: Handle of connection. 866 ** buffer: Buffer of data. 867 ** bufferLen: Length of data. 868 ** 869 ** Returns: True if ok. 870 ** 871 *******************************************************************************/ 872 bool PeerToPeer::send (tJNI_HANDLE jniHandle, UINT8 *buffer, UINT16 bufferLen) 873 { 874 static const char fn [] = "PeerToPeer::send"; 875 tNFA_STATUS nfaStat = NFA_STATUS_FAILED; 876 sp<NfaConn> pConn = NULL; 877 878 if ((pConn = findConnection (jniHandle)) == NULL) 879 { 880 ALOGE ("%s: can't find connection handle: %u", fn, jniHandle); 881 return (false); 882 } 883 884 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: send data; jniHandle: %u nfaHandle: 0x%04X", 885 fn, pConn->mJniHandle, pConn->mNfaConnHandle); 886 887 while (true) 888 { 889 SyncEventGuard guard (pConn->mCongEvent); 890 nfaStat = NFA_P2pSendData (pConn->mNfaConnHandle, bufferLen, buffer); 891 if (nfaStat == NFA_STATUS_CONGESTED) 892 pConn->mCongEvent.wait (); //wait for NFA_P2P_CONGEST_EVT 893 else 894 break; 895 896 if (pConn->mNfaConnHandle == NFA_HANDLE_INVALID) //peer already disconnected 897 { 898 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: peer disconnected", fn); 899 return (false); 900 } 901 } 902 903 if (nfaStat == NFA_STATUS_OK) 904 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit OK; JNI handle: %u NFA Handle: 0x%04x", fn, jniHandle, pConn->mNfaConnHandle); 905 else 906 ALOGE ("%s: Data not sent; JNI handle: %u NFA Handle: 0x%04x error: 0x%04x", 907 fn, jniHandle, pConn->mNfaConnHandle, nfaStat); 908 909 return nfaStat == NFA_STATUS_OK; 910 } 911 912 913 /******************************************************************************* 914 ** 915 ** Function: receive 916 ** 917 ** Description: Receive data from peer. 918 ** jniHandle: Handle of connection. 919 ** buffer: Buffer to store data. 920 ** bufferLen: Max length of buffer. 921 ** actualLen: Actual length received. 922 ** 923 ** Returns: True if ok. 924 ** 925 *******************************************************************************/ 926 bool PeerToPeer::receive (tJNI_HANDLE jniHandle, UINT8* buffer, UINT16 bufferLen, UINT16& actualLen) 927 { 928 static const char fn [] = "PeerToPeer::receive"; 929 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; jniHandle: %u bufferLen: %u", fn, jniHandle, bufferLen); 930 sp<NfaConn> pConn = NULL; 931 tNFA_STATUS stat = NFA_STATUS_FAILED; 932 UINT32 actualDataLen2 = 0; 933 BOOLEAN isMoreData = TRUE; 934 bool retVal = false; 935 936 if ((pConn = findConnection (jniHandle)) == NULL) 937 { 938 ALOGE ("%s: can't find connection handle: %u", fn, jniHandle); 939 return (false); 940 } 941 942 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: jniHandle: %u nfaHandle: 0x%04X buf len=%u", fn, pConn->mJniHandle, pConn->mNfaConnHandle, bufferLen); 943 944 while (pConn->mNfaConnHandle != NFA_HANDLE_INVALID) 945 { 946 //NFA_P2pReadData() is synchronous 947 stat = NFA_P2pReadData (pConn->mNfaConnHandle, bufferLen, &actualDataLen2, buffer, &isMoreData); 948 if ((stat == NFA_STATUS_OK) && (actualDataLen2 > 0)) //received some data 949 { 950 actualLen = (UINT16) actualDataLen2; 951 retVal = true; 952 break; 953 } 954 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: waiting for data...", fn); 955 { 956 SyncEventGuard guard (pConn->mReadEvent); 957 pConn->mReadEvent.wait(); 958 } 959 } //while 960 961 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit; nfa h: 0x%X ok: %u actual len: %u", fn, pConn->mNfaConnHandle, retVal, actualLen); 962 return retVal; 963 } 964 965 966 /******************************************************************************* 967 ** 968 ** Function: disconnectConnOriented 969 ** 970 ** Description: Disconnect a connection-oriented connection with peer. 971 ** jniHandle: Handle of connection. 972 ** 973 ** Returns: True if ok. 974 ** 975 *******************************************************************************/ 976 bool PeerToPeer::disconnectConnOriented (tJNI_HANDLE jniHandle) 977 { 978 static const char fn [] = "PeerToPeer::disconnectConnOriented"; 979 tNFA_STATUS nfaStat = NFA_STATUS_FAILED; 980 sp<P2pClient> pClient = NULL; 981 sp<NfaConn> pConn = NULL; 982 983 ALOGD ("%s: enter; jni handle: %u", fn, jniHandle); 984 985 if ((pConn = findConnection(jniHandle)) == NULL) 986 { 987 ALOGE ("%s: can't find connection handle: %u", fn, jniHandle); 988 return (false); 989 } 990 991 // If this is a client, he may not be connected yet, so unblock him just in case 992 if ( ((pClient = findClient(jniHandle)) != NULL) && (pClient->mIsConnecting) ) 993 { 994 SyncEventGuard guard (pClient->mConnectingEvent); 995 pClient->mConnectingEvent.notifyOne(); 996 return (true); 997 } 998 999 { 1000 SyncEventGuard guard1 (pConn->mCongEvent); 1001 pConn->mCongEvent.notifyOne (); //unblock send() if congested 1002 } 1003 { 1004 SyncEventGuard guard2 (pConn->mReadEvent); 1005 pConn->mReadEvent.notifyOne (); //unblock receive() 1006 } 1007 1008 if (pConn->mNfaConnHandle != NFA_HANDLE_INVALID) 1009 { 1010 ALOGD ("%s: try disconn nfa h=0x%04X", fn, pConn->mNfaConnHandle); 1011 SyncEventGuard guard (pConn->mDisconnectingEvent); 1012 nfaStat = NFA_P2pDisconnect (pConn->mNfaConnHandle, FALSE); 1013 1014 if (nfaStat != NFA_STATUS_OK) 1015 ALOGE ("%s: fail p2p disconnect", fn); 1016 else 1017 pConn->mDisconnectingEvent.wait(); 1018 } 1019 1020 mDisconnectMutex.lock (); 1021 removeConn (jniHandle); 1022 mDisconnectMutex.unlock (); 1023 1024 ALOGD ("%s: exit; jni handle: %u", fn, jniHandle); 1025 return nfaStat == NFA_STATUS_OK; 1026 } 1027 1028 1029 /******************************************************************************* 1030 ** 1031 ** Function: getRemoteMaxInfoUnit 1032 ** 1033 ** Description: Get peer's max information unit. 1034 ** jniHandle: Handle of the connection. 1035 ** 1036 ** Returns: Peer's max information unit. 1037 ** 1038 *******************************************************************************/ 1039 UINT16 PeerToPeer::getRemoteMaxInfoUnit (tJNI_HANDLE jniHandle) 1040 { 1041 static const char fn [] = "PeerToPeer::getRemoteMaxInfoUnit"; 1042 sp<NfaConn> pConn = NULL; 1043 1044 if ((pConn = findConnection(jniHandle)) == NULL) 1045 { 1046 ALOGE ("%s: can't find client jniHandle: %u", fn, jniHandle); 1047 return 0; 1048 } 1049 ALOGD ("%s: jniHandle: %u MIU: %u", fn, jniHandle, pConn->mRemoteMaxInfoUnit); 1050 return (pConn->mRemoteMaxInfoUnit); 1051 } 1052 1053 1054 /******************************************************************************* 1055 ** 1056 ** Function: getRemoteRecvWindow 1057 ** 1058 ** Description: Get peer's receive window size. 1059 ** jniHandle: Handle of the connection. 1060 ** 1061 ** Returns: Peer's receive window size. 1062 ** 1063 *******************************************************************************/ 1064 UINT8 PeerToPeer::getRemoteRecvWindow (tJNI_HANDLE jniHandle) 1065 { 1066 static const char fn [] = "PeerToPeer::getRemoteRecvWindow"; 1067 ALOGD ("%s: client jni handle: %u", fn, jniHandle); 1068 sp<NfaConn> pConn = NULL; 1069 1070 if ((pConn = findConnection(jniHandle)) == NULL) 1071 { 1072 ALOGE ("%s: can't find client", fn); 1073 return 0; 1074 } 1075 return pConn->mRemoteRecvWindow; 1076 } 1077 1078 /******************************************************************************* 1079 ** 1080 ** Function: setP2pListenMask 1081 ** 1082 ** Description: Sets the p2p listen technology mask. 1083 ** p2pListenMask: the p2p listen mask to be set? 1084 ** 1085 ** Returns: None 1086 ** 1087 *******************************************************************************/ 1088 void PeerToPeer::setP2pListenMask (tNFA_TECHNOLOGY_MASK p2pListenMask) { 1089 mP2pListenTechMask = p2pListenMask; 1090 } 1091 1092 1093 /******************************************************************************* 1094 ** 1095 ** Function: getP2pListenMask 1096 ** 1097 ** Description: Get the set of technologies that P2P is listening. 1098 ** 1099 ** Returns: Set of technologies. 1100 ** 1101 *******************************************************************************/ 1102 tNFA_TECHNOLOGY_MASK PeerToPeer::getP2pListenMask () 1103 { 1104 return mP2pListenTechMask; 1105 } 1106 1107 1108 /******************************************************************************* 1109 ** 1110 ** Function: resetP2pListenMask 1111 ** 1112 ** Description: Reset the p2p listen technology mask to initial value. 1113 ** 1114 ** Returns: None. 1115 ** 1116 *******************************************************************************/ 1117 void PeerToPeer::resetP2pListenMask () 1118 { 1119 unsigned long num = 0; 1120 mP2pListenTechMask = NFA_TECHNOLOGY_MASK_A 1121 | NFA_TECHNOLOGY_MASK_F 1122 | NFA_TECHNOLOGY_MASK_A_ACTIVE 1123 | NFA_TECHNOLOGY_MASK_F_ACTIVE; 1124 if (GetNumValue ("P2P_LISTEN_TECH_MASK", &num, sizeof (num))) 1125 mP2pListenTechMask = num; 1126 } 1127 1128 1129 /******************************************************************************* 1130 ** 1131 ** Function: enableP2pListening 1132 ** 1133 ** Description: Start/stop polling/listening to peer that supports P2P. 1134 ** isEnable: Is enable polling/listening? 1135 ** 1136 ** Returns: None 1137 ** 1138 *******************************************************************************/ 1139 void PeerToPeer::enableP2pListening (bool isEnable) 1140 { 1141 static const char fn [] = "PeerToPeer::enableP2pListening"; 1142 tNFA_STATUS nfaStat = NFA_STATUS_FAILED; 1143 1144 ALOGD ("%s: enter isEnable: %u mIsP2pListening: %u", fn, isEnable, mIsP2pListening); 1145 1146 // If request to enable P2P listening, and we were not already listening 1147 if ( (isEnable == true) && (mIsP2pListening == false) && (mP2pListenTechMask != 0) ) 1148 { 1149 SyncEventGuard guard (mSetTechEvent); 1150 if ((nfaStat = NFA_SetP2pListenTech (mP2pListenTechMask)) == NFA_STATUS_OK) 1151 { 1152 mSetTechEvent.wait (); 1153 mIsP2pListening = true; 1154 } 1155 else 1156 ALOGE ("%s: fail enable listen; error=0x%X", fn, nfaStat); 1157 } 1158 else if ( (isEnable == false) && (mIsP2pListening == true) ) 1159 { 1160 SyncEventGuard guard (mSetTechEvent); 1161 // Request to disable P2P listening, check if it was enabled 1162 if ((nfaStat = NFA_SetP2pListenTech(0)) == NFA_STATUS_OK) 1163 { 1164 mSetTechEvent.wait (); 1165 mIsP2pListening = false; 1166 } 1167 else 1168 ALOGE ("%s: fail disable listen; error=0x%X", fn, nfaStat); 1169 } 1170 ALOGD ("%s: exit; mIsP2pListening: %u", fn, mIsP2pListening); 1171 } 1172 1173 1174 /******************************************************************************* 1175 ** 1176 ** Function: handleNfcOnOff 1177 ** 1178 ** Description: Handle events related to turning NFC on/off by the user. 1179 ** isOn: Is NFC turning on? 1180 ** 1181 ** Returns: None 1182 ** 1183 *******************************************************************************/ 1184 void PeerToPeer::handleNfcOnOff (bool isOn) 1185 { 1186 static const char fn [] = "PeerToPeer::handleNfcOnOff"; 1187 ALOGD ("%s: enter; is on=%u", fn, isOn); 1188 1189 mIsP2pListening = false; // In both cases, P2P will not be listening 1190 1191 AutoMutex mutex(mMutex); 1192 if (isOn) 1193 { 1194 // Start with no clients or servers 1195 memset (mServers, 0, sizeof(mServers)); 1196 memset (mClients, 0, sizeof(mClients)); 1197 } 1198 else 1199 { 1200 // Disconnect through all the clients 1201 for (int ii = 0; ii < sMax; ii++) 1202 { 1203 if (mClients[ii] != NULL) 1204 { 1205 if (mClients[ii]->mClientConn->mNfaConnHandle == NFA_HANDLE_INVALID) 1206 { 1207 SyncEventGuard guard (mClients[ii]->mConnectingEvent); 1208 mClients[ii]->mConnectingEvent.notifyOne(); 1209 } 1210 else 1211 { 1212 mClients[ii]->mClientConn->mNfaConnHandle = NFA_HANDLE_INVALID; 1213 { 1214 SyncEventGuard guard1 (mClients[ii]->mClientConn->mCongEvent); 1215 mClients[ii]->mClientConn->mCongEvent.notifyOne (); //unblock send() 1216 } 1217 { 1218 SyncEventGuard guard2 (mClients[ii]->mClientConn->mReadEvent); 1219 mClients[ii]->mClientConn->mReadEvent.notifyOne (); //unblock receive() 1220 } 1221 } 1222 } 1223 } //loop 1224 1225 // Now look through all the server control blocks 1226 for (int ii = 0; ii < sMax; ii++) 1227 { 1228 if (mServers[ii] != NULL) 1229 { 1230 mServers[ii]->unblockAll(); 1231 } 1232 } //loop 1233 1234 } 1235 ALOGD ("%s: exit", fn); 1236 } 1237 1238 1239 /******************************************************************************* 1240 ** 1241 ** Function: nfaServerCallback 1242 ** 1243 ** Description: Receive LLCP-related events from the stack. 1244 ** p2pEvent: Event code. 1245 ** eventData: Event data. 1246 ** 1247 ** Returns: None 1248 ** 1249 *******************************************************************************/ 1250 void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* eventData) 1251 { 1252 static const char fn [] = "PeerToPeer::nfaServerCallback"; 1253 sp<P2pServer> pSrv = NULL; 1254 sp<NfaConn> pConn = NULL; 1255 1256 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; event=0x%X", fn, p2pEvent); 1257 1258 switch (p2pEvent) 1259 { 1260 case NFA_P2P_REG_SERVER_EVT: // NFA_P2pRegisterServer() has started to listen 1261 ALOGD ("%s: NFA_P2P_REG_SERVER_EVT; handle: 0x%04x; service sap=0x%02x name: %s", fn, 1262 eventData->reg_server.server_handle, eventData->reg_server.server_sap, eventData->reg_server.service_name); 1263 1264 sP2p.mMutex.lock(); 1265 pSrv = sP2p.findServerLocked(eventData->reg_server.service_name); 1266 sP2p.mMutex.unlock(); 1267 if (pSrv == NULL) 1268 { 1269 ALOGE ("%s: NFA_P2P_REG_SERVER_EVT for unknown service: %s", fn, eventData->reg_server.service_name); 1270 } 1271 else 1272 { 1273 SyncEventGuard guard (pSrv->mRegServerEvent); 1274 pSrv->mNfaP2pServerHandle = eventData->reg_server.server_handle; 1275 pSrv->mRegServerEvent.notifyOne(); //unblock registerServer() 1276 } 1277 break; 1278 1279 case NFA_P2P_ACTIVATED_EVT: //remote device has activated 1280 ALOGD ("%s: NFA_P2P_ACTIVATED_EVT; handle: 0x%04x", fn, eventData->activated.handle); 1281 break; 1282 1283 case NFA_P2P_DEACTIVATED_EVT: 1284 ALOGD ("%s: NFA_P2P_DEACTIVATED_EVT; handle: 0x%04x", fn, eventData->activated.handle); 1285 break; 1286 1287 case NFA_P2P_CONN_REQ_EVT: 1288 ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; nfa server h=0x%04x; nfa conn h=0x%04x; remote sap=0x%02x", fn, 1289 eventData->conn_req.server_handle, eventData->conn_req.conn_handle, eventData->conn_req.remote_sap); 1290 1291 sP2p.mMutex.lock(); 1292 pSrv = sP2p.findServerLocked(eventData->conn_req.server_handle); 1293 sP2p.mMutex.unlock(); 1294 if (pSrv == NULL) 1295 { 1296 ALOGE ("%s: NFA_P2P_CONN_REQ_EVT; unknown server h", fn); 1297 return; 1298 } 1299 ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; server jni h=%u", fn, pSrv->mJniHandle); 1300 1301 // Look for a connection block that is waiting (handle invalid) 1302 if ((pConn = pSrv->findServerConnection((tNFA_HANDLE) NFA_HANDLE_INVALID)) == NULL) 1303 { 1304 ALOGE ("%s: NFA_P2P_CONN_REQ_EVT; server not listening", fn); 1305 } 1306 else 1307 { 1308 SyncEventGuard guard (pSrv->mConnRequestEvent); 1309 pConn->mNfaConnHandle = eventData->conn_req.conn_handle; 1310 pConn->mRemoteMaxInfoUnit = eventData->conn_req.remote_miu; 1311 pConn->mRemoteRecvWindow = eventData->conn_req.remote_rw; 1312 ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; server jni h=%u; conn jni h=%u; notify conn req", fn, pSrv->mJniHandle, pConn->mJniHandle); 1313 pSrv->mConnRequestEvent.notifyOne(); //unblock accept() 1314 } 1315 break; 1316 1317 case NFA_P2P_CONNECTED_EVT: 1318 ALOGD ("%s: NFA_P2P_CONNECTED_EVT; h=0x%x remote sap=0x%X", fn, 1319 eventData->connected.client_handle, eventData->connected.remote_sap); 1320 break; 1321 1322 case NFA_P2P_DISC_EVT: 1323 ALOGD ("%s: NFA_P2P_DISC_EVT; h=0x%04x; reason=0x%X", fn, eventData->disc.handle, eventData->disc.reason); 1324 // Look for the connection block 1325 if ((pConn = sP2p.findConnection(eventData->disc.handle)) == NULL) 1326 { 1327 ALOGE ("%s: NFA_P2P_DISC_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->disc.handle); 1328 } 1329 else 1330 { 1331 sP2p.mDisconnectMutex.lock (); 1332 pConn->mNfaConnHandle = NFA_HANDLE_INVALID; 1333 { 1334 ALOGD ("%s: NFA_P2P_DISC_EVT; try guard disconn event", fn); 1335 SyncEventGuard guard3 (pConn->mDisconnectingEvent); 1336 pConn->mDisconnectingEvent.notifyOne (); 1337 ALOGD ("%s: NFA_P2P_DISC_EVT; notified disconn event", fn); 1338 } 1339 { 1340 ALOGD ("%s: NFA_P2P_DISC_EVT; try guard congest event", fn); 1341 SyncEventGuard guard1 (pConn->mCongEvent); 1342 pConn->mCongEvent.notifyOne (); //unblock write (if congested) 1343 ALOGD ("%s: NFA_P2P_DISC_EVT; notified congest event", fn); 1344 } 1345 { 1346 ALOGD ("%s: NFA_P2P_DISC_EVT; try guard read event", fn); 1347 SyncEventGuard guard2 (pConn->mReadEvent); 1348 pConn->mReadEvent.notifyOne (); //unblock receive() 1349 ALOGD ("%s: NFA_P2P_DISC_EVT; notified read event", fn); 1350 } 1351 sP2p.mDisconnectMutex.unlock (); 1352 } 1353 break; 1354 1355 case NFA_P2P_DATA_EVT: 1356 // Look for the connection block 1357 if ((pConn = sP2p.findConnection(eventData->data.handle)) == NULL) 1358 { 1359 ALOGE ("%s: NFA_P2P_DATA_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->data.handle); 1360 } 1361 else 1362 { 1363 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: NFA_P2P_DATA_EVT; h=0x%X; remote sap=0x%X", fn, 1364 eventData->data.handle, eventData->data.remote_sap); 1365 SyncEventGuard guard (pConn->mReadEvent); 1366 pConn->mReadEvent.notifyOne(); 1367 } 1368 break; 1369 1370 case NFA_P2P_CONGEST_EVT: 1371 // Look for the connection block 1372 if ((pConn = sP2p.findConnection(eventData->congest.handle)) == NULL) 1373 { 1374 ALOGE ("%s: NFA_P2P_CONGEST_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->congest.handle); 1375 } 1376 else 1377 { 1378 ALOGD ("%s: NFA_P2P_CONGEST_EVT; nfa handle: 0x%04x congested: %u", fn, 1379 eventData->congest.handle, eventData->congest.is_congested); 1380 if (eventData->congest.is_congested == FALSE) 1381 { 1382 SyncEventGuard guard (pConn->mCongEvent); 1383 pConn->mCongEvent.notifyOne(); 1384 } 1385 } 1386 break; 1387 1388 default: 1389 ALOGE ("%s: unknown event 0x%X ????", fn, p2pEvent); 1390 break; 1391 } 1392 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit", fn); 1393 } 1394 1395 1396 /******************************************************************************* 1397 ** 1398 ** Function: nfaClientCallback 1399 ** 1400 ** Description: Receive LLCP-related events from the stack. 1401 ** p2pEvent: Event code. 1402 ** eventData: Event data. 1403 ** 1404 ** Returns: None 1405 ** 1406 *******************************************************************************/ 1407 void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* eventData) 1408 { 1409 static const char fn [] = "PeerToPeer::nfaClientCallback"; 1410 sp<NfaConn> pConn = NULL; 1411 sp<P2pClient> pClient = NULL; 1412 1413 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; event=%u", fn, p2pEvent); 1414 1415 switch (p2pEvent) 1416 { 1417 case NFA_P2P_REG_CLIENT_EVT: 1418 // Look for a client that is trying to register 1419 if ((pClient = sP2p.findClient ((tNFA_HANDLE)NFA_HANDLE_INVALID)) == NULL) 1420 { 1421 ALOGE ("%s: NFA_P2P_REG_CLIENT_EVT: can't find waiting client", fn); 1422 } 1423 else 1424 { 1425 ALOGD ("%s: NFA_P2P_REG_CLIENT_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->reg_client.client_handle, pClient.get()); 1426 1427 SyncEventGuard guard (pClient->mRegisteringEvent); 1428 pClient->mNfaP2pClientHandle = eventData->reg_client.client_handle; 1429 pClient->mRegisteringEvent.notifyOne(); 1430 } 1431 break; 1432 1433 case NFA_P2P_ACTIVATED_EVT: 1434 // Look for a client that is trying to register 1435 if ((pClient = sP2p.findClient (eventData->activated.handle)) == NULL) 1436 { 1437 ALOGE ("%s: NFA_P2P_ACTIVATED_EVT: can't find client", fn); 1438 } 1439 else 1440 { 1441 ALOGD ("%s: NFA_P2P_ACTIVATED_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->activated.handle, pClient.get()); 1442 } 1443 break; 1444 1445 case NFA_P2P_DEACTIVATED_EVT: 1446 ALOGD ("%s: NFA_P2P_DEACTIVATED_EVT: conn handle: 0x%X", fn, eventData->deactivated.handle); 1447 break; 1448 1449 case NFA_P2P_CONNECTED_EVT: 1450 // Look for the client that is trying to connect 1451 if ((pClient = sP2p.findClient (eventData->connected.client_handle)) == NULL) 1452 { 1453 ALOGE ("%s: NFA_P2P_CONNECTED_EVT: can't find client: 0x%04x", fn, eventData->connected.client_handle); 1454 } 1455 else 1456 { 1457 ALOGD ("%s: NFA_P2P_CONNECTED_EVT; client_handle=0x%04x conn_handle: 0x%04x remote sap=0x%X pClient: 0x%p", fn, 1458 eventData->connected.client_handle, eventData->connected.conn_handle, eventData->connected.remote_sap, pClient.get()); 1459 1460 SyncEventGuard guard (pClient->mConnectingEvent); 1461 pClient->mClientConn->mNfaConnHandle = eventData->connected.conn_handle; 1462 pClient->mClientConn->mRemoteMaxInfoUnit = eventData->connected.remote_miu; 1463 pClient->mClientConn->mRemoteRecvWindow = eventData->connected.remote_rw; 1464 pClient->mConnectingEvent.notifyOne(); //unblock createDataLinkConn() 1465 } 1466 break; 1467 1468 case NFA_P2P_DISC_EVT: 1469 ALOGD ("%s: NFA_P2P_DISC_EVT; h=0x%04x; reason=0x%X", fn, eventData->disc.handle, eventData->disc.reason); 1470 // Look for the connection block 1471 if ((pConn = sP2p.findConnection(eventData->disc.handle)) == NULL) 1472 { 1473 // If no connection, may be a client that is trying to connect 1474 if ((pClient = sP2p.findClient (eventData->disc.handle)) == NULL) 1475 { 1476 ALOGE ("%s: NFA_P2P_DISC_EVT: can't find client for NFA handle: 0x%04x", fn, eventData->disc.handle); 1477 return; 1478 } 1479 // Unblock createDataLinkConn() 1480 SyncEventGuard guard (pClient->mConnectingEvent); 1481 pClient->mConnectingEvent.notifyOne(); 1482 } 1483 else 1484 { 1485 sP2p.mDisconnectMutex.lock (); 1486 pConn->mNfaConnHandle = NFA_HANDLE_INVALID; 1487 { 1488 ALOGD ("%s: NFA_P2P_DISC_EVT; try guard disconn event", fn); 1489 SyncEventGuard guard3 (pConn->mDisconnectingEvent); 1490 pConn->mDisconnectingEvent.notifyOne (); 1491 ALOGD ("%s: NFA_P2P_DISC_EVT; notified disconn event", fn); 1492 } 1493 { 1494 ALOGD ("%s: NFA_P2P_DISC_EVT; try guard congest event", fn); 1495 SyncEventGuard guard1 (pConn->mCongEvent); 1496 pConn->mCongEvent.notifyOne(); //unblock write (if congested) 1497 ALOGD ("%s: NFA_P2P_DISC_EVT; notified congest event", fn); 1498 } 1499 { 1500 ALOGD ("%s: NFA_P2P_DISC_EVT; try guard read event", fn); 1501 SyncEventGuard guard2 (pConn->mReadEvent); 1502 pConn->mReadEvent.notifyOne(); //unblock receive() 1503 ALOGD ("%s: NFA_P2P_DISC_EVT; notified read event", fn); 1504 } 1505 sP2p.mDisconnectMutex.unlock (); 1506 } 1507 break; 1508 1509 case NFA_P2P_DATA_EVT: 1510 // Look for the connection block 1511 if ((pConn = sP2p.findConnection(eventData->data.handle)) == NULL) 1512 { 1513 ALOGE ("%s: NFA_P2P_DATA_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->data.handle); 1514 } 1515 else 1516 { 1517 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: NFA_P2P_DATA_EVT; h=0x%X; remote sap=0x%X", fn, 1518 eventData->data.handle, eventData->data.remote_sap); 1519 SyncEventGuard guard (pConn->mReadEvent); 1520 pConn->mReadEvent.notifyOne(); 1521 } 1522 break; 1523 1524 case NFA_P2P_CONGEST_EVT: 1525 // Look for the connection block 1526 if ((pConn = sP2p.findConnection(eventData->congest.handle)) == NULL) 1527 { 1528 ALOGE ("%s: NFA_P2P_CONGEST_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->congest.handle); 1529 } 1530 else 1531 { 1532 ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: NFA_P2P_CONGEST_EVT; nfa handle: 0x%04x congested: %u", fn, 1533 eventData->congest.handle, eventData->congest.is_congested); 1534 1535 SyncEventGuard guard (pConn->mCongEvent); 1536 pConn->mCongEvent.notifyOne(); 1537 } 1538 break; 1539 1540 default: 1541 ALOGE ("%s: unknown event 0x%X ????", fn, p2pEvent); 1542 break; 1543 } 1544 } 1545 1546 1547 /******************************************************************************* 1548 ** 1549 ** Function: connectionEventHandler 1550 ** 1551 ** Description: Receive events from the stack. 1552 ** event: Event code. 1553 ** eventData: Event data. 1554 ** 1555 ** Returns: None 1556 ** 1557 *******************************************************************************/ 1558 void PeerToPeer::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* /*eventData*/) 1559 { 1560 switch (event) 1561 { 1562 case NFA_SET_P2P_LISTEN_TECH_EVT: 1563 { 1564 SyncEventGuard guard (mSetTechEvent); 1565 mSetTechEvent.notifyOne(); //unblock NFA_SetP2pListenTech() 1566 break; 1567 } 1568 } 1569 } 1570 1571 1572 /******************************************************************************* 1573 ** 1574 ** Function: getNextJniHandle 1575 ** 1576 ** Description: Get a new JNI handle. 1577 ** 1578 ** Returns: A new JNI handle. 1579 ** 1580 *******************************************************************************/ 1581 PeerToPeer::tJNI_HANDLE PeerToPeer::getNewJniHandle () 1582 { 1583 tJNI_HANDLE newHandle = 0; 1584 1585 mNewJniHandleMutex.lock (); 1586 newHandle = mNextJniHandle++; 1587 mNewJniHandleMutex.unlock (); 1588 return newHandle; 1589 } 1590 1591 1592 ///////////////////////////////////////////////////////////////////////// 1593 ///////////////////////////////////////////////////////////////////////// 1594 1595 1596 /******************************************************************************* 1597 ** 1598 ** Function: P2pServer 1599 ** 1600 ** Description: Initialize member variables. 1601 ** 1602 ** Returns: None 1603 ** 1604 *******************************************************************************/ 1605 P2pServer::P2pServer(PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName) 1606 : mNfaP2pServerHandle (NFA_HANDLE_INVALID), 1607 mJniHandle (jniHandle) 1608 { 1609 mServiceName.assign (serviceName); 1610 1611 memset (mServerConn, 0, sizeof(mServerConn)); 1612 } 1613 1614 bool P2pServer::registerWithStack() 1615 { 1616 static const char fn [] = "P2pServer::registerWithStack"; 1617 ALOGD ("%s: enter; service name: %s JNI handle: %u", fn, mServiceName.c_str(), mJniHandle); 1618 tNFA_STATUS stat = NFA_STATUS_OK; 1619 UINT8 serverSap = NFA_P2P_ANY_SAP; 1620 1621 /********************** 1622 default values for all LLCP parameters: 1623 - Local Link MIU (LLCP_MIU) 1624 - Option parameter (LLCP_OPT_VALUE) 1625 - Response Waiting Time Index (LLCP_WAITING_TIME) 1626 - Local Link Timeout (LLCP_LTO_VALUE) 1627 - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT) 1628 - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT) 1629 - Delay SYMM response (LLCP_DELAY_RESP_TIME) 1630 - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT) 1631 - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU) 1632 ************************/ 1633 stat = NFA_P2pSetLLCPConfig (LLCP_MAX_MIU, 1634 LLCP_OPT_VALUE, 1635 LLCP_WAITING_TIME, 1636 LLCP_LTO_VALUE, 1637 0, //use 0 for infinite timeout for symmetry procedure when acting as initiator 1638 0, //use 0 for infinite timeout for symmetry procedure when acting as target 1639 LLCP_DELAY_RESP_TIME, 1640 LLCP_DATA_LINK_TIMEOUT, 1641 LLCP_DELAY_TIME_TO_SEND_FIRST_PDU); 1642 if (stat != NFA_STATUS_OK) 1643 ALOGE ("%s: fail set LLCP config; error=0x%X", fn, stat); 1644 1645 if (sSnepServiceName.compare(mServiceName) == 0) 1646 serverSap = LLCP_SAP_SNEP; //LLCP_SAP_SNEP == 4 1647 1648 { 1649 SyncEventGuard guard (mRegServerEvent); 1650 stat = NFA_P2pRegisterServer (serverSap, NFA_P2P_DLINK_TYPE, const_cast<char*>(mServiceName.c_str()), 1651 PeerToPeer::nfaServerCallback); 1652 if (stat != NFA_STATUS_OK) 1653 { 1654 ALOGE ("%s: fail register p2p server; error=0x%X", fn, stat); 1655 return (false); 1656 } 1657 ALOGD ("%s: wait for listen-completion event", fn); 1658 // Wait for NFA_P2P_REG_SERVER_EVT 1659 mRegServerEvent.wait (); 1660 } 1661 1662 return (mNfaP2pServerHandle != NFA_HANDLE_INVALID); 1663 } 1664 1665 bool P2pServer::accept(PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle, 1666 int maxInfoUnit, int recvWindow) 1667 { 1668 static const char fn [] = "P2pServer::accept"; 1669 tNFA_STATUS nfaStat = NFA_STATUS_OK; 1670 1671 sp<NfaConn> connection = allocateConnection(connJniHandle); 1672 if (connection == NULL) { 1673 ALOGE ("%s: failed to allocate new server connection", fn); 1674 return false; 1675 } 1676 1677 { 1678 // Wait for NFA_P2P_CONN_REQ_EVT or NFA_NDEF_DATA_EVT when remote device requests connection 1679 SyncEventGuard guard (mConnRequestEvent); 1680 ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; wait for incoming connection", fn, 1681 serverJniHandle, connJniHandle); 1682 mConnRequestEvent.wait(); 1683 ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X; got incoming connection", fn, 1684 serverJniHandle, connJniHandle, connection->mNfaConnHandle); 1685 } 1686 1687 if (connection->mNfaConnHandle == NFA_HANDLE_INVALID) 1688 { 1689 removeServerConnection(connJniHandle); 1690 ALOGD ("%s: no handle assigned", fn); 1691 return (false); 1692 } 1693 1694 if (maxInfoUnit > (int)LLCP_MIU) 1695 { 1696 ALOGD ("%s: overriding the miu passed by the app(%d) with stack miu(%d)", fn, maxInfoUnit, LLCP_MIU); 1697 maxInfoUnit = LLCP_MIU; 1698 } 1699 1700 ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X; try accept", fn, 1701 serverJniHandle, connJniHandle, connection->mNfaConnHandle); 1702 nfaStat = NFA_P2pAcceptConn (connection->mNfaConnHandle, maxInfoUnit, recvWindow); 1703 1704 if (nfaStat != NFA_STATUS_OK) 1705 { 1706 ALOGE ("%s: fail to accept remote; error=0x%X", fn, nfaStat); 1707 return (false); 1708 } 1709 1710 ALOGD ("%s: exit; serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X", fn, 1711 serverJniHandle, connJniHandle, connection->mNfaConnHandle); 1712 return (true); 1713 } 1714 1715 void P2pServer::unblockAll() 1716 { 1717 AutoMutex mutex(mMutex); 1718 for (int jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) 1719 { 1720 if (mServerConn[jj] != NULL) 1721 { 1722 mServerConn[jj]->mNfaConnHandle = NFA_HANDLE_INVALID; 1723 { 1724 SyncEventGuard guard1 (mServerConn[jj]->mCongEvent); 1725 mServerConn[jj]->mCongEvent.notifyOne (); //unblock write (if congested) 1726 } 1727 { 1728 SyncEventGuard guard2 (mServerConn[jj]->mReadEvent); 1729 mServerConn[jj]->mReadEvent.notifyOne (); //unblock receive() 1730 } 1731 } 1732 } 1733 } 1734 1735 sp<NfaConn> P2pServer::allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle) 1736 { 1737 AutoMutex mutex(mMutex); 1738 // First, find a free connection block to handle the connection 1739 for (int ii = 0; ii < MAX_NFA_CONNS_PER_SERVER; ii++) 1740 { 1741 if (mServerConn[ii] == NULL) 1742 { 1743 mServerConn[ii] = new NfaConn; 1744 mServerConn[ii]->mJniHandle = jniHandle; 1745 return mServerConn[ii]; 1746 } 1747 } 1748 1749 return NULL; 1750 } 1751 1752 1753 /******************************************************************************* 1754 ** 1755 ** Function: findServerConnection 1756 ** 1757 ** Description: Find a P2pServer that has the handle. 1758 ** nfaConnHandle: NFA connection handle. 1759 ** 1760 ** Returns: P2pServer object. 1761 ** 1762 *******************************************************************************/ 1763 sp<NfaConn> P2pServer::findServerConnection (tNFA_HANDLE nfaConnHandle) 1764 { 1765 int jj = 0; 1766 1767 AutoMutex mutex(mMutex); 1768 for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) 1769 { 1770 if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mNfaConnHandle == nfaConnHandle) ) 1771 return (mServerConn[jj]); 1772 } 1773 1774 // If here, not found 1775 return (NULL); 1776 } 1777 1778 /******************************************************************************* 1779 ** 1780 ** Function: findServerConnection 1781 ** 1782 ** Description: Find a P2pServer that has the handle. 1783 ** nfaConnHandle: NFA connection handle. 1784 ** 1785 ** Returns: P2pServer object. 1786 ** 1787 *******************************************************************************/ 1788 sp<NfaConn> P2pServer::findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle) 1789 { 1790 int jj = 0; 1791 1792 AutoMutex mutex(mMutex); 1793 for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) 1794 { 1795 if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mJniHandle == jniHandle) ) 1796 return (mServerConn[jj]); 1797 } 1798 1799 // If here, not found 1800 return (NULL); 1801 } 1802 1803 /******************************************************************************* 1804 ** 1805 ** Function: removeServerConnection 1806 ** 1807 ** Description: Find a P2pServer that has the handle. 1808 ** nfaConnHandle: NFA connection handle. 1809 ** 1810 ** Returns: P2pServer object. 1811 ** 1812 *******************************************************************************/ 1813 bool P2pServer::removeServerConnection (PeerToPeer::tJNI_HANDLE jniHandle) 1814 { 1815 int jj = 0; 1816 1817 AutoMutex mutex(mMutex); 1818 for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++) 1819 { 1820 if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mJniHandle == jniHandle) ) { 1821 mServerConn[jj] = NULL; 1822 return true; 1823 } 1824 } 1825 1826 // If here, not found 1827 return false; 1828 } 1829 ///////////////////////////////////////////////////////////////////////// 1830 ///////////////////////////////////////////////////////////////////////// 1831 1832 1833 /******************************************************************************* 1834 ** 1835 ** Function: P2pClient 1836 ** 1837 ** Description: Initialize member variables. 1838 ** 1839 ** Returns: None 1840 ** 1841 *******************************************************************************/ 1842 P2pClient::P2pClient () 1843 : mNfaP2pClientHandle (NFA_HANDLE_INVALID), 1844 mIsConnecting (false) 1845 { 1846 mClientConn = new NfaConn(); 1847 } 1848 1849 1850 /******************************************************************************* 1851 ** 1852 ** Function: ~P2pClient 1853 ** 1854 ** Description: Free all resources. 1855 ** 1856 ** Returns: None 1857 ** 1858 *******************************************************************************/ 1859 P2pClient::~P2pClient () 1860 { 1861 } 1862 1863 1864 ///////////////////////////////////////////////////////////////////////// 1865 ///////////////////////////////////////////////////////////////////////// 1866 1867 1868 /******************************************************************************* 1869 ** 1870 ** Function: NfaConn 1871 ** 1872 ** Description: Initialize member variables. 1873 ** 1874 ** Returns: None 1875 ** 1876 *******************************************************************************/ 1877 NfaConn::NfaConn() 1878 : mNfaConnHandle (NFA_HANDLE_INVALID), 1879 mJniHandle (0), 1880 mMaxInfoUnit (0), 1881 mRecvWindow (0), 1882 mRemoteMaxInfoUnit (0), 1883 mRemoteRecvWindow (0) 1884 { 1885 } 1886