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