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