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