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