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