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 * Manage listen-mode AID routing to the host.
19 */
20 #include "OverrideLog.h"
21 #include "HostAidRouter.h"
22 #include "config.h"
23 #include "SecureElement.h"
24
25
26 HostAidRouter HostAidRouter::sHostAidRouter; //singleton HostAidRouter object
27
28
29 /*******************************************************************************
30 **
31 ** Function: HostAidRouter
32 **
33 ** Description: Private constructor to prevent public call.
34 **
35 ** Returns: None.
36 **
37 *******************************************************************************/
HostAidRouter()38 HostAidRouter::HostAidRouter ()
39 : mTempHandle (NFA_HANDLE_INVALID),
40 mIsFeatureEnabled (true)
41 {
42 }
43
44
45 /*******************************************************************************
46 **
47 ** Function: ~HostAidRouter
48 **
49 ** Description: Private destructor to prevent public call.
50 **
51 ** Returns: None.
52 **
53 *******************************************************************************/
~HostAidRouter()54 HostAidRouter::~HostAidRouter ()
55 {
56 }
57
58
59 /*******************************************************************************
60 **
61 ** Function: getInstance
62 **
63 ** Description: Obtain a reference to the singleton object of HostAidRouter
64 **
65 ** Returns: Reference to HostAidRouter object.
66 **
67 *******************************************************************************/
getInstance()68 HostAidRouter& HostAidRouter::getInstance ()
69 {
70 return sHostAidRouter;
71 }
72
73
74 /*******************************************************************************
75 **
76 ** Function: initialize
77 **
78 ** Description: Initialize all resources.
79 **
80 ** Returns: True if ok.
81 **
82 *******************************************************************************/
initialize()83 bool HostAidRouter::initialize ()
84 {
85 unsigned long num = 0;
86 mTempHandle = NFA_HANDLE_INVALID;
87 mHandleDatabase.clear ();
88
89 if (GetNumValue (NAME_REGISTER_VIRTUAL_SE, &num, sizeof (num)))
90 mIsFeatureEnabled = num != 0;
91 return true;
92 }
93
94
95 /*******************************************************************************
96 **
97 ** Function: addPpseRoute
98 **
99 ** Description: Route Proximity Payment System Environment request
100 ** to the host. This function is called when there is no
101 ** route data.
102 **
103 ** Returns: True if ok.
104 **
105 *******************************************************************************/
addPpseRoute()106 bool HostAidRouter::addPpseRoute ()
107 {
108 static const char fn [] = "HostAidRouter::addPpseRoute";
109 ALOGD ("%s: enter", fn);
110 tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
111 bool retval = false;
112
113 if (! mIsFeatureEnabled)
114 {
115 ALOGD ("%s: feature disabled", fn);
116 goto TheEnd;
117 }
118
119 {
120 ALOGD ("%s: register PPSE AID", fn);
121 SyncEventGuard guard (mRegisterEvent);
122 mTempHandle = NFA_HANDLE_INVALID;
123 nfaStat = NFA_CeRegisterAidOnDH ((UINT8*) "2PAY.SYS.DDF01", 14, stackCallback);
124 if (nfaStat == NFA_STATUS_OK)
125 {
126 mRegisterEvent.wait (); //wait for NFA_CE_REGISTERED_EVT
127 if (mTempHandle == NFA_HANDLE_INVALID)
128 {
129 ALOGE ("%s: received invalid handle", fn);
130 goto TheEnd;
131 }
132 else
133 mHandleDatabase.push_back (mTempHandle);
134 }
135 else
136 {
137 ALOGE ("%s: fail register", fn);
138 goto TheEnd;
139 }
140 }
141 retval = true;
142
143 TheEnd:
144 ALOGD ("%s: exit; ok=%u", fn, retval);
145 return retval;
146 }
147
148
149 /*******************************************************************************
150 **
151 ** Function: deleteAllRoutes
152 **
153 ** Description: Delete all AID routes to the host.
154 **
155 ** Returns: True if ok.
156 **
157 *******************************************************************************/
deleteAllRoutes()158 bool HostAidRouter::deleteAllRoutes ()
159 {
160 static const char fn [] = "HostAidRouter::deleteAllRoutes";
161 ALOGD ("%s: enter", fn);
162 tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
163 bool retval = false;
164
165 if (! mIsFeatureEnabled)
166 {
167 ALOGD ("%s: feature disabled", fn);
168 goto TheEnd;
169 }
170
171 //deregister each registered AID from the stack
172 for (AidHandleDatabase::iterator iter1 = mHandleDatabase.begin(); iter1 != mHandleDatabase.end(); iter1++)
173 {
174 tNFA_HANDLE aidHandle = *iter1;
175 ALOGD ("%s: deregister h=0x%X", fn, aidHandle);
176 SyncEventGuard guard (mDeregisterEvent);
177 nfaStat = NFA_CeDeregisterAidOnDH (aidHandle);
178 if (nfaStat == NFA_STATUS_OK)
179 mDeregisterEvent.wait (); //wait for NFA_CE_DEREGISTERED_EVT
180 else
181 ALOGE ("%s: fail deregister", fn);
182 }
183 mHandleDatabase.clear ();
184 retval = true;
185
186 TheEnd:
187 ALOGD ("%s: exit; ok=%u", fn, retval);
188 return retval;
189 }
190
191
192 /*******************************************************************************
193 **
194 ** Function: startRoute
195 **
196 ** Description: Begin to route AID request to the host.
197 ** aid: Buffer that contains Application ID
198 ** aidLen: Actual length of the buffer.
199 **
200 ** Returns: True if ok.
201 **
202 *******************************************************************************/
startRoute(const UINT8 * aid,UINT8 aidLen)203 bool HostAidRouter::startRoute (const UINT8* aid, UINT8 aidLen)
204 {
205 static const char fn [] = "HostAidRouter::startRoute";
206 ALOGD ("%s: enter", fn);
207 tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
208 bool retval = false;
209
210 if (! mIsFeatureEnabled)
211 {
212 ALOGD ("%s: feature disabled", fn);
213 goto TheEnd;
214 }
215
216 {
217 ALOGD ("%s: register AID; len=%u", fn, aidLen);
218 SyncEventGuard guard (mRegisterEvent);
219 mTempHandle = NFA_HANDLE_INVALID;
220 nfaStat = NFA_CeRegisterAidOnDH ((UINT8*) aid, aidLen, stackCallback);
221 if (nfaStat == NFA_STATUS_OK)
222 {
223 mRegisterEvent.wait (); //wait for NFA_CE_REGISTERED_EVT
224 if (mTempHandle == NFA_HANDLE_INVALID)
225 {
226 ALOGE ("%s: received invalid handle", fn);
227 goto TheEnd;
228 }
229 else
230 mHandleDatabase.push_back (mTempHandle);
231 }
232 else
233 {
234 ALOGE ("%s: fail register", fn);
235 goto TheEnd;
236 }
237 }
238
239 TheEnd:
240 ALOGD ("%s: exit; ok=%u", fn, retval);
241 return retval;
242 }
243
244
245 /*******************************************************************************
246 **
247 ** Function: stackCallback
248 **
249 ** Description: Receive events from the NFC stack.
250 **
251 ** Returns: None.
252 **
253 *******************************************************************************/
stackCallback(UINT8 event,tNFA_CONN_EVT_DATA * eventData)254 void HostAidRouter::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
255 {
256 static const char fn [] = "HostAidRouter::stackCallback";
257 ALOGD("%s: event=0x%X", fn, event);
258
259 switch (event)
260 {
261 case NFA_CE_REGISTERED_EVT:
262 {
263 tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
264 ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
265 SyncEventGuard guard (sHostAidRouter.mRegisterEvent);
266 if (ce_registered.status == NFA_STATUS_OK)
267 sHostAidRouter.mTempHandle = ce_registered.handle;
268 else
269 sHostAidRouter.mTempHandle = NFA_HANDLE_INVALID;
270 sHostAidRouter.mRegisterEvent.notifyOne();
271 }
272 break;
273
274 case NFA_CE_DEREGISTERED_EVT:
275 {
276 tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
277 ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
278 SyncEventGuard guard (sHostAidRouter.mDeregisterEvent);
279 sHostAidRouter.mDeregisterEvent.notifyOne();
280 }
281 break;
282
283 case NFA_CE_DATA_EVT:
284 {
285 tNFA_CE_DATA& ce_data = eventData->ce_data;
286 ALOGD("%s: NFA_CE_DATA_EVT; h=0x%X; data len=%u", fn, ce_data.handle, ce_data.len);
287 SecureElement::getInstance().notifyTransactionListenersOfAid ((UINT8 *)"2PAY.SYS.DDF01", 14);
288 }
289 break;
290 }
291 }
292