Home | History | Annotate | Download | only in jni
      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 <cutils/log.h>
     22 #include <ScopedLocalRef.h>
     23 #include <JNIHelp.h>
     24 #include "config.h"
     25 #include "JavaClassConstants.h"
     26 #include "RoutingManager.h"
     27 
     28 extern "C"
     29 {
     30     #include "nfa_ee_api.h"
     31     #include "nfa_ce_api.h"
     32 }
     33 extern bool gActivated;
     34 extern SyncEvent gDeactivatedEvent;
     35 
     36 
     37 const JNINativeMethod RoutingManager::sMethods [] =
     38 {
     39     {"doGetDefaultRouteDestination", "()I", (void*) RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination},
     40     {"doGetDefaultOffHostRouteDestination", "()I", (void*) RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination},
     41     {"doGetAidMatchingMode", "()I", (void*) RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode}
     42 };
     43 
     44 static const int MAX_NUM_EE = 5;
     45 
     46 RoutingManager::RoutingManager ()
     47 {
     48     static const char fn [] = "RoutingManager::RoutingManager()";
     49     unsigned long num = 0;
     50 
     51     // Get the active SE
     52     if (GetNumValue("ACTIVE_SE", &num, sizeof(num)))
     53         mActiveSe = num;
     54     else
     55         mActiveSe = 0x00;
     56 
     57     // Get the "default" route
     58     if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num)))
     59         mDefaultEe = num;
     60     else
     61         mDefaultEe = 0x00;
     62     ALOGD("%s: default route is 0x%02X", fn, mDefaultEe);
     63 
     64     // Get the default "off-host" route.  This is hard-coded at the Java layer
     65     // but we can override it here to avoid forcing Java changes.
     66     if (GetNumValue("DEFAULT_OFFHOST_ROUTE", &num, sizeof(num)))
     67         mOffHostEe = num;
     68     else
     69         mOffHostEe = 0xf4;
     70 
     71     if (GetNumValue("AID_MATCHING_MODE", &num, sizeof(num)))
     72         mAidMatchingMode = num;
     73     else
     74         mAidMatchingMode = AID_MATCHING_EXACT_ONLY;
     75 
     76     ALOGD("%s: mOffHostEe=0x%02X", fn, mOffHostEe);
     77 
     78     memset (&mEeInfo, 0, sizeof(mEeInfo));
     79     mReceivedEeInfo = false;
     80     mSeTechMask = 0x00;
     81 }
     82 
     83 RoutingManager::~RoutingManager ()
     84 {
     85     NFA_EeDeregister (nfaEeCallback);
     86 }
     87 
     88 bool RoutingManager::initialize (nfc_jni_native_data* native)
     89 {
     90     static const char fn [] = "RoutingManager::initialize()";
     91     mNativeData = native;
     92 
     93     tNFA_STATUS nfaStat;
     94     {
     95         SyncEventGuard guard (mEeRegisterEvent);
     96         ALOGD ("%s: try ee register", fn);
     97         nfaStat = NFA_EeRegister (nfaEeCallback);
     98         if (nfaStat != NFA_STATUS_OK)
     99         {
    100             ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat);
    101             return false;
    102         }
    103         mEeRegisterEvent.wait ();
    104     }
    105 
    106     mRxDataBuffer.clear ();
    107 
    108     if (mActiveSe != 0) {
    109         {
    110             // Wait for EE info if needed
    111             SyncEventGuard guard (mEeInfoEvent);
    112             if (!mReceivedEeInfo)
    113             {
    114                 ALOGE("Waiting for EE info");
    115                 mEeInfoEvent.wait();
    116             }
    117         }
    118         for (UINT8 i = 0; i < mEeInfo.num_ee; i++)
    119         {
    120              ALOGD ("%s   EE[%u] Handle: 0x%04x  techA: 0x%02x  techB: 0x%02x  techF: 0x%02x  techBprime: 0x%02x",
    121                 fn, i, mEeInfo.ee_disc_info[i].ee_handle,
    122                 mEeInfo.ee_disc_info[i].la_protocol,
    123                 mEeInfo.ee_disc_info[i].lb_protocol,
    124                 mEeInfo.ee_disc_info[i].lf_protocol,
    125                 mEeInfo.ee_disc_info[i].lbp_protocol);
    126              if (mEeInfo.ee_disc_info[i].ee_handle == (mActiveSe | NFA_HANDLE_GROUP_EE))
    127              {
    128                  if (mEeInfo.ee_disc_info[i].la_protocol != 0) mSeTechMask |= NFA_TECHNOLOGY_MASK_A;
    129 
    130                  if (mSeTechMask != 0x00)
    131                  {
    132                      ALOGD("Configuring tech mask 0x%02x on EE 0x%04x", mSeTechMask, mEeInfo.ee_disc_info[i].ee_handle);
    133                      nfaStat = NFA_CeConfigureUiccListenTech(mEeInfo.ee_disc_info[i].ee_handle, mSeTechMask);
    134                      if (nfaStat != NFA_STATUS_OK)
    135                          ALOGE ("Failed to configure UICC listen technologies.");
    136                      // Set technology routes to UICC if it's there
    137                      nfaStat = NFA_EeSetDefaultTechRouting(mEeInfo.ee_disc_info[i].ee_handle, mSeTechMask, mSeTechMask,
    138                              mSeTechMask);
    139                      if (nfaStat != NFA_STATUS_OK)
    140                          ALOGE ("Failed to configure UICC technology routing.");
    141                  }
    142              }
    143         }
    144     }
    145 
    146     // Tell the host-routing to only listen on Nfc-A
    147     nfaStat = NFA_CeSetIsoDepListenTech(NFA_TECHNOLOGY_MASK_A);
    148     if (nfaStat != NFA_STATUS_OK)
    149         ALOGE ("Failed to configure CE IsoDep technologies");
    150 
    151     // Register a wild-card for AIDs routed to the host
    152     nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
    153     if (nfaStat != NFA_STATUS_OK)
    154         ALOGE("Failed to register wildcard AID for DH");
    155 
    156     return true;
    157 }
    158 
    159 RoutingManager& RoutingManager::getInstance ()
    160 {
    161     static RoutingManager manager;
    162     return manager;
    163 }
    164 
    165 void RoutingManager::enableRoutingToHost()
    166 {
    167     tNFA_STATUS nfaStat;
    168 
    169     {
    170         SyncEventGuard guard (mRoutingEvent);
    171 
    172         // Route Nfc-A to host if we don't have a SE
    173         if (mSeTechMask == 0)
    174         {
    175             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, NFA_TECHNOLOGY_MASK_A, 0, 0);
    176             if (nfaStat == NFA_STATUS_OK)
    177                 mRoutingEvent.wait ();
    178             else
    179                 ALOGE ("Fail to set default tech routing");
    180         }
    181 
    182         // Default routing for IsoDep protocol
    183         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0);
    184         if (nfaStat == NFA_STATUS_OK)
    185             mRoutingEvent.wait ();
    186         else
    187             ALOGE ("Fail to set default proto routing");
    188     }
    189 }
    190 
    191 void RoutingManager::disableRoutingToHost()
    192 {
    193     tNFA_STATUS nfaStat;
    194 
    195     {
    196         SyncEventGuard guard (mRoutingEvent);
    197         // Default routing for NFC-A technology if we don't have a SE
    198         if (mSeTechMask == 0)
    199         {
    200             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0);
    201             if (nfaStat == NFA_STATUS_OK)
    202                 mRoutingEvent.wait ();
    203             else
    204                 ALOGE ("Fail to set default tech routing");
    205         }
    206 
    207         // Default routing for IsoDep protocol
    208         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0);
    209         if (nfaStat == NFA_STATUS_OK)
    210             mRoutingEvent.wait ();
    211         else
    212             ALOGE ("Fail to set default proto routing");
    213     }
    214 }
    215 
    216 bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route)
    217 {
    218     static const char fn [] = "RoutingManager::addAidRouting";
    219     ALOGD ("%s: enter", fn);
    220     tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01);
    221     if (nfaStat == NFA_STATUS_OK)
    222     {
    223         ALOGD ("%s: routed AID", fn);
    224         return true;
    225     } else
    226     {
    227         ALOGE ("%s: failed to route AID", fn);
    228         return false;
    229     }
    230 }
    231 
    232 bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen)
    233 {
    234     static const char fn [] = "RoutingManager::removeAidRouting";
    235     ALOGD ("%s: enter", fn);
    236     tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid);
    237     if (nfaStat == NFA_STATUS_OK)
    238     {
    239         ALOGD ("%s: removed AID", fn);
    240         return true;
    241     } else
    242     {
    243         ALOGE ("%s: failed to remove AID", fn);
    244         return false;
    245     }
    246 }
    247 
    248 bool RoutingManager::commitRouting()
    249 {
    250     static const char fn [] = "RoutingManager::commitRouting";
    251     tNFA_STATUS nfaStat = 0;
    252     ALOGD ("%s", fn);
    253     {
    254         SyncEventGuard guard (mEeUpdateEvent);
    255         nfaStat = NFA_EeUpdateNow();
    256         if (nfaStat == NFA_STATUS_OK)
    257         {
    258             mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT
    259         }
    260     }
    261     return (nfaStat == NFA_STATUS_OK);
    262 }
    263 
    264 void RoutingManager::onNfccShutdown ()
    265 {
    266     static const char fn [] = "RoutingManager:onNfccShutdown";
    267     if (mActiveSe == 0x00) return;
    268 
    269     tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
    270     UINT8 actualNumEe = MAX_NUM_EE;
    271     tNFA_EE_INFO eeInfo[MAX_NUM_EE];
    272 
    273     memset (&eeInfo, 0, sizeof(eeInfo));
    274     if ((nfaStat = NFA_EeGetInfo (&actualNumEe, eeInfo)) != NFA_STATUS_OK)
    275     {
    276         ALOGE ("%s: fail get info; error=0x%X", fn, nfaStat);
    277         return;
    278     }
    279     if (actualNumEe != 0)
    280     {
    281         for (UINT8 xx = 0; xx < actualNumEe; xx++)
    282         {
    283             if ((eeInfo[xx].num_interface != 0)
    284                 && (eeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS)
    285                 && (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE))
    286             {
    287                 ALOGD ("%s: Handle: 0x%04x Change Status Active to Inactive", fn, eeInfo[xx].ee_handle);
    288                 SyncEventGuard guard (mEeSetModeEvent);
    289                 if ((nfaStat = NFA_EeModeSet (eeInfo[xx].ee_handle, NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK)
    290                 {
    291                     mEeSetModeEvent.wait (); //wait for NFA_EE_MODE_SET_EVT
    292                 }
    293                 else
    294                 {
    295                     ALOGE ("Failed to set EE inactive");
    296                 }
    297             }
    298         }
    299     }
    300     else
    301     {
    302         ALOGD ("%s: No active EEs found", fn);
    303     }
    304 }
    305 
    306 void RoutingManager::notifyActivated ()
    307 {
    308     JNIEnv* e = NULL;
    309     ScopedAttach attach(mNativeData->vm, &e);
    310     if (e == NULL)
    311     {
    312         ALOGE ("jni env is null");
    313         return;
    314     }
    315 
    316     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated);
    317     if (e->ExceptionCheck())
    318     {
    319         e->ExceptionClear();
    320         ALOGE ("fail notify");
    321     }
    322 }
    323 
    324 void RoutingManager::notifyDeactivated ()
    325 {
    326     mRxDataBuffer.clear();
    327     JNIEnv* e = NULL;
    328     ScopedAttach attach(mNativeData->vm, &e);
    329     if (e == NULL)
    330     {
    331         ALOGE ("jni env is null");
    332         return;
    333     }
    334 
    335     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated);
    336     if (e->ExceptionCheck())
    337     {
    338         e->ExceptionClear();
    339         ALOGE ("fail notify");
    340     }
    341 }
    342 
    343 void RoutingManager::handleData (const UINT8* data, UINT32 dataLen, tNFA_STATUS status)
    344 {
    345     if (dataLen <= 0)
    346     {
    347         ALOGE("no data");
    348         goto TheEnd;
    349     }
    350 
    351     if (status == NFA_STATUS_CONTINUE)
    352     {
    353         mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data; more to come
    354         return; //expect another NFA_CE_DATA_EVT to come
    355     }
    356     else if (status == NFA_STATUS_OK)
    357     {
    358         mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data
    359         //entire data packet has been received; no more NFA_CE_DATA_EVT
    360     }
    361     else if (status == NFA_STATUS_FAILED)
    362     {
    363         ALOGE("RoutingManager::handleData: read data fail");
    364         goto TheEnd;
    365     }
    366 
    367     {
    368         JNIEnv* e = NULL;
    369         ScopedAttach attach(mNativeData->vm, &e);
    370         if (e == NULL)
    371         {
    372             ALOGE ("jni env is null");
    373             goto TheEnd;
    374         }
    375 
    376         ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(mRxDataBuffer.size()));
    377         if (dataJavaArray.get() == NULL)
    378         {
    379             ALOGE ("fail allocate array");
    380             goto TheEnd;
    381         }
    382 
    383         e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, mRxDataBuffer.size(),
    384                 (jbyte *)(&mRxDataBuffer[0]));
    385         if (e->ExceptionCheck())
    386         {
    387             e->ExceptionClear();
    388             ALOGE ("fail fill array");
    389             goto TheEnd;
    390         }
    391 
    392         e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData, dataJavaArray.get());
    393         if (e->ExceptionCheck())
    394         {
    395             e->ExceptionClear();
    396             ALOGE ("fail notify");
    397         }
    398     }
    399 TheEnd:
    400     mRxDataBuffer.clear();
    401 }
    402 
    403 void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
    404 {
    405     static const char fn [] = "RoutingManager::stackCallback";
    406     ALOGD("%s: event=0x%X", fn, event);
    407     RoutingManager& routingManager = RoutingManager::getInstance();
    408 
    409     switch (event)
    410     {
    411     case NFA_CE_REGISTERED_EVT:
    412         {
    413             tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
    414             ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
    415         }
    416         break;
    417 
    418     case NFA_CE_DEREGISTERED_EVT:
    419         {
    420             tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
    421             ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
    422         }
    423         break;
    424 
    425     case NFA_CE_ACTIVATED_EVT:
    426         {
    427             routingManager.notifyActivated();
    428         }
    429         break;
    430 
    431     case NFA_DEACTIVATED_EVT:
    432     case NFA_CE_DEACTIVATED_EVT:
    433         {
    434             ALOGD("%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn);
    435             routingManager.notifyDeactivated();
    436             SyncEventGuard g (gDeactivatedEvent);
    437             gActivated = false; //guard this variable from multi-threaded access
    438             gDeactivatedEvent.notifyOne ();
    439         }
    440         break;
    441 
    442     case NFA_CE_DATA_EVT:
    443         {
    444             tNFA_CE_DATA& ce_data = eventData->ce_data;
    445             ALOGD("%s: NFA_CE_DATA_EVT; stat=0x%X; h=0x%X; data len=%u", fn, ce_data.status, ce_data.handle, ce_data.len);
    446             getInstance().handleData(ce_data.p_data, ce_data.len, ce_data.status);
    447         }
    448         break;
    449     }
    450 }
    451 /*******************************************************************************
    452 **
    453 ** Function:        nfaEeCallback
    454 **
    455 ** Description:     Receive execution environment-related events from stack.
    456 **                  event: Event code.
    457 **                  eventData: Event data.
    458 **
    459 ** Returns:         None
    460 **
    461 *******************************************************************************/
    462 void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
    463 {
    464     static const char fn [] = "RoutingManager::nfaEeCallback";
    465 
    466     RoutingManager& routingManager = RoutingManager::getInstance();
    467 
    468     switch (event)
    469     {
    470     case NFA_EE_REGISTER_EVT:
    471         {
    472             SyncEventGuard guard (routingManager.mEeRegisterEvent);
    473             ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
    474             routingManager.mEeRegisterEvent.notifyOne();
    475         }
    476         break;
    477 
    478     case NFA_EE_MODE_SET_EVT:
    479         {
    480             SyncEventGuard guard (routingManager.mEeSetModeEvent);
    481             ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  ", fn,
    482                     eventData->mode_set.status, eventData->mode_set.ee_handle);
    483             routingManager.mEeSetModeEvent.notifyOne();
    484         }
    485         break;
    486 
    487     case NFA_EE_SET_TECH_CFG_EVT:
    488         {
    489             ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
    490             SyncEventGuard guard(routingManager.mRoutingEvent);
    491             routingManager.mRoutingEvent.notifyOne();
    492         }
    493         break;
    494 
    495     case NFA_EE_SET_PROTO_CFG_EVT:
    496         {
    497             ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
    498             SyncEventGuard guard(routingManager.mRoutingEvent);
    499             routingManager.mRoutingEvent.notifyOne();
    500         }
    501         break;
    502 
    503     case NFA_EE_ACTION_EVT:
    504         {
    505             tNFA_EE_ACTION& action = eventData->action;
    506             if (action.trigger == NFC_EE_TRIG_SELECT)
    507                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger);
    508             else if (action.trigger == NFC_EE_TRIG_APP_INIT)
    509             {
    510                 tNFC_APP_INIT& app_init = action.param.app_init;
    511                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn,
    512                         action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data);
    513             }
    514             else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
    515                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger);
    516             else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
    517                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger);
    518             else
    519                 ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger);
    520         }
    521         break;
    522 
    523     case NFA_EE_DISCOVER_REQ_EVT:
    524         {
    525             ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__,
    526                     eventData->discover_req.status, eventData->discover_req.num_ee);
    527             SyncEventGuard guard (routingManager.mEeInfoEvent);
    528             memcpy (&routingManager.mEeInfo, &eventData->discover_req, sizeof(routingManager.mEeInfo));
    529             routingManager.mReceivedEeInfo = true;
    530             routingManager.mEeInfoEvent.notifyOne();
    531         }
    532         break;
    533 
    534     case NFA_EE_NO_CB_ERR_EVT:
    535         ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
    536         break;
    537 
    538     case NFA_EE_ADD_AID_EVT:
    539         {
    540             ALOGD ("%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
    541         }
    542         break;
    543 
    544     case NFA_EE_REMOVE_AID_EVT:
    545         {
    546             ALOGD ("%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
    547         }
    548         break;
    549 
    550     case NFA_EE_NEW_EE_EVT:
    551         {
    552             ALOGD ("%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
    553                 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
    554         }
    555         break;
    556 
    557     case NFA_EE_UPDATED_EVT:
    558         {
    559             ALOGD("%s: NFA_EE_UPDATED_EVT", fn);
    560             SyncEventGuard guard(routingManager.mEeUpdateEvent);
    561             routingManager.mEeUpdateEvent.notifyOne();
    562         }
    563         break;
    564 
    565     default:
    566         ALOGE ("%s: unknown event=%u ????", fn, event);
    567         break;
    568     }
    569 }
    570 
    571 int RoutingManager::registerJniFunctions (JNIEnv* e)
    572 {
    573     static const char fn [] = "RoutingManager::registerJniFunctions";
    574     ALOGD ("%s", fn);
    575     return jniRegisterNativeMethods (e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods, NELEM(sMethods));
    576 }
    577 
    578 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination (JNIEnv*)
    579 {
    580     return getInstance().mDefaultEe;
    581 }
    582 
    583 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination (JNIEnv*)
    584 {
    585     return getInstance().mOffHostEe;
    586 }
    587 
    588 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode (JNIEnv*)
    589 {
    590     return getInstance().mAidMatchingMode;
    591 }
    592