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