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