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