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 {"doGetOffHostUiccDestination", "()[B",
46 (void*)RoutingManager::
47 com_android_nfc_cardemulation_doGetOffHostUiccDestination},
48 {"doGetOffHostEseDestination", "()[B",
49 (void*)RoutingManager::
50 com_android_nfc_cardemulation_doGetOffHostEseDestination},
51 {"doGetAidMatchingMode", "()I",
52 (void*)RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode},
53 {"doGetDefaultIsoDepRouteDestination", "()I",
54 (void*)RoutingManager::
55 com_android_nfc_cardemulation_doGetDefaultIsoDepRouteDestination}};
56
57 static const int MAX_NUM_EE = 5;
58 // SCBR from host works only when App is in foreground
59 static const uint8_t SYS_CODE_PWR_STATE_HOST = 0x01;
60 static const uint16_t DEFAULT_SYS_CODE = 0xFEFE;
61
62 static const uint8_t AID_ROUTE_QUAL_PREFIX = 0x10;
63
RoutingManager()64 RoutingManager::RoutingManager()
65 : mSecureNfcEnabled(false),
66 mNativeData(NULL),
67 mAidRoutingConfigured(false) {
68 static const char fn[] = "RoutingManager::RoutingManager()";
69
70 mDefaultOffHostRoute =
71 NfcConfig::getUnsigned(NAME_DEFAULT_OFFHOST_ROUTE, 0x00);
72
73 if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_UICC)) {
74 mOffHostRouteUicc = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_UICC);
75 }
76
77 if (NfcConfig::hasKey(NAME_OFFHOST_ROUTE_ESE)) {
78 mOffHostRouteEse = NfcConfig::getBytes(NAME_OFFHOST_ROUTE_ESE);
79 }
80
81 mDefaultFelicaRoute = NfcConfig::getUnsigned(NAME_DEFAULT_NFCF_ROUTE, 0x00);
82 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
83 "%s: Active SE for Nfc-F is 0x%02X", fn, mDefaultFelicaRoute);
84
85 mDefaultEe = NfcConfig::getUnsigned(NAME_DEFAULT_ROUTE, 0x00);
86 DLOG_IF(INFO, nfc_debug_enabled)
87 << StringPrintf("%s: default route is 0x%02X", fn, mDefaultEe);
88
89 mAidMatchingMode =
90 NfcConfig::getUnsigned(NAME_AID_MATCHING_MODE, AID_MATCHING_EXACT_ONLY);
91
92 mDefaultSysCodeRoute =
93 NfcConfig::getUnsigned(NAME_DEFAULT_SYS_CODE_ROUTE, 0xC0);
94
95 mDefaultSysCodePowerstate =
96 NfcConfig::getUnsigned(NAME_DEFAULT_SYS_CODE_PWR_STATE, 0x19);
97
98 mDefaultSysCode = DEFAULT_SYS_CODE;
99 if (NfcConfig::hasKey(NAME_DEFAULT_SYS_CODE)) {
100 std::vector<uint8_t> pSysCode = NfcConfig::getBytes(NAME_DEFAULT_SYS_CODE);
101 if (pSysCode.size() == 0x02) {
102 mDefaultSysCode = ((pSysCode[0] << 8) | ((int)pSysCode[1] << 0));
103 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
104 "%s: DEFAULT_SYS_CODE: 0x%02X", __func__, mDefaultSysCode);
105 }
106 }
107
108 mOffHostAidRoutingPowerState =
109 NfcConfig::getUnsigned(NAME_OFFHOST_AID_ROUTE_PWR_STATE, 0x01);
110
111 mDefaultIsoDepRoute = NfcConfig::getUnsigned(NAME_DEFAULT_ISODEP_ROUTE, 0x0);
112
113 mHostListenTechMask =
114 NfcConfig::getUnsigned(NAME_HOST_LISTEN_TECH_MASK,
115 NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F);
116
117 memset(&mEeInfo, 0, sizeof(mEeInfo));
118 mReceivedEeInfo = false;
119 mSeTechMask = 0x00;
120 mIsScbrSupported = false;
121
122 mNfcFOnDhHandle = NFA_HANDLE_INVALID;
123
124 mDeinitializing = false;
125 mEeInfoChanged = false;
126 }
127
~RoutingManager()128 RoutingManager::~RoutingManager() {}
129
initialize(nfc_jni_native_data * native)130 bool RoutingManager::initialize(nfc_jni_native_data* native) {
131 static const char fn[] = "RoutingManager::initialize()";
132 mNativeData = native;
133 mRxDataBuffer.clear();
134
135 {
136 SyncEventGuard guard(mEeRegisterEvent);
137 DLOG_IF(INFO, nfc_debug_enabled) << fn << ": try ee register";
138 tNFA_STATUS nfaStat = NFA_EeRegister(nfaEeCallback);
139 if (nfaStat != NFA_STATUS_OK) {
140 LOG(ERROR) << StringPrintf("%s: fail ee register; error=0x%X", fn,
141 nfaStat);
142 return false;
143 }
144 mEeRegisterEvent.wait();
145 }
146
147 if ((mDefaultOffHostRoute != 0) || (mDefaultFelicaRoute != 0)) {
148 // Wait for EE info if needed
149 SyncEventGuard guard(mEeInfoEvent);
150 if (!mReceivedEeInfo) {
151 LOG(INFO) << fn << "Waiting for EE info";
152 mEeInfoEvent.wait();
153 }
154 }
155 mSeTechMask = updateEeTechRouteSetting();
156
157 // Set the host-routing Tech
158 tNFA_STATUS nfaStat = NFA_CeSetIsoDepListenTech(
159 mHostListenTechMask & (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B));
160
161 if (nfaStat != NFA_STATUS_OK)
162 LOG(ERROR) << StringPrintf("Failed to configure CE IsoDep technologies");
163
164 // Register a wild-card for AIDs routed to the host
165 nfaStat = NFA_CeRegisterAidOnDH(NULL, 0, stackCallback);
166 if (nfaStat != NFA_STATUS_OK)
167 LOG(ERROR) << fn << "Failed to register wildcard AID for DH";
168
169 updateDefaultRoute();
170 updateDefaultProtocolRoute();
171
172 return true;
173 }
174
getInstance()175 RoutingManager& RoutingManager::getInstance() {
176 static RoutingManager manager;
177 return manager;
178 }
179
enableRoutingToHost()180 void RoutingManager::enableRoutingToHost() {
181 static const char fn[] = "RoutingManager::enableRoutingToHost()";
182 tNFA_STATUS nfaStat;
183 SyncEventGuard guard(mRoutingEvent);
184
185 // Default routing for T3T protocol
186 if (!mIsScbrSupported && mDefaultEe == NFC_DH_ID) {
187 nfaStat = NFA_EeSetDefaultProtoRouting(NFC_DH_ID, NFA_PROTOCOL_MASK_T3T, 0,
188 0, 0, 0, 0);
189 if (nfaStat == NFA_STATUS_OK)
190 mRoutingEvent.wait();
191 else
192 LOG(ERROR) << fn << "Fail to set default proto routing for T3T";
193 }
194
195 // Default routing for IsoDep protocol
196 tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
197 if (mDefaultIsoDepRoute == NFC_DH_ID) {
198 nfaStat = NFA_EeSetDefaultProtoRouting(
199 NFC_DH_ID, protoMask, 0, 0, mSecureNfcEnabled ? 0 : protoMask, 0, 0);
200 if (nfaStat == NFA_STATUS_OK)
201 mRoutingEvent.wait();
202 else
203 LOG(ERROR) << fn << "Fail to set default proto routing for IsoDep";
204 }
205
206 // Route Nfc-A to host if we don't have a SE
207 tNFA_TECHNOLOGY_MASK techMask = NFA_TECHNOLOGY_MASK_A;
208 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
209 (mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
210 nfaStat = NFA_EeSetDefaultTechRouting(
211 NFC_DH_ID, techMask, 0, 0, mSecureNfcEnabled ? 0 : techMask,
212 mSecureNfcEnabled ? 0 : techMask, mSecureNfcEnabled ? 0 : techMask);
213 if (nfaStat == NFA_STATUS_OK)
214 mRoutingEvent.wait();
215 else
216 LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-A";
217 }
218
219 // Route Nfc-B to host if we don't have a SE
220 techMask = NFA_TECHNOLOGY_MASK_B;
221 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
222 (mSeTechMask & NFA_TECHNOLOGY_MASK_B) == 0) {
223 nfaStat = NFA_EeSetDefaultTechRouting(
224 NFC_DH_ID, techMask, 0, 0, mSecureNfcEnabled ? 0 : techMask,
225 mSecureNfcEnabled ? 0 : techMask, mSecureNfcEnabled ? 0 : techMask);
226 if (nfaStat == NFA_STATUS_OK)
227 mRoutingEvent.wait();
228 else
229 LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-B";
230 }
231
232 // Route Nfc-F to host if we don't have a SE
233 techMask = NFA_TECHNOLOGY_MASK_F;
234 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
235 (mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
236 nfaStat = NFA_EeSetDefaultTechRouting(
237 NFC_DH_ID, techMask, 0, 0, mSecureNfcEnabled ? 0 : techMask,
238 mSecureNfcEnabled ? 0 : techMask, mSecureNfcEnabled ? 0 : techMask);
239 if (nfaStat == NFA_STATUS_OK)
240 mRoutingEvent.wait();
241 else
242 LOG(ERROR) << fn << "Fail to set default tech routing for Nfc-F";
243 }
244 }
245
disableRoutingToHost()246 void RoutingManager::disableRoutingToHost() {
247 static const char fn[] = "RoutingManager::disableRoutingToHost()";
248 tNFA_STATUS nfaStat;
249 SyncEventGuard guard(mRoutingEvent);
250
251 // Clear default routing for IsoDep protocol
252 if (mDefaultIsoDepRoute == NFC_DH_ID) {
253 nfaStat =
254 NFA_EeClearDefaultProtoRouting(NFC_DH_ID, NFA_PROTOCOL_MASK_ISO_DEP);
255 if (nfaStat == NFA_STATUS_OK)
256 mRoutingEvent.wait();
257 else
258 LOG(ERROR) << fn << "Fail to clear default proto routing for IsoDep";
259 }
260
261 // Clear default routing for Nfc-A technology if we don't have a SE
262 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
263 (mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0) {
264 nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_A);
265 if (nfaStat == NFA_STATUS_OK)
266 mRoutingEvent.wait();
267 else
268 LOG(ERROR) << fn << "Fail to clear default tech routing for Nfc-A";
269 }
270
271 // Clear default routing for Nfc-B technology if we don't have a SE
272 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
273 (mSeTechMask & NFA_TECHNOLOGY_MASK_B) == 0) {
274 nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_B);
275 if (nfaStat == NFA_STATUS_OK)
276 mRoutingEvent.wait();
277 else
278 LOG(ERROR) << fn << "Fail to clear default tech routing for Nfc-B";
279 }
280
281 // Clear default routing for Nfc-F technology if we don't have a SE
282 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
283 (mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0) {
284 nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_F);
285 if (nfaStat == NFA_STATUS_OK)
286 mRoutingEvent.wait();
287 else
288 LOG(ERROR) << fn << "Fail to clear default tech routing for Nfc-F";
289 }
290
291 // Clear default routing for T3T protocol
292 if (!mIsScbrSupported && mDefaultEe == NFC_DH_ID) {
293 nfaStat = NFA_EeClearDefaultProtoRouting(NFC_DH_ID, NFA_PROTOCOL_MASK_T3T);
294 if (nfaStat == NFA_STATUS_OK)
295 mRoutingEvent.wait();
296 else
297 LOG(ERROR) << fn << "Fail to clear default proto routing for T3T";
298 }
299 }
300
301 /*******************************************************************************
302 **
303 ** Function: isTypeATypeBTechSupportedInEe
304 **
305 ** Description: receive eeHandle
306 **
307 ** Returns: true : if EE support protocol type A/B
308 ** false : if EE doesn't protocol type A/B
309 **
310 *******************************************************************************/
isTypeATypeBTechSupportedInEe(tNFA_HANDLE eeHandle)311 bool RoutingManager::isTypeATypeBTechSupportedInEe(tNFA_HANDLE eeHandle) {
312 static const char fn[] = "RoutingManager::isTypeATypeBTechSupportedInEe";
313 bool status = false;
314 uint8_t mActualNumEe = MAX_NUM_EE;
315 tNFA_EE_INFO eeInfo[mActualNumEe];
316 memset(&eeInfo, 0, mActualNumEe * sizeof(tNFA_EE_INFO));
317 tNFA_STATUS nfaStat = NFA_EeGetInfo(&mActualNumEe, eeInfo);
318 DLOG_IF(INFO, nfc_debug_enabled) << fn;
319 if (nfaStat != NFA_STATUS_OK) {
320 return status;
321 }
322 for (auto i = 0; i < mActualNumEe; i++) {
323 if (eeHandle == eeInfo[i].ee_handle) {
324 if (eeInfo[i].la_protocol || eeInfo[i].lb_protocol) {
325 status = true;
326 break;
327 }
328 }
329 }
330 return status;
331 }
332
addAidRouting(const uint8_t * aid,uint8_t aidLen,int route,int aidInfo,int power)333 bool RoutingManager::addAidRouting(const uint8_t* aid, uint8_t aidLen,
334 int route, int aidInfo, int power) {
335 static const char fn[] = "RoutingManager::addAidRouting";
336 DLOG_IF(INFO, nfc_debug_enabled) << fn << ": enter";
337 uint8_t powerState = 0x01;
338 if (!mSecureNfcEnabled) {
339 if (power == 0x00) {
340 powerState = (route != 0x00) ? mOffHostAidRoutingPowerState : 0x11;
341 } else {
342 powerState =
343 (route != 0x00) ? mOffHostAidRoutingPowerState & power : power;
344 }
345 }
346 SyncEventGuard guard(mRoutingEvent);
347 mAidRoutingConfigured = false;
348 tNFA_STATUS nfaStat =
349 NFA_EeAddAidRouting(route, aidLen, (uint8_t*)aid, powerState, aidInfo);
350 if (nfaStat == NFA_STATUS_OK) {
351 mRoutingEvent.wait();
352 }
353 if (mAidRoutingConfigured) {
354 DLOG_IF(INFO, nfc_debug_enabled) << fn << ": routed AID";
355 return true;
356 } else {
357 LOG(ERROR) << fn << ": failed to route AID";
358 return false;
359 }
360 }
361
removeAidRouting(const uint8_t * aid,uint8_t aidLen)362 bool RoutingManager::removeAidRouting(const uint8_t* aid, uint8_t aidLen) {
363 static const char fn[] = "RoutingManager::removeAidRouting";
364 DLOG_IF(INFO, nfc_debug_enabled) << fn << ": enter";
365 SyncEventGuard guard(mRoutingEvent);
366 mAidRoutingConfigured = false;
367 tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (uint8_t*)aid);
368 if (nfaStat == NFA_STATUS_OK) {
369 mRoutingEvent.wait();
370 }
371 if (mAidRoutingConfigured) {
372 DLOG_IF(INFO, nfc_debug_enabled) << fn << ": removed AID";
373 return true;
374 } else {
375 LOG(WARNING) << fn << ": failed to remove AID";
376 return false;
377 }
378 }
379
commitRouting()380 bool RoutingManager::commitRouting() {
381 static const char fn[] = "RoutingManager::commitRouting";
382 tNFA_STATUS nfaStat = 0;
383 DLOG_IF(INFO, nfc_debug_enabled) << fn;
384 if(mEeInfoChanged) {
385 mSeTechMask = updateEeTechRouteSetting();
386 mEeInfoChanged = false;
387 }
388 {
389 SyncEventGuard guard(mEeUpdateEvent);
390 nfaStat = NFA_EeUpdateNow();
391 if (nfaStat == NFA_STATUS_OK) {
392 mEeUpdateEvent.wait(); // wait for NFA_EE_UPDATED_EVT
393 }
394 }
395 return (nfaStat == NFA_STATUS_OK);
396 }
397
onNfccShutdown()398 void RoutingManager::onNfccShutdown() {
399 static const char fn[] = "RoutingManager:onNfccShutdown";
400 if (mDefaultOffHostRoute == 0x00 && mDefaultFelicaRoute == 0x00) return;
401
402 tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
403 uint8_t actualNumEe = MAX_NUM_EE;
404 tNFA_EE_INFO eeInfo[MAX_NUM_EE];
405 mDeinitializing = true;
406
407 memset(&eeInfo, 0, sizeof(eeInfo));
408 if ((nfaStat = NFA_EeGetInfo(&actualNumEe, eeInfo)) != NFA_STATUS_OK) {
409 LOG(ERROR) << StringPrintf("%s: fail get info; error=0x%X", fn, nfaStat);
410 return;
411 }
412 if (actualNumEe != 0) {
413 for (uint8_t xx = 0; xx < actualNumEe; xx++) {
414 bool bIsOffHostEEPresent =
415 (NFC_GetNCIVersion() < NCI_VERSION_2_0)
416 ? (eeInfo[xx].num_interface != 0)
417 : (eeInfo[xx].ee_interface[0] !=
418 NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
419 (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE);
420 if (bIsOffHostEEPresent) {
421 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
422 "%s: Handle: 0x%04x Change Status Active to Inactive", fn,
423 eeInfo[xx].ee_handle);
424 SyncEventGuard guard(mEeSetModeEvent);
425 if ((nfaStat = NFA_EeModeSet(eeInfo[xx].ee_handle,
426 NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK) {
427 mEeSetModeEvent.wait(); // wait for NFA_EE_MODE_SET_EVT
428 } else {
429 LOG(ERROR) << fn << "Failed to set EE inactive";
430 }
431 }
432 }
433 } else {
434 DLOG_IF(INFO, nfc_debug_enabled) << fn << ": No active EEs found";
435 }
436 }
437
notifyActivated(uint8_t technology)438 void RoutingManager::notifyActivated(uint8_t technology) {
439 JNIEnv* e = NULL;
440 ScopedAttach attach(mNativeData->vm, &e);
441 if (e == NULL) {
442 LOG(ERROR) << "jni env is null";
443 return;
444 }
445
446 e->CallVoidMethod(mNativeData->manager,
447 android::gCachedNfcManagerNotifyHostEmuActivated,
448 (int)technology);
449 if (e->ExceptionCheck()) {
450 e->ExceptionClear();
451 LOG(ERROR) << "fail notify";
452 }
453 }
454
notifyDeactivated(uint8_t technology)455 void RoutingManager::notifyDeactivated(uint8_t technology) {
456 mRxDataBuffer.clear();
457 JNIEnv* e = NULL;
458 ScopedAttach attach(mNativeData->vm, &e);
459 if (e == NULL) {
460 LOG(ERROR) << "jni env is null";
461 return;
462 }
463
464 e->CallVoidMethod(mNativeData->manager,
465 android::gCachedNfcManagerNotifyHostEmuDeactivated,
466 (int)technology);
467 if (e->ExceptionCheck()) {
468 e->ExceptionClear();
469 LOG(ERROR) << StringPrintf("fail notify");
470 }
471 }
472
handleData(uint8_t technology,const uint8_t * data,uint32_t dataLen,tNFA_STATUS status)473 void RoutingManager::handleData(uint8_t technology, const uint8_t* data,
474 uint32_t dataLen, tNFA_STATUS status) {
475 if (status == NFC_STATUS_CONTINUE) {
476 if (dataLen > 0) {
477 mRxDataBuffer.insert(mRxDataBuffer.end(), &data[0],
478 &data[dataLen]); // append data; more to come
479 }
480 return; // expect another NFA_CE_DATA_EVT to come
481 } else if (status == NFA_STATUS_OK) {
482 if (dataLen > 0) {
483 mRxDataBuffer.insert(mRxDataBuffer.end(), &data[0],
484 &data[dataLen]); // append data
485 }
486 // entire data packet has been received; no more NFA_CE_DATA_EVT
487 } else if (status == NFA_STATUS_FAILED) {
488 LOG(ERROR) << "RoutingManager::handleData: read data fail";
489 goto TheEnd;
490 }
491
492 {
493 JNIEnv* e = NULL;
494 ScopedAttach attach(mNativeData->vm, &e);
495 if (e == NULL) {
496 LOG(ERROR) << "jni env is null";
497 goto TheEnd;
498 }
499
500 ScopedLocalRef<jobject> dataJavaArray(
501 e, e->NewByteArray(mRxDataBuffer.size()));
502 if (dataJavaArray.get() == NULL) {
503 LOG(ERROR) << "fail allocate array";
504 goto TheEnd;
505 }
506
507 e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0,
508 mRxDataBuffer.size(), (jbyte*)(&mRxDataBuffer[0]));
509 if (e->ExceptionCheck()) {
510 e->ExceptionClear();
511 LOG(ERROR) << "fail fill array";
512 goto TheEnd;
513 }
514
515 e->CallVoidMethod(mNativeData->manager,
516 android::gCachedNfcManagerNotifyHostEmuData,
517 (int)technology, dataJavaArray.get());
518 if (e->ExceptionCheck()) {
519 e->ExceptionClear();
520 LOG(ERROR) << "fail notify";
521 }
522 }
523 TheEnd:
524 mRxDataBuffer.clear();
525 }
526
notifyEeUpdated()527 void RoutingManager::notifyEeUpdated() {
528 JNIEnv* e = NULL;
529 ScopedAttach attach(mNativeData->vm, &e);
530 if (e == NULL) {
531 LOG(ERROR) << "jni env is null";
532 return;
533 }
534
535 e->CallVoidMethod(mNativeData->manager,
536 android::gCachedNfcManagerNotifyEeUpdated);
537 if (e->ExceptionCheck()) {
538 e->ExceptionClear();
539 LOG(ERROR) << "fail notify";
540 }
541 }
542
stackCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)543 void RoutingManager::stackCallback(uint8_t event,
544 tNFA_CONN_EVT_DATA* eventData) {
545 static const char fn[] = "RoutingManager::stackCallback";
546 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: event=0x%X", fn, event);
547 RoutingManager& routingManager = RoutingManager::getInstance();
548
549 switch (event) {
550 case NFA_CE_REGISTERED_EVT: {
551 tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
552 DLOG_IF(INFO, nfc_debug_enabled)
553 << StringPrintf("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn,
554 ce_registered.status, ce_registered.handle);
555 } break;
556
557 case NFA_CE_DEREGISTERED_EVT: {
558 tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
559 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
560 "%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
561 } break;
562
563 case NFA_CE_ACTIVATED_EVT: {
564 routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_A);
565 } break;
566
567 case NFA_DEACTIVATED_EVT:
568 case NFA_CE_DEACTIVATED_EVT: {
569 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
570 "%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn);
571 routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_A);
572 SyncEventGuard g(gDeactivatedEvent);
573 gActivated = false; // guard this variable from multi-threaded access
574 gDeactivatedEvent.notifyOne();
575 } break;
576
577 case NFA_CE_DATA_EVT: {
578 tNFA_CE_DATA& ce_data = eventData->ce_data;
579 DLOG_IF(INFO, nfc_debug_enabled)
580 << StringPrintf("%s: NFA_CE_DATA_EVT; stat=0x%X; h=0x%X; data len=%u",
581 fn, ce_data.status, ce_data.handle, ce_data.len);
582 getInstance().handleData(NFA_TECHNOLOGY_MASK_A, ce_data.p_data,
583 ce_data.len, ce_data.status);
584 } break;
585 }
586 }
587
updateRoutingTable()588 void RoutingManager::updateRoutingTable() {
589 updateEeTechRouteSetting();
590 updateDefaultProtocolRoute();
591 updateDefaultRoute();
592 }
593
updateDefaultProtocolRoute()594 void RoutingManager::updateDefaultProtocolRoute() {
595 static const char fn[] = "RoutingManager::updateDefaultProtocolRoute";
596
597 // Default Routing for ISO-DEP
598 tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
599 tNFA_STATUS nfaStat;
600 if (mDefaultIsoDepRoute != NFC_DH_ID &&
601 isTypeATypeBTechSupportedInEe(mDefaultIsoDepRoute |
602 NFA_HANDLE_GROUP_EE)) {
603 nfaStat = NFA_EeClearDefaultProtoRouting(mDefaultIsoDepRoute, protoMask);
604 nfaStat = NFA_EeSetDefaultProtoRouting(
605 mDefaultIsoDepRoute, protoMask, mSecureNfcEnabled ? 0 : protoMask, 0,
606 mSecureNfcEnabled ? 0 : protoMask, mSecureNfcEnabled ? 0 : protoMask,
607 mSecureNfcEnabled ? 0 : protoMask);
608 } else {
609 nfaStat = NFA_EeClearDefaultProtoRouting(NFC_DH_ID, protoMask);
610 nfaStat = NFA_EeSetDefaultProtoRouting(
611 NFC_DH_ID, protoMask, 0, 0, mSecureNfcEnabled ? 0 : protoMask, 0, 0);
612 }
613 if (nfaStat == NFA_STATUS_OK)
614 DLOG_IF(INFO, nfc_debug_enabled)
615 << fn << ": Succeed to register default ISO-DEP route";
616 else
617 LOG(ERROR) << fn << ": failed to register default ISO-DEP route";
618
619 // Default routing for T3T protocol
620 if (!mIsScbrSupported) {
621 SyncEventGuard guard(mRoutingEvent);
622 tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_T3T;
623 if (mDefaultEe == NFC_DH_ID) {
624 nfaStat =
625 NFA_EeSetDefaultProtoRouting(NFC_DH_ID, protoMask, 0, 0, 0, 0, 0);
626 } else {
627 nfaStat = NFA_EeClearDefaultProtoRouting(mDefaultEe, protoMask);
628 nfaStat = NFA_EeSetDefaultProtoRouting(
629 mDefaultEe, protoMask, 0, 0, mSecureNfcEnabled ? 0 : protoMask,
630 mSecureNfcEnabled ? 0 : protoMask, mSecureNfcEnabled ? 0 : protoMask);
631 }
632 if (nfaStat == NFA_STATUS_OK)
633 mRoutingEvent.wait();
634 else
635 LOG(ERROR) << fn << "Fail to set default proto routing for T3T";
636 }
637 }
638
updateDefaultRoute()639 void RoutingManager::updateDefaultRoute() {
640 static const char fn[] = "RoutingManager::updateDefaultRoute";
641 if (NFC_GetNCIVersion() != NCI_VERSION_2_0) return;
642
643 // Register System Code for routing
644 SyncEventGuard guard(mRoutingEvent);
645 tNFA_STATUS nfaStat = NFA_EeAddSystemCodeRouting(
646 mDefaultSysCode, mDefaultSysCodeRoute,
647 mSecureNfcEnabled ? 0x01 : mDefaultSysCodePowerstate);
648 if (nfaStat == NFA_STATUS_NOT_SUPPORTED) {
649 mIsScbrSupported = false;
650 LOG(ERROR) << fn << ": SCBR not supported";
651 } else if (nfaStat == NFA_STATUS_OK) {
652 mIsScbrSupported = true;
653 mRoutingEvent.wait();
654 DLOG_IF(INFO, nfc_debug_enabled)
655 << fn << ": Succeed to register system code";
656 } else {
657 LOG(ERROR) << fn << ": Fail to register system code";
658 // still support SCBR routing for other NFCEEs
659 mIsScbrSupported = true;
660 }
661
662 // Register zero lengthy Aid for default Aid Routing
663 if (mDefaultEe != mDefaultIsoDepRoute) {
664 if ((mDefaultEe != NFC_DH_ID) &&
665 (!isTypeATypeBTechSupportedInEe(mDefaultEe | NFA_HANDLE_GROUP_EE))) {
666 DLOG_IF(INFO, nfc_debug_enabled)
667 << fn << ": mDefaultEE Doesn't support either Tech A/B. Returning...";
668 return;
669 }
670 uint8_t powerState = 0x01;
671 if (!mSecureNfcEnabled)
672 powerState = (mDefaultEe != 0x00) ? mOffHostAidRoutingPowerState : 0x11;
673 nfaStat = NFA_EeAddAidRouting(mDefaultEe, 0, NULL, powerState,
674 AID_ROUTE_QUAL_PREFIX);
675 if (nfaStat == NFA_STATUS_OK)
676 DLOG_IF(INFO, nfc_debug_enabled)
677 << fn << ": Succeed to register zero length AID";
678 else
679 LOG(ERROR) << fn << ": failed to register zero length AID";
680 }
681 }
682
updateEeTechRouteSetting()683 tNFA_TECHNOLOGY_MASK RoutingManager::updateEeTechRouteSetting() {
684 static const char fn[] = "RoutingManager::updateEeTechRouteSetting";
685 tNFA_TECHNOLOGY_MASK allSeTechMask = 0x00;
686
687 if (mDefaultOffHostRoute == 0 && mDefaultFelicaRoute == 0)
688 return allSeTechMask;
689
690 DLOG_IF(INFO, nfc_debug_enabled)
691 << fn << ": Number of EE is " << (int)mEeInfo.num_ee;
692
693 tNFA_STATUS nfaStat;
694 for (uint8_t i = 0; i < mEeInfo.num_ee; i++) {
695 tNFA_HANDLE eeHandle = mEeInfo.ee_disc_info[i].ee_handle;
696 tNFA_TECHNOLOGY_MASK seTechMask = 0;
697
698 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
699 "%s EE[%u] Handle: 0x%04x techA: 0x%02x techB: "
700 "0x%02x techF: 0x%02x techBprime: 0x%02x",
701 fn, i, eeHandle, mEeInfo.ee_disc_info[i].la_protocol,
702 mEeInfo.ee_disc_info[i].lb_protocol,
703 mEeInfo.ee_disc_info[i].lf_protocol,
704 mEeInfo.ee_disc_info[i].lbp_protocol);
705
706 if ((mDefaultOffHostRoute != 0) &&
707 (eeHandle == (mDefaultOffHostRoute | NFA_HANDLE_GROUP_EE))) {
708 if (mEeInfo.ee_disc_info[i].la_protocol != 0)
709 seTechMask |= NFA_TECHNOLOGY_MASK_A;
710 if (mEeInfo.ee_disc_info[i].lb_protocol != 0)
711 seTechMask |= NFA_TECHNOLOGY_MASK_B;
712 }
713 if ((mDefaultFelicaRoute != 0) &&
714 (eeHandle == (mDefaultFelicaRoute | NFA_HANDLE_GROUP_EE))) {
715 if (mEeInfo.ee_disc_info[i].lf_protocol != 0)
716 seTechMask |= NFA_TECHNOLOGY_MASK_F;
717 }
718
719 DLOG_IF(INFO, nfc_debug_enabled)
720 << StringPrintf("%s: seTechMask[%u]=0x%02x", fn, i, seTechMask);
721 if (seTechMask != 0x00) {
722 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
723 "Configuring tech mask 0x%02x on EE 0x%04x", seTechMask, eeHandle);
724
725 nfaStat = NFA_CeConfigureUiccListenTech(eeHandle, seTechMask);
726 if (nfaStat != NFA_STATUS_OK)
727 LOG(ERROR) << fn << "Failed to configure UICC listen technologies.";
728
729 // clear previous before setting new power state
730 nfaStat = NFA_EeClearDefaultTechRouting(eeHandle, seTechMask);
731 if (nfaStat != NFA_STATUS_OK)
732 LOG(ERROR) << fn << "Failed to clear EE technology routing.";
733
734 nfaStat = NFA_EeSetDefaultTechRouting(
735 eeHandle, seTechMask, mSecureNfcEnabled ? 0 : seTechMask, 0,
736 mSecureNfcEnabled ? 0 : seTechMask,
737 mSecureNfcEnabled ? 0 : seTechMask,
738 mSecureNfcEnabled ? 0 : seTechMask);
739 if (nfaStat != NFA_STATUS_OK)
740 LOG(ERROR) << fn << "Failed to configure UICC technology routing.";
741
742 allSeTechMask |= seTechMask;
743 }
744 }
745
746 // Clear DH technology route on NFC-A
747 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
748 (allSeTechMask & NFA_TECHNOLOGY_MASK_A) != 0) {
749 nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_A);
750 if (nfaStat != NFA_STATUS_OK)
751 LOG(ERROR) << "Failed to clear DH technology routing on NFC-A.";
752 }
753
754 // Clear DH technology route on NFC-B
755 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
756 (allSeTechMask & NFA_TECHNOLOGY_MASK_B) != 0) {
757 nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_B);
758 if (nfaStat != NFA_STATUS_OK)
759 LOG(ERROR) << "Failed to clear DH technology routing on NFC-B.";
760 }
761
762 // Clear DH technology route on NFC-F
763 if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
764 (allSeTechMask & NFA_TECHNOLOGY_MASK_F) != 0) {
765 nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_F);
766 if (nfaStat != NFA_STATUS_OK)
767 LOG(ERROR) << "Failed to clear DH technology routing on NFC-F.";
768 }
769 return allSeTechMask;
770 }
771
772 /*******************************************************************************
773 **
774 ** Function: nfaEeCallback
775 **
776 ** Description: Receive execution environment-related events from stack.
777 ** event: Event code.
778 ** eventData: Event data.
779 **
780 ** Returns: None
781 **
782 *******************************************************************************/
nfaEeCallback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * eventData)783 void RoutingManager::nfaEeCallback(tNFA_EE_EVT event,
784 tNFA_EE_CBACK_DATA* eventData) {
785 static const char fn[] = "RoutingManager::nfaEeCallback";
786
787 RoutingManager& routingManager = RoutingManager::getInstance();
788 if (!eventData) {
789 LOG(ERROR) << "eventData is null";
790 return;
791 }
792 routingManager.mCbEventData = *eventData;
793 switch (event) {
794 case NFA_EE_REGISTER_EVT: {
795 SyncEventGuard guard(routingManager.mEeRegisterEvent);
796 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
797 "%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
798 routingManager.mEeRegisterEvent.notifyOne();
799 } break;
800
801 case NFA_EE_DEREGISTER_EVT: {
802 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
803 "%s: NFA_EE_DEREGISTER_EVT; status=0x%X", fn, eventData->status);
804 routingManager.mReceivedEeInfo = false;
805 routingManager.mDeinitializing = false;
806 } break;
807
808 case NFA_EE_MODE_SET_EVT: {
809 SyncEventGuard guard(routingManager.mEeSetModeEvent);
810 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
811 "%s: NFA_EE_MODE_SET_EVT; status: 0x%04X handle: 0x%04X ", fn,
812 eventData->mode_set.status, eventData->mode_set.ee_handle);
813 routingManager.mEeSetModeEvent.notifyOne();
814 } break;
815
816 case NFA_EE_SET_TECH_CFG_EVT: {
817 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
818 "%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
819 SyncEventGuard guard(routingManager.mRoutingEvent);
820 routingManager.mRoutingEvent.notifyOne();
821 } break;
822
823 case NFA_EE_CLEAR_TECH_CFG_EVT: {
824 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
825 "%s: NFA_EE_CLEAR_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
826 SyncEventGuard guard(routingManager.mRoutingEvent);
827 routingManager.mRoutingEvent.notifyOne();
828 } break;
829
830 case NFA_EE_SET_PROTO_CFG_EVT: {
831 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
832 "%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
833 SyncEventGuard guard(routingManager.mRoutingEvent);
834 routingManager.mRoutingEvent.notifyOne();
835 } break;
836
837 case NFA_EE_CLEAR_PROTO_CFG_EVT: {
838 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
839 "%s: NFA_EE_CLEAR_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
840 SyncEventGuard guard(routingManager.mRoutingEvent);
841 routingManager.mRoutingEvent.notifyOne();
842 } break;
843
844 case NFA_EE_ACTION_EVT: {
845 tNFA_EE_ACTION& action = eventData->action;
846 if (action.trigger == NFC_EE_TRIG_SELECT)
847 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
848 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn,
849 action.ee_handle, action.trigger);
850 else if (action.trigger == NFC_EE_TRIG_APP_INIT) {
851 tNFC_APP_INIT& app_init = action.param.app_init;
852 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
853 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init "
854 "(0x%X); aid len=%u; data len=%u",
855 fn, action.ee_handle, action.trigger, app_init.len_aid,
856 app_init.len_data);
857 } else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
858 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
859 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn,
860 action.ee_handle, action.trigger);
861 else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
862 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
863 "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn,
864 action.ee_handle, action.trigger);
865 else
866 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
867 "%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn,
868 action.ee_handle, action.trigger);
869 } break;
870
871 case NFA_EE_DISCOVER_REQ_EVT: {
872 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
873 "%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __func__,
874 eventData->discover_req.status, eventData->discover_req.num_ee);
875 SyncEventGuard guard(routingManager.mEeInfoEvent);
876 memcpy(&routingManager.mEeInfo, &eventData->discover_req,
877 sizeof(routingManager.mEeInfo));
878 if (routingManager.mReceivedEeInfo && !routingManager.mDeinitializing) {
879 routingManager.mEeInfoChanged = true;
880 routingManager.notifyEeUpdated();
881 }
882 routingManager.mReceivedEeInfo = true;
883 routingManager.mEeInfoEvent.notifyOne();
884 } break;
885
886 case NFA_EE_NO_CB_ERR_EVT:
887 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
888 "%s: NFA_EE_NO_CB_ERR_EVT status=%u", fn, eventData->status);
889 break;
890
891 case NFA_EE_ADD_AID_EVT: {
892 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
893 "%s: NFA_EE_ADD_AID_EVT status=%u", fn, eventData->status);
894 SyncEventGuard guard(routingManager.mRoutingEvent);
895 routingManager.mAidRoutingConfigured =
896 (eventData->status == NFA_STATUS_OK);
897 routingManager.mRoutingEvent.notifyOne();
898 } break;
899
900 case NFA_EE_ADD_SYSCODE_EVT: {
901 SyncEventGuard guard(routingManager.mRoutingEvent);
902 routingManager.mRoutingEvent.notifyOne();
903 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
904 "%s: NFA_EE_ADD_SYSCODE_EVT status=%u", fn, eventData->status);
905 } break;
906
907 case NFA_EE_REMOVE_SYSCODE_EVT: {
908 SyncEventGuard guard(routingManager.mRoutingEvent);
909 routingManager.mRoutingEvent.notifyOne();
910 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
911 "%s: NFA_EE_REMOVE_SYSCODE_EVT status=%u", fn, eventData->status);
912 } break;
913
914 case NFA_EE_REMOVE_AID_EVT: {
915 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
916 "%s: NFA_EE_REMOVE_AID_EVT status=%u", fn, eventData->status);
917 SyncEventGuard guard(routingManager.mRoutingEvent);
918 routingManager.mAidRoutingConfigured =
919 (eventData->status == NFA_STATUS_OK);
920 routingManager.mRoutingEvent.notifyOne();
921 } break;
922
923 case NFA_EE_NEW_EE_EVT: {
924 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
925 "%s: NFA_EE_NEW_EE_EVT h=0x%X; status=%u", fn,
926 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
927 } break;
928
929 case NFA_EE_UPDATED_EVT: {
930 DLOG_IF(INFO, nfc_debug_enabled)
931 << StringPrintf("%s: NFA_EE_UPDATED_EVT", fn);
932 SyncEventGuard guard(routingManager.mEeUpdateEvent);
933 routingManager.mEeUpdateEvent.notifyOne();
934 } break;
935
936 case NFA_EE_PWR_AND_LINK_CTRL_EVT: {
937 DLOG_IF(INFO, nfc_debug_enabled)
938 << StringPrintf("%s: NFA_EE_PWR_AND_LINK_CTRL_EVT", fn);
939 SyncEventGuard guard(routingManager.mEePwrAndLinkCtrlEvent);
940 routingManager.mEePwrAndLinkCtrlEvent.notifyOne();
941 } break;
942
943 default:
944 DLOG_IF(INFO, nfc_debug_enabled)
945 << StringPrintf("%s: unknown event=%u ????", fn, event);
946 break;
947 }
948 }
949
registerT3tIdentifier(uint8_t * t3tId,uint8_t t3tIdLen)950 int RoutingManager::registerT3tIdentifier(uint8_t* t3tId, uint8_t t3tIdLen) {
951 static const char fn[] = "RoutingManager::registerT3tIdentifier";
952
953 DLOG_IF(INFO, nfc_debug_enabled)
954 << fn << ": Start to register NFC-F system on DH";
955
956 if (t3tIdLen != (2 + NCI_RF_F_UID_LEN + NCI_T3T_PMM_LEN)) {
957 LOG(ERROR) << fn << ": Invalid length of T3T Identifier";
958 return NFA_HANDLE_INVALID;
959 }
960
961 mNfcFOnDhHandle = NFA_HANDLE_INVALID;
962
963 uint16_t systemCode;
964 uint8_t nfcid2[NCI_RF_F_UID_LEN];
965 uint8_t t3tPmm[NCI_T3T_PMM_LEN];
966
967 systemCode = (((int)t3tId[0] << 8) | ((int)t3tId[1] << 0));
968 memcpy(nfcid2, t3tId + 2, NCI_RF_F_UID_LEN);
969 memcpy(t3tPmm, t3tId + 10, NCI_T3T_PMM_LEN);
970 {
971 SyncEventGuard guard(mRoutingEvent);
972 tNFA_STATUS nfaStat = NFA_CeRegisterFelicaSystemCodeOnDH(
973 systemCode, nfcid2, t3tPmm, nfcFCeCallback);
974 if (nfaStat == NFA_STATUS_OK) {
975 mRoutingEvent.wait();
976 } else {
977 LOG(ERROR) << fn << ": Fail to register NFC-F system on DH";
978 return NFA_HANDLE_INVALID;
979 }
980 }
981 DLOG_IF(INFO, nfc_debug_enabled)
982 << fn << ": Succeed to register NFC-F system on DH";
983
984 // Register System Code for routing
985 if (mIsScbrSupported) {
986 SyncEventGuard guard(mRoutingEvent);
987 tNFA_STATUS nfaStat = NFA_EeAddSystemCodeRouting(systemCode, NCI_DH_ID,
988 SYS_CODE_PWR_STATE_HOST);
989 if (nfaStat == NFA_STATUS_OK) {
990 mRoutingEvent.wait();
991 }
992 if ((nfaStat != NFA_STATUS_OK) || (mCbEventData.status != NFA_STATUS_OK)) {
993 LOG(ERROR) << StringPrintf("%s: Fail to register system code on DH", fn);
994 return NFA_HANDLE_INVALID;
995 }
996 DLOG_IF(INFO, nfc_debug_enabled)
997 << StringPrintf("%s: Succeed to register system code on DH", fn);
998 // add handle and system code pair to the map
999 mMapScbrHandle.emplace(mNfcFOnDhHandle, systemCode);
1000 } else {
1001 LOG(ERROR) << StringPrintf("%s: SCBR Not supported", fn);
1002 }
1003
1004 return mNfcFOnDhHandle;
1005 }
1006
deregisterT3tIdentifier(int handle)1007 void RoutingManager::deregisterT3tIdentifier(int handle) {
1008 static const char fn[] = "RoutingManager::deregisterT3tIdentifier";
1009
1010 DLOG_IF(INFO, nfc_debug_enabled)
1011 << StringPrintf("%s: Start to deregister NFC-F system on DH", fn);
1012 {
1013 SyncEventGuard guard(mRoutingEvent);
1014 tNFA_STATUS nfaStat = NFA_CeDeregisterFelicaSystemCodeOnDH(handle);
1015 if (nfaStat == NFA_STATUS_OK) {
1016 mRoutingEvent.wait();
1017 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1018 "%s: Succeeded in deregistering NFC-F system on DH", fn);
1019 } else {
1020 LOG(ERROR) << StringPrintf("%s: Fail to deregister NFC-F system on DH",
1021 fn);
1022 }
1023 }
1024 if (mIsScbrSupported) {
1025 map<int, uint16_t>::iterator it = mMapScbrHandle.find(handle);
1026 // find system code for given handle
1027 if (it != mMapScbrHandle.end()) {
1028 uint16_t systemCode = it->second;
1029 mMapScbrHandle.erase(handle);
1030 if (systemCode != 0) {
1031 SyncEventGuard guard(mRoutingEvent);
1032 tNFA_STATUS nfaStat = NFA_EeRemoveSystemCodeRouting(systemCode);
1033 if (nfaStat == NFA_STATUS_OK) {
1034 mRoutingEvent.wait();
1035 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
1036 "%s: Succeeded in deregistering system Code on DH", fn);
1037 } else {
1038 LOG(ERROR) << StringPrintf("%s: Fail to deregister system Code on DH",
1039 fn);
1040 }
1041 }
1042 }
1043 }
1044 }
1045
nfcFCeCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)1046 void RoutingManager::nfcFCeCallback(uint8_t event,
1047 tNFA_CONN_EVT_DATA* eventData) {
1048 static const char fn[] = "RoutingManager::nfcFCeCallback";
1049 RoutingManager& routingManager = RoutingManager::getInstance();
1050
1051 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: 0x%x", __func__, event);
1052
1053 switch (event) {
1054 case NFA_CE_REGISTERED_EVT: {
1055 DLOG_IF(INFO, nfc_debug_enabled)
1056 << StringPrintf("%s: registerd event notified", fn);
1057 routingManager.mNfcFOnDhHandle = eventData->ce_registered.handle;
1058 SyncEventGuard guard(routingManager.mRoutingEvent);
1059 routingManager.mRoutingEvent.notifyOne();
1060 } break;
1061 case NFA_CE_DEREGISTERED_EVT: {
1062 DLOG_IF(INFO, nfc_debug_enabled)
1063 << StringPrintf("%s: deregisterd event notified", fn);
1064 SyncEventGuard guard(routingManager.mRoutingEvent);
1065 routingManager.mRoutingEvent.notifyOne();
1066 } break;
1067 case NFA_CE_ACTIVATED_EVT: {
1068 DLOG_IF(INFO, nfc_debug_enabled)
1069 << StringPrintf("%s: activated event notified", fn);
1070 routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_F);
1071 } break;
1072 case NFA_CE_DEACTIVATED_EVT: {
1073 DLOG_IF(INFO, nfc_debug_enabled)
1074 << StringPrintf("%s: deactivated event notified", fn);
1075 routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_F);
1076 } break;
1077 case NFA_CE_DATA_EVT: {
1078 DLOG_IF(INFO, nfc_debug_enabled)
1079 << StringPrintf("%s: data event notified", fn);
1080 tNFA_CE_DATA& ce_data = eventData->ce_data;
1081 routingManager.handleData(NFA_TECHNOLOGY_MASK_F, ce_data.p_data,
1082 ce_data.len, ce_data.status);
1083 } break;
1084 default: {
1085 DLOG_IF(INFO, nfc_debug_enabled)
1086 << StringPrintf("%s: unknown event=%u ????", fn, event);
1087 } break;
1088 }
1089 }
1090
setNfcSecure(bool enable)1091 bool RoutingManager::setNfcSecure(bool enable) {
1092 mSecureNfcEnabled = enable;
1093 DLOG_IF(INFO, true) << "setNfcSecure NfcService " << enable;
1094 return true;
1095 }
1096
1097 /*******************************************************************************
1098 **
1099 ** Function: eeSetPwrAndLinkCtrl
1100 **
1101 ** Description: Programs the NCI command NFCEE_POWER_AND_LINK_CTRL_CMD
1102 **
1103 ** Returns: None
1104 **
1105 *******************************************************************************/
eeSetPwrAndLinkCtrl(uint8_t config)1106 void RoutingManager::eeSetPwrAndLinkCtrl(uint8_t config) {
1107 static const char fn[] = "RoutingManager::eeSetPwrAndLinkCtrl";
1108 tNFA_STATUS status = NFA_STATUS_OK;
1109
1110 if (mOffHostRouteEse.size() > 0) {
1111 DLOG_IF(INFO, nfc_debug_enabled)
1112 << StringPrintf("%s - nfceeId: 0x%02X, config: 0x%02X", fn,
1113 mOffHostRouteEse[0], config);
1114
1115 SyncEventGuard guard(mEePwrAndLinkCtrlEvent);
1116 status =
1117 NFA_EePowerAndLinkCtrl(
1118 ((uint8_t)mOffHostRouteEse[0] | NFA_HANDLE_GROUP_EE), config);
1119 if (status != NFA_STATUS_OK) {
1120 LOG(ERROR) << StringPrintf("%s: fail NFA_EePowerAndLinkCtrl; error=0x%X",
1121 __FUNCTION__, status);
1122 return;
1123 } else {
1124 mEePwrAndLinkCtrlEvent.wait();
1125 }
1126 } else {
1127 LOG(ERROR) << StringPrintf("%s: No ESE specified", __FUNCTION__);
1128 }
1129 }
1130
deinitialize()1131 void RoutingManager::deinitialize() {
1132 onNfccShutdown();
1133 NFA_EeDeregister(nfaEeCallback);
1134 }
1135
registerJniFunctions(JNIEnv * e)1136 int RoutingManager::registerJniFunctions(JNIEnv* e) {
1137 static const char fn[] = "RoutingManager::registerJniFunctions";
1138 DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
1139 return jniRegisterNativeMethods(
1140 e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods,
1141 NELEM(sMethods));
1142 }
1143
com_android_nfc_cardemulation_doGetDefaultRouteDestination(JNIEnv *)1144 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination(
1145 JNIEnv*) {
1146 return getInstance().mDefaultEe;
1147 }
1148
1149 int RoutingManager::
com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv *)1150 com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv*) {
1151 return getInstance().mDefaultOffHostRoute;
1152 }
1153
1154 jbyteArray
com_android_nfc_cardemulation_doGetOffHostUiccDestination(JNIEnv * e)1155 RoutingManager::com_android_nfc_cardemulation_doGetOffHostUiccDestination(
1156 JNIEnv* e) {
1157 std::vector<uint8_t> uicc = getInstance().mOffHostRouteUicc;
1158 if (uicc.size() == 0) {
1159 return NULL;
1160 }
1161 CHECK(e);
1162 jbyteArray uiccJavaArray = e->NewByteArray(uicc.size());
1163 CHECK(uiccJavaArray);
1164 e->SetByteArrayRegion(uiccJavaArray, 0, uicc.size(), (jbyte*)&uicc[0]);
1165 return uiccJavaArray;
1166 }
1167
1168 jbyteArray
com_android_nfc_cardemulation_doGetOffHostEseDestination(JNIEnv * e)1169 RoutingManager::com_android_nfc_cardemulation_doGetOffHostEseDestination(
1170 JNIEnv* e) {
1171 std::vector<uint8_t> ese = getInstance().mOffHostRouteEse;
1172 if (ese.size() == 0) {
1173 return NULL;
1174 }
1175 CHECK(e);
1176 jbyteArray eseJavaArray = e->NewByteArray(ese.size());
1177 CHECK(eseJavaArray);
1178 e->SetByteArrayRegion(eseJavaArray, 0, ese.size(), (jbyte*)&ese[0]);
1179 return eseJavaArray;
1180 }
1181
com_android_nfc_cardemulation_doGetAidMatchingMode(JNIEnv *)1182 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode(
1183 JNIEnv*) {
1184 return getInstance().mAidMatchingMode;
1185 }
1186
1187 int RoutingManager::
com_android_nfc_cardemulation_doGetDefaultIsoDepRouteDestination(JNIEnv *)1188 com_android_nfc_cardemulation_doGetDefaultIsoDepRouteDestination(JNIEnv*) {
1189 return getInstance().mDefaultIsoDepRoute;
1190 }
1191