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