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