Home | History | Annotate | Download | only in jni
      1 
      2 /*
      3  * Copyright (C) 2013 The Android Open Source Project
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 /*
     19  *  Manage the listen-mode routing table.
     20  */
     21 
     22 #include <cutils/log.h>
     23 #include <ScopedLocalRef.h>
     24 #include "config.h"
     25 #include "JavaClassConstants.h"
     26 #include "RoutingManager.h"
     27 
     28 RoutingManager::RoutingManager ()
     29 {
     30 }
     31 
     32 RoutingManager::~RoutingManager ()
     33 {
     34     NFA_EeDeregister (nfaEeCallback);
     35 }
     36 
     37 bool RoutingManager::initialize (nfc_jni_native_data* native)
     38 {
     39     static const char fn [] = "RoutingManager::initialize()";
     40     unsigned long num = 0;
     41     mNativeData = native;
     42 
     43     tNFA_STATUS nfaStat;
     44     {
     45         SyncEventGuard guard (mEeRegisterEvent);
     46         ALOGD ("%s: try ee register", fn);
     47         nfaStat = NFA_EeRegister (nfaEeCallback);
     48         if (nfaStat != NFA_STATUS_OK)
     49         {
     50             ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat);
     51             return false;
     52         }
     53         mEeRegisterEvent.wait ();
     54     }
     55 
     56     // Get the "default" route
     57     if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num)))
     58         mDefaultEe = num;
     59     else
     60         mDefaultEe = 0x00;
     61 
     62     ALOGD("%s: default route is 0x%02X", fn, mDefaultEe);
     63     setDefaultRouting();
     64     return true;
     65 }
     66 
     67 RoutingManager& RoutingManager::getInstance ()
     68 {
     69     static RoutingManager manager;
     70     return manager;
     71 }
     72 
     73 void RoutingManager::setDefaultRouting()
     74 {
     75     tNFA_STATUS nfaStat;
     76     SyncEventGuard guard (mRoutingEvent);
     77     // Default routing for NFC-A technology
     78     nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0x01, 0, 0);
     79     if (nfaStat == NFA_STATUS_OK)
     80         mRoutingEvent.wait ();
     81     else
     82         ALOGE ("Fail to set default tech routing");
     83 
     84     // Default routing for IsoDep protocol
     85     nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0);
     86     if (nfaStat == NFA_STATUS_OK)
     87         mRoutingEvent.wait ();
     88     else
     89         ALOGE ("Fail to set default proto routing");
     90 
     91     // Tell the UICC to only listen on Nfc-A
     92     nfaStat = NFA_CeConfigureUiccListenTech (mDefaultEe, 0x01);
     93     if (nfaStat != NFA_STATUS_OK)
     94         ALOGE ("Failed to configure UICC listen technologies");
     95 
     96     // Tell the host-routing to only listen on Nfc-A
     97     nfaStat = NFA_CeSetIsoDepListenTech(0x01);
     98     if (nfaStat != NFA_STATUS_OK)
     99         ALOGE ("Failed to configure CE IsoDep technologies");
    100 
    101     // Register a wild-card for AIDs routed to the host
    102     nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
    103     if (nfaStat != NFA_STATUS_OK)
    104         ALOGE("Failed to register wildcard AID for DH");
    105 
    106     // Commit the routing configuration
    107     nfaStat = NFA_EeUpdateNow();
    108     if (nfaStat != NFA_STATUS_OK)
    109         ALOGE("Failed to commit routing configuration");
    110 }
    111 
    112 bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route)
    113 {
    114     static const char fn [] = "RoutingManager::addAidRouting";
    115     ALOGD ("%s: enter", fn);
    116     tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01);
    117     if (nfaStat == NFA_STATUS_OK)
    118     {
    119         ALOGD ("%s: routed AID", fn);
    120         return true;
    121     } else
    122     {
    123         ALOGE ("%s: failed to route AID", fn);
    124         return false;
    125     }
    126 }
    127 
    128 bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen)
    129 {
    130     static const char fn [] = "RoutingManager::removeAidRouting";
    131     ALOGD ("%s: enter", fn);
    132     tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid);
    133     if (nfaStat == NFA_STATUS_OK)
    134     {
    135         ALOGD ("%s: removed AID", fn);
    136         return true;
    137     } else
    138     {
    139         ALOGE ("%s: failed to remove AID", fn);
    140         return false;
    141     }
    142 }
    143 
    144 bool RoutingManager::commitRouting()
    145 {
    146     tNFA_STATUS nfaStat = NFA_EeUpdateNow();
    147     return (nfaStat == NFA_STATUS_OK);
    148 }
    149 
    150 void RoutingManager::notifyActivated ()
    151 {
    152     JNIEnv* e = NULL;
    153     ScopedAttach attach(mNativeData->vm, &e);
    154     if (e == NULL)
    155     {
    156         ALOGE ("jni env is null");
    157         return;
    158     }
    159 
    160     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated);
    161     if (e->ExceptionCheck())
    162     {
    163         e->ExceptionClear();
    164         ALOGE ("fail notify");
    165     }
    166 }
    167 
    168 void RoutingManager::notifyDeactivated ()
    169 {
    170     SecureElement::getInstance().notifyListenModeState (false);
    171 
    172     JNIEnv* e = NULL;
    173     ScopedAttach attach(mNativeData->vm, &e);
    174     if (e == NULL)
    175     {
    176         ALOGE ("jni env is null");
    177         return;
    178     }
    179 
    180     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated);
    181     if (e->ExceptionCheck())
    182     {
    183         e->ExceptionClear();
    184         ALOGE ("fail notify");
    185     }
    186 }
    187 
    188 void RoutingManager::handleData (const UINT8* data, UINT8 dataLen)
    189 {
    190     if (dataLen <= 0)
    191     {
    192         ALOGE("no data");
    193         return;
    194     }
    195 
    196     JNIEnv* e = NULL;
    197     ScopedAttach attach(mNativeData->vm, &e);
    198     if (e == NULL)
    199     {
    200         ALOGE ("jni env is null");
    201         return;
    202     }
    203 
    204     ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(dataLen));
    205     if (dataJavaArray.get() == NULL)
    206     {
    207         ALOGE ("fail allocate array");
    208         return;
    209     }
    210 
    211     e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, dataLen, (jbyte *)data);
    212     if (e->ExceptionCheck())
    213     {
    214         e->ExceptionClear();
    215         ALOGE ("fail fill array");
    216         return;
    217     }
    218 
    219     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData, dataJavaArray.get());
    220     if (e->ExceptionCheck())
    221     {
    222         e->ExceptionClear();
    223         ALOGE ("fail notify");
    224     }
    225 }
    226 
    227 void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
    228 {
    229     static const char fn [] = "RoutingManager::stackCallback";
    230     ALOGD("%s: event=0x%X", fn, event);
    231     RoutingManager& routingManager = RoutingManager::getInstance();
    232 
    233     switch (event)
    234     {
    235     case NFA_CE_REGISTERED_EVT:
    236         {
    237             tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
    238             ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
    239         }
    240         break;
    241 
    242     case NFA_CE_DEREGISTERED_EVT:
    243         {
    244             tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
    245             ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
    246         }
    247         break;
    248 
    249     case NFA_CE_ACTIVATED_EVT:
    250         {
    251             routingManager.notifyActivated();
    252         }
    253         break;
    254     case NFA_DEACTIVATED_EVT:
    255     case NFA_CE_DEACTIVATED_EVT:
    256         {
    257             routingManager.notifyDeactivated();
    258         }
    259         break;
    260     case NFA_CE_DATA_EVT:
    261         {
    262             tNFA_CE_DATA& ce_data = eventData->ce_data;
    263             ALOGD("%s: NFA_CE_DATA_EVT; h=0x%X; data len=%u", fn, ce_data.handle, ce_data.len);
    264             getInstance().handleData(ce_data.p_data, ce_data.len);
    265         }
    266         break;
    267     }
    268 
    269 }
    270 /*******************************************************************************
    271 **
    272 ** Function:        nfaEeCallback
    273 **
    274 ** Description:     Receive execution environment-related events from stack.
    275 **                  event: Event code.
    276 **                  eventData: Event data.
    277 **
    278 ** Returns:         None
    279 **
    280 *******************************************************************************/
    281 void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
    282 {
    283     static const char fn [] = "RoutingManager::nfaEeCallback";
    284 
    285     SecureElement& se = SecureElement::getInstance();
    286     RoutingManager& routingManager = RoutingManager::getInstance();
    287 
    288     switch (event)
    289     {
    290     case NFA_EE_REGISTER_EVT:
    291         {
    292             SyncEventGuard guard (routingManager.mEeRegisterEvent);
    293             ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
    294             routingManager.mEeRegisterEvent.notifyOne();
    295         }
    296         break;
    297 
    298     case NFA_EE_MODE_SET_EVT:
    299         {
    300             ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  mActiveEeHandle: 0x%04X", fn,
    301                     eventData->mode_set.status, eventData->mode_set.ee_handle, se.mActiveEeHandle);
    302             se.notifyModeSet(eventData->mode_set.ee_handle, eventData->mode_set.status);
    303         }
    304         break;
    305 
    306     case NFA_EE_SET_TECH_CFG_EVT:
    307         {
    308             ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
    309             SyncEventGuard guard(routingManager.mRoutingEvent);
    310             routingManager.mRoutingEvent.notifyOne();
    311         }
    312         break;
    313 
    314     case NFA_EE_SET_PROTO_CFG_EVT:
    315         {
    316             ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
    317             SyncEventGuard guard(routingManager.mRoutingEvent);
    318             routingManager.mRoutingEvent.notifyOne();
    319         }
    320         break;
    321 
    322     case NFA_EE_ACTION_EVT:
    323         {
    324             tNFA_EE_ACTION& action = eventData->action;
    325             if (action.trigger == NFC_EE_TRIG_SELECT)
    326                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger);
    327             else if (action.trigger == NFC_EE_TRIG_APP_INIT)
    328             {
    329                 tNFC_APP_INIT& app_init = action.param.app_init;
    330                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn,
    331                         action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data);
    332                 //if app-init operation is successful;
    333                 //app_init.data[] contains two bytes, which are the status codes of the event;
    334                 //app_init.data[] does not contain an APDU response;
    335                 //see EMV Contactless Specification for Payment Systems; Book B; Entry Point Specification;
    336                 //version 2.1; March 2011; section 3.3.3.5;
    337                 if ( (app_init.len_data > 1) &&
    338                      (app_init.data[0] == 0x90) &&
    339                      (app_init.data[1] == 0x00) )
    340                 {
    341                     se.notifyTransactionListenersOfAid (app_init.aid, app_init.len_aid);
    342                 }
    343             }
    344             else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
    345                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger);
    346             else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
    347                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger);
    348             else
    349                 ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger);
    350         }
    351         break;
    352 
    353     case NFA_EE_DISCOVER_REQ_EVT:
    354         ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__,
    355                 eventData->discover_req.status, eventData->discover_req.num_ee);
    356         break;
    357 
    358     case NFA_EE_NO_CB_ERR_EVT:
    359         ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
    360         break;
    361 
    362     case NFA_EE_ADD_AID_EVT:
    363         {
    364             ALOGD ("%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
    365         }
    366         break;
    367 
    368     case NFA_EE_REMOVE_AID_EVT:
    369         {
    370             ALOGD ("%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
    371         }
    372         break;
    373 
    374     case NFA_EE_NEW_EE_EVT:
    375         {
    376             ALOGD ("%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
    377                 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
    378         }
    379         break;
    380 
    381     default:
    382         ALOGE ("%s: unknown event=%u ????", fn, event);
    383         break;
    384     }
    385 }
    386