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_t 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_t miu, uint8_t rw);
194
195
196    /*******************************************************************************
197    **
198    ** Function:        connectConnOriented
199    **
200    ** Description:     Establish 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:     Establish 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_t 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_t* buffer, uint16_t 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_t* buffer, uint16_t bufferLen, uint16_t& 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_t 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_t 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    **
309    ** Function:        getP2pListenMask
310    **
311    ** Description:     Get the set of technologies that P2P is listening.
312    **
313    ** Returns:         Set of technologies.
314    **
315    *******************************************************************************/
316    tNFA_TECHNOLOGY_MASK getP2pListenMask ();
317
318
319    /*******************************************************************************
320    **
321    ** Function:        resetP2pListenMask
322    **
323    ** Description:     Reset the p2p listen technology mask to initial value.
324    **
325    ** Returns:         None.
326    **
327    *******************************************************************************/
328    void resetP2pListenMask ();
329
330    /*******************************************************************************
331    **
332    ** Function:        enableP2pListening
333    **
334    ** Description:     Start/stop polling/listening to peer that supports P2P.
335    **                  isEnable: Is enable polling/listening?
336    **
337    ** Returns:         None
338    **
339    *******************************************************************************/
340    void enableP2pListening (bool isEnable);
341
342
343    /*******************************************************************************
344    **
345    ** Function:        handleNfcOnOff
346    **
347    ** Description:     Handle events related to turning NFC on/off by the user.
348    **                  isOn: Is NFC turning on?
349    **
350    ** Returns:         None
351    **
352    *******************************************************************************/
353    void handleNfcOnOff (bool isOn);
354
355
356    /*******************************************************************************
357    **
358    ** Function:        getNextJniHandle
359    **
360    ** Description:     Get a new JNI handle.
361    **
362    ** Returns:         A new JNI handle.
363    **
364    *******************************************************************************/
365    tJNI_HANDLE getNewJniHandle ();
366
367    /*******************************************************************************
368    **
369    ** Function:        nfaServerCallback
370    **
371    ** Description:     Receive LLCP-related events from the stack.
372    **                  p2pEvent: Event code.
373    **                  eventData: Event data.
374    **
375    ** Returns:         None
376    **
377    *******************************************************************************/
378    static void nfaServerCallback  (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData);
379
380
381    /*******************************************************************************
382    **
383    ** Function:        nfaClientCallback
384    **
385    ** Description:     Receive LLCP-related events from the stack.
386    **                  p2pEvent: Event code.
387    **                  eventData: Event data.
388    **
389    ** Returns:         None
390    **
391    *******************************************************************************/
392    static void nfaClientCallback  (tNFA_P2P_EVT p2pEvent, tNFA_P2P_EVT_DATA *eventData);
393
394private:
395    static const int sMax = 10;
396    static PeerToPeer sP2p;
397
398    // Variables below only accessed from a single thread
399    uint16_t        mRemoteWKS;                 // Peer's well known services
400    bool            mIsP2pListening;            // If P2P listening is enabled or not
401    tNFA_TECHNOLOGY_MASK    mP2pListenTechMask; // P2P Listen mask
402
403    // Variable below is protected by mNewJniHandleMutex
404    tJNI_HANDLE     mNextJniHandle;
405
406    // Variables below protected by mMutex
407    // A note on locking order: mMutex in PeerToPeer is *ALWAYS*
408    // locked before any locks / guards in P2pServer / P2pClient
409    Mutex                    mMutex;
410    android::sp<P2pServer>   mServers [sMax];
411    android::sp<P2pClient>   mClients [sMax];
412
413    // Synchronization variables
414    SyncEvent       mSetTechEvent;              // completion event for NFA_SetP2pListenTech()
415    SyncEvent       mSnepDefaultServerStartStopEvent; // completion event for NFA_SnepStartDefaultServer(), NFA_SnepStopDefaultServer()
416    SyncEvent       mSnepRegisterEvent;         // completion event for NFA_SnepRegisterClient()
417    Mutex           mDisconnectMutex;           // synchronize the disconnect operation
418    Mutex           mNewJniHandleMutex;         // synchronize the creation of a new JNI handle
419
420
421    /*******************************************************************************
422    **
423    ** Function:        ndefTypeCallback
424    **
425    ** Description:     Receive NDEF-related events from the stack.
426    **                  ndefEvent: Event code.
427    **                  eventData: Event data.
428    **
429    ** Returns:         None
430    **
431    *******************************************************************************/
432    static void ndefTypeCallback   (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *evetnData);
433
434
435    /*******************************************************************************
436    **
437    ** Function:        findServer
438    **
439    ** Description:     Find a PeerToPeer object by connection handle.
440    **                  nfaP2pServerHandle: Connectin handle.
441    **
442    ** Returns:         PeerToPeer object.
443    **
444    *******************************************************************************/
445    android::sp<P2pServer>   findServerLocked (tNFA_HANDLE nfaP2pServerHandle);
446
447
448    /*******************************************************************************
449    **
450    ** Function:        findServer
451    **
452    ** Description:     Find a PeerToPeer object by connection handle.
453    **                  serviceName: service name.
454    **
455    ** Returns:         PeerToPeer object.
456    **
457    *******************************************************************************/
458    android::sp<P2pServer>   findServerLocked (tJNI_HANDLE jniHandle);
459
460
461    /*******************************************************************************
462    **
463    ** Function:        findServer
464    **
465    ** Description:     Find a PeerToPeer object by service name
466    **                  serviceName: service name.
467    **
468    ** Returns:         PeerToPeer object.
469    **
470    *******************************************************************************/
471    android::sp<P2pServer>   findServerLocked (const char *serviceName);
472
473
474    /*******************************************************************************
475    **
476    ** Function:        removeServer
477    **
478    ** Description:     Free resources related to a server.
479    **                  jniHandle: Connection handle.
480    **
481    ** Returns:         None
482    **
483    *******************************************************************************/
484    void        removeServer (tJNI_HANDLE jniHandle);
485
486
487    /*******************************************************************************
488    **
489    ** Function:        removeConn
490    **
491    ** Description:     Free resources related to a connection.
492    **                  jniHandle: Connection handle.
493    **
494    ** Returns:         None
495    **
496    *******************************************************************************/
497    void        removeConn (tJNI_HANDLE jniHandle);
498
499
500    /*******************************************************************************
501    **
502    ** Function:        createDataLinkConn
503    **
504    ** Description:     Establish a connection-oriented connection to a peer.
505    **                  jniHandle: Connection handle.
506    **                  serviceName: Peer's service name.
507    **                  destinationSap: Peer's service access point.
508    **
509    ** Returns:         True if ok.
510    **
511    *******************************************************************************/
512    bool        createDataLinkConn (tJNI_HANDLE jniHandle, const char* serviceName, uint8_t destinationSap);
513
514
515    /*******************************************************************************
516    **
517    ** Function:        findClient
518    **
519    ** Description:     Find a PeerToPeer object with a client connection handle.
520    **                  nfaConnHandle: Connection handle.
521    **
522    ** Returns:         PeerToPeer object.
523    **
524    *******************************************************************************/
525    android::sp<P2pClient>   findClient (tNFA_HANDLE nfaConnHandle);
526
527
528    /*******************************************************************************
529    **
530    ** Function:        findClient
531    **
532    ** Description:     Find a PeerToPeer object with a client connection handle.
533    **                  jniHandle: Connection handle.
534    **
535    ** Returns:         PeerToPeer object.
536    **
537    *******************************************************************************/
538    android::sp<P2pClient>   findClient (tJNI_HANDLE jniHandle);
539
540
541    /*******************************************************************************
542    **
543    ** Function:        findClientCon
544    **
545    ** Description:     Find a PeerToPeer object with a client connection handle.
546    **                  nfaConnHandle: Connection handle.
547    **
548    ** Returns:         PeerToPeer object.
549    **
550    *******************************************************************************/
551    android::sp<P2pClient>   findClientCon (tNFA_HANDLE nfaConnHandle);
552
553
554    /*******************************************************************************
555    **
556    ** Function:        findConnection
557    **
558    ** Description:     Find a PeerToPeer object with a connection handle.
559    **                  nfaConnHandle: Connection handle.
560    **
561    ** Returns:         PeerToPeer object.
562    **
563    *******************************************************************************/
564    android::sp<NfaConn>     findConnection (tNFA_HANDLE nfaConnHandle);
565
566
567    /*******************************************************************************
568    **
569    ** Function:        findConnection
570    **
571    ** Description:     Find a PeerToPeer object with a connection handle.
572    **                  jniHandle: Connection handle.
573    **
574    ** Returns:         PeerToPeer object.
575    **
576    *******************************************************************************/
577    android::sp<NfaConn>     findConnection (tJNI_HANDLE jniHandle);
578};
579
580
581/*****************************************************************************
582**
583**  Name:           NfaConn
584**
585**  Description:    Store information about a connection related to a peer.
586**
587*****************************************************************************/
588class NfaConn : public android::RefBase
589{
590public:
591    tNFA_HANDLE         mNfaConnHandle;         // NFA handle of the P2P connection
592    PeerToPeer::tJNI_HANDLE         mJniHandle;             // JNI handle of the P2P connection
593    uint16_t            mMaxInfoUnit;
594    uint8_t             mRecvWindow;
595    uint16_t            mRemoteMaxInfoUnit;
596    uint8_t             mRemoteRecvWindow;
597    SyncEvent           mReadEvent;             // event for reading
598    SyncEvent           mCongEvent;             // event for congestion
599    SyncEvent           mDisconnectingEvent;     // event for disconnecting
600
601
602    /*******************************************************************************
603    **
604    ** Function:        NfaConn
605    **
606    ** Description:     Initialize member variables.
607    **
608    ** Returns:         None
609    **
610    *******************************************************************************/
611    NfaConn();
612};
613
614
615/*****************************************************************************
616**
617**  Name:           P2pServer
618**
619**  Description:    Store information about an in-bound connection from a peer.
620**
621*****************************************************************************/
622class P2pServer : public android::RefBase
623{
624public:
625    static const std::string sSnepServiceName;
626
627    tNFA_HANDLE     mNfaP2pServerHandle;    // NFA p2p handle of local server
628    PeerToPeer::tJNI_HANDLE     mJniHandle;     // JNI Handle
629    SyncEvent       mRegServerEvent;        // for NFA_P2pRegisterServer()
630    SyncEvent       mConnRequestEvent;      // for accept()
631    std::string     mServiceName;
632
633    /*******************************************************************************
634    **
635    ** Function:        P2pServer
636    **
637    ** Description:     Initialize member variables.
638    **
639    ** Returns:         None
640    **
641    *******************************************************************************/
642    P2pServer (PeerToPeer::tJNI_HANDLE jniHandle, const char* serviceName);
643
644    /*******************************************************************************
645    **
646    ** Function:        registerWithStack
647    **
648    ** Description:     Register this server with the stack.
649    **
650    ** Returns:         True if ok.
651    **
652    *******************************************************************************/
653    bool registerWithStack();
654
655    /*******************************************************************************
656    **
657    ** Function:        accept
658    **
659    ** Description:     Accept a peer's request to connect.
660    **                  serverJniHandle: Server's handle.
661    **                  connJniHandle: Connection handle.
662    **                  maxInfoUnit: Maximum information unit.
663    **                  recvWindow: Receive window size.
664    **
665    ** Returns:         True if ok.
666    **
667    *******************************************************************************/
668    bool accept (PeerToPeer::tJNI_HANDLE serverJniHandle, PeerToPeer::tJNI_HANDLE connJniHandle,
669            int maxInfoUnit, int recvWindow);
670
671    /*******************************************************************************
672    **
673    ** Function:        unblockAll
674    **
675    ** Description:     Unblocks all server connections
676    **
677    ** Returns:         True if ok.
678    **
679    *******************************************************************************/
680    void unblockAll();
681
682    /*******************************************************************************
683    **
684    ** Function:        findServerConnection
685    **
686    ** Description:     Find a P2pServer that has the handle.
687    **                  nfaConnHandle: NFA connection handle.
688    **
689    ** Returns:         P2pServer object.
690    **
691    *******************************************************************************/
692    android::sp<NfaConn> findServerConnection (tNFA_HANDLE nfaConnHandle);
693
694    /*******************************************************************************
695    **
696    ** Function:        findServerConnection
697    **
698    ** Description:     Find a P2pServer that has the handle.
699    **                  jniHandle: JNI connection handle.
700    **
701    ** Returns:         P2pServer object.
702    **
703    *******************************************************************************/
704    android::sp<NfaConn> findServerConnection (PeerToPeer::tJNI_HANDLE jniHandle);
705
706    /*******************************************************************************
707    **
708    ** Function:        removeServerConnection
709    **
710    ** Description:     Remove a server connection with the provided handle.
711    **                  jniHandle: JNI connection handle.
712    **
713    ** Returns:         True if connection found and removed.
714    **
715    *******************************************************************************/
716    bool removeServerConnection(PeerToPeer::tJNI_HANDLE jniHandle);
717
718private:
719    Mutex           mMutex;
720    // mServerConn is protected by mMutex
721    android::sp<NfaConn>     mServerConn[MAX_NFA_CONNS_PER_SERVER];
722
723    /*******************************************************************************
724    **
725    ** Function:        allocateConnection
726    **
727    ** Description:     Allocate a new connection to accept on
728    **                  jniHandle: JNI connection handle.
729    **
730    ** Returns:         Allocated connection object
731    **                  NULL if the maximum number of connections was reached
732    **
733    *******************************************************************************/
734    android::sp<NfaConn> allocateConnection (PeerToPeer::tJNI_HANDLE jniHandle);
735};
736
737
738/*****************************************************************************
739**
740**  Name:           P2pClient
741**
742**  Description:    Store information about an out-bound connection to a peer.
743**
744*****************************************************************************/
745class P2pClient : public android::RefBase
746{
747public:
748    tNFA_HANDLE           mNfaP2pClientHandle;    // NFA p2p handle of client
749    bool                  mIsConnecting;          // Set true while connecting
750    android::sp<NfaConn>  mClientConn;
751    SyncEvent             mRegisteringEvent;      // For client registration
752    SyncEvent             mConnectingEvent;       // for NFA_P2pConnectByName or Sap()
753    SyncEvent             mSnepEvent;             // To wait for SNEP completion
754
755    /*******************************************************************************
756    **
757    ** Function:        P2pClient
758    **
759    ** Description:     Initialize member variables.
760    **
761    ** Returns:         None
762    **
763    *******************************************************************************/
764    P2pClient ();
765
766
767    /*******************************************************************************
768    **
769    ** Function:        ~P2pClient
770    **
771    ** Description:     Free all resources.
772    **
773    ** Returns:         None
774    **
775    *******************************************************************************/
776    ~P2pClient ();
777
778
779    /*******************************************************************************
780    **
781    ** Function:        unblock
782    **
783    ** Description:     Unblocks any threads that are locked on this connection
784    **
785    ** Returns:         None
786    **
787    *******************************************************************************/
788    void unblock();
789};
790
791