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