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 **
19 **  Description:    Implement operations that provide compatibility with NXP
20 **                  PN544 controller.  Specifically facilitate peer-to-peer
21 **                  operations with PN544 controller.
22 **
23 *****************************************************************************/
24 #include "OverrideLog.h"
25 #include "Pn544Interop.h"
26 #include "IntervalTimer.h"
27 #include "Mutex.h"
28 #include "NfcTag.h"
29 namespace android
30 {
31     extern void startStopPolling (bool isStartPolling);
32 }
33 
34 
35 /*****************************************************************************
36 **
37 ** private variables and functions
38 **
39 *****************************************************************************/
40 
41 
42 static const int gIntervalTime = 1000; //millisecond between the check to restore polling
43 static IntervalTimer gTimer;
44 static Mutex gMutex;
45 static void pn544InteropStartPolling (union sigval); //callback function for interval timer
46 static bool gIsBusy = false; //is timer busy?
47 static bool gAbortNow = false; //stop timer during next callback
48 
49 
50 /*******************************************************************************
51 **
52 ** Function:        pn544InteropStopPolling
53 **
54 ** Description:     Stop polling to let NXP PN544 controller poll.
55 **                  PN544 should activate in P2P mode.
56 **
57 ** Returns:         None
58 **
59 *******************************************************************************/
pn544InteropStopPolling()60 void pn544InteropStopPolling ()
61 {
62     ALOGD ("%s: enter", __FUNCTION__);
63     gMutex.lock ();
64     gTimer.kill ();
65     android::startStopPolling (false);
66     gIsBusy = true;
67     gAbortNow = false;
68     gTimer.set (gIntervalTime, pn544InteropStartPolling); //after some time, start polling again
69     gMutex.unlock ();
70     ALOGD ("%s: exit", __FUNCTION__);
71 }
72 
73 
74 /*******************************************************************************
75 **
76 ** Function:        pn544InteropStartPolling
77 **
78 ** Description:     Start polling when activation state is idle.
79 **                  sigval: Unused.
80 **
81 ** Returns:         None
82 **
83 *******************************************************************************/
pn544InteropStartPolling(union sigval)84 void pn544InteropStartPolling (union sigval)
85 {
86     ALOGD ("%s: enter", __FUNCTION__);
87     gMutex.lock ();
88     NfcTag::ActivationState state = NfcTag::getInstance ().getActivationState ();
89 
90     if (gAbortNow)
91     {
92         ALOGD ("%s: abort now", __FUNCTION__);
93         gIsBusy = false;
94         goto TheEnd;
95     }
96 
97     if (state == NfcTag::Idle)
98     {
99         ALOGD ("%s: start polling", __FUNCTION__);
100         android::startStopPolling (true);
101         gIsBusy = false;
102     }
103     else
104     {
105         ALOGD ("%s: try again later", __FUNCTION__);
106         gTimer.set (gIntervalTime, pn544InteropStartPolling); //after some time, start polling again
107     }
108 
109 TheEnd:
110     gMutex.unlock ();
111     ALOGD ("%s: exit", __FUNCTION__);
112 }
113 
114 
115 /*******************************************************************************
116 **
117 ** Function:        pn544InteropIsBusy
118 **
119 ** Description:     Is the code performing operations?
120 **
121 ** Returns:         True if the code is busy.
122 **
123 *******************************************************************************/
pn544InteropIsBusy()124 bool pn544InteropIsBusy ()
125 {
126     bool isBusy = false;
127     gMutex.lock ();
128     isBusy = gIsBusy;
129     gMutex.unlock ();
130     ALOGD ("%s: %u", __FUNCTION__, isBusy);
131     return isBusy;
132 }
133 
134 
135 /*******************************************************************************
136 **
137 ** Function:        pn544InteropAbortNow
138 **
139 ** Description:     Request to abort all operations.
140 **
141 ** Returns:         None.
142 **
143 *******************************************************************************/
pn544InteropAbortNow()144 void pn544InteropAbortNow ()
145 {
146     ALOGD ("%s", __FUNCTION__);
147     gMutex.lock ();
148     gAbortNow = true;
149     gMutex.unlock ();
150 }
151 
152