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