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