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 
addAidRouting(const uint8_t * aid,uint8_t aidLen,int route,int aidInfo)301 bool RoutingManager::addAidRouting(const uint8_t* aid, uint8_t aidLen,
302                                    int route, int aidInfo) {
303   static const char fn[] = "RoutingManager::addAidRouting";
304   DLOG_IF(INFO, nfc_debug_enabled) << fn << ": enter";
305   uint8_t powerState = 0x01;
306   if (!mSecureNfcEnabled) {
307     powerState = (route != 0x00) ? mOffHostAidRoutingPowerState : 0x11;
308   }
309   SyncEventGuard guard(mRoutingEvent);
310   mAidRoutingConfigured = false;
311   tNFA_STATUS nfaStat =
312       NFA_EeAddAidRouting(route, aidLen, (uint8_t*)aid, powerState, aidInfo);
313   if (nfaStat == NFA_STATUS_OK) {
314     mRoutingEvent.wait();
315   }
316   if (mAidRoutingConfigured) {
317     DLOG_IF(INFO, nfc_debug_enabled) << fn << ": routed AID";
318     return true;
319   } else {
320     LOG(ERROR) << fn << ": failed to route AID";
321     return false;
322   }
323 }
324 
removeAidRouting(const uint8_t * aid,uint8_t aidLen)325 bool RoutingManager::removeAidRouting(const uint8_t* aid, uint8_t aidLen) {
326   static const char fn[] = "RoutingManager::removeAidRouting";
327   DLOG_IF(INFO, nfc_debug_enabled) << fn << ": enter";
328   SyncEventGuard guard(mRoutingEvent);
329   mAidRoutingConfigured = false;
330   tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (uint8_t*)aid);
331   if (nfaStat == NFA_STATUS_OK) {
332     mRoutingEvent.wait();
333   }
334   if (mAidRoutingConfigured) {
335     DLOG_IF(INFO, nfc_debug_enabled) << fn << ": removed AID";
336     return true;
337   } else {
338     LOG(ERROR) << fn << ": failed to remove AID";
339     return false;
340   }
341 }
342 
commitRouting()343 bool RoutingManager::commitRouting() {
344   static const char fn[] = "RoutingManager::commitRouting";
345   tNFA_STATUS nfaStat = 0;
346   DLOG_IF(INFO, nfc_debug_enabled) << fn;
347   if(mEeInfoChanged) {
348     mSeTechMask = updateEeTechRouteSetting();
349     mEeInfoChanged = false;
350   }
351   {
352     SyncEventGuard guard(mEeUpdateEvent);
353     nfaStat = NFA_EeUpdateNow();
354     if (nfaStat == NFA_STATUS_OK) {
355       mEeUpdateEvent.wait();  // wait for NFA_EE_UPDATED_EVT
356     }
357   }
358   return (nfaStat == NFA_STATUS_OK);
359 }
360 
onNfccShutdown()361 void RoutingManager::onNfccShutdown() {
362   static const char fn[] = "RoutingManager:onNfccShutdown";
363   if (mDefaultOffHostRoute == 0x00 && mDefaultFelicaRoute == 0x00) return;
364 
365   tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
366   uint8_t actualNumEe = MAX_NUM_EE;
367   tNFA_EE_INFO eeInfo[MAX_NUM_EE];
368   mDeinitializing = true;
369 
370   memset(&eeInfo, 0, sizeof(eeInfo));
371   if ((nfaStat = NFA_EeGetInfo(&actualNumEe, eeInfo)) != NFA_STATUS_OK) {
372     LOG(ERROR) << StringPrintf("%s: fail get info; error=0x%X", fn, nfaStat);
373     return;
374   }
375   if (actualNumEe != 0) {
376     for (uint8_t xx = 0; xx < actualNumEe; xx++) {
377       bool bIsOffHostEEPresent =
378           (NFC_GetNCIVersion() < NCI_VERSION_2_0)
379               ? (eeInfo[xx].num_interface != 0)
380               : (eeInfo[xx].ee_interface[0] !=
381                  NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
382                     (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE);
383       if (bIsOffHostEEPresent) {
384         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
385             "%s: Handle: 0x%04x Change Status Active to Inactive", fn,
386             eeInfo[xx].ee_handle);
387         SyncEventGuard guard(mEeSetModeEvent);
388         if ((nfaStat = NFA_EeModeSet(eeInfo[xx].ee_handle,
389                                      NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK) {
390           mEeSetModeEvent.wait();  // wait for NFA_EE_MODE_SET_EVT
391         } else {
392           LOG(ERROR) << fn << "Failed to set EE inactive";
393         }
394       }
395     }
396   } else {
397     DLOG_IF(INFO, nfc_debug_enabled) << fn << ": No active EEs found";
398   }
399 }
400 
notifyActivated(uint8_t technology)401 void RoutingManager::notifyActivated(uint8_t technology) {
402   JNIEnv* e = NULL;
403   ScopedAttach attach(mNativeData->vm, &e);
404   if (e == NULL) {
405     LOG(ERROR) << "jni env is null";
406     return;
407   }
408 
409   e->CallVoidMethod(mNativeData->manager,
410                     android::gCachedNfcManagerNotifyHostEmuActivated,
411                     (int)technology);
412   if (e->ExceptionCheck()) {
413     e->ExceptionClear();
414     LOG(ERROR) << "fail notify";
415   }
416 }
417 
notifyDeactivated(uint8_t technology)418 void RoutingManager::notifyDeactivated(uint8_t technology) {
419   mRxDataBuffer.clear();
420   JNIEnv* e = NULL;
421   ScopedAttach attach(mNativeData->vm, &e);
422   if (e == NULL) {
423     LOG(ERROR) << "jni env is null";
424     return;
425   }
426 
427   e->CallVoidMethod(mNativeData->manager,
428                     android::gCachedNfcManagerNotifyHostEmuDeactivated,
429                     (int)technology);
430   if (e->ExceptionCheck()) {
431     e->ExceptionClear();
432     LOG(ERROR) << StringPrintf("fail notify");
433   }
434 }
435 
handleData(uint8_t technology,const uint8_t * data,uint32_t dataLen,tNFA_STATUS status)436 void RoutingManager::handleData(uint8_t technology, const uint8_t* data,
437                                 uint32_t dataLen, tNFA_STATUS status) {
438   if (status == NFC_STATUS_CONTINUE) {
439     if (dataLen > 0) {
440       mRxDataBuffer.insert(mRxDataBuffer.end(), &data[0],
441                            &data[dataLen]);  // append data; more to come
442     }
443     return;  // expect another NFA_CE_DATA_EVT to come
444   } else if (status == NFA_STATUS_OK) {
445     if (dataLen > 0) {
446       mRxDataBuffer.insert(mRxDataBuffer.end(), &data[0],
447                            &data[dataLen]);  // append data
448     }
449     // entire data packet has been received; no more NFA_CE_DATA_EVT
450   } else if (status == NFA_STATUS_FAILED) {
451     LOG(ERROR) << "RoutingManager::handleData: read data fail";
452     goto TheEnd;
453   }
454 
455   {
456     JNIEnv* e = NULL;
457     ScopedAttach attach(mNativeData->vm, &e);
458     if (e == NULL) {
459       LOG(ERROR) << "jni env is null";
460       goto TheEnd;
461     }
462 
463     ScopedLocalRef<jobject> dataJavaArray(
464         e, e->NewByteArray(mRxDataBuffer.size()));
465     if (dataJavaArray.get() == NULL) {
466       LOG(ERROR) << "fail allocate array";
467       goto TheEnd;
468     }
469 
470     e->SetByteArrayRegion((jbyteArray)dataJavaArray.get(), 0,
471                           mRxDataBuffer.size(), (jbyte*)(&mRxDataBuffer[0]));
472     if (e->ExceptionCheck()) {
473       e->ExceptionClear();
474       LOG(ERROR) << "fail fill array";
475       goto TheEnd;
476     }
477 
478     e->CallVoidMethod(mNativeData->manager,
479                       android::gCachedNfcManagerNotifyHostEmuData,
480                       (int)technology, dataJavaArray.get());
481     if (e->ExceptionCheck()) {
482       e->ExceptionClear();
483       LOG(ERROR) << "fail notify";
484     }
485   }
486 TheEnd:
487   mRxDataBuffer.clear();
488 }
489 
notifyEeUpdated()490 void RoutingManager::notifyEeUpdated() {
491   JNIEnv* e = NULL;
492   ScopedAttach attach(mNativeData->vm, &e);
493   if (e == NULL) {
494     LOG(ERROR) << "jni env is null";
495     return;
496   }
497 
498   e->CallVoidMethod(mNativeData->manager,
499                     android::gCachedNfcManagerNotifyEeUpdated);
500   if (e->ExceptionCheck()) {
501     e->ExceptionClear();
502     LOG(ERROR) << "fail notify";
503   }
504 }
505 
stackCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)506 void RoutingManager::stackCallback(uint8_t event,
507                                    tNFA_CONN_EVT_DATA* eventData) {
508   static const char fn[] = "RoutingManager::stackCallback";
509   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: event=0x%X", fn, event);
510   RoutingManager& routingManager = RoutingManager::getInstance();
511 
512   switch (event) {
513     case NFA_CE_REGISTERED_EVT: {
514       tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
515       DLOG_IF(INFO, nfc_debug_enabled)
516           << StringPrintf("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn,
517                           ce_registered.status, ce_registered.handle);
518     } break;
519 
520     case NFA_CE_DEREGISTERED_EVT: {
521       tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
522       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
523           "%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
524     } break;
525 
526     case NFA_CE_ACTIVATED_EVT: {
527       routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_A);
528     } break;
529 
530     case NFA_DEACTIVATED_EVT:
531     case NFA_CE_DEACTIVATED_EVT: {
532       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
533           "%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn);
534       routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_A);
535       SyncEventGuard g(gDeactivatedEvent);
536       gActivated = false;  // guard this variable from multi-threaded access
537       gDeactivatedEvent.notifyOne();
538     } break;
539 
540     case NFA_CE_DATA_EVT: {
541       tNFA_CE_DATA& ce_data = eventData->ce_data;
542       DLOG_IF(INFO, nfc_debug_enabled)
543           << StringPrintf("%s: NFA_CE_DATA_EVT; stat=0x%X; h=0x%X; data len=%u",
544                           fn, ce_data.status, ce_data.handle, ce_data.len);
545       getInstance().handleData(NFA_TECHNOLOGY_MASK_A, ce_data.p_data,
546                                ce_data.len, ce_data.status);
547     } break;
548   }
549 }
550 
updateRoutingTable()551 void RoutingManager::updateRoutingTable() {
552   updateEeTechRouteSetting();
553   updateDefaultProtocolRoute();
554   updateDefaultRoute();
555 }
556 
updateDefaultProtocolRoute()557 void RoutingManager::updateDefaultProtocolRoute() {
558   static const char fn[] = "RoutingManager::updateDefaultProtocolRoute";
559 
560   // Default Routing for ISO-DEP
561   tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
562   tNFA_STATUS nfaStat;
563   if (mDefaultIsoDepRoute != NFC_DH_ID) {
564     nfaStat = NFA_EeClearDefaultProtoRouting(mDefaultIsoDepRoute, protoMask);
565     nfaStat = NFA_EeSetDefaultProtoRouting(
566         mDefaultIsoDepRoute, protoMask, mSecureNfcEnabled ? 0 : protoMask, 0,
567         mSecureNfcEnabled ? 0 : protoMask, mSecureNfcEnabled ? 0 : protoMask,
568         mSecureNfcEnabled ? 0 : protoMask);
569   } else {
570     nfaStat = NFA_EeClearDefaultProtoRouting(NFC_DH_ID, protoMask);
571     nfaStat = NFA_EeSetDefaultProtoRouting(
572         NFC_DH_ID, protoMask, 0, 0, mSecureNfcEnabled ? 0 : protoMask, 0, 0);
573   }
574   if (nfaStat == NFA_STATUS_OK)
575     DLOG_IF(INFO, nfc_debug_enabled)
576         << fn << ": Succeed to register default ISO-DEP route";
577   else
578     LOG(ERROR) << fn << ": failed to register default ISO-DEP route";
579 
580   // Default routing for T3T protocol
581   if (!mIsScbrSupported) {
582     SyncEventGuard guard(mRoutingEvent);
583     tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_T3T;
584     if (mDefaultEe == NFC_DH_ID) {
585       nfaStat =
586           NFA_EeSetDefaultProtoRouting(NFC_DH_ID, protoMask, 0, 0, 0, 0, 0);
587     } else {
588       nfaStat = NFA_EeClearDefaultProtoRouting(mDefaultEe, protoMask);
589       nfaStat = NFA_EeSetDefaultProtoRouting(
590           mDefaultEe, protoMask, 0, 0, mSecureNfcEnabled ? 0 : protoMask,
591           mSecureNfcEnabled ? 0 : protoMask, mSecureNfcEnabled ? 0 : protoMask);
592     }
593     if (nfaStat == NFA_STATUS_OK)
594       mRoutingEvent.wait();
595     else
596       LOG(ERROR) << fn << "Fail to set default proto routing for T3T";
597   }
598 }
599 
updateDefaultRoute()600 void RoutingManager::updateDefaultRoute() {
601   static const char fn[] = "RoutingManager::updateDefaultRoute";
602   if (NFC_GetNCIVersion() != NCI_VERSION_2_0) return;
603 
604   // Register System Code for routing
605   SyncEventGuard guard(mRoutingEvent);
606   tNFA_STATUS nfaStat = NFA_EeAddSystemCodeRouting(
607       mDefaultSysCode, mDefaultSysCodeRoute,
608       mSecureNfcEnabled ? 0x01 : mDefaultSysCodePowerstate);
609   if (nfaStat == NFA_STATUS_NOT_SUPPORTED) {
610     mIsScbrSupported = false;
611     LOG(ERROR) << fn << ": SCBR not supported";
612   } else if (nfaStat == NFA_STATUS_OK) {
613     mIsScbrSupported = true;
614     mRoutingEvent.wait();
615     DLOG_IF(INFO, nfc_debug_enabled)
616         << fn << ": Succeed to register system code";
617   } else {
618     LOG(ERROR) << fn << ": Fail to register system code";
619   }
620 
621   // Register zero lengthy Aid for default Aid Routing
622   if (mDefaultEe != mDefaultIsoDepRoute) {
623     uint8_t powerState = 0x01;
624     if (!mSecureNfcEnabled)
625       powerState = (mDefaultEe != 0x00) ? mOffHostAidRoutingPowerState : 0x11;
626     nfaStat = NFA_EeAddAidRouting(mDefaultEe, 0, NULL, powerState,
627                                   AID_ROUTE_QUAL_PREFIX);
628     if (nfaStat == NFA_STATUS_OK)
629       DLOG_IF(INFO, nfc_debug_enabled)
630           << fn << ": Succeed to register zero length AID";
631     else
632       LOG(ERROR) << fn << ": failed to register zero length AID";
633   }
634 }
635 
updateEeTechRouteSetting()636 tNFA_TECHNOLOGY_MASK RoutingManager::updateEeTechRouteSetting() {
637   static const char fn[] = "RoutingManager::updateEeTechRouteSetting";
638   tNFA_TECHNOLOGY_MASK allSeTechMask = 0x00;
639 
640   if (mDefaultOffHostRoute == 0 && mDefaultFelicaRoute == 0)
641     return allSeTechMask;
642 
643   DLOG_IF(INFO, nfc_debug_enabled)
644       << fn << ": Number of EE is " << (int)mEeInfo.num_ee;
645 
646   tNFA_STATUS nfaStat;
647   for (uint8_t i = 0; i < mEeInfo.num_ee; i++) {
648     tNFA_HANDLE eeHandle = mEeInfo.ee_disc_info[i].ee_handle;
649     tNFA_TECHNOLOGY_MASK seTechMask = 0;
650 
651     DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
652         "%s   EE[%u] Handle: 0x%04x  techA: 0x%02x  techB: "
653         "0x%02x  techF: 0x%02x  techBprime: 0x%02x",
654         fn, i, eeHandle, mEeInfo.ee_disc_info[i].la_protocol,
655         mEeInfo.ee_disc_info[i].lb_protocol,
656         mEeInfo.ee_disc_info[i].lf_protocol,
657         mEeInfo.ee_disc_info[i].lbp_protocol);
658 
659     if ((mDefaultOffHostRoute != 0) &&
660         (eeHandle == (mDefaultOffHostRoute | NFA_HANDLE_GROUP_EE))) {
661       if (mEeInfo.ee_disc_info[i].la_protocol != 0)
662         seTechMask |= NFA_TECHNOLOGY_MASK_A;
663       if (mEeInfo.ee_disc_info[i].lb_protocol != 0)
664         seTechMask |= NFA_TECHNOLOGY_MASK_B;
665     }
666     if ((mDefaultFelicaRoute != 0) &&
667         (eeHandle == (mDefaultFelicaRoute | NFA_HANDLE_GROUP_EE))) {
668       if (mEeInfo.ee_disc_info[i].lf_protocol != 0)
669         seTechMask |= NFA_TECHNOLOGY_MASK_F;
670     }
671 
672     DLOG_IF(INFO, nfc_debug_enabled)
673         << StringPrintf("%s: seTechMask[%u]=0x%02x", fn, i, seTechMask);
674     if (seTechMask != 0x00) {
675       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
676           "Configuring tech mask 0x%02x on EE 0x%04x", seTechMask, eeHandle);
677 
678       nfaStat = NFA_CeConfigureUiccListenTech(eeHandle, seTechMask);
679       if (nfaStat != NFA_STATUS_OK)
680         LOG(ERROR) << fn << "Failed to configure UICC listen technologies.";
681 
682       // clear previous before setting new power state
683       nfaStat = NFA_EeClearDefaultTechRouting(eeHandle, seTechMask);
684       if (nfaStat != NFA_STATUS_OK)
685         LOG(ERROR) << fn << "Failed to clear EE technology routing.";
686 
687       nfaStat = NFA_EeSetDefaultTechRouting(
688           eeHandle, seTechMask, mSecureNfcEnabled ? 0 : seTechMask, 0,
689           mSecureNfcEnabled ? 0 : seTechMask,
690           mSecureNfcEnabled ? 0 : seTechMask,
691           mSecureNfcEnabled ? 0 : seTechMask);
692       if (nfaStat != NFA_STATUS_OK)
693         LOG(ERROR) << fn << "Failed to configure UICC technology routing.";
694 
695       allSeTechMask |= seTechMask;
696     }
697   }
698 
699   // Clear DH technology route on NFC-A
700   if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_A) &&
701       (allSeTechMask & NFA_TECHNOLOGY_MASK_A) != 0) {
702     nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_A);
703     if (nfaStat != NFA_STATUS_OK)
704       LOG(ERROR) << "Failed to clear DH technology routing on NFC-A.";
705   }
706 
707   // Clear DH technology route on NFC-B
708   if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_B) &&
709       (allSeTechMask & NFA_TECHNOLOGY_MASK_B) != 0) {
710     nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_B);
711     if (nfaStat != NFA_STATUS_OK)
712       LOG(ERROR) << "Failed to clear DH technology routing on NFC-B.";
713   }
714 
715   // Clear DH technology route on NFC-F
716   if ((mHostListenTechMask & NFA_TECHNOLOGY_MASK_F) &&
717       (allSeTechMask & NFA_TECHNOLOGY_MASK_F) != 0) {
718     nfaStat = NFA_EeClearDefaultTechRouting(NFC_DH_ID, NFA_TECHNOLOGY_MASK_F);
719     if (nfaStat != NFA_STATUS_OK)
720       LOG(ERROR) << "Failed to clear DH technology routing on NFC-F.";
721   }
722   return allSeTechMask;
723 }
724 
725 /*******************************************************************************
726 **
727 ** Function:        nfaEeCallback
728 **
729 ** Description:     Receive execution environment-related events from stack.
730 **                  event: Event code.
731 **                  eventData: Event data.
732 **
733 ** Returns:         None
734 **
735 *******************************************************************************/
nfaEeCallback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * eventData)736 void RoutingManager::nfaEeCallback(tNFA_EE_EVT event,
737                                    tNFA_EE_CBACK_DATA* eventData) {
738   static const char fn[] = "RoutingManager::nfaEeCallback";
739 
740   RoutingManager& routingManager = RoutingManager::getInstance();
741   if (!eventData) {
742     LOG(ERROR) << "eventData is null";
743     return;
744   }
745   routingManager.mCbEventData = *eventData;
746   switch (event) {
747     case NFA_EE_REGISTER_EVT: {
748       SyncEventGuard guard(routingManager.mEeRegisterEvent);
749       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
750           "%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
751       routingManager.mEeRegisterEvent.notifyOne();
752     } break;
753 
754     case NFA_EE_DEREGISTER_EVT: {
755       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
756           "%s: NFA_EE_DEREGISTER_EVT; status=0x%X", fn, eventData->status);
757       routingManager.mReceivedEeInfo = false;
758       routingManager.mDeinitializing = false;
759     } break;
760 
761     case NFA_EE_MODE_SET_EVT: {
762       SyncEventGuard guard(routingManager.mEeSetModeEvent);
763       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
764           "%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  ", fn,
765           eventData->mode_set.status, eventData->mode_set.ee_handle);
766       routingManager.mEeSetModeEvent.notifyOne();
767     } break;
768 
769     case NFA_EE_SET_TECH_CFG_EVT: {
770       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
771           "%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
772       SyncEventGuard guard(routingManager.mRoutingEvent);
773       routingManager.mRoutingEvent.notifyOne();
774     } break;
775 
776     case NFA_EE_CLEAR_TECH_CFG_EVT: {
777       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
778           "%s: NFA_EE_CLEAR_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
779       SyncEventGuard guard(routingManager.mRoutingEvent);
780       routingManager.mRoutingEvent.notifyOne();
781     } break;
782 
783     case NFA_EE_SET_PROTO_CFG_EVT: {
784       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
785           "%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
786       SyncEventGuard guard(routingManager.mRoutingEvent);
787       routingManager.mRoutingEvent.notifyOne();
788     } break;
789 
790     case NFA_EE_CLEAR_PROTO_CFG_EVT: {
791       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
792           "%s: NFA_EE_CLEAR_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
793       SyncEventGuard guard(routingManager.mRoutingEvent);
794       routingManager.mRoutingEvent.notifyOne();
795     } break;
796 
797     case NFA_EE_ACTION_EVT: {
798       tNFA_EE_ACTION& action = eventData->action;
799       if (action.trigger == NFC_EE_TRIG_SELECT)
800         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
801             "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn,
802             action.ee_handle, action.trigger);
803       else if (action.trigger == NFC_EE_TRIG_APP_INIT) {
804         tNFC_APP_INIT& app_init = action.param.app_init;
805         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
806             "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init "
807             "(0x%X); aid len=%u; data len=%u",
808             fn, action.ee_handle, action.trigger, app_init.len_aid,
809             app_init.len_data);
810       } else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
811         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
812             "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn,
813             action.ee_handle, action.trigger);
814       else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
815         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
816             "%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn,
817             action.ee_handle, action.trigger);
818       else
819         DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
820             "%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn,
821             action.ee_handle, action.trigger);
822     } break;
823 
824     case NFA_EE_DISCOVER_REQ_EVT: {
825       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
826           "%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __func__,
827           eventData->discover_req.status, eventData->discover_req.num_ee);
828       SyncEventGuard guard(routingManager.mEeInfoEvent);
829       memcpy(&routingManager.mEeInfo, &eventData->discover_req,
830              sizeof(routingManager.mEeInfo));
831       if (routingManager.mReceivedEeInfo && !routingManager.mDeinitializing) {
832         routingManager.mEeInfoChanged = true;
833         routingManager.notifyEeUpdated();
834       }
835       routingManager.mReceivedEeInfo = true;
836       routingManager.mEeInfoEvent.notifyOne();
837     } break;
838 
839     case NFA_EE_NO_CB_ERR_EVT:
840       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
841           "%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
842       break;
843 
844     case NFA_EE_ADD_AID_EVT: {
845       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
846           "%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
847       SyncEventGuard guard(routingManager.mRoutingEvent);
848       routingManager.mAidRoutingConfigured =
849           (eventData->status == NFA_STATUS_OK);
850       routingManager.mRoutingEvent.notifyOne();
851     } break;
852 
853     case NFA_EE_ADD_SYSCODE_EVT: {
854       SyncEventGuard guard(routingManager.mRoutingEvent);
855       routingManager.mRoutingEvent.notifyOne();
856       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
857           "%s: NFA_EE_ADD_SYSCODE_EVT  status=%u", fn, eventData->status);
858     } break;
859 
860     case NFA_EE_REMOVE_SYSCODE_EVT: {
861       SyncEventGuard guard(routingManager.mRoutingEvent);
862       routingManager.mRoutingEvent.notifyOne();
863       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
864           "%s: NFA_EE_REMOVE_SYSCODE_EVT  status=%u", fn, eventData->status);
865     } break;
866 
867     case NFA_EE_REMOVE_AID_EVT: {
868       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
869           "%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
870       SyncEventGuard guard(routingManager.mRoutingEvent);
871       routingManager.mAidRoutingConfigured =
872           (eventData->status == NFA_STATUS_OK);
873       routingManager.mRoutingEvent.notifyOne();
874     } break;
875 
876     case NFA_EE_NEW_EE_EVT: {
877       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
878           "%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
879           eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
880     } break;
881 
882     case NFA_EE_UPDATED_EVT: {
883       DLOG_IF(INFO, nfc_debug_enabled)
884           << StringPrintf("%s: NFA_EE_UPDATED_EVT", fn);
885       SyncEventGuard guard(routingManager.mEeUpdateEvent);
886       routingManager.mEeUpdateEvent.notifyOne();
887     } break;
888 
889     default:
890       DLOG_IF(INFO, nfc_debug_enabled)
891           << StringPrintf("%s: unknown event=%u ????", fn, event);
892       break;
893   }
894 }
895 
registerT3tIdentifier(uint8_t * t3tId,uint8_t t3tIdLen)896 int RoutingManager::registerT3tIdentifier(uint8_t* t3tId, uint8_t t3tIdLen) {
897   static const char fn[] = "RoutingManager::registerT3tIdentifier";
898 
899   DLOG_IF(INFO, nfc_debug_enabled)
900       << fn << ": Start to register NFC-F system on DH";
901 
902   if (t3tIdLen != (2 + NCI_RF_F_UID_LEN + NCI_T3T_PMM_LEN)) {
903     LOG(ERROR) << fn << ": Invalid length of T3T Identifier";
904     return NFA_HANDLE_INVALID;
905   }
906 
907   mNfcFOnDhHandle = NFA_HANDLE_INVALID;
908 
909   uint16_t systemCode;
910   uint8_t nfcid2[NCI_RF_F_UID_LEN];
911   uint8_t t3tPmm[NCI_T3T_PMM_LEN];
912 
913   systemCode = (((int)t3tId[0] << 8) | ((int)t3tId[1] << 0));
914   memcpy(nfcid2, t3tId + 2, NCI_RF_F_UID_LEN);
915   memcpy(t3tPmm, t3tId + 10, NCI_T3T_PMM_LEN);
916   {
917     SyncEventGuard guard(mRoutingEvent);
918     tNFA_STATUS nfaStat = NFA_CeRegisterFelicaSystemCodeOnDH(
919         systemCode, nfcid2, t3tPmm, nfcFCeCallback);
920     if (nfaStat == NFA_STATUS_OK) {
921       mRoutingEvent.wait();
922     } else {
923       LOG(ERROR) << fn << ": Fail to register NFC-F system on DH";
924       return NFA_HANDLE_INVALID;
925     }
926   }
927   DLOG_IF(INFO, nfc_debug_enabled)
928       << fn << ": Succeed to register NFC-F system on DH";
929 
930   // Register System Code for routing
931   if (mIsScbrSupported) {
932     SyncEventGuard guard(mRoutingEvent);
933     tNFA_STATUS nfaStat = NFA_EeAddSystemCodeRouting(systemCode, NCI_DH_ID,
934                                                      SYS_CODE_PWR_STATE_HOST);
935     if (nfaStat == NFA_STATUS_OK) {
936       mRoutingEvent.wait();
937     }
938     if ((nfaStat != NFA_STATUS_OK) || (mCbEventData.status != NFA_STATUS_OK)) {
939       LOG(ERROR) << StringPrintf("%s: Fail to register system code on DH", fn);
940       return NFA_HANDLE_INVALID;
941     }
942     DLOG_IF(INFO, nfc_debug_enabled)
943         << StringPrintf("%s: Succeed to register system code on DH", fn);
944     // add handle and system code pair to the map
945     mMapScbrHandle.emplace(mNfcFOnDhHandle, systemCode);
946   } else {
947     LOG(ERROR) << StringPrintf("%s: SCBR Not supported", fn);
948   }
949 
950   return mNfcFOnDhHandle;
951 }
952 
deregisterT3tIdentifier(int handle)953 void RoutingManager::deregisterT3tIdentifier(int handle) {
954   static const char fn[] = "RoutingManager::deregisterT3tIdentifier";
955 
956   DLOG_IF(INFO, nfc_debug_enabled)
957       << StringPrintf("%s: Start to deregister NFC-F system on DH", fn);
958   {
959     SyncEventGuard guard(mRoutingEvent);
960     tNFA_STATUS nfaStat = NFA_CeDeregisterFelicaSystemCodeOnDH(handle);
961     if (nfaStat == NFA_STATUS_OK) {
962       mRoutingEvent.wait();
963       DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
964           "%s: Succeeded in deregistering NFC-F system on DH", fn);
965     } else {
966       LOG(ERROR) << StringPrintf("%s: Fail to deregister NFC-F system on DH",
967                                  fn);
968     }
969   }
970   if (mIsScbrSupported) {
971     map<int, uint16_t>::iterator it = mMapScbrHandle.find(handle);
972     // find system code for given handle
973     if (it != mMapScbrHandle.end()) {
974       uint16_t systemCode = it->second;
975       mMapScbrHandle.erase(handle);
976       if (systemCode != 0) {
977         SyncEventGuard guard(mRoutingEvent);
978         tNFA_STATUS nfaStat = NFA_EeRemoveSystemCodeRouting(systemCode);
979         if (nfaStat == NFA_STATUS_OK) {
980           mRoutingEvent.wait();
981           DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf(
982               "%s: Succeeded in deregistering system Code on DH", fn);
983         } else {
984           LOG(ERROR) << StringPrintf("%s: Fail to deregister system Code on DH",
985                                      fn);
986         }
987       }
988     }
989   }
990 }
991 
nfcFCeCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)992 void RoutingManager::nfcFCeCallback(uint8_t event,
993                                     tNFA_CONN_EVT_DATA* eventData) {
994   static const char fn[] = "RoutingManager::nfcFCeCallback";
995   RoutingManager& routingManager = RoutingManager::getInstance();
996 
997   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s: 0x%x", __func__, event);
998 
999   switch (event) {
1000     case NFA_CE_REGISTERED_EVT: {
1001       DLOG_IF(INFO, nfc_debug_enabled)
1002           << StringPrintf("%s: registerd event notified", fn);
1003       routingManager.mNfcFOnDhHandle = eventData->ce_registered.handle;
1004       SyncEventGuard guard(routingManager.mRoutingEvent);
1005       routingManager.mRoutingEvent.notifyOne();
1006     } break;
1007     case NFA_CE_DEREGISTERED_EVT: {
1008       DLOG_IF(INFO, nfc_debug_enabled)
1009           << StringPrintf("%s: deregisterd event notified", fn);
1010       SyncEventGuard guard(routingManager.mRoutingEvent);
1011       routingManager.mRoutingEvent.notifyOne();
1012     } break;
1013     case NFA_CE_ACTIVATED_EVT: {
1014       DLOG_IF(INFO, nfc_debug_enabled)
1015           << StringPrintf("%s: activated event notified", fn);
1016       routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_F);
1017     } break;
1018     case NFA_CE_DEACTIVATED_EVT: {
1019       DLOG_IF(INFO, nfc_debug_enabled)
1020           << StringPrintf("%s: deactivated event notified", fn);
1021       routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_F);
1022     } break;
1023     case NFA_CE_DATA_EVT: {
1024       DLOG_IF(INFO, nfc_debug_enabled)
1025           << StringPrintf("%s: data event notified", fn);
1026       tNFA_CE_DATA& ce_data = eventData->ce_data;
1027       routingManager.handleData(NFA_TECHNOLOGY_MASK_F, ce_data.p_data,
1028                                 ce_data.len, ce_data.status);
1029     } break;
1030     default: {
1031       DLOG_IF(INFO, nfc_debug_enabled)
1032           << StringPrintf("%s: unknown event=%u ????", fn, event);
1033     } break;
1034   }
1035 }
1036 
setNfcSecure(bool enable)1037 bool RoutingManager::setNfcSecure(bool enable) {
1038   mSecureNfcEnabled = enable;
1039   DLOG_IF(INFO, true) << "setNfcSecure NfcService " << enable;
1040   return true;
1041 }
1042 
deinitialize()1043 void RoutingManager::deinitialize() {
1044   onNfccShutdown();
1045   NFA_EeDeregister(nfaEeCallback);
1046 }
1047 
registerJniFunctions(JNIEnv * e)1048 int RoutingManager::registerJniFunctions(JNIEnv* e) {
1049   static const char fn[] = "RoutingManager::registerJniFunctions";
1050   DLOG_IF(INFO, nfc_debug_enabled) << StringPrintf("%s", fn);
1051   return jniRegisterNativeMethods(
1052       e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods,
1053       NELEM(sMethods));
1054 }
1055 
com_android_nfc_cardemulation_doGetDefaultRouteDestination(JNIEnv *)1056 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination(
1057     JNIEnv*) {
1058   return getInstance().mDefaultEe;
1059 }
1060 
1061 int RoutingManager::
com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv *)1062     com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv*) {
1063   return getInstance().mDefaultOffHostRoute;
1064 }
1065 
1066 jbyteArray
com_android_nfc_cardemulation_doGetOffHostUiccDestination(JNIEnv * e)1067 RoutingManager::com_android_nfc_cardemulation_doGetOffHostUiccDestination(
1068     JNIEnv* e) {
1069   std::vector<uint8_t> uicc = getInstance().mOffHostRouteUicc;
1070   if (uicc.size() == 0) {
1071     return NULL;
1072   }
1073   CHECK(e);
1074   jbyteArray uiccJavaArray = e->NewByteArray(uicc.size());
1075   CHECK(uiccJavaArray);
1076   e->SetByteArrayRegion(uiccJavaArray, 0, uicc.size(), (jbyte*)&uicc[0]);
1077   return uiccJavaArray;
1078 }
1079 
1080 jbyteArray
com_android_nfc_cardemulation_doGetOffHostEseDestination(JNIEnv * e)1081 RoutingManager::com_android_nfc_cardemulation_doGetOffHostEseDestination(
1082     JNIEnv* e) {
1083   std::vector<uint8_t> ese = getInstance().mOffHostRouteEse;
1084   if (ese.size() == 0) {
1085     return NULL;
1086   }
1087   CHECK(e);
1088   jbyteArray eseJavaArray = e->NewByteArray(ese.size());
1089   CHECK(eseJavaArray);
1090   e->SetByteArrayRegion(eseJavaArray, 0, ese.size(), (jbyte*)&ese[0]);
1091   return eseJavaArray;
1092 }
1093 
com_android_nfc_cardemulation_doGetAidMatchingMode(JNIEnv *)1094 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode(
1095     JNIEnv*) {
1096   return getInstance().mAidMatchingMode;
1097 }
1098 
1099 int RoutingManager::
com_android_nfc_cardemulation_doGetDefaultIsoDepRouteDestination(JNIEnv *)1100     com_android_nfc_cardemulation_doGetDefaultIsoDepRouteDestination(JNIEnv*) {
1101   return getInstance().mDefaultIsoDepRoute;
1102 }
1103