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#pragma once
21#include <utils/RefBase.h>
22#include <utils/StrongPointer.h>
23#include "SyncEvent.h"
24#include "NfcJniUtil.h"
25#include <string>
26extern "C"
27{
28    #include "nfa_p2p_api.h"
29}
30
31class P2pServer;
32class P2pClient;
33class NfaConn;
34#define MAX_NFA_CONNS_PER_SERVER    5
35
36/*****************************************************************************
37**
38**  Name:           PeerToPeer
39**
40**  Description:    Communicate with a peer using NFC-DEP, LLCP, SNEP.
41**
42*****************************************************************************/
43class PeerToPeer
44{
45public:
46    typedef unsigned int tJNI_HANDLE;
47
48    /*******************************************************************************
49    **
50    ** Function:        PeerToPeer
51    **
52    ** Description:     Initialize member variables.
53    **
54    ** Returns:         None
55    **
56    *******************************************************************************/
57    PeerToPeer ();
58
59
60    /*******************************************************************************
61    **
62    ** Function:        ~PeerToPeer
63    **
64    ** Description:     Free all resources.
65    **
66    ** Returns:         None
67    **
68    *******************************************************************************/
69    ~PeerToPeer ();
70
71
72    /*******************************************************************************
73    **
74    ** Function:        getInstance
75    **
76    ** Description:     Get the singleton PeerToPeer object.
77    **
78    ** Returns:         Singleton PeerToPeer object.
79    **
80    *******************************************************************************/
81    static PeerToPeer& getInstance();
82
83
84    /*******************************************************************************
85    **
86    ** Function:        initialize
87    **
88    ** Description:     Initialize member variables.
89    **
90    ** Returns:         None
91    **
92    *******************************************************************************/
93    void initialize ();
94
95
96    /*******************************************************************************
97    **
98    ** Function:        llcpActivatedHandler
99    **
100    ** Description:     Receive LLLCP-activated event from stack.
101    **                  nat: JVM-related data.
102    **                  activated: Event data.
103    **
104    ** Returns:         None
105    **
106    *******************************************************************************/
107    void llcpActivatedHandler (nfc_jni_native_data* nativeData, tNFA_LLCP_ACTIVATED& activated);
108
109
110    /*******************************************************************************
111    **
112    ** Function:        llcpDeactivatedHandler
113    **
114    ** Description:     Receive LLLCP-deactivated event from stack.
115    **                  nat: JVM-related data.
116    **                  deactivated: Event data.
117    **
118    ** Returns:         None
119    **
120    *******************************************************************************/
121    void llcpDeactivatedHandler (nfc_jni_native_data* nativeData, tNFA_LLCP_DEACTIVATED& deactivated);
122
123    void llcpFirstPacketHandler(nfc_jni_native_data* nativeData);
124
125    /*******************************************************************************
126    **
127    ** Function:        connectionEventHandler
128    **
129    ** Description:     Receive events from the stack.
130    **                  event: Event code.
131    **                  eventData: Event data.
132    **
133    ** Returns:         None
134    **
135    *******************************************************************************/
136    void connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* eventData);
137
138
139    /*******************************************************************************
140    **
141    ** Function:        registerServer
142    **
143    ** Description:     Let a server start listening for peer's connection request.
144    **                  jniHandle: Connection handle.
145    **                  serviceName: Server's service name.
146    **
147    ** Returns:         True if ok.
148    **
149    *******************************************************************************/
150    bool registerServer (tJNI_HANDLE jniHandle, const char* serviceName);
151
152
153    /*******************************************************************************
154    **
155    ** Function:        deregisterServer
156    **
157    ** Description:     Stop a P2pServer from listening for peer.
158    **
159    ** Returns:         True if ok.
160    **
161    *******************************************************************************/
162    bool deregisterServer (tJNI_HANDLE jniHandle);
163
164
165    /*******************************************************************************
166    **
167    ** Function:        accept
168    **
169    ** Description:     Accept a peer's request to connect.
170    **                  serverJniHandle: Server's handle.
171    **                  connJniHandle: Connection handle.
172    **                  maxInfoUnit: Maximum information unit.
173    **                  recvWindow: Receive window size.
174    **
175    ** Returns:         True if ok.
176    **
177    *******************************************************************************/
178    bool accept (tJNI_HANDLE serverJniHandle, tJNI_HANDLE connJniHandle, int maxInfoUnit, int recvWindow);
179
180
181    /*******************************************************************************
182    **
183    ** Function:        createClient
184    **
185    ** Description:     Create a P2pClient object for a new out-bound connection.
186    **                  jniHandle: Connection handle.
187    **                  miu: Maximum information unit.
188    **                  rw: Receive window size.
189    **
190    ** Returns:         True if ok.
191    **
192    *******************************************************************************/
193    bool createClient (tJNI_HANDLE jniHandle, UINT16 miu, UINT8 rw);
194
195
196    /*******************************************************************************
197    **
198    ** Function:        connectConnOriented
199    **
200    ** Description:     Estabish a connection-oriented connection to a peer.
201    **                  jniHandle: Connection handle.
202    **                  serviceName: Peer's service name.
203    **
204    ** Returns:         True if ok.
205    **
206    *******************************************************************************/
207    bool connectConnOriented (tJNI_HANDLE jniHandle, const char* serviceName);
208
209
210    /*******************************************************************************
211    **
212    ** Function:        connectConnOriented
213    **
214    ** Description:     Estabish a connection-oriented connection to a peer.
215    **                  jniHandle: Connection handle.
216    **                  destinationSap: Peer's service access point.
217    **
218    ** Returns:         True if ok.
219    **
220    *******************************************************************************/
221    bool connectConnOriented (tJNI_HANDLE jniHandle, UINT8 destinationSap);
222
223
224    /*******************************************************************************
225    **
226    ** Function:        send
227    **
228    ** Description:     Send data to peer.
229    **                  jniHandle: Handle of connection.
230    **                  buffer: Buffer of data.
231    **                  bufferLen: Length of data.
232    **
233    ** Returns:         True if ok.
234    **
235    *******************************************************************************/
236    bool send (tJNI_HANDLE jniHandle, UINT8* buffer, UINT16 bufferLen);
237
238
239    /*******************************************************************************
240    **
241    ** Function:        receive
242    **
243    ** Description:     Receive data from peer.
244    **                  jniHandle: Handle of connection.
245    **                  buffer: Buffer to store data.
246    **                  bufferLen: Max length of buffer.
247    **                  actualLen: Actual length received.
248    **
249    ** Returns:         True if ok.
250    **
251    *******************************************************************************/
252    bool receive (tJNI_HANDLE jniHandle, UINT8* buffer, UINT16 bufferLen, UINT16& actualLen);
253
254
255    /*******************************************************************************
256    **
257    ** Function:        disconnectConnOriented
258    **
259    ** Description:     Disconnect a connection-oriented connection with peer.
260    **                  jniHandle: Handle of connection.
261    **
262    ** Returns:         True if ok.
263    **
264    *******************************************************************************/
265    bool disconnectConnOriented (tJNI_HANDLE jniHandle);
266
267
268    /*******************************************************************************
269    **
270    ** Function:        getRemoteMaxInfoUnit
271    **
272    ** Description:     Get peer's max information unit.
273    **                  jniHandle: Handle of the connection.
274    **
275    ** Returns:         Peer's max information unit.
276    **
277    *******************************************************************************/
278    UINT16 getRemoteMaxInfoUnit (tJNI_HANDLE jniHandle);
279
280
281    /*******************************************************************************
282    **
283    ** Function:        getRemoteRecvWindow
284    **
285    ** Description:     Get peer's receive window size.
286    **                  jniHandle: Handle of the connection.
287    **
288    ** Returns:         Peer's receive window size.
289    **
290    *******************************************************************************/
291    UINT8 getRemoteRecvWindow (tJNI_HANDLE jniHandle);
292
293
294    /*******************************************************************************
295    **
296    ** Function:        setP2pListenMask
297    **
298    ** Description:     Sets the p2p listen technology mask.
299    **                  p2pListenMask: the p2p listen mask to be set?
300    **
301    ** Returns:         None
302    **
303    *******************************************************************************/
304    void setP2pListenMask (tNFA_TECHNOLOGY_MASK p2pListenMask);
305
306    /*******************************************************************************
307    **
308    ** Function:        enableP2pListening
309    **
310    ** Description:     Start/stop polling/listening to peer that supports P2P.
311    **                  isEnable: Is enable polling/listening?
312    **
313    ** Returns:         None
314    **
315    *******************************************************************************/
316    void enableP2pListening (bool isEnable);
317
318
319    /*******************************************************************************
320    **
321    ** Function:        handleNfcOnOff
322    **
323    ** Description:     Handle events related to turning NFC on/off by the user.
324    **                  isOn: Is NFC turning on?
325    **
326    ** Returns:         None
327    **
328    *******************************************************************************/
329    void handleNfcOnOff (bool isOn);
330
331
332    /*******************************************************************************
333    **
334    ** Function:        getNextJniHandle
335    **
336    ** Description:     Get a new JNI handle.
337    **
338    ** Returns:         A new JNI handle.
339    **
340    *******************************************************************************/
341    tJNI_HANDLE getNewJniHandle ();
342
343    /*******************************************************************************
344    **
345    ** Function:        nfaServerCallback
346    **
347    ** Description:     Receive LLCP-related events from the stack.
348    **                  p2pEvent: Event code.
349    **                  eventData: Event data.
350    **
351    ** Returns:         None
352    **
353    *******************************************************************************/
354    static void nfaServerCallback  (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData);
355
356
357    /*******************************************************************************
358    **
359    ** Function:        nfaClientCallback
360    **
361    ** Description:     Receive LLCP-related events from the stack.
362    **                  p2pEvent: Event code.
363    **                  eventData: Event data.
364    **
365    ** Returns:         None
366    **
367    *******************************************************************************/
368    static void nfaClientCallback  (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData);
369
370private:
371    static const int sMax = 10;
372    static PeerToPeer sP2p;
373
374    // Variables below only accessed from a single thread
375    UINT16          mRemoteWKS;                 // Peer's well known services
376    bool            mIsP2pListening;            // If P2P listening is enabled or not
377    tNFA_TECHNOLOGY_MASK    mP2pListenTechMask; // P2P Listen mask
378
379    // Variable below is protected by mNewJniHandleMutex
380    tJNI_HANDLE     mNextJniHandle;
381
382    // Variables below protected by mMutex
383    // A note on locking order: mMutex in PeerToPeer is *ALWAYS*
384    // locked before any locks / guards in P2pServer / P2pClient
385    Mutex                    mMutex;
386    android::sp<P2pServer>   mServers [sMax];
387    android::sp<P2pClient>   mClients [sMax];
388
389    // Synchronization variables
390    SyncEvent       mSetTechEvent;              // completion event for NFA_SetP2pListenTech()
391    SyncEvent       mSnepDefaultServerStartStopEvent; // completion event for NFA_SnepStartDefaultServer(), NFA_SnepStopDefaultServer()
392    SyncEvent       mSnepRegisterEvent;         // completion event for NFA_SnepRegisterClient()
393    Mutex           mDisconnectMutex;           // synchronize the disconnect operation
394    Mutex           mNewJniHandleMutex;         // synchronize the creation of a new JNI handle
395
396
397    /*******************************************************************************
398    **
399    ** Function:        ndefTypeCallback
400    **
401    ** Description:     Receive NDEF-related events from the stack.
402    **                  ndefEvent: Event code.
403    **                  eventData: Event data.
404    **
405    ** Returns:         None
406    **
407    *******************************************************************************/
408    static void ndefTypeCallback   (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *evetnData);
409
410
411    /*******************************************************************************
412    **
413    ** Function:        findServer
414    **
415    ** Description:     Find a PeerToPeer object by connection handle.
416    **                  nfaP2pServerHandle: Connectin handle.
417    **
418    ** Returns:         PeerToPeer object.
419    **
420    *******************************************************************************/
421    android::sp<P2pServer>   findServerLocked (tNFA_HANDLE nfaP2pServerHandle);
422
423
424    /*******************************************************************************
425    **
426    ** Function:        findServer
427    **
428    ** Description:     Find a PeerToPeer object by connection handle.
429    **                  serviceName: service name.
430    **
431    ** Returns:         PeerToPeer object.
432    **
433    *******************************************************************************/
434    android::sp<P2pServer>   findServerLocked (tJNI_HANDLE jniHandle);
435
436
437    /*******************************************************************************
438    **
439    ** Function:        findServer
440    **
441    ** Description:     Find a PeerToPeer object by service name
442    **                  serviceName: service name.
443    **
444    ** Returns:         PeerToPeer object.
445    **
446    *******************************************************************************/
447    android::sp<P2pServer>   findServerLocked (const char *serviceName);
448
449
450    /*******************************************************************************
451    **
452    ** Function:        removeServer
453    **
454    ** Description:     Free resources related to a server.
455    **                  jniHandle: Connection handle.
456    **
457    ** Returns:         None
458    **
459    *******************************************************************************/
460    void        removeServer (tJNI_HANDLE jniHandle);
461
462
463    /*******************************************************************************
464    **
465    ** Function:        removeConn
466    **
467    ** Description:     Free resources related to a connection.
468    **                  jniHandle: Connection handle.
469    **
470    ** Returns:         None
471    **
472    *******************************************************************************/
473    void        removeConn (tJNI_HANDLE jniHandle);
474
475
476    /*******************************************************************************
477    **
478    ** Function:        createDataLinkConn
479    **
480    ** Description:     Establish a connection-oriented connection to a peer.
481    **                  jniHandle: Connection handle.
482    **                  serviceName: Peer's service name.
483    **                  destinationSap: Peer's service access point.
484    **
485    ** Returns:         True if ok.
486    **
487    *******************************************************************************/
488    bool        createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceName, UINT8 destinationSap);
489
490
491    /*******************************************************************************
492    **
493    ** Function:        findClient
494    **
495    ** Description:     Find a PeerToPeer object with a client connection handle.
496    **                  nfaConnHandle: Connection handle.
497    **
498    ** Returns:         PeerToPeer object.
499    **
500    *******************************************************************************/
501    android::sp<P2pClient>   findClient (tNFA_HANDLE nfaConnHandle);
502
503
504    /*******************************************************************************
505    **
506    ** Function:        findClient
507    **
508    ** Description:     Find a PeerToPeer object with a client connection handle.
509    **                  jniHandle: Connection handle.
510    **
511    ** Returns:         PeerToPeer object.
512    **
513    *******************************************************************************/
514    android::sp<P2pClient>   findClient (tJNI_HANDLE jniHandle);
515
516
517    /*******************************************************************************
518    **
519    ** Function:        findClientCon
520    **
521    ** Description:     Find a PeerToPeer object with a client connection handle.
522    **                  nfaConnHandle: Connection handle.
523    **
524    ** Returns:         PeerToPeer object.
525    **
526    *******************************************************************************/
527    android::sp<P2pClient>   findClientCon (tNFA_HANDLE nfaConnHandle);
528
529
530    /*******************************************************************************
531    **
532    ** Function:        findConnection
533    **
534    ** Description:     Find a PeerToPeer object with a connection handle.
535    **                  nfaConnHandle: Connection handle.
536    **
537    ** Returns:         PeerToPeer object.
538    **
539    *******************************************************************************/
540    android::sp<NfaConn>     findConnection (tNFA_HANDLE nfaConnHandle);
541
542
543    /*******************************************************************************
544    **
545    ** Function:        findConnection
546    **
547    ** Description:     Find a PeerToPeer object with a connection handle.
548    **                  jniHandle: Connection handle.
549    **
550    ** Returns:         PeerToPeer object.
551    **
552    *******************************************************************************/
553    android::sp<NfaConn>     findConnection (tJNI_HANDLE jniHandle);
554};
555
556
557/*****************************************************************************
558**
559**  Name:           NfaConn
560**
561**  Description:    Store information about a connection related to a peer.
562**
563*****************************************************************************/
564class NfaConn : public android::RefBase
565{
566public:
567    tNFA_HANDLE         mNfaConnHandle;         // NFA handle of the P2P connection
568    PeerToPeer::tJNI_HANDLE         mJniHandle;             // JNI handle of the P2P connection
569    UINT16              mMaxInfoUnit;
570    UINT8               mRecvWindow;
571    UINT16              mRemoteMaxInfoUnit;
572    UINT8               mRemoteRecvWindow;
573    SyncEvent           mReadEvent;             // event for reading
574    SyncEvent           mCongEvent;             // event for congestion
575    SyncEvent           mDisconnectingEvent;     // event for disconnecting
576
577
578    /*******************************************************************************
579    **
580    ** Function:        NfaConn
581    **
582    ** Description:     Initialize member variables.
583    **
584    ** Returns:         None
585    **
586    *******************************************************************************/
587    NfaConn();
588};
589
590
591/*****************************************************************************
592**
593**  Name:           P2pServer
594**
595**  Description:    Store information about an in-bound connection from a peer.
596**
597*****************************************************************************/
598class P2pServer : public android::RefBase
599{
600public:
601    static const std::string sSnepServiceName;
602
603    tNFA_HANDLE     mNfaP2pServerHandle;    // NFA p2p handle of local server
604    PeerToPeer::tJNI_HANDLE     mJniHandle;     // JNI Handle
605    SyncEvent       mRegServerEvent;        // for NFA_P2pRegisterServer()
606    SyncEvent       mConnRequestEvent;      // for accept()
607    std::string     mServiceName;
608
609    /*******************************************************************************
610    **
611    ** Function:        P2pServer
612    **
613    ** Description:     Initialize member variables.
614    **
615    ** Returns:         None
616    **
617    *******************************************************************************/
618    P2pServer (PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName);
619
620    /*******************************************************************************
621    **
622    ** Function:        registerWithStack
623    **
624    ** Description:     Register this server with the stack.
625    **
626    ** Returns:         True if ok.
627    **
628    *******************************************************************************/
629    bool registerWithStack();
630
631    /*******************************************************************************
632    **
633    ** Function:        accept
634    **
635    ** Description:     Accept a peer's request to connect.
636    **                  serverJniHandle: Server's handle.
637    **                  connJniHandle: Connection handle.
638    **                  maxInfoUnit: Maximum information unit.
639    **                  recvWindow: Receive window size.
640    **
641    ** Returns:         True if ok.
642    **
643    *******************************************************************************/
644    bool accept (PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle,
645            int maxInfoUnit, int recvWindow);
646
647    /*******************************************************************************
648    **
649    ** Function:        unblockAll
650    **
651    ** Description:     Unblocks all server connections
652    **
653    ** Returns:         True if ok.
654    **
655    *******************************************************************************/
656    void unblockAll();
657
658    /*******************************************************************************
659    **
660    ** Function:        findServerConnection
661    **
662    ** Description:     Find a P2pServer that has the handle.
663    **                  nfaConnHandle: NFA connection handle.
664    **
665    ** Returns:         P2pServer object.
666    **
667    *******************************************************************************/
668    android::sp<NfaConn> findServerConnection (tNFA_HANDLE nfaConnHandle);
669
670    /*******************************************************************************
671    **
672    ** Function:        findServerConnection
673    **
674    ** Description:     Find a P2pServer that has the handle.
675    **                  jniHandle: JNI connection handle.
676    **
677    ** Returns:         P2pServer object.
678    **
679    *******************************************************************************/
680    android::sp<NfaConn> findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle);
681
682    /*******************************************************************************
683    **
684    ** Function:        removeServerConnection
685    **
686    ** Description:     Remove a server connection with the provided handle.
687    **                  jniHandle: JNI connection handle.
688    **
689    ** Returns:         True if connection found and removed.
690    **
691    *******************************************************************************/
692    bool removeServerConnection(PeerToPeer::tJNI_HANDLE jniHandle);
693
694private:
695    Mutex           mMutex;
696    // mServerConn is protected by mMutex
697    android::sp<NfaConn>     mServerConn[MAX_NFA_CONNS_PER_SERVER];
698
699    /*******************************************************************************
700    **
701    ** Function:        allocateConnection
702    **
703    ** Description:     Allocate a new connection to accept on
704    **                  jniHandle: JNI connection handle.
705    **
706    ** Returns:         Allocated connection object
707    **                  NULL if the maximum number of connections was reached
708    **
709    *******************************************************************************/
710    android::sp<NfaConn> allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle);
711};
712
713
714/*****************************************************************************
715**
716**  Name:           P2pClient
717**
718**  Description:    Store information about an out-bound connection to a peer.
719**
720*****************************************************************************/
721class P2pClient : public android::RefBase
722{
723public:
724    tNFA_HANDLE           mNfaP2pClientHandle;    // NFA p2p handle of client
725    bool                  mIsConnecting;          // Set true while connecting
726    android::sp<NfaConn>  mClientConn;
727    SyncEvent             mRegisteringEvent;      // For client registration
728    SyncEvent             mConnectingEvent;       // for NFA_P2pConnectByName or Sap()
729    SyncEvent             mSnepEvent;             // To wait for SNEP completion
730
731    /*******************************************************************************
732    **
733    ** Function:        P2pClient
734    **
735    ** Description:     Initialize member variables.
736    **
737    ** Returns:         None
738    **
739    *******************************************************************************/
740    P2pClient ();
741
742
743    /*******************************************************************************
744    **
745    ** Function:        ~P2pClient
746    **
747    ** Description:     Free all resources.
748    **
749    ** Returns:         None
750    **
751    *******************************************************************************/
752    ~P2pClient ();
753
754
755    /*******************************************************************************
756    **
757    ** Function:        unblock
758    **
759    ** Description:     Unblocks any threads that are locked on this connection
760    **
761    ** Returns:         None
762    **
763    *******************************************************************************/
764    void unblock();
765};
766
767