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