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