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