1 /*
2 * Copyright (C) 2013 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 the listen-mode routing table.
19 */
20
21 #include <android-base/stringprintf.h>
22 #include <base/logging.h>
23 #include <nativehelper/JNIHelp.h>
24 #include <nativehelper/ScopedLocalRef.h>
25
26 #include "JavaClassConstants.h"
27 #include "RoutingManager.h"
28 #include "nfa_ce_api.h"
29 #include "nfa_ee_api.h"
30 #include "nfc_config.h"
31
32 using android::base::StringPrintf;
33
34 extern bool gActivated;
35 extern SyncEvent gDeactivatedEvent;
36 extern bool nfc_debug_enabled;
37
38 const JNINativeMethod RoutingManager::sMethods[] = {
39 {"doGetDefaultRouteDestination", "()I",
40 (void*)RoutingManager::
41 com_android_nfc_cardemulation_doGetDefaultRouteDestination},
42 {"doGetDefaultOffHostRouteDestination", "()I",
43 (void*)RoutingManager::
44 com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination},
45 {"doGetAidMatchingMode", "()I",
46 (void*)
47 RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode}};
48
49 static const int MAX_NUM_EE = 5;
50 // SCBR from host works only when App is in foreground
51 static const uint8_t SYS_CODE_PWR_STATE_HOST = 0x01;
52 static const uint16_t DEFAULT_SYS_CODE = 0xFEFE;
53
RoutingManager()54 RoutingManager::RoutingManager() {
55 static const char fn[] = "RoutingManager::RoutingManager()";
56
57 mDefaultOffHostRoute =
58 NfcConfig::getUnsigned(NAME_DEFAULT_OFFHOST_ROUTE, 0x00);
59
60 mDefaultFelicaRoute = NfcConfig::getUnsigned(NAME_DEFAULT_NFCF_ROUTE, 0x00);
61 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
62 "%s: Active SE for Nfc-F is 0x%02X", fn, mDefaultFelicaRoute);
63
64 mDefaultEe = NfcConfig::getUnsigned(NAME_DEFAULT_ROUTE, 0x00);
65 DLOG_IF(INFO, nfc_debug_enabled)
66 << StringPrintf("%s: default route is 0x%02X", fn, mDefaultEe);
67
68 mAidMatchingMode =
69 NfcConfig::getUnsigned(NAME_AID_MATCHING_MODE, AID_MATCHING_EXACT_ONLY);
70
71 mDefaultSysCodeRoute =
72 NfcConfig::getUnsigned(NAME_DEFAULT_SYS_CODE_ROUTE, 0xC0);
73
74 mDefaultSysCodePowerstate =
75 NfcConfig::getUnsigned(NAME_DEFAULT_SYS_CODE_PWR_STATE, 0x19);
76
77 mDefaultSysCode = DEFAULT_SYS_CODE;
78 if (NfcConfig::hasKey(NAME_DEFAULT_SYS_CODE)) {
79 std::vector<uint8_t> pSysCode = NfcConfig::getBytes(NAME_DEFAULT_SYS_CODE);
80 if (pSysCode.size() == 0x02) {
81 mDefaultSysCode = ((pSysCode[0] << 8) | ((int)pSysCode[1] << 0));
82 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
83 "%s: DEFAULT_SYS_CODE: 0x%02X", __func__, mDefaultSysCode);
84 }
85 }
86
87 mOffHostAidRoutingPowerState =
88 NfcConfig::getUnsigned(NAME_OFFHOST_AID_ROUTE_PWR_STATE, 0x01);
89
90 memset(&mEeInfo, 0, sizeof(mEeInfo));
91 mReceivedEeInfo = false;
92 mSeTechMask = 0x00;
93 mIsScbrSupported = false;
94
95 mNfcFOnDhHandle = NFA_HANDLE_INVALID;
96 }
97
~RoutingManager()98 RoutingManager::~RoutingManager() { NFA_EeDeregister(nfaEeCallback); }
99
initialize(nfc_jni_native_data * native)100 bool RoutingManager::initialize(nfc_jni_native_data* native) {
101 static const char fn[] = "RoutingManager::initialize()";
102 mNativeData = native;
103
104 tNFA_STATUS nfaStat;
105 {
106 SyncEventGuard guard(mEeRegisterEvent);
107 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: try ee register", fn);
108 nfaStat = NFA_EeRegister(nfaEeCallback);
109 if (nfaStat != NFA_STATUS_OK) {
110 LOG(ERROR) << StringPrintf("%s: fail ee register; error=0x%X", fn,
111 nfaStat);
112 return false;
113 }
114 mEeRegisterEvent.wait();
115 }
116
117 mRxDataBuffer.clear();
118
119 if ((mDefaultOffHostRoute != 0) || (mDefaultFelicaRoute != 0)) {
120 DLOG_IF(INFO, nfc_debug_enabled)
121 << StringPrintf("%s: Technology Routing (NfcASe:0x%02x, NfcFSe:0x%02x)",
122 fn, mDefaultOffHostRoute, mDefaultFelicaRoute);
123 {
124 // Wait for EE info if needed
125 SyncEventGuard guard(mEeInfoEvent);
126 if (!mReceivedEeInfo) {
127 LOG(INFO) << StringPrintf("Waiting for EE info");
128 mEeInfoEvent.wait();
129 }
130 }
131
132 DLOG_IF(INFO, nfc_debug_enabled)
133 << StringPrintf("%s: Number of EE is %d", fn, mEeInfo.num_ee);
134 for (uint8_t i = 0; i < mEeInfo.num_ee; i++) {
135 tNFA_HANDLE eeHandle = mEeInfo.ee_disc_info[i].ee_handle;
136 tNFA_TECHNOLOGY_MASK seTechMask = 0;
137
138 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
139 "%s EE[%u] Handle: 0x%04x techA: 0x%02x techB: "
140 "0x%02x techF: 0x%02x techBprime: 0x%02x",
141 fn, i, eeHandle, mEeInfo.ee_disc_info[i].la_protocol,
142 mEeInfo.ee_disc_info[i].lb_protocol,
143 mEeInfo.ee_disc_info[i].lf_protocol,
144 mEeInfo.ee_disc_info[i].lbp_protocol);
145 if ((mDefaultOffHostRoute != 0) &&
146 (eeHandle == (mDefaultOffHostRoute | NFA_HANDLE_GROUP_EE))) {
147 if (mEeInfo.ee_disc_info[i].la_protocol != 0)
148 seTechMask |= NFA_TECHNOLOGY_MASK_A;
149 if (mEeInfo.ee_disc_info[i].lb_protocol != 0)
150 seTechMask |= NFA_TECHNOLOGY_MASK_B;
151 }
152 if ((mDefaultFelicaRoute != 0) &&
153 (eeHandle == (mDefaultFelicaRoute | NFA_HANDLE_GROUP_EE))) {
154 if (mEeInfo.ee_disc_info[i].lf_protocol != 0)
155 seTechMask |= NFA_TECHNOLOGY_MASK_F;
156 }
157
158 DLOG_IF(INFO, nfc_debug_enabled)
159 << StringPrintf("%s: seTechMask[%u]=0x%02x", fn, i, seTechMask);
160 if (seTechMask != 0x00) {
161 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
162 "Configuring tech mask 0x%02x on EE 0x%04x", seTechMask, eeHandle);
163
164 nfaStat = NFA_CeConfigureUiccListenTech(eeHandle, seTechMask);
165 if (nfaStat != NFA_STATUS_OK)
166 LOG(ERROR) << StringPrintf(
167 "Failed to configure UICC listen technologies.");
168
169 // Set technology routes to UICC if it's there
170 nfaStat =
171 NFA_EeSetDefaultTechRouting(eeHandle, seTechMask, seTechMask, 0,
172 seTechMask, seTechMask, seTechMask);
173
174 if (nfaStat != NFA_STATUS_OK)
175 LOG(ERROR) << StringPrintf(
176 "Failed to configure UICC technology routing.");
177
178 mSeTechMask |= seTechMask;
179 }
180 }
181 }
182
183 // Tell the host-routing to only listen on Nfc-A
184 nfaStat = NFA_CeSetIsoDepListenTech(NFA_TECHNOLOGY_MASK_A);
185 if (nfaStat != NFA_STATUS_OK)
186 LOG(ERROR) << StringPrintf("Failed to configure CE IsoDep technologies");
187
188 // Register a wild-card for AIDs routed to the host
189 nfaStat = NFA_CeRegisterAidOnDH(NULL, 0, stackCallback);
190 if (nfaStat != NFA_STATUS_OK)
191 LOG(ERROR) << StringPrintf("Failed to register wildcard AID for DH");
192
193 if (NFC_GetNCIVersion() == NCI_VERSION_2_0) {
194 SyncEventGuard guard(mRoutingEvent);
195 // Register System Code for routing
196 nfaStat = NFA_EeAddSystemCodeRouting(mDefaultSysCode, mDefaultSysCodeRoute,
197 mDefaultSysCodePowerstate);
198 if (nfaStat == NFA_STATUS_NOT_SUPPORTED) {
199 mIsScbrSupported = false;
200 LOG(ERROR) << StringPrintf("%s: SCBR not supported", fn);
201 } else if (nfaStat == NFA_STATUS_OK) {
202 mIsScbrSupported = true;
203 mRoutingEvent.wait();
204 DLOG_IF(INFO, nfc_debug_enabled)
205 << StringPrintf("%s: Succeed to register system code", fn);
206 } else {
207 LOG(ERROR) << StringPrintf("%s: Fail to register system code", fn);
208 }
209 }
210 return true;
211 }
212
getInstance()213 RoutingManager& RoutingManager::getInstance() {
214 static RoutingManager manager;
215 return manager;
216 }
217
enableRoutingToHost()218 void RoutingManager::enableRoutingToHost() {
219 tNFA_STATUS nfaStat;
220 tNFA_TECHNOLOGY_MASK techMask;
221 tNFA_PROTOCOL_MASK protoMask;
222 SyncEventGuard guard(mRoutingEvent);
223
224 // Set default routing at one time when the NFCEE IDs for Nfc-A and Nfc-F are
225 // same
226 if (mDefaultEe == mDefaultFelicaRoute) {
227 // Route Nfc-A/Nfc-F to host if we don't have a SE
228 techMask = (mSeTechMask ^ (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F));
229 if (techMask != 0) {
230 nfaStat = NFA_EeSetDefaultTechRouting(mDefaultEe, techMask, 0, 0,
231 techMask, techMask, techMask);
232 if (nfaStat == NFA_STATUS_OK)
233 mRoutingEvent.wait();
234 else
235 LOG(ERROR) << StringPrintf(
236 "Fail to set default tech routing for Nfc-A/Nfc-F");
237 }
238 // Default routing for IsoDep and T3T protocol
239 if (mIsScbrSupported)
240 protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
241 else
242 protoMask = (NFA_PROTOCOL_MASK_ISO_DEP | NFA_PROTOCOL_MASK_T3T);
243
244 nfaStat = NFA_EeSetDefaultProtoRouting(
245 mDefaultEe, protoMask, 0, 0, protoMask, mDefaultEe ? protoMask : 0,
246 mDefaultEe ? protoMask : 0);
247 if (nfaStat == NFA_STATUS_OK)
248 mRoutingEvent.wait();
249 else
250 LOG(ERROR) << StringPrintf(
251 "Fail to set default proto routing for protocol: 0x%x", protoMask);
252 } else {
253 // Route Nfc-A to host if we don't have a SE
254 techMask = NFA_TECHNOLOGY_MASK_A;
255 if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
256 nfaStat = NFA_EeSetDefaultTechRouting(mDefaultEe, techMask, 0, 0,
257 techMask, techMask, techMask);
258 if (nfaStat == NFA_STATUS_OK)
259 mRoutingEvent.wait();
260 else
261 LOG(ERROR) << StringPrintf(
262 "Fail to set default tech routing for Nfc-A");
263 }
264 // Default routing for IsoDep protocol
265 protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
266 nfaStat = NFA_EeSetDefaultProtoRouting(
267 mDefaultEe, protoMask, 0, 0, protoMask, mDefaultEe ? protoMask : 0,
268 mDefaultEe ? protoMask : 0);
269 if (nfaStat == NFA_STATUS_OK)
270 mRoutingEvent.wait();
271 else
272 LOG(ERROR) << StringPrintf(
273 "Fail to set default proto routing for IsoDep");
274
275 // Route Nfc-F to host if we don't have a SE
276 techMask = NFA_TECHNOLOGY_MASK_F;
277 if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
278 nfaStat = NFA_EeSetDefaultTechRouting(mDefaultFelicaRoute, techMask, 0, 0,
279 techMask, techMask, techMask);
280 if (nfaStat == NFA_STATUS_OK)
281 mRoutingEvent.wait();
282 else
283 LOG(ERROR) << StringPrintf(
284 "Fail to set default tech routing for Nfc-F");
285 }
286 // Default routing for T3T protocol
287 if (!mIsScbrSupported) {
288 protoMask = NFA_PROTOCOL_MASK_T3T;
289 nfaStat =
290 NFA_EeSetDefaultProtoRouting(NFC_DH_ID, protoMask, 0, 0, 0, 0, 0);
291 if (nfaStat == NFA_STATUS_OK)
292 mRoutingEvent.wait();
293 else
294 LOG(ERROR) << StringPrintf("Fail to set default proto routing for T3T");
295 }
296 }
297 }
298
disableRoutingToHost()299 void RoutingManager::disableRoutingToHost() {
300 tNFA_STATUS nfaStat;
301 tNFA_TECHNOLOGY_MASK techMask;
302 SyncEventGuard guard(mRoutingEvent);
303
304 // Set default routing at one time when the NFCEE IDs for Nfc-A and Nfc-F are
305 // same
306 if (mDefaultEe == mDefaultFelicaRoute) {
307 // Default routing for Nfc-A/Nfc-F technology if we don't have a SE
308 techMask = (mSeTechMask ^ (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F));
309 if (techMask != 0) {
310 nfaStat = NFA_EeSetDefaultTechRouting(mDefaultEe, 0, 0, 0, 0, 0, 0);
311 if (nfaStat == NFA_STATUS_OK)
312 mRoutingEvent.wait();
313 else
314 LOG(ERROR) << StringPrintf(
315 "Fail to set default tech routing for Nfc-A/Nfc-F");
316 }
317 // Default routing for IsoDep
318 nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0, 0, 0, 0);
319 if (nfaStat == NFA_STATUS_OK)
320 mRoutingEvent.wait();
321 else
322 LOG(ERROR) << StringPrintf(
323 "Fail to set default proto routing for IsoDep");
324 } else {
325 // Default routing for Nfc-A technology if we don't have a SE
326 if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
327 nfaStat = NFA_EeSetDefaultTechRouting(mDefaultEe, 0, 0, 0, 0, 0, 0);
328 if (nfaStat == NFA_STATUS_OK)
329 mRoutingEvent.wait();
330 else
331 LOG(ERROR) << StringPrintf(
332 "Fail to set default tech routing for Nfc-A");
333 }
334 // Default routing for IsoDep protocol
335 nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0, 0, 0, 0);
336 if (nfaStat == NFA_STATUS_OK)
337 mRoutingEvent.wait();
338 else
339 LOG(ERROR) << StringPrintf(
340 "Fail to set default proto routing for IsoDep");
341
342 // Default routing for Nfc-F technology if we don't have a SE
343 if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
344 nfaStat =
345 NFA_EeSetDefaultTechRouting(mDefaultFelicaRoute, 0, 0, 0, 0, 0, 0);
346 if (nfaStat == NFA_STATUS_OK)
347 mRoutingEvent.wait();
348 else
349 LOG(ERROR) << StringPrintf(
350 "Fail to set default tech routing for Nfc-F");
351 }
352 // Default routing for T3T protocol
353 if (!mIsScbrSupported) {
354 nfaStat = NFA_EeSetDefaultProtoRouting(NFC_DH_ID, 0, 0, 0, 0, 0, 0);
355 if (nfaStat == NFA_STATUS_OK)
356 mRoutingEvent.wait();
357 else
358 LOG(ERROR) << StringPrintf("Fail to set default proto routing for T3T");
359 }
360 }
361 }
362
addAidRouting(const uint8_t * aid,uint8_t aidLen,int route,int aidInfo)363 bool RoutingManager::addAidRouting(const uint8_t* aid, uint8_t aidLen,
364 int route, int aidInfo) {
365 static const char fn[] = "RoutingManager::addAidRouting";
366 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
367 uint8_t powerState =
368 (route == mDefaultOffHostRoute) ? mOffHostAidRoutingPowerState : 0x01;
369 tNFA_STATUS nfaStat =
370 NFA_EeAddAidRouting(route, aidLen, (uint8_t*)aid, powerState, aidInfo);
371 if (nfaStat == NFA_STATUS_OK) {
372 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: routed AID", fn);
373 return true;
374 } else {
375 LOG(ERROR) << StringPrintf("%s: failed to route AID", fn);
376 return false;
377 }
378 }
379
removeAidRouting(const uint8_t * aid,uint8_t aidLen)380 bool RoutingManager::removeAidRouting(const uint8_t* aid, uint8_t aidLen) {
381 static const char fn[] = "RoutingManager::removeAidRouting";
382 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: enter", fn);
383 tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (uint8_t*)aid);
384 if (nfaStat == NFA_STATUS_OK) {
385 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: removed AID", fn);
386 return true;
387 } else {
388 LOG(ERROR) << StringPrintf("%s: failed to remove AID", fn);
389 return false;
390 }
391 }
392
commitRouting()393 bool RoutingManager::commitRouting() {
394 static const char fn[] = "RoutingManager::commitRouting";
395 tNFA_STATUS nfaStat = 0;
396 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
397 {
398 SyncEventGuard guard(mEeUpdateEvent);
399 nfaStat = NFA_EeUpdateNow();
400 if (nfaStat == NFA_STATUS_OK) {
401 mEeUpdateEvent.wait(); // wait for NFA_EE_UPDATED_EVT
402 }
403 }
404 return (nfaStat == NFA_STATUS_OK);
405 }
406
onNfccShutdown()407 void RoutingManager::onNfccShutdown() {
408 static const char fn[] = "RoutingManager:onNfccShutdown";
409 if (mDefaultOffHostRoute == 0x00) return;
410
411 tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
412 uint8_t actualNumEe = MAX_NUM_EE;
413 tNFA_EE_INFO eeInfo[MAX_NUM_EE];
414
415 memset(&eeInfo, 0, sizeof(eeInfo));
416 if ((nfaStat = NFA_EeGetInfo(&actualNumEe, eeInfo)) != NFA_STATUS_OK) {
417 LOG(ERROR) << StringPrintf("%s: fail get info; error=0x%X", fn, nfaStat);
418 return;
419 }
420 if (actualNumEe != 0) {
421 for (uint8_t xx = 0; xx < actualNumEe; xx++) {
422 if ((eeInfo[xx].num_interface != 0) &&
423 (eeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
424 (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE)) {
425 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
426 "%s: Handle: 0x%04x Change Status Active to Inactive", fn,
427 eeInfo[xx].ee_handle);
428 SyncEventGuard guard(mEeSetModeEvent);
429 if ((nfaStat = NFA_EeModeSet(eeInfo[xx].ee_handle,
430 NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK) {
431 mEeSetModeEvent.wait(); // wait for NFA_EE_MODE_SET_EVT
432 } else {
433 LOG(ERROR) << StringPrintf("Failed to set EE inactive");
434 }
435 }
436 }
437 } else {
438 DLOG_IF(INFO, nfc_debug_enabled)
439 << StringPrintf("%s: No active EEs found", fn);
440 }
441 }
442
notifyActivated(uint8_t technology)443 void RoutingManager::notifyActivated(uint8_t technology) {
444 JNIEnv* e = NULL;
445 ScopedAttach attach(mNativeData->vm, &e);
446 if (e == NULL) {
447 LOG(ERROR) << StringPrintf("jni env is null");
448 return;
449 }
450
451 e->CallVoidMethod(mNativeData->manager,
452 android::gCachedNfcManagerNotifyHostEmuActivated,
453 (int)technology);
454 if (e->ExceptionCheck()) {
455 e->ExceptionClear();
456 LOG(ERROR) << StringPrintf("fail notify");
457 }
458 }
459
notifyDeactivated(uint8_t technology)460 void RoutingManager::notifyDeactivated(uint8_t technology) {
461 mRxDataBuffer.clear();
462 JNIEnv* e = NULL;
463 ScopedAttach attach(mNativeData->vm, &e);
464 if (e == NULL) {
465 LOG(ERROR) << StringPrintf("jni env is null");
466 return;
467 }
468
469 e->CallVoidMethod(mNativeData->manager,
470 android::gCachedNfcManagerNotifyHostEmuDeactivated,
471 (int)technology);
472 if (e->ExceptionCheck()) {
473 e->ExceptionClear();
474 LOG(ERROR) << StringPrintf("fail notify");
475 }
476 }
477
handleData(uint8_t technology,const uint8_t * data,uint32_t dataLen,tNFA_STATUS status)478 void RoutingManager::handleData(uint8_t technology, const uint8_t* data,
479 uint32_t dataLen, tNFA_STATUS status) {
480 if (status == NFC_STATUS_CONTINUE) {
481 if (dataLen > 0) {
482 mRxDataBuffer.insert(mRxDataBuffer.end(), &data[0],
483 &data[dataLen]); // append data; more to come
484 }
485 return; // expect another NFA_CE_DATA_EVT to come
486 } else if (status == NFA_STATUS_OK) {
487 if (dataLen > 0) {
488 mRxDataBuffer.insert(mRxDataBuffer.end(), &data[0],
489 &data[dataLen]); // append data
490 }
491 // entire data packet has been received; no more NFA_CE_DATA_EVT
492 } else if (status == NFA_STATUS_FAILED) {
493 LOG(ERROR) << StringPrintf("RoutingManager::handleData: read data fail");
494 goto TheEnd;
495 }
496
497 {
498 JNIEnv* e = NULL;
499 ScopedAttach attach(mNativeData->vm, &e);
500 if (e == NULL) {
501 LOG(ERROR) << StringPrintf("jni env is null");
502 goto TheEnd;
503 }
504
505 ScopedLocalRef<jobject> dataJavaArray(
506 e, e->NewByteArray(mRxDataBuffer.size()));
507 if (dataJavaArray.get() == NULL) {
508 LOG(ERROR) << StringPrintf("fail allocate array");
509 goto TheEnd;
510 }
511
512 e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0,
513 mRxDataBuffer.size(), (jbyte*)(&mRxDataBuffer[0]));
514 if (e->ExceptionCheck()) {
515 e->ExceptionClear();
516 LOG(ERROR) << StringPrintf("fail fill array");
517 goto TheEnd;
518 }
519
520 e->CallVoidMethod(mNativeData->manager,
521 android::gCachedNfcManagerNotifyHostEmuData,
522 (int)technology, dataJavaArray.get());
523 if (e->ExceptionCheck()) {
524 e->ExceptionClear();
525 LOG(ERROR) << StringPrintf("fail notify");
526 }
527 }
528 TheEnd:
529 mRxDataBuffer.clear();
530 }
531
stackCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)532 void RoutingManager::stackCallback(uint8_t event,
533 tNFA_CONN_EVT_DATA* eventData) {
534 static const char fn[] = "RoutingManager::stackCallback";
535 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: event=0x%X", fn, event);
536 RoutingManager& routingManager = RoutingManager::getInstance();
537
538 switch (event) {
539 case NFA_CE_REGISTERED_EVT: {
540 tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
541 DLOG_IF(INFO, nfc_debug_enabled)
542 << StringPrintf("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn,
543 ce_registered.status, ce_registered.handle);
544 } break;
545
546 case NFA_CE_DEREGISTERED_EVT: {
547 tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
548 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
549 "%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
550 } break;
551
552 case NFA_CE_ACTIVATED_EVT: {
553 routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_A);
554 } break;
555
556 case NFA_DEACTIVATED_EVT:
557 case NFA_CE_DEACTIVATED_EVT: {
558 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
559 "%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn);
560 routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_A);
561 SyncEventGuard g(gDeactivatedEvent);
562 gActivated = false; // guard this variable from multi-threaded access
563 gDeactivatedEvent.notifyOne();
564 } break;
565
566 case NFA_CE_DATA_EVT: {
567 tNFA_CE_DATA& ce_data = eventData->ce_data;
568 DLOG_IF(INFO, nfc_debug_enabled)
569 << StringPrintf("%s: NFA_CE_DATA_EVT; stat=0x%X; h=0x%X; data len=%u",
570 fn, ce_data.status, ce_data.handle, ce_data.len);
571 getInstance().handleData(NFA_TECHNOLOGY_MASK_A, ce_data.p_data,
572 ce_data.len, ce_data.status);
573 } break;
574 }
575 }
576 /*******************************************************************************
577 **
578 ** Function: nfaEeCallback
579 **
580 ** Description: Receive execution environment-related events from stack.
581 ** event: Event code.
582 ** eventData: Event data.
583 **
584 ** Returns: None
585 **
586 *******************************************************************************/
nfaEeCallback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * eventData)587 void RoutingManager::nfaEeCallback(tNFA_EE_EVT event,
588 tNFA_EE_CBACK_DATA* eventData) {
589 static const char fn[] = "RoutingManager::nfaEeCallback";
590
591 RoutingManager& routingManager = RoutingManager::getInstance();
592 if (eventData) routingManager.mCbEventData = *eventData;
593
594 switch (event) {
595 case NFA_EE_REGISTER_EVT: {
596 SyncEventGuard guard(routingManager.mEeRegisterEvent);
597 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
598 "%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
599 routingManager.mEeRegisterEvent.notifyOne();
600 } break;
601
602 case NFA_EE_MODE_SET_EVT: {
603 SyncEventGuard guard(routingManager.mEeSetModeEvent);
604 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
605 "%s: NFA_EE_MODE_SET_EVT; status: 0x%04X handle: 0x%04X ", fn,
606 eventData->mode_set.status, eventData->mode_set.ee_handle);
607 routingManager.mEeSetModeEvent.notifyOne();
608 } break;
609
610 case NFA_EE_SET_TECH_CFG_EVT: {
611 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
612 "%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
613 SyncEventGuard guard(routingManager.mRoutingEvent);
614 routingManager.mRoutingEvent.notifyOne();
615 } break;
616
617 case NFA_EE_SET_PROTO_CFG_EVT: {
618 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
619 "%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
620 SyncEventGuard guard(routingManager.mRoutingEvent);
621 routingManager.mRoutingEvent.notifyOne();
622 } break;
623
624 case NFA_EE_ACTION_EVT: {
625 tNFA_EE_ACTION& action = eventData->action;
626 if (action.trigger == NFC_EE_TRIG_SELECT)
627 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
628 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn,
629 action.ee_handle, action.trigger);
630 else if (action.trigger == NFC_EE_TRIG_APP_INIT) {
631 tNFC_APP_INIT& app_init = action.param.app_init;
632 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
633 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init "
634 "(0x%X); aid len=%u; data len=%u",
635 fn, action.ee_handle, action.trigger, app_init.len_aid,
636 app_init.len_data);
637 } else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
638 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
639 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn,
640 action.ee_handle, action.trigger);
641 else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
642 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
643 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn,
644 action.ee_handle, action.trigger);
645 else
646 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
647 "%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn,
648 action.ee_handle, action.trigger);
649 } break;
650
651 case NFA_EE_DISCOVER_REQ_EVT: {
652 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
653 "%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __func__,
654 eventData->discover_req.status, eventData->discover_req.num_ee);
655 SyncEventGuard guard(routingManager.mEeInfoEvent);
656 memcpy(&routingManager.mEeInfo, &eventData->discover_req,
657 sizeof(routingManager.mEeInfo));
658 routingManager.mReceivedEeInfo = true;
659 routingManager.mEeInfoEvent.notifyOne();
660 } break;
661
662 case NFA_EE_NO_CB_ERR_EVT:
663 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
664 "%s: NFA_EE_NO_CB_ERR_EVT status=%u", fn, eventData->status);
665 break;
666
667 case NFA_EE_ADD_AID_EVT: {
668 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
669 "%s: NFA_EE_ADD_AID_EVT status=%u", fn, eventData->status);
670 } break;
671
672 case NFA_EE_ADD_SYSCODE_EVT: {
673 SyncEventGuard guard(routingManager.mRoutingEvent);
674 routingManager.mRoutingEvent.notifyOne();
675 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
676 "%s: NFA_EE_ADD_SYSCODE_EVT status=%u", fn, eventData->status);
677 } break;
678
679 case NFA_EE_REMOVE_SYSCODE_EVT: {
680 SyncEventGuard guard(routingManager.mRoutingEvent);
681 routingManager.mRoutingEvent.notifyOne();
682 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
683 "%s: NFA_EE_REMOVE_SYSCODE_EVT status=%u", fn, eventData->status);
684 } break;
685
686 case NFA_EE_REMOVE_AID_EVT: {
687 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
688 "%s: NFA_EE_REMOVE_AID_EVT status=%u", fn, eventData->status);
689 } break;
690
691 case NFA_EE_NEW_EE_EVT: {
692 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
693 "%s: NFA_EE_NEW_EE_EVT h=0x%X; status=%u", fn,
694 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
695 } break;
696
697 case NFA_EE_UPDATED_EVT: {
698 DLOG_IF(INFO, nfc_debug_enabled)
699 << StringPrintf("%s: NFA_EE_UPDATED_EVT", fn);
700 SyncEventGuard guard(routingManager.mEeUpdateEvent);
701 routingManager.mEeUpdateEvent.notifyOne();
702 } break;
703
704 default:
705 DLOG_IF(INFO, nfc_debug_enabled)
706 << StringPrintf("%s: unknown event=%u ????", fn, event);
707 break;
708 }
709 }
710
registerT3tIdentifier(uint8_t * t3tId,uint8_t t3tIdLen)711 int RoutingManager::registerT3tIdentifier(uint8_t* t3tId, uint8_t t3tIdLen) {
712 static const char fn[] = "RoutingManager::registerT3tIdentifier";
713
714 DLOG_IF(INFO, nfc_debug_enabled)
715 << StringPrintf("%s: Start to register NFC-F system on DH", fn);
716
717 if (t3tIdLen != (2 + NCI_RF_F_UID_LEN + NCI_T3T_PMM_LEN)) {
718 LOG(ERROR) << StringPrintf("%s: Invalid length of T3T Identifier", fn);
719 return NFA_HANDLE_INVALID;
720 }
721
722 mNfcFOnDhHandle = NFA_HANDLE_INVALID;
723
724 uint16_t systemCode;
725 uint8_t nfcid2[NCI_RF_F_UID_LEN];
726 uint8_t t3tPmm[NCI_T3T_PMM_LEN];
727
728 systemCode = (((int)t3tId[0] << 8) | ((int)t3tId[1] << 0));
729 memcpy(nfcid2, t3tId + 2, NCI_RF_F_UID_LEN);
730 memcpy(t3tPmm, t3tId + 10, NCI_T3T_PMM_LEN);
731 {
732 SyncEventGuard guard(mRoutingEvent);
733 tNFA_STATUS nfaStat = NFA_CeRegisterFelicaSystemCodeOnDH(
734 systemCode, nfcid2, t3tPmm, nfcFCeCallback);
735 if (nfaStat == NFA_STATUS_OK) {
736 mRoutingEvent.wait();
737 } else {
738 LOG(ERROR) << StringPrintf("%s: Fail to register NFC-F system on DH", fn);
739 return NFA_HANDLE_INVALID;
740 }
741 }
742 DLOG_IF(INFO, nfc_debug_enabled)
743 << StringPrintf("%s: Succeed to register NFC-F system on DH", fn);
744
745 // Register System Code for routing
746 if (mIsScbrSupported) {
747 SyncEventGuard guard(mRoutingEvent);
748 tNFA_STATUS nfaStat = NFA_EeAddSystemCodeRouting(systemCode, NCI_DH_ID,
749 SYS_CODE_PWR_STATE_HOST);
750 if (nfaStat == NFA_STATUS_OK) {
751 mRoutingEvent.wait();
752 }
753 if ((nfaStat != NFA_STATUS_OK) || (mCbEventData.status != NFA_STATUS_OK)) {
754 LOG(ERROR) << StringPrintf("%s: Fail to register system code on DH", fn);
755 return NFA_HANDLE_INVALID;
756 }
757 DLOG_IF(INFO, nfc_debug_enabled)
758 << StringPrintf("%s: Succeed to register system code on DH", fn);
759 // add handle and system code pair to the map
760 mMapScbrHandle.emplace(mNfcFOnDhHandle, systemCode);
761 } else {
762 LOG(ERROR) << StringPrintf("%s: SCBR Not supported", fn);
763 }
764
765 return mNfcFOnDhHandle;
766 }
767
deregisterT3tIdentifier(int handle)768 void RoutingManager::deregisterT3tIdentifier(int handle) {
769 static const char fn[] = "RoutingManager::deregisterT3tIdentifier";
770
771 DLOG_IF(INFO, nfc_debug_enabled)
772 << StringPrintf("%s: Start to deregister NFC-F system on DH", fn);
773 {
774 SyncEventGuard guard(mRoutingEvent);
775 tNFA_STATUS nfaStat = NFA_CeDeregisterFelicaSystemCodeOnDH(handle);
776 if (nfaStat == NFA_STATUS_OK) {
777 mRoutingEvent.wait();
778 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
779 "%s: Succeeded in deregistering NFC-F system on DH", fn);
780 } else {
781 LOG(ERROR) << StringPrintf("%s: Fail to deregister NFC-F system on DH",
782 fn);
783 }
784 }
785 if (mIsScbrSupported) {
786 map<int, uint16_t>::iterator it = mMapScbrHandle.find(handle);
787 // find system code for given handle
788 if (it != mMapScbrHandle.end()) {
789 uint16_t systemCode = it->second;
790 mMapScbrHandle.erase(handle);
791 if (systemCode != 0) {
792 SyncEventGuard guard(mRoutingEvent);
793 tNFA_STATUS nfaStat = NFA_EeRemoveSystemCodeRouting(systemCode);
794 if (nfaStat == NFA_STATUS_OK) {
795 mRoutingEvent.wait();
796 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
797 "%s: Succeeded in deregistering system Code on DH", fn);
798 } else {
799 LOG(ERROR) << StringPrintf("%s: Fail to deregister system Code on DH",
800 fn);
801 }
802 }
803 }
804 }
805 }
806
nfcFCeCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)807 void RoutingManager::nfcFCeCallback(uint8_t event,
808 tNFA_CONN_EVT_DATA* eventData) {
809 static const char fn[] = "RoutingManager::nfcFCeCallback";
810 RoutingManager& routingManager = RoutingManager::getInstance();
811
812 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: 0x%x", __func__, event);
813
814 switch (event) {
815 case NFA_CE_REGISTERED_EVT: {
816 DLOG_IF(INFO, nfc_debug_enabled)
817 << StringPrintf("%s: registerd event notified", fn);
818 routingManager.mNfcFOnDhHandle = eventData->ce_registered.handle;
819 SyncEventGuard guard(routingManager.mRoutingEvent);
820 routingManager.mRoutingEvent.notifyOne();
821 } break;
822 case NFA_CE_DEREGISTERED_EVT: {
823 DLOG_IF(INFO, nfc_debug_enabled)
824 << StringPrintf("%s: deregisterd event notified", fn);
825 SyncEventGuard guard(routingManager.mRoutingEvent);
826 routingManager.mRoutingEvent.notifyOne();
827 } break;
828 case NFA_CE_ACTIVATED_EVT: {
829 DLOG_IF(INFO, nfc_debug_enabled)
830 << StringPrintf("%s: activated event notified", fn);
831 routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_F);
832 } break;
833 case NFA_CE_DEACTIVATED_EVT: {
834 DLOG_IF(INFO, nfc_debug_enabled)
835 << StringPrintf("%s: deactivated event notified", fn);
836 routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_F);
837 } break;
838 case NFA_CE_DATA_EVT: {
839 DLOG_IF(INFO, nfc_debug_enabled)
840 << StringPrintf("%s: data event notified", fn);
841 tNFA_CE_DATA& ce_data = eventData->ce_data;
842 routingManager.handleData(NFA_TECHNOLOGY_MASK_F, ce_data.p_data,
843 ce_data.len, ce_data.status);
844 } break;
845 default: {
846 DLOG_IF(INFO, nfc_debug_enabled)
847 << StringPrintf("%s: unknown event=%u ????", fn, event);
848 } break;
849 }
850 }
851
registerJniFunctions(JNIEnv * e)852 int RoutingManager::registerJniFunctions(JNIEnv* e) {
853 static const char fn[] = "RoutingManager::registerJniFunctions";
854 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
855 return jniRegisterNativeMethods(
856 e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods,
857 NELEM(sMethods));
858 }
859
com_android_nfc_cardemulation_doGetDefaultRouteDestination(JNIEnv *)860 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination(
861 JNIEnv*) {
862 return getInstance().mDefaultEe;
863 }
864
865 int RoutingManager::
com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv *)866 com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv*) {
867 return getInstance().mDefaultOffHostRoute;
868 }
869
com_android_nfc_cardemulation_doGetAidMatchingMode(JNIEnv *)870 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode(
871 JNIEnv*) {
872 return getInstance().mAidMatchingMode;
873 }
874