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"); 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"); 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