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, it may not be connected yet, so unblock it 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