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**
1095** Function:        getP2pListenMask
1096**
1097** Description:     Get the set of technologies that P2P is listening.
1098**
1099** Returns:         Set of technologies.
1100**
1101*******************************************************************************/
1102tNFA_TECHNOLOGY_MASK PeerToPeer::getP2pListenMask ()
1103{
1104    return mP2pListenTechMask;
1105}
1106
1107
1108/*******************************************************************************
1109**
1110** Function:        resetP2pListenMask
1111**
1112** Description:     Reset the p2p listen technology mask to initial value.
1113**
1114** Returns:         None.
1115**
1116*******************************************************************************/
1117void PeerToPeer::resetP2pListenMask ()
1118{
1119    unsigned long num = 0;
1120    mP2pListenTechMask = NFA_TECHNOLOGY_MASK_A
1121                        | NFA_TECHNOLOGY_MASK_F
1122                        | NFA_TECHNOLOGY_MASK_A_ACTIVE
1123                        | NFA_TECHNOLOGY_MASK_F_ACTIVE;
1124    if (GetNumValue ("P2P_LISTEN_TECH_MASK", &num, sizeof (num)))
1125        mP2pListenTechMask = num;
1126}
1127
1128
1129/*******************************************************************************
1130**
1131** Function:        enableP2pListening
1132**
1133** Description:     Start/stop polling/listening to peer that supports P2P.
1134**                  isEnable: Is enable polling/listening?
1135**
1136** Returns:         None
1137**
1138*******************************************************************************/
1139void PeerToPeer::enableP2pListening (bool isEnable)
1140{
1141    static const char    fn []   = "PeerToPeer::enableP2pListening";
1142    tNFA_STATUS          nfaStat = NFA_STATUS_FAILED;
1143
1144    ALOGD ("%s: enter isEnable: %u  mIsP2pListening: %u", fn, isEnable, mIsP2pListening);
1145
1146    // If request to enable P2P listening, and we were not already listening
1147    if ( (isEnable == true) && (mIsP2pListening == false) && (mP2pListenTechMask != 0) )
1148    {
1149        SyncEventGuard guard (mSetTechEvent);
1150        if ((nfaStat = NFA_SetP2pListenTech (mP2pListenTechMask)) == NFA_STATUS_OK)
1151        {
1152            mSetTechEvent.wait ();
1153            mIsP2pListening = true;
1154        }
1155        else
1156            ALOGE ("%s: fail enable listen; error=0x%X", fn, nfaStat);
1157    }
1158    else if ( (isEnable == false) && (mIsP2pListening == true) )
1159    {
1160        SyncEventGuard guard (mSetTechEvent);
1161        // Request to disable P2P listening, check if it was enabled
1162        if ((nfaStat = NFA_SetP2pListenTech(0)) == NFA_STATUS_OK)
1163        {
1164            mSetTechEvent.wait ();
1165            mIsP2pListening = false;
1166        }
1167        else
1168            ALOGE ("%s: fail disable listen; error=0x%X", fn, nfaStat);
1169    }
1170    ALOGD ("%s: exit; mIsP2pListening: %u", fn, mIsP2pListening);
1171}
1172
1173
1174/*******************************************************************************
1175**
1176** Function:        handleNfcOnOff
1177**
1178** Description:     Handle events related to turning NFC on/off by the user.
1179**                  isOn: Is NFC turning on?
1180**
1181** Returns:         None
1182**
1183*******************************************************************************/
1184void PeerToPeer::handleNfcOnOff (bool isOn)
1185{
1186    static const char fn [] = "PeerToPeer::handleNfcOnOff";
1187    ALOGD ("%s: enter; is on=%u", fn, isOn);
1188
1189    mIsP2pListening = false;            // In both cases, P2P will not be listening
1190
1191    AutoMutex mutex(mMutex);
1192    if (isOn)
1193    {
1194        // Start with no clients or servers
1195        memset (mServers, 0, sizeof(mServers));
1196        memset (mClients, 0, sizeof(mClients));
1197    }
1198    else
1199    {
1200        // Disconnect through all the clients
1201        for (int ii = 0; ii < sMax; ii++)
1202        {
1203            if (mClients[ii] != NULL)
1204            {
1205                if (mClients[ii]->mClientConn->mNfaConnHandle == NFA_HANDLE_INVALID)
1206                {
1207                    SyncEventGuard guard (mClients[ii]->mConnectingEvent);
1208                    mClients[ii]->mConnectingEvent.notifyOne();
1209                }
1210                else
1211                {
1212                    mClients[ii]->mClientConn->mNfaConnHandle = NFA_HANDLE_INVALID;
1213                    {
1214                        SyncEventGuard guard1 (mClients[ii]->mClientConn->mCongEvent);
1215                        mClients[ii]->mClientConn->mCongEvent.notifyOne (); //unblock send()
1216                    }
1217                    {
1218                        SyncEventGuard guard2 (mClients[ii]->mClientConn->mReadEvent);
1219                        mClients[ii]->mClientConn->mReadEvent.notifyOne (); //unblock receive()
1220                    }
1221                }
1222            }
1223        } //loop
1224
1225        // Now look through all the server control blocks
1226        for (int ii = 0; ii < sMax; ii++)
1227        {
1228            if (mServers[ii] != NULL)
1229            {
1230                mServers[ii]->unblockAll();
1231            }
1232        } //loop
1233
1234    }
1235    ALOGD ("%s: exit", fn);
1236}
1237
1238
1239/*******************************************************************************
1240**
1241** Function:        nfaServerCallback
1242**
1243** Description:     Receive LLCP-related events from the stack.
1244**                  p2pEvent: Event code.
1245**                  eventData: Event data.
1246**
1247** Returns:         None
1248**
1249*******************************************************************************/
1250void PeerToPeer::nfaServerCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* eventData)
1251{
1252    static const char fn [] = "PeerToPeer::nfaServerCallback";
1253    sp<P2pServer>   pSrv = NULL;
1254    sp<NfaConn>     pConn = NULL;
1255
1256    ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; event=0x%X", fn, p2pEvent);
1257
1258    switch (p2pEvent)
1259    {
1260    case NFA_P2P_REG_SERVER_EVT:  // NFA_P2pRegisterServer() has started to listen
1261        ALOGD ("%s: NFA_P2P_REG_SERVER_EVT; handle: 0x%04x; service sap=0x%02x  name: %s", fn,
1262              eventData->reg_server.server_handle, eventData->reg_server.server_sap, eventData->reg_server.service_name);
1263
1264        sP2p.mMutex.lock();
1265        pSrv = sP2p.findServerLocked(eventData->reg_server.service_name);
1266        sP2p.mMutex.unlock();
1267        if (pSrv == NULL)
1268        {
1269            ALOGE ("%s: NFA_P2P_REG_SERVER_EVT for unknown service: %s", fn, eventData->reg_server.service_name);
1270        }
1271        else
1272        {
1273            SyncEventGuard guard (pSrv->mRegServerEvent);
1274            pSrv->mNfaP2pServerHandle = eventData->reg_server.server_handle;
1275            pSrv->mRegServerEvent.notifyOne(); //unblock registerServer()
1276        }
1277        break;
1278
1279    case NFA_P2P_ACTIVATED_EVT: //remote device has activated
1280        ALOGD ("%s: NFA_P2P_ACTIVATED_EVT; handle: 0x%04x", fn, eventData->activated.handle);
1281        break;
1282
1283    case NFA_P2P_DEACTIVATED_EVT:
1284        ALOGD ("%s: NFA_P2P_DEACTIVATED_EVT; handle: 0x%04x", fn, eventData->activated.handle);
1285        break;
1286
1287    case NFA_P2P_CONN_REQ_EVT:
1288        ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; nfa server h=0x%04x; nfa conn h=0x%04x; remote sap=0x%02x", fn,
1289                eventData->conn_req.server_handle, eventData->conn_req.conn_handle, eventData->conn_req.remote_sap);
1290
1291        sP2p.mMutex.lock();
1292        pSrv = sP2p.findServerLocked(eventData->conn_req.server_handle);
1293        sP2p.mMutex.unlock();
1294        if (pSrv == NULL)
1295        {
1296            ALOGE ("%s: NFA_P2P_CONN_REQ_EVT; unknown server h", fn);
1297            return;
1298        }
1299        ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; server jni h=%u", fn, pSrv->mJniHandle);
1300
1301        // Look for a connection block that is waiting (handle invalid)
1302        if ((pConn = pSrv->findServerConnection((tNFA_HANDLE) NFA_HANDLE_INVALID)) == NULL)
1303        {
1304            ALOGE ("%s: NFA_P2P_CONN_REQ_EVT; server not listening", fn);
1305        }
1306        else
1307        {
1308            SyncEventGuard guard (pSrv->mConnRequestEvent);
1309            pConn->mNfaConnHandle = eventData->conn_req.conn_handle;
1310            pConn->mRemoteMaxInfoUnit = eventData->conn_req.remote_miu;
1311            pConn->mRemoteRecvWindow = eventData->conn_req.remote_rw;
1312            ALOGD ("%s: NFA_P2P_CONN_REQ_EVT; server jni h=%u; conn jni h=%u; notify conn req", fn, pSrv->mJniHandle, pConn->mJniHandle);
1313            pSrv->mConnRequestEvent.notifyOne(); //unblock accept()
1314        }
1315        break;
1316
1317    case NFA_P2P_CONNECTED_EVT:
1318        ALOGD ("%s: NFA_P2P_CONNECTED_EVT; h=0x%x  remote sap=0x%X", fn,
1319                eventData->connected.client_handle, eventData->connected.remote_sap);
1320        break;
1321
1322    case NFA_P2P_DISC_EVT:
1323        ALOGD ("%s: NFA_P2P_DISC_EVT; h=0x%04x; reason=0x%X", fn, eventData->disc.handle, eventData->disc.reason);
1324        // Look for the connection block
1325        if ((pConn = sP2p.findConnection(eventData->disc.handle)) == NULL)
1326        {
1327            ALOGE ("%s: NFA_P2P_DISC_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->disc.handle);
1328        }
1329        else
1330        {
1331            sP2p.mDisconnectMutex.lock ();
1332            pConn->mNfaConnHandle = NFA_HANDLE_INVALID;
1333            {
1334                ALOGD ("%s: NFA_P2P_DISC_EVT; try guard disconn event", fn);
1335                SyncEventGuard guard3 (pConn->mDisconnectingEvent);
1336                pConn->mDisconnectingEvent.notifyOne ();
1337                ALOGD ("%s: NFA_P2P_DISC_EVT; notified disconn event", fn);
1338            }
1339            {
1340                ALOGD ("%s: NFA_P2P_DISC_EVT; try guard congest event", fn);
1341                SyncEventGuard guard1 (pConn->mCongEvent);
1342                pConn->mCongEvent.notifyOne (); //unblock write (if congested)
1343                ALOGD ("%s: NFA_P2P_DISC_EVT; notified congest event", fn);
1344            }
1345            {
1346                ALOGD ("%s: NFA_P2P_DISC_EVT; try guard read event", fn);
1347                SyncEventGuard guard2 (pConn->mReadEvent);
1348                pConn->mReadEvent.notifyOne (); //unblock receive()
1349                ALOGD ("%s: NFA_P2P_DISC_EVT; notified read event", fn);
1350            }
1351            sP2p.mDisconnectMutex.unlock ();
1352        }
1353        break;
1354
1355    case NFA_P2P_DATA_EVT:
1356        // Look for the connection block
1357        if ((pConn = sP2p.findConnection(eventData->data.handle)) == NULL)
1358        {
1359            ALOGE ("%s: NFA_P2P_DATA_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->data.handle);
1360        }
1361        else
1362        {
1363            ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: NFA_P2P_DATA_EVT; h=0x%X; remote sap=0x%X", fn,
1364                    eventData->data.handle, eventData->data.remote_sap);
1365            SyncEventGuard guard (pConn->mReadEvent);
1366            pConn->mReadEvent.notifyOne();
1367        }
1368        break;
1369
1370    case NFA_P2P_CONGEST_EVT:
1371        // Look for the connection block
1372        if ((pConn = sP2p.findConnection(eventData->congest.handle)) == NULL)
1373        {
1374            ALOGE ("%s: NFA_P2P_CONGEST_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->congest.handle);
1375        }
1376        else
1377        {
1378            ALOGD ("%s: NFA_P2P_CONGEST_EVT; nfa handle: 0x%04x  congested: %u", fn,
1379                    eventData->congest.handle, eventData->congest.is_congested);
1380            if (eventData->congest.is_congested == FALSE)
1381            {
1382                SyncEventGuard guard (pConn->mCongEvent);
1383                pConn->mCongEvent.notifyOne();
1384            }
1385        }
1386        break;
1387
1388    default:
1389        ALOGE ("%s: unknown event 0x%X ????", fn, p2pEvent);
1390        break;
1391    }
1392    ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: exit", fn);
1393}
1394
1395
1396/*******************************************************************************
1397**
1398** Function:        nfaClientCallback
1399**
1400** Description:     Receive LLCP-related events from the stack.
1401**                  p2pEvent: Event code.
1402**                  eventData: Event data.
1403**
1404** Returns:         None
1405**
1406*******************************************************************************/
1407void PeerToPeer::nfaClientCallback (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA* eventData)
1408{
1409    static const char fn [] = "PeerToPeer::nfaClientCallback";
1410    sp<NfaConn>     pConn = NULL;
1411    sp<P2pClient>   pClient = NULL;
1412
1413    ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: enter; event=%u", fn, p2pEvent);
1414
1415    switch (p2pEvent)
1416    {
1417    case NFA_P2P_REG_CLIENT_EVT:
1418        // Look for a client that is trying to register
1419        if ((pClient = sP2p.findClient ((tNFA_HANDLE)NFA_HANDLE_INVALID)) == NULL)
1420        {
1421            ALOGE ("%s: NFA_P2P_REG_CLIENT_EVT: can't find waiting client", fn);
1422        }
1423        else
1424        {
1425            ALOGD ("%s: NFA_P2P_REG_CLIENT_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->reg_client.client_handle, pClient.get());
1426
1427            SyncEventGuard guard (pClient->mRegisteringEvent);
1428            pClient->mNfaP2pClientHandle = eventData->reg_client.client_handle;
1429            pClient->mRegisteringEvent.notifyOne();
1430        }
1431        break;
1432
1433    case NFA_P2P_ACTIVATED_EVT:
1434        // Look for a client that is trying to register
1435        if ((pClient = sP2p.findClient (eventData->activated.handle)) == NULL)
1436        {
1437            ALOGE ("%s: NFA_P2P_ACTIVATED_EVT: can't find client", fn);
1438        }
1439        else
1440        {
1441            ALOGD ("%s: NFA_P2P_ACTIVATED_EVT; Conn Handle: 0x%04x, pClient: 0x%p", fn, eventData->activated.handle, pClient.get());
1442        }
1443        break;
1444
1445    case NFA_P2P_DEACTIVATED_EVT:
1446        ALOGD ("%s: NFA_P2P_DEACTIVATED_EVT: conn handle: 0x%X", fn, eventData->deactivated.handle);
1447        break;
1448
1449    case NFA_P2P_CONNECTED_EVT:
1450        // Look for the client that is trying to connect
1451        if ((pClient = sP2p.findClient (eventData->connected.client_handle)) == NULL)
1452        {
1453            ALOGE ("%s: NFA_P2P_CONNECTED_EVT: can't find client: 0x%04x", fn, eventData->connected.client_handle);
1454        }
1455        else
1456        {
1457            ALOGD ("%s: NFA_P2P_CONNECTED_EVT; client_handle=0x%04x  conn_handle: 0x%04x  remote sap=0x%X  pClient: 0x%p", fn,
1458                    eventData->connected.client_handle, eventData->connected.conn_handle, eventData->connected.remote_sap, pClient.get());
1459
1460            SyncEventGuard guard (pClient->mConnectingEvent);
1461            pClient->mClientConn->mNfaConnHandle     = eventData->connected.conn_handle;
1462            pClient->mClientConn->mRemoteMaxInfoUnit = eventData->connected.remote_miu;
1463            pClient->mClientConn->mRemoteRecvWindow  = eventData->connected.remote_rw;
1464            pClient->mConnectingEvent.notifyOne(); //unblock createDataLinkConn()
1465        }
1466        break;
1467
1468    case NFA_P2P_DISC_EVT:
1469        ALOGD ("%s: NFA_P2P_DISC_EVT; h=0x%04x; reason=0x%X", fn, eventData->disc.handle, eventData->disc.reason);
1470        // Look for the connection block
1471        if ((pConn = sP2p.findConnection(eventData->disc.handle)) == NULL)
1472        {
1473            // If no connection, may be a client that is trying to connect
1474            if ((pClient = sP2p.findClient (eventData->disc.handle)) == NULL)
1475            {
1476                ALOGE ("%s: NFA_P2P_DISC_EVT: can't find client for NFA handle: 0x%04x", fn, eventData->disc.handle);
1477                return;
1478            }
1479            // Unblock createDataLinkConn()
1480            SyncEventGuard guard (pClient->mConnectingEvent);
1481            pClient->mConnectingEvent.notifyOne();
1482        }
1483        else
1484        {
1485            sP2p.mDisconnectMutex.lock ();
1486            pConn->mNfaConnHandle = NFA_HANDLE_INVALID;
1487            {
1488                ALOGD ("%s: NFA_P2P_DISC_EVT; try guard disconn event", fn);
1489                SyncEventGuard guard3 (pConn->mDisconnectingEvent);
1490                pConn->mDisconnectingEvent.notifyOne ();
1491                ALOGD ("%s: NFA_P2P_DISC_EVT; notified disconn event", fn);
1492            }
1493            {
1494                ALOGD ("%s: NFA_P2P_DISC_EVT; try guard congest event", fn);
1495                SyncEventGuard guard1 (pConn->mCongEvent);
1496                pConn->mCongEvent.notifyOne(); //unblock write (if congested)
1497                ALOGD ("%s: NFA_P2P_DISC_EVT; notified congest event", fn);
1498            }
1499            {
1500                ALOGD ("%s: NFA_P2P_DISC_EVT; try guard read event", fn);
1501                SyncEventGuard guard2 (pConn->mReadEvent);
1502                pConn->mReadEvent.notifyOne(); //unblock receive()
1503                ALOGD ("%s: NFA_P2P_DISC_EVT; notified read event", fn);
1504            }
1505            sP2p.mDisconnectMutex.unlock ();
1506        }
1507        break;
1508
1509    case NFA_P2P_DATA_EVT:
1510        // Look for the connection block
1511        if ((pConn = sP2p.findConnection(eventData->data.handle)) == NULL)
1512        {
1513            ALOGE ("%s: NFA_P2P_DATA_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->data.handle);
1514        }
1515        else
1516        {
1517            ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: NFA_P2P_DATA_EVT; h=0x%X; remote sap=0x%X", fn,
1518                    eventData->data.handle, eventData->data.remote_sap);
1519            SyncEventGuard guard (pConn->mReadEvent);
1520            pConn->mReadEvent.notifyOne();
1521        }
1522        break;
1523
1524    case NFA_P2P_CONGEST_EVT:
1525        // Look for the connection block
1526        if ((pConn = sP2p.findConnection(eventData->congest.handle)) == NULL)
1527        {
1528            ALOGE ("%s: NFA_P2P_CONGEST_EVT: can't find conn for NFA handle: 0x%04x", fn, eventData->congest.handle);
1529        }
1530        else
1531        {
1532            ALOGD_IF ((appl_trace_level>=BT_TRACE_LEVEL_DEBUG), "%s: NFA_P2P_CONGEST_EVT; nfa handle: 0x%04x  congested: %u", fn,
1533                    eventData->congest.handle, eventData->congest.is_congested);
1534
1535            SyncEventGuard guard (pConn->mCongEvent);
1536            pConn->mCongEvent.notifyOne();
1537        }
1538        break;
1539
1540    default:
1541        ALOGE ("%s: unknown event 0x%X ????", fn, p2pEvent);
1542        break;
1543    }
1544}
1545
1546
1547/*******************************************************************************
1548**
1549** Function:        connectionEventHandler
1550**
1551** Description:     Receive events from the stack.
1552**                  event: Event code.
1553**                  eventData: Event data.
1554**
1555** Returns:         None
1556**
1557*******************************************************************************/
1558void PeerToPeer::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* /*eventData*/)
1559{
1560    switch (event)
1561    {
1562    case NFA_SET_P2P_LISTEN_TECH_EVT:
1563        {
1564            SyncEventGuard guard (mSetTechEvent);
1565            mSetTechEvent.notifyOne(); //unblock NFA_SetP2pListenTech()
1566            break;
1567        }
1568    }
1569}
1570
1571
1572/*******************************************************************************
1573**
1574** Function:        getNextJniHandle
1575**
1576** Description:     Get a new JNI handle.
1577**
1578** Returns:         A new JNI handle.
1579**
1580*******************************************************************************/
1581PeerToPeer::tJNI_HANDLE PeerToPeer::getNewJniHandle ()
1582{
1583    tJNI_HANDLE newHandle = 0;
1584
1585    mNewJniHandleMutex.lock ();
1586    newHandle = mNextJniHandle++;
1587    mNewJniHandleMutex.unlock ();
1588    return newHandle;
1589}
1590
1591
1592/////////////////////////////////////////////////////////////////////////
1593/////////////////////////////////////////////////////////////////////////
1594
1595
1596/*******************************************************************************
1597**
1598** Function:        P2pServer
1599**
1600** Description:     Initialize member variables.
1601**
1602** Returns:         None
1603**
1604*******************************************************************************/
1605P2pServer::P2pServer(PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName)
1606:   mNfaP2pServerHandle (NFA_HANDLE_INVALID),
1607    mJniHandle (jniHandle)
1608{
1609    mServiceName.assign (serviceName);
1610
1611    memset (mServerConn, 0, sizeof(mServerConn));
1612}
1613
1614bool P2pServer::registerWithStack()
1615{
1616    static const char fn [] = "P2pServer::registerWithStack";
1617    ALOGD ("%s: enter; service name: %s  JNI handle: %u", fn, mServiceName.c_str(), mJniHandle);
1618    tNFA_STATUS     stat  = NFA_STATUS_OK;
1619    UINT8           serverSap = NFA_P2P_ANY_SAP;
1620
1621    /**********************
1622   default values for all LLCP parameters:
1623   - Local Link MIU (LLCP_MIU)
1624   - Option parameter (LLCP_OPT_VALUE)
1625   - Response Waiting Time Index (LLCP_WAITING_TIME)
1626   - Local Link Timeout (LLCP_LTO_VALUE)
1627   - Inactivity Timeout as initiator role (LLCP_INIT_INACTIVITY_TIMEOUT)
1628   - Inactivity Timeout as target role (LLCP_TARGET_INACTIVITY_TIMEOUT)
1629   - Delay SYMM response (LLCP_DELAY_RESP_TIME)
1630   - Data link connection timeout (LLCP_DATA_LINK_CONNECTION_TOUT)
1631   - Delay timeout to send first PDU as initiator (LLCP_DELAY_TIME_TO_SEND_FIRST_PDU)
1632   ************************/
1633   stat = NFA_P2pSetLLCPConfig (LLCP_MAX_MIU,
1634           LLCP_OPT_VALUE,
1635           LLCP_WAITING_TIME,
1636           LLCP_LTO_VALUE,
1637           0, //use 0 for infinite timeout for symmetry procedure when acting as initiator
1638           0, //use 0 for infinite timeout for symmetry procedure when acting as target
1639           LLCP_DELAY_RESP_TIME,
1640           LLCP_DATA_LINK_TIMEOUT,
1641           LLCP_DELAY_TIME_TO_SEND_FIRST_PDU);
1642   if (stat != NFA_STATUS_OK)
1643       ALOGE ("%s: fail set LLCP config; error=0x%X", fn, stat);
1644
1645   if (sSnepServiceName.compare(mServiceName) == 0)
1646       serverSap = LLCP_SAP_SNEP; //LLCP_SAP_SNEP == 4
1647
1648   {
1649       SyncEventGuard guard (mRegServerEvent);
1650       stat = NFA_P2pRegisterServer (serverSap, NFA_P2P_DLINK_TYPE, const_cast<char*>(mServiceName.c_str()),
1651               PeerToPeer::nfaServerCallback);
1652       if (stat != NFA_STATUS_OK)
1653       {
1654           ALOGE ("%s: fail register p2p server; error=0x%X", fn, stat);
1655           return (false);
1656       }
1657       ALOGD ("%s: wait for listen-completion event", fn);
1658       // Wait for NFA_P2P_REG_SERVER_EVT
1659       mRegServerEvent.wait ();
1660   }
1661
1662   return (mNfaP2pServerHandle != NFA_HANDLE_INVALID);
1663}
1664
1665bool P2pServer::accept(PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle,
1666        int maxInfoUnit, int recvWindow)
1667{
1668    static const char fn [] = "P2pServer::accept";
1669    tNFA_STATUS     nfaStat  = NFA_STATUS_OK;
1670
1671    sp<NfaConn> connection = allocateConnection(connJniHandle);
1672    if (connection == NULL) {
1673        ALOGE ("%s: failed to allocate new server connection", fn);
1674        return false;
1675    }
1676
1677    {
1678        // Wait for NFA_P2P_CONN_REQ_EVT or NFA_NDEF_DATA_EVT when remote device requests connection
1679        SyncEventGuard guard (mConnRequestEvent);
1680        ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; wait for incoming connection", fn,
1681                serverJniHandle, connJniHandle);
1682        mConnRequestEvent.wait();
1683        ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X; got incoming connection", fn,
1684                serverJniHandle, connJniHandle, connection->mNfaConnHandle);
1685    }
1686
1687    if (connection->mNfaConnHandle == NFA_HANDLE_INVALID)
1688    {
1689        removeServerConnection(connJniHandle);
1690        ALOGD ("%s: no handle assigned", fn);
1691        return (false);
1692    }
1693
1694    if (maxInfoUnit > (int)LLCP_MIU)
1695    {
1696        ALOGD ("%s: overriding the miu passed by the app(%d) with stack miu(%d)", fn, maxInfoUnit, LLCP_MIU);
1697        maxInfoUnit = LLCP_MIU;
1698    }
1699
1700    ALOGD ("%s: serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X; try accept", fn,
1701            serverJniHandle, connJniHandle, connection->mNfaConnHandle);
1702    nfaStat = NFA_P2pAcceptConn (connection->mNfaConnHandle, maxInfoUnit, recvWindow);
1703
1704    if (nfaStat != NFA_STATUS_OK)
1705    {
1706        ALOGE ("%s: fail to accept remote; error=0x%X", fn, nfaStat);
1707        return (false);
1708    }
1709
1710    ALOGD ("%s: exit; serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X", fn,
1711            serverJniHandle, connJniHandle, connection->mNfaConnHandle);
1712    return (true);
1713}
1714
1715void P2pServer::unblockAll()
1716{
1717    AutoMutex mutex(mMutex);
1718    for (int jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++)
1719    {
1720        if (mServerConn[jj] != NULL)
1721        {
1722            mServerConn[jj]->mNfaConnHandle = NFA_HANDLE_INVALID;
1723            {
1724                SyncEventGuard guard1 (mServerConn[jj]->mCongEvent);
1725                mServerConn[jj]->mCongEvent.notifyOne (); //unblock write (if congested)
1726            }
1727            {
1728                SyncEventGuard guard2 (mServerConn[jj]->mReadEvent);
1729                mServerConn[jj]->mReadEvent.notifyOne (); //unblock receive()
1730            }
1731        }
1732    }
1733}
1734
1735sp<NfaConn> P2pServer::allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle)
1736{
1737    AutoMutex mutex(mMutex);
1738    // First, find a free connection block to handle the connection
1739    for (int ii = 0; ii < MAX_NFA_CONNS_PER_SERVER; ii++)
1740    {
1741        if (mServerConn[ii] == NULL)
1742        {
1743            mServerConn[ii] = new NfaConn;
1744            mServerConn[ii]->mJniHandle = jniHandle;
1745            return mServerConn[ii];
1746        }
1747    }
1748
1749    return NULL;
1750}
1751
1752
1753/*******************************************************************************
1754**
1755** Function:        findServerConnection
1756**
1757** Description:     Find a P2pServer that has the handle.
1758**                  nfaConnHandle: NFA connection handle.
1759**
1760** Returns:         P2pServer object.
1761**
1762*******************************************************************************/
1763sp<NfaConn> P2pServer::findServerConnection (tNFA_HANDLE nfaConnHandle)
1764{
1765    int jj = 0;
1766
1767    AutoMutex mutex(mMutex);
1768    for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++)
1769    {
1770        if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mNfaConnHandle == nfaConnHandle) )
1771            return (mServerConn[jj]);
1772    }
1773
1774    // If here, not found
1775    return (NULL);
1776}
1777
1778/*******************************************************************************
1779**
1780** Function:        findServerConnection
1781**
1782** Description:     Find a P2pServer that has the handle.
1783**                  nfaConnHandle: NFA connection handle.
1784**
1785** Returns:         P2pServer object.
1786**
1787*******************************************************************************/
1788sp<NfaConn> P2pServer::findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle)
1789{
1790    int jj = 0;
1791
1792    AutoMutex mutex(mMutex);
1793    for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++)
1794    {
1795        if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mJniHandle == jniHandle) )
1796            return (mServerConn[jj]);
1797    }
1798
1799    // If here, not found
1800    return (NULL);
1801}
1802
1803/*******************************************************************************
1804**
1805** Function:        removeServerConnection
1806**
1807** Description:     Find a P2pServer that has the handle.
1808**                  nfaConnHandle: NFA connection handle.
1809**
1810** Returns:         P2pServer object.
1811**
1812*******************************************************************************/
1813bool P2pServer::removeServerConnection (PeerToPeer::tJNI_HANDLE jniHandle)
1814{
1815    int jj = 0;
1816
1817    AutoMutex mutex(mMutex);
1818    for (jj = 0; jj < MAX_NFA_CONNS_PER_SERVER; jj++)
1819    {
1820        if ( (mServerConn[jj] != NULL) && (mServerConn[jj]->mJniHandle == jniHandle) ) {
1821            mServerConn[jj] = NULL;
1822            return true;
1823        }
1824    }
1825
1826    // If here, not found
1827    return false;
1828}
1829/////////////////////////////////////////////////////////////////////////
1830/////////////////////////////////////////////////////////////////////////
1831
1832
1833/*******************************************************************************
1834**
1835** Function:        P2pClient
1836**
1837** Description:     Initialize member variables.
1838**
1839** Returns:         None
1840**
1841*******************************************************************************/
1842P2pClient::P2pClient ()
1843:   mNfaP2pClientHandle (NFA_HANDLE_INVALID),
1844    mIsConnecting (false)
1845{
1846    mClientConn = new NfaConn();
1847}
1848
1849
1850/*******************************************************************************
1851**
1852** Function:        ~P2pClient
1853**
1854** Description:     Free all resources.
1855**
1856** Returns:         None
1857**
1858*******************************************************************************/
1859P2pClient::~P2pClient ()
1860{
1861}
1862
1863
1864/////////////////////////////////////////////////////////////////////////
1865/////////////////////////////////////////////////////////////////////////
1866
1867
1868/*******************************************************************************
1869**
1870** Function:        NfaConn
1871**
1872** Description:     Initialize member variables.
1873**
1874** Returns:         None
1875**
1876*******************************************************************************/
1877NfaConn::NfaConn()
1878:   mNfaConnHandle (NFA_HANDLE_INVALID),
1879    mJniHandle (0),
1880    mMaxInfoUnit (0),
1881    mRecvWindow (0),
1882    mRemoteMaxInfoUnit (0),
1883    mRemoteRecvWindow (0)
1884{
1885}
1886