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