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