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