1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /*
18  *  Communicate with a peer using NFC-DEP, LLCP, SNEP.
19  */
20 #include "_OverrideLog.h"
21 #include "PeerToPeer.h"
22 #include "NfcJniUtil.h"
23 #include "llcp_defs.h"
24 #include "config.h"
25 #include "JavaClassConstants.h"
26 #include <ScopedLocalRef.h>
27 
28 /* Some older PN544-based solutions would only send the first SYMM back
29  * (as an initiator) after the full LTO (750ms). But our connect timer
30  * starts immediately, and hence we may timeout if the timer is set to
31  * 1000 ms. Worse, this causes us to immediately connect to the NPP
32  * socket, causing concurrency issues in that stack. Increase the default
33  * timeout to 2000 ms, giving us enough time to complete the first connect.
34  */
35 #define LLCP_DATA_LINK_TIMEOUT    2000
36 
37 using namespace android;
38 
39 namespace android
40 {
41     extern void nativeNfcTag_registerNdefTypeHandler ();
42     extern void nativeNfcTag_deregisterNdefTypeHandler ();
43     extern void startRfDiscovery (bool isStart);
44     extern bool isDiscoveryStarted ();
45 }
46 
47 
48 PeerToPeer PeerToPeer::sP2p;
49 const 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 *******************************************************************************/
PeerToPeer()61 PeerToPeer::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 *******************************************************************************/
~PeerToPeer()84 PeerToPeer::~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 *******************************************************************************/
getInstance()98 PeerToPeer& 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 *******************************************************************************/
initialize()113 void PeerToPeer::initialize ()
114 {
115     ALOGV("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 *******************************************************************************/
findServerLocked(tNFA_HANDLE nfaP2pServerHandle)134 sp<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 *******************************************************************************/
findServerLocked(tJNI_HANDLE jniHandle)161 sp<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 *******************************************************************************/
findServerLocked(const char * serviceName)188 sp<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 *******************************************************************************/
registerServer(tJNI_HANDLE jniHandle,const char * serviceName)212 bool PeerToPeer::registerServer (tJNI_HANDLE jniHandle, const char *serviceName)
213 {
214     static const char fn [] = "PeerToPeer::registerServer";
215     ALOGV("%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         ALOGV("%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             ALOGV("%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         ALOGV("%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 *******************************************************************************/
removeServer(tJNI_HANDLE jniHandle)269 void 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             ALOGV("%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 *******************************************************************************/
llcpActivatedHandler(nfc_jni_native_data * nat,tNFA_LLCP_ACTIVATED & activated)301 void PeerToPeer::llcpActivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_ACTIVATED& activated)
302 {
303     static const char fn [] = "PeerToPeer::llcpActivatedHandler";
304     ALOGV("%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     ALOGV("%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     ALOGV("%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         ALOGV("%s: p2p initiator", fn);
337         e->SetIntField(tag.get(), f, (jint) MODE_P2P_INITIATOR);
338     } else {
339         ALOGV("%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     ALOGV("%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     ALOGV("%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 *******************************************************************************/
llcpDeactivatedHandler(nfc_jni_native_data * nat,tNFA_LLCP_DEACTIVATED &)379 void PeerToPeer::llcpDeactivatedHandler (nfc_jni_native_data* nat, tNFA_LLCP_DEACTIVATED& /*deactivated*/)
380 {
381     static const char fn [] = "PeerToPeer::llcpDeactivatedHandler";
382     ALOGV("%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     ALOGV("%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     ALOGV("%s: exit", fn);
404 }
405 
llcpFirstPacketHandler(nfc_jni_native_data * nat)406 void PeerToPeer::llcpFirstPacketHandler (nfc_jni_native_data* nat)
407 {
408     static const char fn [] = "PeerToPeer::llcpFirstPacketHandler";
409     ALOGV("%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     ALOGV("%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     ALOGV("%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 *******************************************************************************/
accept(tJNI_HANDLE serverJniHandle,tJNI_HANDLE connJniHandle,int maxInfoUnit,int recvWindow)444 bool 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     ALOGV("%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 *******************************************************************************/
deregisterServer(tJNI_HANDLE jniHandle)474 bool PeerToPeer::deregisterServer (tJNI_HANDLE jniHandle)
475 {
476     static const char fn [] = "PeerToPeer::deregisterServer";
477     ALOGV("%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     ALOGV("%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 *******************************************************************************/
createClient(tJNI_HANDLE jniHandle,uint16_t miu,uint8_t rw)532 bool PeerToPeer::createClient (tJNI_HANDLE jniHandle, uint16_t miu, uint8_t rw)
533 {
534     static const char fn [] = "PeerToPeer::createClient";
535     int i = 0;
536     ALOGV("%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     ALOGV("%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         ALOGV("%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 *******************************************************************************/
removeConn(tJNI_HANDLE jniHandle)592 void 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             ALOGV("%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 *******************************************************************************/
connectConnOriented(tJNI_HANDLE jniHandle,const char * serviceName)637 bool PeerToPeer::connectConnOriented (tJNI_HANDLE jniHandle, const char* serviceName)
638 {
639     static const char fn [] = "PeerToPeer::connectConnOriented";
640     ALOGV("%s: enter; h: %u  service name=%s", fn, jniHandle, serviceName);
641     bool stat = createDataLinkConn (jniHandle, serviceName, 0);
642     ALOGV("%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 *******************************************************************************/
connectConnOriented(tJNI_HANDLE jniHandle,uint8_t destinationSap)658 bool PeerToPeer::connectConnOriented (tJNI_HANDLE jniHandle, uint8_t destinationSap)
659 {
660     static const char fn [] = "PeerToPeer::connectConnOriented";
661     ALOGV("%s: enter; h: %u  dest sap: 0x%X", fn, jniHandle, destinationSap);
662     bool stat = createDataLinkConn (jniHandle, NULL, destinationSap);
663     ALOGV("%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 *******************************************************************************/
createDataLinkConn(tJNI_HANDLE jniHandle,const char * serviceName,uint8_t destinationSap)680 bool PeerToPeer::createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceName, uint8_t destinationSap)
681 {
682     static const char fn [] = "PeerToPeer::createDataLinkConn";
683     ALOGV("%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             ALOGV("%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     ALOGV("%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 *******************************************************************************/
findClient(tNFA_HANDLE nfaConnHandle)742 sp<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 *******************************************************************************/
findClient(tJNI_HANDLE jniHandle)764 sp<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 *******************************************************************************/
findClientCon(tNFA_HANDLE nfaConnHandle)786 sp<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 *******************************************************************************/
findConnection(tNFA_HANDLE nfaConnHandle)808 sp<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 *******************************************************************************/
findConnection(tJNI_HANDLE jniHandle)847 sp<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 *******************************************************************************/
send(tJNI_HANDLE jniHandle,uint8_t * buffer,uint16_t bufferLen)888 bool PeerToPeer::send (tJNI_HANDLE jniHandle, uint8_t *buffer, uint16_t 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     ALOGV_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             ALOGV_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         ALOGV_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 *******************************************************************************/
receive(tJNI_HANDLE jniHandle,uint8_t * buffer,uint16_t bufferLen,uint16_t & actualLen)942 bool PeerToPeer::receive (tJNI_HANDLE jniHandle, uint8_t* buffer, uint16_t bufferLen, uint16_t& actualLen)
943 {
944     static const char fn [] = "PeerToPeer::receive";
945     ALOGV_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_t actualDataLen2 = 0;
949     bool    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     ALOGV_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_t) actualDataLen2;
967             retVal = true;
968             break;
969         }
970         ALOGV_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     ALOGV_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 *******************************************************************************/
disconnectConnOriented(tJNI_HANDLE jniHandle)992 bool 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     ALOGV("%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         ALOGV("%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     ALOGV("%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 *******************************************************************************/
getRemoteMaxInfoUnit(tJNI_HANDLE jniHandle)1055 uint16_t 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     ALOGV("%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 *******************************************************************************/
getRemoteRecvWindow(tJNI_HANDLE jniHandle)1080 uint8_t PeerToPeer::getRemoteRecvWindow (tJNI_HANDLE jniHandle)
1081 {
1082     static const char fn [] = "PeerToPeer::getRemoteRecvWindow";
1083     ALOGV("%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 *******************************************************************************/
setP2pListenMask(tNFA_TECHNOLOGY_MASK p2pListenMask)1104 void 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 *******************************************************************************/
getP2pListenMask()1118 tNFA_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 *******************************************************************************/
resetP2pListenMask()1133 void 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 *******************************************************************************/
enableP2pListening(bool isEnable)1155 void PeerToPeer::enableP2pListening (bool isEnable)
1156 {
1157     static const char    fn []   = "PeerToPeer::enableP2pListening";
1158     tNFA_STATUS          nfaStat = NFA_STATUS_FAILED;
1159 
1160     ALOGV("%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     ALOGV("%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 *******************************************************************************/
handleNfcOnOff(bool isOn)1200 void PeerToPeer::handleNfcOnOff (bool isOn)
1201 {
1202     static const char fn [] = "PeerToPeer::handleNfcOnOff";
1203     ALOGV("%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     ALOGV("%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 *******************************************************************************/
nfaServerCallback(tNFA_P2P_EVT p2pEvent,tNFA_P2P_EVT_DATA * eventData)1266 void 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     ALOGV_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         ALOGV("%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         ALOGV("%s: NFA_P2P_ACTIVATED_EVT; handle: 0x%04x", fn, eventData->activated.handle);
1297         break;
1298 
1299     case NFA_P2P_DEACTIVATED_EVT:
1300         ALOGV("%s: NFA_P2P_DEACTIVATED_EVT; handle: 0x%04x", fn, eventData->activated.handle);
1301         break;
1302 
1303     case NFA_P2P_CONN_REQ_EVT:
1304         ALOGV("%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         ALOGV("%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             ALOGV("%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         ALOGV("%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         ALOGV("%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                 ALOGV("%s: NFA_P2P_DISC_EVT; try guard disconn event", fn);
1351                 SyncEventGuard guard3 (pConn->mDisconnectingEvent);
1352                 pConn->mDisconnectingEvent.notifyOne ();
1353                 ALOGV("%s: NFA_P2P_DISC_EVT; notified disconn event", fn);
1354             }
1355             {
1356                 ALOGV("%s: NFA_P2P_DISC_EVT; try guard congest event", fn);
1357                 SyncEventGuard guard1 (pConn->mCongEvent);
1358                 pConn->mCongEvent.notifyOne (); //unblock write (if congested)
1359                 ALOGV("%s: NFA_P2P_DISC_EVT; notified congest event", fn);
1360             }
1361             {
1362                 ALOGV("%s: NFA_P2P_DISC_EVT; try guard read event", fn);
1363                 SyncEventGuard guard2 (pConn->mReadEvent);
1364                 pConn->mReadEvent.notifyOne (); //unblock receive()
1365                 ALOGV("%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             ALOGV_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             ALOGV("%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         ALOGV("%s: unknown event 0x%X ????", fn, p2pEvent);
1406         break;
1407     }
1408     ALOGV_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 *******************************************************************************/
nfaClientCallback(tNFA_P2P_EVT p2pEvent,tNFA_P2P_EVT_DATA * eventData)1423 void 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     ALOGV_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             ALOGV("%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             ALOGV("%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         ALOGV("%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             ALOGV("%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         ALOGV("%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                 ALOGV("%s: NFA_P2P_DISC_EVT; try guard disconn event", fn);
1505                 SyncEventGuard guard3 (pConn->mDisconnectingEvent);
1506                 pConn->mDisconnectingEvent.notifyOne ();
1507                 ALOGV("%s: NFA_P2P_DISC_EVT; notified disconn event", fn);
1508             }
1509             {
1510                 ALOGV("%s: NFA_P2P_DISC_EVT; try guard congest event", fn);
1511                 SyncEventGuard guard1 (pConn->mCongEvent);
1512                 pConn->mCongEvent.notifyOne(); //unblock write (if congested)
1513                 ALOGV("%s: NFA_P2P_DISC_EVT; notified congest event", fn);
1514             }
1515             {
1516                 ALOGV("%s: NFA_P2P_DISC_EVT; try guard read event", fn);
1517                 SyncEventGuard guard2 (pConn->mReadEvent);
1518                 pConn->mReadEvent.notifyOne(); //unblock receive()
1519                 ALOGV("%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             ALOGV_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             ALOGV_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 *******************************************************************************/
connectionEventHandler(uint8_t event,tNFA_CONN_EVT_DATA *)1574 void PeerToPeer::connectionEventHandler (uint8_t 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 *******************************************************************************/
getNewJniHandle()1597 PeerToPeer::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 *******************************************************************************/
P2pServer(PeerToPeer::tJNI_HANDLE jniHandle,const char * serviceName)1621 P2pServer::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 
registerWithStack()1630 bool P2pServer::registerWithStack()
1631 {
1632     static const char fn [] = "P2pServer::registerWithStack";
1633     ALOGV("%s: enter; service name: %s  JNI handle: %u", fn, mServiceName.c_str(), mJniHandle);
1634     tNFA_STATUS     stat  = NFA_STATUS_OK;
1635     uint8_t         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        ALOGV("%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 
accept(PeerToPeer::tJNI_HANDLE serverJniHandle,PeerToPeer::tJNI_HANDLE connJniHandle,int maxInfoUnit,int recvWindow)1681 bool 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         ALOGV("%s: serverJniHandle: %u; connJniHandle: %u; wait for incoming connection", fn,
1697                 serverJniHandle, connJniHandle);
1698         mConnRequestEvent.wait();
1699         ALOGV("%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         ALOGV("%s: no handle assigned", fn);
1707         return (false);
1708     }
1709 
1710     if (maxInfoUnit > (int)LLCP_MIU)
1711     {
1712         ALOGV("%s: overriding the miu passed by the app(%d) with stack miu(%zu)", fn, maxInfoUnit, LLCP_MIU);
1713         maxInfoUnit = LLCP_MIU;
1714     }
1715 
1716     ALOGV("%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     ALOGV("%s: exit; serverJniHandle: %u; connJniHandle: %u; nfa conn h: 0x%X", fn,
1727             serverJniHandle, connJniHandle, connection->mNfaConnHandle);
1728     return (true);
1729 }
1730 
unblockAll()1731 void 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 
allocateConnection(PeerToPeer::tJNI_HANDLE jniHandle)1751 sp<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 *******************************************************************************/
findServerConnection(tNFA_HANDLE nfaConnHandle)1779 sp<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 *******************************************************************************/
findServerConnection(PeerToPeer::tJNI_HANDLE jniHandle)1804 sp<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 *******************************************************************************/
removeServerConnection(PeerToPeer::tJNI_HANDLE jniHandle)1829 bool 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 *******************************************************************************/
P2pClient()1858 P2pClient::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 *******************************************************************************/
~P2pClient()1875 P2pClient::~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 *******************************************************************************/
NfaConn()1893 NfaConn::NfaConn()
1894 :   mNfaConnHandle (NFA_HANDLE_INVALID),
1895     mJniHandle (0),
1896     mMaxInfoUnit (0),
1897     mRecvWindow (0),
1898     mRemoteMaxInfoUnit (0),
1899     mRemoteRecvWindow (0)
1900 {
1901 }
1902