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