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 active SE for Nfc-F
     58     if (GetNumValue("ACTIVE_SE_NFCF", &num, sizeof(num)))
     59         mActiveSeNfcF = num;
     60     else
     61         mActiveSeNfcF = 0x00;
     62     ALOGD("%s: Active SE for Nfc-F is 0x%02X", fn, mActiveSeNfcF);
     63 
     64     // Get the "default" route
     65     if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num)))
     66         mDefaultEe = num;
     67     else
     68         mDefaultEe = 0x00;
     69     ALOGD("%s: default route is 0x%02X", fn, mDefaultEe);
     70 
     71     // Get the "default" route for Nfc-F
     72     if (GetNumValue("DEFAULT_NFCF_ROUTE", &num, sizeof(num)))
     73         mDefaultEeNfcF = num;
     74     else
     75         mDefaultEeNfcF = 0x00;
     76     ALOGD("%s: default route for Nfc-F is 0x%02X", fn, mDefaultEeNfcF);
     77 
     78     // Get the default "off-host" route.  This is hard-coded at the Java layer
     79     // but we can override it here to avoid forcing Java changes.
     80     if (GetNumValue("DEFAULT_OFFHOST_ROUTE", &num, sizeof(num)))
     81         mOffHostEe = num;
     82     else
     83         mOffHostEe = 0xf4;
     84 
     85     if (GetNumValue("AID_MATCHING_MODE", &num, sizeof(num)))
     86         mAidMatchingMode = num;
     87     else
     88         mAidMatchingMode = AID_MATCHING_EXACT_ONLY;
     89 
     90     ALOGD("%s: mOffHostEe=0x%02X", fn, mOffHostEe);
     91 
     92     memset (&mEeInfo, 0, sizeof(mEeInfo));
     93     mReceivedEeInfo = false;
     94     mSeTechMask = 0x00;
     95 
     96     mNfcFOnDhHandle = NFA_HANDLE_INVALID;
     97 }
     98 
     99 RoutingManager::~RoutingManager ()
    100 {
    101     NFA_EeDeregister (nfaEeCallback);
    102 }
    103 
    104 bool RoutingManager::initialize (nfc_jni_native_data* native)
    105 {
    106     static const char fn [] = "RoutingManager::initialize()";
    107     mNativeData = native;
    108 
    109     tNFA_STATUS nfaStat;
    110     {
    111         SyncEventGuard guard (mEeRegisterEvent);
    112         ALOGD ("%s: try ee register", fn);
    113         nfaStat = NFA_EeRegister (nfaEeCallback);
    114         if (nfaStat != NFA_STATUS_OK)
    115         {
    116             ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat);
    117             return false;
    118         }
    119         mEeRegisterEvent.wait ();
    120     }
    121 
    122     mRxDataBuffer.clear ();
    123 
    124     if ((mActiveSe != 0) || (mActiveSeNfcF != 0))
    125     {
    126         ALOGD ("%s: Technology Routing (NfcASe:0x%02x, NfcFSe:0x%02x)", fn, mActiveSe, mActiveSeNfcF);
    127         {
    128             // Wait for EE info if needed
    129             SyncEventGuard guard (mEeInfoEvent);
    130             if (!mReceivedEeInfo)
    131             {
    132                 ALOGE("Waiting for EE info");
    133                 mEeInfoEvent.wait();
    134             }
    135         }
    136 
    137         ALOGD ("%s: Number of EE is %d", fn, mEeInfo.num_ee);
    138         for (UINT8 i = 0; i < mEeInfo.num_ee; i++)
    139         {
    140             tNFA_HANDLE eeHandle = mEeInfo.ee_disc_info[i].ee_handle;
    141             tNFA_TECHNOLOGY_MASK seTechMask = 0;
    142 
    143             ALOGD ("%s   EE[%u] Handle: 0x%04x  techA: 0x%02x  techB: 0x%02x  techF: 0x%02x  techBprime: 0x%02x",
    144                    fn, i, eeHandle,
    145                    mEeInfo.ee_disc_info[i].la_protocol,
    146                    mEeInfo.ee_disc_info[i].lb_protocol,
    147                    mEeInfo.ee_disc_info[i].lf_protocol,
    148                    mEeInfo.ee_disc_info[i].lbp_protocol);
    149             if ((mActiveSe != 0) && (eeHandle == (mActiveSe | NFA_HANDLE_GROUP_EE)))
    150             {
    151                 if (mEeInfo.ee_disc_info[i].la_protocol != 0)
    152                     seTechMask |= NFA_TECHNOLOGY_MASK_A;
    153             }
    154             if ((mActiveSeNfcF != 0) && (eeHandle == (mActiveSeNfcF | NFA_HANDLE_GROUP_EE)))
    155             {
    156                 if (mEeInfo.ee_disc_info[i].lf_protocol != 0)
    157                     seTechMask |= NFA_TECHNOLOGY_MASK_F;
    158             }
    159 
    160             ALOGD ("%s: seTechMask[%u]=0x%02x", fn, i, seTechMask);
    161             if (seTechMask != 0x00)
    162             {
    163                 ALOGD("Configuring tech mask 0x%02x on EE 0x%04x", seTechMask, eeHandle);
    164 
    165                 nfaStat = NFA_CeConfigureUiccListenTech(eeHandle, seTechMask);
    166                 if (nfaStat != NFA_STATUS_OK)
    167                     ALOGE ("Failed to configure UICC listen technologies.");
    168 
    169                 // Set technology routes to UICC if it's there
    170                 nfaStat = NFA_EeSetDefaultTechRouting(eeHandle, seTechMask, seTechMask, seTechMask);
    171                 if (nfaStat != NFA_STATUS_OK)
    172                     ALOGE ("Failed to configure UICC technology routing.");
    173 
    174                 mSeTechMask |= seTechMask;
    175             }
    176         }
    177     }
    178 
    179     // Tell the host-routing to only listen on Nfc-A
    180     nfaStat = NFA_CeSetIsoDepListenTech(NFA_TECHNOLOGY_MASK_A);
    181     if (nfaStat != NFA_STATUS_OK)
    182         ALOGE ("Failed to configure CE IsoDep technologies");
    183 
    184     // Register a wild-card for AIDs routed to the host
    185     nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
    186     if (nfaStat != NFA_STATUS_OK)
    187         ALOGE("Failed to register wildcard AID for DH");
    188 
    189     return true;
    190 }
    191 
    192 RoutingManager& RoutingManager::getInstance ()
    193 {
    194     static RoutingManager manager;
    195     return manager;
    196 }
    197 
    198 void RoutingManager::enableRoutingToHost()
    199 {
    200     tNFA_STATUS nfaStat;
    201     tNFA_TECHNOLOGY_MASK techMask;
    202     tNFA_PROTOCOL_MASK protoMask;
    203     SyncEventGuard guard (mRoutingEvent);
    204 
    205     // Set default routing at one time when the NFCEE IDs for Nfc-A and Nfc-F are same
    206     if (mDefaultEe == mDefaultEeNfcF)
    207     {
    208         // Route Nfc-A/Nfc-F to host if we don't have a SE
    209         techMask = (mSeTechMask ^ (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F));
    210         if (techMask != 0)
    211         {
    212             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, techMask, 0, 0);
    213             if (nfaStat == NFA_STATUS_OK)
    214                 mRoutingEvent.wait ();
    215             else
    216                 ALOGE ("Fail to set default tech routing for Nfc-A/Nfc-F");
    217         }
    218         // Default routing for IsoDep and T3T protocol
    219         protoMask = (NFA_PROTOCOL_MASK_ISO_DEP | NFA_PROTOCOL_MASK_T3T);
    220         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, protoMask, 0, 0);
    221         if (nfaStat == NFA_STATUS_OK)
    222             mRoutingEvent.wait ();
    223         else
    224             ALOGE ("Fail to set default proto routing for IsoDep and T3T");
    225     }
    226     else
    227     {
    228         // Route Nfc-A to host if we don't have a SE
    229         techMask = NFA_TECHNOLOGY_MASK_A;
    230         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0)
    231         {
    232             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, techMask, 0, 0);
    233             if (nfaStat == NFA_STATUS_OK)
    234                 mRoutingEvent.wait ();
    235             else
    236                 ALOGE ("Fail to set default tech routing for Nfc-A");
    237         }
    238         // Default routing for IsoDep protocol
    239         protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
    240         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, protoMask, 0, 0);
    241         if (nfaStat == NFA_STATUS_OK)
    242             mRoutingEvent.wait ();
    243         else
    244             ALOGE ("Fail to set default proto routing for IsoDep");
    245 
    246         // Route Nfc-F to host if we don't have a SE
    247         techMask = NFA_TECHNOLOGY_MASK_F;
    248         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0)
    249         {
    250             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEeNfcF, techMask, 0, 0);
    251             if (nfaStat == NFA_STATUS_OK)
    252                 mRoutingEvent.wait ();
    253             else
    254                 ALOGE ("Fail to set default tech routing for Nfc-F");
    255         }
    256         // Default routing for T3T protocol
    257         protoMask = NFA_PROTOCOL_MASK_T3T;
    258         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEeNfcF, protoMask, 0, 0);
    259         if (nfaStat == NFA_STATUS_OK)
    260             mRoutingEvent.wait ();
    261         else
    262             ALOGE ("Fail to set default proto routing for T3T");
    263     }
    264 }
    265 
    266 void RoutingManager::disableRoutingToHost()
    267 {
    268     tNFA_STATUS nfaStat;
    269     tNFA_TECHNOLOGY_MASK techMask;
    270     SyncEventGuard guard (mRoutingEvent);
    271 
    272     // Set default routing at one time when the NFCEE IDs for Nfc-A and Nfc-F are same
    273     if (mDefaultEe == mDefaultEeNfcF)
    274     {
    275         // Default routing for Nfc-A/Nfc-F technology if we don't have a SE
    276         techMask = (mSeTechMask ^ (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F));
    277         if (techMask != 0)
    278         {
    279             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0);
    280             if (nfaStat == NFA_STATUS_OK)
    281                 mRoutingEvent.wait ();
    282             else
    283                 ALOGE ("Fail to set default tech routing for Nfc-A/Nfc-F");
    284         }
    285         // Default routing for IsoDep and T3T protocol
    286         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0);
    287         if (nfaStat == NFA_STATUS_OK)
    288             mRoutingEvent.wait ();
    289         else
    290             ALOGE ("Fail to set default proto routing for IsoDep and T3T");
    291     }
    292     else
    293     {
    294         // Default routing for Nfc-A technology if we don't have a SE
    295         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0)
    296         {
    297             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0);
    298             if (nfaStat == NFA_STATUS_OK)
    299                 mRoutingEvent.wait ();
    300             else
    301                 ALOGE ("Fail to set default tech routing for Nfc-A");
    302         }
    303         // Default routing for IsoDep protocol
    304         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0);
    305         if (nfaStat == NFA_STATUS_OK)
    306             mRoutingEvent.wait ();
    307         else
    308             ALOGE ("Fail to set default proto routing for IsoDep");
    309 
    310         // Default routing for Nfc-F technology if we don't have a SE
    311         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0)
    312         {
    313             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEeNfcF, 0, 0, 0);
    314             if (nfaStat == NFA_STATUS_OK)
    315                 mRoutingEvent.wait ();
    316             else
    317                 ALOGE ("Fail to set default tech routing for Nfc-F");
    318         }
    319         // Default routing for T3T protocol
    320         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEeNfcF, 0, 0, 0);
    321         if (nfaStat == NFA_STATUS_OK)
    322             mRoutingEvent.wait ();
    323         else
    324             ALOGE ("Fail to set default proto routing for T3T");
    325     }
    326 }
    327 
    328 bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route)
    329 {
    330     static const char fn [] = "RoutingManager::addAidRouting";
    331     ALOGD ("%s: enter", fn);
    332     tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01);
    333     if (nfaStat == NFA_STATUS_OK)
    334     {
    335         ALOGD ("%s: routed AID", fn);
    336         return true;
    337     } else
    338     {
    339         ALOGE ("%s: failed to route AID", fn);
    340         return false;
    341     }
    342 }
    343 
    344 bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen)
    345 {
    346     static const char fn [] = "RoutingManager::removeAidRouting";
    347     ALOGD ("%s: enter", fn);
    348     tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid);
    349     if (nfaStat == NFA_STATUS_OK)
    350     {
    351         ALOGD ("%s: removed AID", fn);
    352         return true;
    353     } else
    354     {
    355         ALOGE ("%s: failed to remove AID", fn);
    356         return false;
    357     }
    358 }
    359 
    360 bool RoutingManager::commitRouting()
    361 {
    362     static const char fn [] = "RoutingManager::commitRouting";
    363     tNFA_STATUS nfaStat = 0;
    364     ALOGD ("%s", fn);
    365     {
    366         SyncEventGuard guard (mEeUpdateEvent);
    367         nfaStat = NFA_EeUpdateNow();
    368         if (nfaStat == NFA_STATUS_OK)
    369         {
    370             mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT
    371         }
    372     }
    373     return (nfaStat == NFA_STATUS_OK);
    374 }
    375 
    376 void RoutingManager::onNfccShutdown ()
    377 {
    378     static const char fn [] = "RoutingManager:onNfccShutdown";
    379     if (mActiveSe == 0x00) return;
    380 
    381     tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
    382     UINT8 actualNumEe = MAX_NUM_EE;
    383     tNFA_EE_INFO eeInfo[MAX_NUM_EE];
    384 
    385     memset (&eeInfo, 0, sizeof(eeInfo));
    386     if ((nfaStat = NFA_EeGetInfo (&actualNumEe, eeInfo)) != NFA_STATUS_OK)
    387     {
    388         ALOGE ("%s: fail get info; error=0x%X", fn, nfaStat);
    389         return;
    390     }
    391     if (actualNumEe != 0)
    392     {
    393         for (UINT8 xx = 0; xx < actualNumEe; xx++)
    394         {
    395             if ((eeInfo[xx].num_interface != 0)
    396                 && (eeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS)
    397                 && (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE))
    398             {
    399                 ALOGD ("%s: Handle: 0x%04x Change Status Active to Inactive", fn, eeInfo[xx].ee_handle);
    400                 SyncEventGuard guard (mEeSetModeEvent);
    401                 if ((nfaStat = NFA_EeModeSet (eeInfo[xx].ee_handle, NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK)
    402                 {
    403                     mEeSetModeEvent.wait (); //wait for NFA_EE_MODE_SET_EVT
    404                 }
    405                 else
    406                 {
    407                     ALOGE ("Failed to set EE inactive");
    408                 }
    409             }
    410         }
    411     }
    412     else
    413     {
    414         ALOGD ("%s: No active EEs found", fn);
    415     }
    416 }
    417 
    418 void RoutingManager::notifyActivated (UINT8 technology)
    419 {
    420     JNIEnv* e = NULL;
    421     ScopedAttach attach(mNativeData->vm, &e);
    422     if (e == NULL)
    423     {
    424         ALOGE ("jni env is null");
    425         return;
    426     }
    427 
    428     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated, (int)technology);
    429     if (e->ExceptionCheck())
    430     {
    431         e->ExceptionClear();
    432         ALOGE ("fail notify");
    433     }
    434 }
    435 
    436 void RoutingManager::notifyDeactivated (UINT8 technology)
    437 {
    438     mRxDataBuffer.clear();
    439     JNIEnv* e = NULL;
    440     ScopedAttach attach(mNativeData->vm, &e);
    441     if (e == NULL)
    442     {
    443         ALOGE ("jni env is null");
    444         return;
    445     }
    446 
    447     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated, (int)technology);
    448     if (e->ExceptionCheck())
    449     {
    450         e->ExceptionClear();
    451         ALOGE ("fail notify");
    452     }
    453 }
    454 
    455 void RoutingManager::handleData (UINT8 technology, const UINT8* data, UINT32 dataLen, tNFA_STATUS status)
    456 {
    457     if (status == NFA_STATUS_CONTINUE)
    458     {
    459         if (dataLen > 0)
    460         {
    461             mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data; more to come
    462         }
    463         return; //expect another NFA_CE_DATA_EVT to come
    464     }
    465     else if (status == NFA_STATUS_OK)
    466     {
    467         if (dataLen > 0)
    468         {
    469             mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data
    470         }
    471         //entire data packet has been received; no more NFA_CE_DATA_EVT
    472     }
    473     else if (status == NFA_STATUS_FAILED)
    474     {
    475         ALOGE("RoutingManager::handleData: read data fail");
    476         goto TheEnd;
    477     }
    478 
    479     {
    480         JNIEnv* e = NULL;
    481         ScopedAttach attach(mNativeData->vm, &e);
    482         if (e == NULL)
    483         {
    484             ALOGE ("jni env is null");
    485             goto TheEnd;
    486         }
    487 
    488         ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(mRxDataBuffer.size()));
    489         if (dataJavaArray.get() == NULL)
    490         {
    491             ALOGE ("fail allocate array");
    492             goto TheEnd;
    493         }
    494 
    495         e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, mRxDataBuffer.size(),
    496                 (jbyte *)(&mRxDataBuffer[0]));
    497         if (e->ExceptionCheck())
    498         {
    499             e->ExceptionClear();
    500             ALOGE ("fail fill array");
    501             goto TheEnd;
    502         }
    503 
    504         e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData,
    505                 (int)technology, dataJavaArray.get());
    506         if (e->ExceptionCheck())
    507         {
    508             e->ExceptionClear();
    509             ALOGE ("fail notify");
    510         }
    511     }
    512 TheEnd:
    513     mRxDataBuffer.clear();
    514 }
    515 
    516 void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
    517 {
    518     static const char fn [] = "RoutingManager::stackCallback";
    519     ALOGD("%s: event=0x%X", fn, event);
    520     RoutingManager& routingManager = RoutingManager::getInstance();
    521 
    522     switch (event)
    523     {
    524     case NFA_CE_REGISTERED_EVT:
    525         {
    526             tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
    527             ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
    528         }
    529         break;
    530 
    531     case NFA_CE_DEREGISTERED_EVT:
    532         {
    533             tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
    534             ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
    535         }
    536         break;
    537 
    538     case NFA_CE_ACTIVATED_EVT:
    539         {
    540             routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_A);
    541         }
    542         break;
    543 
    544     case NFA_DEACTIVATED_EVT:
    545     case NFA_CE_DEACTIVATED_EVT:
    546         {
    547             ALOGD("%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn);
    548             routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_A);
    549             SyncEventGuard g (gDeactivatedEvent);
    550             gActivated = false; //guard this variable from multi-threaded access
    551             gDeactivatedEvent.notifyOne ();
    552         }
    553         break;
    554 
    555     case NFA_CE_DATA_EVT:
    556         {
    557             tNFA_CE_DATA& ce_data = eventData->ce_data;
    558             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);
    559             getInstance().handleData(NFA_TECHNOLOGY_MASK_A, ce_data.p_data, ce_data.len, ce_data.status);
    560         }
    561         break;
    562     }
    563 }
    564 /*******************************************************************************
    565 **
    566 ** Function:        nfaEeCallback
    567 **
    568 ** Description:     Receive execution environment-related events from stack.
    569 **                  event: Event code.
    570 **                  eventData: Event data.
    571 **
    572 ** Returns:         None
    573 **
    574 *******************************************************************************/
    575 void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
    576 {
    577     static const char fn [] = "RoutingManager::nfaEeCallback";
    578 
    579     RoutingManager& routingManager = RoutingManager::getInstance();
    580 
    581     switch (event)
    582     {
    583     case NFA_EE_REGISTER_EVT:
    584         {
    585             SyncEventGuard guard (routingManager.mEeRegisterEvent);
    586             ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
    587             routingManager.mEeRegisterEvent.notifyOne();
    588         }
    589         break;
    590 
    591     case NFA_EE_MODE_SET_EVT:
    592         {
    593             SyncEventGuard guard (routingManager.mEeSetModeEvent);
    594             ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  ", fn,
    595                     eventData->mode_set.status, eventData->mode_set.ee_handle);
    596             routingManager.mEeSetModeEvent.notifyOne();
    597         }
    598         break;
    599 
    600     case NFA_EE_SET_TECH_CFG_EVT:
    601         {
    602             ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
    603             SyncEventGuard guard(routingManager.mRoutingEvent);
    604             routingManager.mRoutingEvent.notifyOne();
    605         }
    606         break;
    607 
    608     case NFA_EE_SET_PROTO_CFG_EVT:
    609         {
    610             ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
    611             SyncEventGuard guard(routingManager.mRoutingEvent);
    612             routingManager.mRoutingEvent.notifyOne();
    613         }
    614         break;
    615 
    616     case NFA_EE_ACTION_EVT:
    617         {
    618             tNFA_EE_ACTION& action = eventData->action;
    619             if (action.trigger == NFC_EE_TRIG_SELECT)
    620                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger);
    621             else if (action.trigger == NFC_EE_TRIG_APP_INIT)
    622             {
    623                 tNFC_APP_INIT& app_init = action.param.app_init;
    624                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn,
    625                         action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data);
    626             }
    627             else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
    628                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger);
    629             else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
    630                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger);
    631             else
    632                 ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger);
    633         }
    634         break;
    635 
    636     case NFA_EE_DISCOVER_REQ_EVT:
    637         {
    638             ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__,
    639                     eventData->discover_req.status, eventData->discover_req.num_ee);
    640             SyncEventGuard guard (routingManager.mEeInfoEvent);
    641             memcpy (&routingManager.mEeInfo, &eventData->discover_req, sizeof(routingManager.mEeInfo));
    642             routingManager.mReceivedEeInfo = true;
    643             routingManager.mEeInfoEvent.notifyOne();
    644         }
    645         break;
    646 
    647     case NFA_EE_NO_CB_ERR_EVT:
    648         ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
    649         break;
    650 
    651     case NFA_EE_ADD_AID_EVT:
    652         {
    653             ALOGD ("%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
    654         }
    655         break;
    656 
    657     case NFA_EE_REMOVE_AID_EVT:
    658         {
    659             ALOGD ("%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
    660         }
    661         break;
    662 
    663     case NFA_EE_NEW_EE_EVT:
    664         {
    665             ALOGD ("%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
    666                 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
    667         }
    668         break;
    669 
    670     case NFA_EE_UPDATED_EVT:
    671         {
    672             ALOGD("%s: NFA_EE_UPDATED_EVT", fn);
    673             SyncEventGuard guard(routingManager.mEeUpdateEvent);
    674             routingManager.mEeUpdateEvent.notifyOne();
    675         }
    676         break;
    677 
    678     default:
    679         ALOGE ("%s: unknown event=%u ????", fn, event);
    680         break;
    681     }
    682 }
    683 
    684 int RoutingManager::registerT3tIdentifier(UINT8* t3tId, UINT8 t3tIdLen)
    685 {
    686     static const char fn [] = "RoutingManager::registerT3tIdentifier";
    687 
    688     ALOGD ("%s: Start to register NFC-F system on DH", fn);
    689 
    690     if (t3tIdLen != (2 + NCI_RF_F_UID_LEN))
    691     {
    692         ALOGE ("%s: Invalid length of T3T Identifier", fn);
    693         return NFA_HANDLE_INVALID;
    694     }
    695 
    696     SyncEventGuard guard (mRoutingEvent);
    697     mNfcFOnDhHandle = NFA_HANDLE_INVALID;
    698 
    699     int systemCode;
    700     UINT8 nfcid2[NCI_RF_F_UID_LEN];
    701 
    702     systemCode = (((int)t3tId[0] << 8) | ((int)t3tId[1] << 0));
    703     memcpy(nfcid2, t3tId + 2, NCI_RF_F_UID_LEN);
    704 
    705     tNFA_STATUS nfaStat = NFA_CeRegisterFelicaSystemCodeOnDH (systemCode, nfcid2, nfcFCeCallback);
    706     if (nfaStat == NFA_STATUS_OK)
    707     {
    708         mRoutingEvent.wait ();
    709     }
    710     else
    711     {
    712         ALOGE ("%s: Fail to register NFC-F system on DH", fn);
    713         return NFA_HANDLE_INVALID;
    714     }
    715 
    716     ALOGD ("%s: Succeed to register NFC-F system on DH", fn);
    717 
    718     return mNfcFOnDhHandle;
    719 }
    720 
    721 void RoutingManager::deregisterT3tIdentifier(int handle)
    722 {
    723     static const char fn [] = "RoutingManager::deregisterT3tIdentifier";
    724 
    725     ALOGD ("%s: Start to deregister NFC-F system on DH", fn);
    726 
    727     SyncEventGuard guard (mRoutingEvent);
    728     tNFA_STATUS nfaStat = NFA_CeDeregisterFelicaSystemCodeOnDH (handle);
    729     if (nfaStat == NFA_STATUS_OK)
    730     {
    731         mRoutingEvent.wait ();
    732         ALOGD ("%s: Succeeded in deregistering NFC-F system on DH", fn);
    733     }
    734     else
    735     {
    736         ALOGE ("%s: Fail to deregister NFC-F system on DH", fn);
    737     }
    738 }
    739 
    740 void RoutingManager::nfcFCeCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
    741 {
    742     static const char fn [] = "RoutingManager::nfcFCeCallback";
    743     RoutingManager& routingManager = RoutingManager::getInstance();
    744 
    745     ALOGD("%s: 0x%x", __FUNCTION__, event);
    746 
    747     switch (event)
    748     {
    749     case NFA_CE_REGISTERED_EVT:
    750         {
    751             ALOGD ("%s: registerd event notified", fn);
    752             routingManager.mNfcFOnDhHandle = eventData->ce_registered.handle;
    753             SyncEventGuard guard(routingManager.mRoutingEvent);
    754             routingManager.mRoutingEvent.notifyOne();
    755         }
    756         break;
    757     case NFA_CE_DEREGISTERED_EVT:
    758         {
    759             ALOGD ("%s: deregisterd event notified", fn);
    760             SyncEventGuard guard(routingManager.mRoutingEvent);
    761             routingManager.mRoutingEvent.notifyOne();
    762         }
    763         break;
    764     case NFA_CE_ACTIVATED_EVT:
    765         {
    766             ALOGD ("%s: activated event notified", fn);
    767             routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_F);
    768         }
    769         break;
    770     case NFA_CE_DEACTIVATED_EVT:
    771         {
    772             ALOGD ("%s: deactivated event notified", fn);
    773             routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_F);
    774         }
    775         break;
    776     case NFA_CE_DATA_EVT:
    777         {
    778             ALOGD ("%s: data event notified", fn);
    779             tNFA_CE_DATA& ce_data = eventData->ce_data;
    780             routingManager.handleData(NFA_TECHNOLOGY_MASK_F, ce_data.p_data, ce_data.len, ce_data.status);
    781         }
    782         break;
    783     default:
    784         {
    785             ALOGE ("%s: unknown event=%u ????", fn, event);
    786         }
    787         break;
    788     }
    789 }
    790 
    791 int RoutingManager::registerJniFunctions (JNIEnv* e)
    792 {
    793     static const char fn [] = "RoutingManager::registerJniFunctions";
    794     ALOGD ("%s", fn);
    795     return jniRegisterNativeMethods (e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods, NELEM(sMethods));
    796 }
    797 
    798 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination (JNIEnv*)
    799 {
    800     return getInstance().mDefaultEe;
    801 }
    802 
    803 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination (JNIEnv*)
    804 {
    805     return getInstance().mOffHostEe;
    806 }
    807 
    808 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode (JNIEnv*)
    809 {
    810     return getInstance().mAidMatchingMode;
    811 }
    812