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