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