1 /* 2 * Copyright (C) 2013 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * Manage the listen-mode routing table. 19 */ 20 21 #include <cutils/log.h> 22 #include <ScopedLocalRef.h> 23 #include <JNIHelp.h> 24 #include "config.h" 25 #include "JavaClassConstants.h" 26 #include "RoutingManager.h" 27 28 extern "C" 29 { 30 #include "nfa_ee_api.h" 31 #include "nfa_ce_api.h" 32 } 33 extern bool gActivated; 34 extern SyncEvent gDeactivatedEvent; 35 36 37 const JNINativeMethod RoutingManager::sMethods [] = 38 { 39 {"doGetDefaultRouteDestination", "()I", (void*) RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination}, 40 {"doGetDefaultOffHostRouteDestination", "()I", (void*) RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination}, 41 {"doGetAidMatchingMode", "()I", (void*) RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode} 42 }; 43 44 static const int MAX_NUM_EE = 5; 45 46 RoutingManager::RoutingManager () 47 { 48 static const char fn [] = "RoutingManager::RoutingManager()"; 49 unsigned long num = 0; 50 51 // Get the active SE 52 if (GetNumValue("ACTIVE_SE", &num, sizeof(num))) 53 mActiveSe = num; 54 else 55 mActiveSe = 0x00; 56 57 // Get the "default" route 58 if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num))) 59 mDefaultEe = num; 60 else 61 mDefaultEe = 0x00; 62 ALOGD("%s: default route is 0x%02X", fn, mDefaultEe); 63 64 // Get the default "off-host" route. This is hard-coded at the Java layer 65 // but we can override it here to avoid forcing Java changes. 66 if (GetNumValue("DEFAULT_OFFHOST_ROUTE", &num, sizeof(num))) 67 mOffHostEe = num; 68 else 69 mOffHostEe = 0xf4; 70 71 if (GetNumValue("AID_MATCHING_MODE", &num, sizeof(num))) 72 mAidMatchingMode = num; 73 else 74 mAidMatchingMode = AID_MATCHING_EXACT_ONLY; 75 76 ALOGD("%s: mOffHostEe=0x%02X", fn, mOffHostEe); 77 78 memset (&mEeInfo, 0, sizeof(mEeInfo)); 79 mReceivedEeInfo = false; 80 mSeTechMask = 0x00; 81 } 82 83 RoutingManager::~RoutingManager () 84 { 85 NFA_EeDeregister (nfaEeCallback); 86 } 87 88 bool RoutingManager::initialize (nfc_jni_native_data* native) 89 { 90 static const char fn [] = "RoutingManager::initialize()"; 91 mNativeData = native; 92 93 tNFA_STATUS nfaStat; 94 { 95 SyncEventGuard guard (mEeRegisterEvent); 96 ALOGD ("%s: try ee register", fn); 97 nfaStat = NFA_EeRegister (nfaEeCallback); 98 if (nfaStat != NFA_STATUS_OK) 99 { 100 ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat); 101 return false; 102 } 103 mEeRegisterEvent.wait (); 104 } 105 106 mRxDataBuffer.clear (); 107 108 if (mActiveSe != 0) { 109 { 110 // Wait for EE info if needed 111 SyncEventGuard guard (mEeInfoEvent); 112 if (!mReceivedEeInfo) 113 { 114 ALOGE("Waiting for EE info"); 115 mEeInfoEvent.wait(); 116 } 117 } 118 for (UINT8 i = 0; i < mEeInfo.num_ee; i++) 119 { 120 ALOGD ("%s EE[%u] Handle: 0x%04x techA: 0x%02x techB: 0x%02x techF: 0x%02x techBprime: 0x%02x", 121 fn, i, mEeInfo.ee_disc_info[i].ee_handle, 122 mEeInfo.ee_disc_info[i].la_protocol, 123 mEeInfo.ee_disc_info[i].lb_protocol, 124 mEeInfo.ee_disc_info[i].lf_protocol, 125 mEeInfo.ee_disc_info[i].lbp_protocol); 126 if (mEeInfo.ee_disc_info[i].ee_handle == (mActiveSe | NFA_HANDLE_GROUP_EE)) 127 { 128 if (mEeInfo.ee_disc_info[i].la_protocol != 0) mSeTechMask |= NFA_TECHNOLOGY_MASK_A; 129 130 if (mSeTechMask != 0x00) 131 { 132 ALOGD("Configuring tech mask 0x%02x on EE 0x%04x", mSeTechMask, mEeInfo.ee_disc_info[i].ee_handle); 133 nfaStat = NFA_CeConfigureUiccListenTech(mEeInfo.ee_disc_info[i].ee_handle, mSeTechMask); 134 if (nfaStat != NFA_STATUS_OK) 135 ALOGE ("Failed to configure UICC listen technologies."); 136 // Set technology routes to UICC if it's there 137 nfaStat = NFA_EeSetDefaultTechRouting(mEeInfo.ee_disc_info[i].ee_handle, mSeTechMask, mSeTechMask, 138 mSeTechMask); 139 if (nfaStat != NFA_STATUS_OK) 140 ALOGE ("Failed to configure UICC technology routing."); 141 } 142 } 143 } 144 } 145 146 // Tell the host-routing to only listen on Nfc-A 147 nfaStat = NFA_CeSetIsoDepListenTech(NFA_TECHNOLOGY_MASK_A); 148 if (nfaStat != NFA_STATUS_OK) 149 ALOGE ("Failed to configure CE IsoDep technologies"); 150 151 // Register a wild-card for AIDs routed to the host 152 nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback); 153 if (nfaStat != NFA_STATUS_OK) 154 ALOGE("Failed to register wildcard AID for DH"); 155 156 return true; 157 } 158 159 RoutingManager& RoutingManager::getInstance () 160 { 161 static RoutingManager manager; 162 return manager; 163 } 164 165 void RoutingManager::enableRoutingToHost() 166 { 167 tNFA_STATUS nfaStat; 168 169 { 170 SyncEventGuard guard (mRoutingEvent); 171 172 // Route Nfc-A to host if we don't have a SE 173 if (mSeTechMask == 0) 174 { 175 nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, NFA_TECHNOLOGY_MASK_A, 0, 0); 176 if (nfaStat == NFA_STATUS_OK) 177 mRoutingEvent.wait (); 178 else 179 ALOGE ("Fail to set default tech routing"); 180 } 181 182 // Default routing for IsoDep protocol 183 nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0); 184 if (nfaStat == NFA_STATUS_OK) 185 mRoutingEvent.wait (); 186 else 187 ALOGE ("Fail to set default proto routing"); 188 } 189 } 190 191 void RoutingManager::disableRoutingToHost() 192 { 193 tNFA_STATUS nfaStat; 194 195 { 196 SyncEventGuard guard (mRoutingEvent); 197 // Default routing for NFC-A technology if we don't have a SE 198 if (mSeTechMask == 0) 199 { 200 nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0); 201 if (nfaStat == NFA_STATUS_OK) 202 mRoutingEvent.wait (); 203 else 204 ALOGE ("Fail to set default tech routing"); 205 } 206 207 // Default routing for IsoDep protocol 208 nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0); 209 if (nfaStat == NFA_STATUS_OK) 210 mRoutingEvent.wait (); 211 else 212 ALOGE ("Fail to set default proto routing"); 213 } 214 } 215 216 bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route) 217 { 218 static const char fn [] = "RoutingManager::addAidRouting"; 219 ALOGD ("%s: enter", fn); 220 tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01); 221 if (nfaStat == NFA_STATUS_OK) 222 { 223 ALOGD ("%s: routed AID", fn); 224 return true; 225 } else 226 { 227 ALOGE ("%s: failed to route AID", fn); 228 return false; 229 } 230 } 231 232 bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen) 233 { 234 static const char fn [] = "RoutingManager::removeAidRouting"; 235 ALOGD ("%s: enter", fn); 236 tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid); 237 if (nfaStat == NFA_STATUS_OK) 238 { 239 ALOGD ("%s: removed AID", fn); 240 return true; 241 } else 242 { 243 ALOGE ("%s: failed to remove AID", fn); 244 return false; 245 } 246 } 247 248 bool RoutingManager::commitRouting() 249 { 250 static const char fn [] = "RoutingManager::commitRouting"; 251 tNFA_STATUS nfaStat = 0; 252 ALOGD ("%s", fn); 253 { 254 SyncEventGuard guard (mEeUpdateEvent); 255 nfaStat = NFA_EeUpdateNow(); 256 if (nfaStat == NFA_STATUS_OK) 257 { 258 mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT 259 } 260 } 261 return (nfaStat == NFA_STATUS_OK); 262 } 263 264 void RoutingManager::onNfccShutdown () 265 { 266 static const char fn [] = "RoutingManager:onNfccShutdown"; 267 if (mActiveSe == 0x00) return; 268 269 tNFA_STATUS nfaStat = NFA_STATUS_FAILED; 270 UINT8 actualNumEe = MAX_NUM_EE; 271 tNFA_EE_INFO eeInfo[MAX_NUM_EE]; 272 273 memset (&eeInfo, 0, sizeof(eeInfo)); 274 if ((nfaStat = NFA_EeGetInfo (&actualNumEe, eeInfo)) != NFA_STATUS_OK) 275 { 276 ALOGE ("%s: fail get info; error=0x%X", fn, nfaStat); 277 return; 278 } 279 if (actualNumEe != 0) 280 { 281 for (UINT8 xx = 0; xx < actualNumEe; xx++) 282 { 283 if ((eeInfo[xx].num_interface != 0) 284 && (eeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) 285 && (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE)) 286 { 287 ALOGD ("%s: Handle: 0x%04x Change Status Active to Inactive", fn, eeInfo[xx].ee_handle); 288 SyncEventGuard guard (mEeSetModeEvent); 289 if ((nfaStat = NFA_EeModeSet (eeInfo[xx].ee_handle, NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK) 290 { 291 mEeSetModeEvent.wait (); //wait for NFA_EE_MODE_SET_EVT 292 } 293 else 294 { 295 ALOGE ("Failed to set EE inactive"); 296 } 297 } 298 } 299 } 300 else 301 { 302 ALOGD ("%s: No active EEs found", fn); 303 } 304 } 305 306 void RoutingManager::notifyActivated () 307 { 308 JNIEnv* e = NULL; 309 ScopedAttach attach(mNativeData->vm, &e); 310 if (e == NULL) 311 { 312 ALOGE ("jni env is null"); 313 return; 314 } 315 316 e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated); 317 if (e->ExceptionCheck()) 318 { 319 e->ExceptionClear(); 320 ALOGE ("fail notify"); 321 } 322 } 323 324 void RoutingManager::notifyDeactivated () 325 { 326 mRxDataBuffer.clear(); 327 JNIEnv* e = NULL; 328 ScopedAttach attach(mNativeData->vm, &e); 329 if (e == NULL) 330 { 331 ALOGE ("jni env is null"); 332 return; 333 } 334 335 e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated); 336 if (e->ExceptionCheck()) 337 { 338 e->ExceptionClear(); 339 ALOGE ("fail notify"); 340 } 341 } 342 343 void RoutingManager::handleData (const UINT8* data, UINT32 dataLen, tNFA_STATUS status) 344 { 345 if (dataLen <= 0) 346 { 347 ALOGE("no data"); 348 goto TheEnd; 349 } 350 351 if (status == NFA_STATUS_CONTINUE) 352 { 353 mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data; more to come 354 return; //expect another NFA_CE_DATA_EVT to come 355 } 356 else if (status == NFA_STATUS_OK) 357 { 358 mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data 359 //entire data packet has been received; no more NFA_CE_DATA_EVT 360 } 361 else if (status == NFA_STATUS_FAILED) 362 { 363 ALOGE("RoutingManager::handleData: read data fail"); 364 goto TheEnd; 365 } 366 367 { 368 JNIEnv* e = NULL; 369 ScopedAttach attach(mNativeData->vm, &e); 370 if (e == NULL) 371 { 372 ALOGE ("jni env is null"); 373 goto TheEnd; 374 } 375 376 ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(mRxDataBuffer.size())); 377 if (dataJavaArray.get() == NULL) 378 { 379 ALOGE ("fail allocate array"); 380 goto TheEnd; 381 } 382 383 e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, mRxDataBuffer.size(), 384 (jbyte *)(&mRxDataBuffer[0])); 385 if (e->ExceptionCheck()) 386 { 387 e->ExceptionClear(); 388 ALOGE ("fail fill array"); 389 goto TheEnd; 390 } 391 392 e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData, dataJavaArray.get()); 393 if (e->ExceptionCheck()) 394 { 395 e->ExceptionClear(); 396 ALOGE ("fail notify"); 397 } 398 } 399 TheEnd: 400 mRxDataBuffer.clear(); 401 } 402 403 void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData) 404 { 405 static const char fn [] = "RoutingManager::stackCallback"; 406 ALOGD("%s: event=0x%X", fn, event); 407 RoutingManager& routingManager = RoutingManager::getInstance(); 408 409 switch (event) 410 { 411 case NFA_CE_REGISTERED_EVT: 412 { 413 tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered; 414 ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle); 415 } 416 break; 417 418 case NFA_CE_DEREGISTERED_EVT: 419 { 420 tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered; 421 ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle); 422 } 423 break; 424 425 case NFA_CE_ACTIVATED_EVT: 426 { 427 routingManager.notifyActivated(); 428 } 429 break; 430 431 case NFA_DEACTIVATED_EVT: 432 case NFA_CE_DEACTIVATED_EVT: 433 { 434 ALOGD("%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn); 435 routingManager.notifyDeactivated(); 436 SyncEventGuard g (gDeactivatedEvent); 437 gActivated = false; //guard this variable from multi-threaded access 438 gDeactivatedEvent.notifyOne (); 439 } 440 break; 441 442 case NFA_CE_DATA_EVT: 443 { 444 tNFA_CE_DATA& ce_data = eventData->ce_data; 445 ALOGD("%s: NFA_CE_DATA_EVT; stat=0x%X; h=0x%X; data len=%u", fn, ce_data.status, ce_data.handle, ce_data.len); 446 getInstance().handleData(ce_data.p_data, ce_data.len, ce_data.status); 447 } 448 break; 449 } 450 } 451 /******************************************************************************* 452 ** 453 ** Function: nfaEeCallback 454 ** 455 ** Description: Receive execution environment-related events from stack. 456 ** event: Event code. 457 ** eventData: Event data. 458 ** 459 ** Returns: None 460 ** 461 *******************************************************************************/ 462 void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData) 463 { 464 static const char fn [] = "RoutingManager::nfaEeCallback"; 465 466 RoutingManager& routingManager = RoutingManager::getInstance(); 467 468 switch (event) 469 { 470 case NFA_EE_REGISTER_EVT: 471 { 472 SyncEventGuard guard (routingManager.mEeRegisterEvent); 473 ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register); 474 routingManager.mEeRegisterEvent.notifyOne(); 475 } 476 break; 477 478 case NFA_EE_MODE_SET_EVT: 479 { 480 SyncEventGuard guard (routingManager.mEeSetModeEvent); 481 ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X handle: 0x%04X ", fn, 482 eventData->mode_set.status, eventData->mode_set.ee_handle); 483 routingManager.mEeSetModeEvent.notifyOne(); 484 } 485 break; 486 487 case NFA_EE_SET_TECH_CFG_EVT: 488 { 489 ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status); 490 SyncEventGuard guard(routingManager.mRoutingEvent); 491 routingManager.mRoutingEvent.notifyOne(); 492 } 493 break; 494 495 case NFA_EE_SET_PROTO_CFG_EVT: 496 { 497 ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status); 498 SyncEventGuard guard(routingManager.mRoutingEvent); 499 routingManager.mRoutingEvent.notifyOne(); 500 } 501 break; 502 503 case NFA_EE_ACTION_EVT: 504 { 505 tNFA_EE_ACTION& action = eventData->action; 506 if (action.trigger == NFC_EE_TRIG_SELECT) 507 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger); 508 else if (action.trigger == NFC_EE_TRIG_APP_INIT) 509 { 510 tNFC_APP_INIT& app_init = action.param.app_init; 511 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn, 512 action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data); 513 } 514 else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL) 515 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger); 516 else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY) 517 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger); 518 else 519 ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger); 520 } 521 break; 522 523 case NFA_EE_DISCOVER_REQ_EVT: 524 { 525 ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__, 526 eventData->discover_req.status, eventData->discover_req.num_ee); 527 SyncEventGuard guard (routingManager.mEeInfoEvent); 528 memcpy (&routingManager.mEeInfo, &eventData->discover_req, sizeof(routingManager.mEeInfo)); 529 routingManager.mReceivedEeInfo = true; 530 routingManager.mEeInfoEvent.notifyOne(); 531 } 532 break; 533 534 case NFA_EE_NO_CB_ERR_EVT: 535 ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT status=%u", fn, eventData->status); 536 break; 537 538 case NFA_EE_ADD_AID_EVT: 539 { 540 ALOGD ("%s: NFA_EE_ADD_AID_EVT status=%u", fn, eventData->status); 541 } 542 break; 543 544 case NFA_EE_REMOVE_AID_EVT: 545 { 546 ALOGD ("%s: NFA_EE_REMOVE_AID_EVT status=%u", fn, eventData->status); 547 } 548 break; 549 550 case NFA_EE_NEW_EE_EVT: 551 { 552 ALOGD ("%s: NFA_EE_NEW_EE_EVT h=0x%X; status=%u", fn, 553 eventData->new_ee.ee_handle, eventData->new_ee.ee_status); 554 } 555 break; 556 557 case NFA_EE_UPDATED_EVT: 558 { 559 ALOGD("%s: NFA_EE_UPDATED_EVT", fn); 560 SyncEventGuard guard(routingManager.mEeUpdateEvent); 561 routingManager.mEeUpdateEvent.notifyOne(); 562 } 563 break; 564 565 default: 566 ALOGE ("%s: unknown event=%u ????", fn, event); 567 break; 568 } 569 } 570 571 int RoutingManager::registerJniFunctions (JNIEnv* e) 572 { 573 static const char fn [] = "RoutingManager::registerJniFunctions"; 574 ALOGD ("%s", fn); 575 return jniRegisterNativeMethods (e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods, NELEM(sMethods)); 576 } 577 578 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination (JNIEnv*) 579 { 580 return getInstance().mDefaultEe; 581 } 582 583 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination (JNIEnv*) 584 { 585 return getInstance().mOffHostEe; 586 } 587 588 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode (JNIEnv*) 589 { 590 return getInstance().mAidMatchingMode; 591 } 592