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