RoutingManager.cpp revision 8e147262068865ee69157ab2249040fd1db16ff1
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 "config.h" 24#include "JavaClassConstants.h" 25#include "RoutingManager.h" 26 27extern "C" 28{ 29 #include "nfa_ee_api.h" 30 #include "nfa_ce_api.h" 31} 32 33RoutingManager::RoutingManager () 34{ 35} 36 37RoutingManager::~RoutingManager () 38{ 39 NFA_EeDeregister (nfaEeCallback); 40} 41 42bool RoutingManager::initialize (nfc_jni_native_data* native) 43{ 44 static const char fn [] = "RoutingManager::initialize()"; 45 unsigned long num = 0; 46 mNativeData = native; 47 48 tNFA_STATUS nfaStat; 49 { 50 SyncEventGuard guard (mEeRegisterEvent); 51 ALOGD ("%s: try ee register", fn); 52 nfaStat = NFA_EeRegister (nfaEeCallback); 53 if (nfaStat != NFA_STATUS_OK) 54 { 55 ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat); 56 return false; 57 } 58 mEeRegisterEvent.wait (); 59 } 60 61 // Get the "default" route 62 if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num))) 63 mDefaultEe = num; 64 else 65 mDefaultEe = 0x00; 66 67 ALOGD("%s: default route is 0x%02X", fn, mDefaultEe); 68 setDefaultRouting(); 69 return true; 70} 71 72RoutingManager& RoutingManager::getInstance () 73{ 74 static RoutingManager manager; 75 return manager; 76} 77 78void RoutingManager::setDefaultRouting() 79{ 80 tNFA_STATUS nfaStat; 81 SyncEventGuard guard (mRoutingEvent); 82 // Default routing for NFC-A technology 83 nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0x01, 0, 0); 84 if (nfaStat == NFA_STATUS_OK) 85 mRoutingEvent.wait (); 86 else 87 ALOGE ("Fail to set default tech routing"); 88 89 // Default routing for IsoDep protocol 90 nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, NFA_PROTOCOL_MASK_ISO_DEP, 0, 0); 91 if (nfaStat == NFA_STATUS_OK) 92 mRoutingEvent.wait (); 93 else 94 ALOGE ("Fail to set default proto routing"); 95 96 // Tell the UICC to only listen on Nfc-A 97 nfaStat = NFA_CeConfigureUiccListenTech (mDefaultEe, 0x01); 98 if (nfaStat != NFA_STATUS_OK) 99 ALOGE ("Failed to configure UICC listen technologies"); 100 101 // Tell the host-routing to only listen on Nfc-A 102 nfaStat = NFA_CeSetIsoDepListenTech(0x01); 103 if (nfaStat != NFA_STATUS_OK) 104 ALOGE ("Failed to configure CE IsoDep technologies"); 105 106 // Register a wild-card for AIDs routed to the host 107 nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback); 108 if (nfaStat != NFA_STATUS_OK) 109 ALOGE("Failed to register wildcard AID for DH"); 110 111 { 112 SyncEventGuard guard (mEeUpdateEvent); 113 // Commit the routing configuration 114 nfaStat = NFA_EeUpdateNow(); 115 if (nfaStat == NFA_STATUS_OK) 116 { 117 mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT 118 } 119 else 120 ALOGE("Failed to commit routing configuration"); 121 } 122} 123 124bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route) 125{ 126 static const char fn [] = "RoutingManager::addAidRouting"; 127 ALOGD ("%s: enter", fn); 128 tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01); 129 if (nfaStat == NFA_STATUS_OK) 130 { 131 ALOGD ("%s: routed AID", fn); 132 return true; 133 } else 134 { 135 ALOGE ("%s: failed to route AID", fn); 136 return false; 137 } 138} 139 140bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen) 141{ 142 static const char fn [] = "RoutingManager::removeAidRouting"; 143 ALOGD ("%s: enter", fn); 144 tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid); 145 if (nfaStat == NFA_STATUS_OK) 146 { 147 ALOGD ("%s: removed AID", fn); 148 return true; 149 } else 150 { 151 ALOGE ("%s: failed to remove AID", fn); 152 return false; 153 } 154} 155 156bool RoutingManager::commitRouting() 157{ 158 static const char fn [] = "RoutingManager::commitRouting"; 159 tNFA_STATUS nfaStat = 0; 160 ALOGD ("%s", fn); 161 { 162 SyncEventGuard guard (mEeUpdateEvent); 163 nfaStat = NFA_EeUpdateNow(); 164 if (nfaStat == NFA_STATUS_OK) 165 { 166 mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT 167 } 168 } 169 return (nfaStat == NFA_STATUS_OK); 170} 171 172void RoutingManager::notifyActivated () 173{ 174 JNIEnv* e = NULL; 175 ScopedAttach attach(mNativeData->vm, &e); 176 if (e == NULL) 177 { 178 ALOGE ("jni env is null"); 179 return; 180 } 181 182 e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated); 183 if (e->ExceptionCheck()) 184 { 185 e->ExceptionClear(); 186 ALOGE ("fail notify"); 187 } 188} 189 190void RoutingManager::notifyDeactivated () 191{ 192 JNIEnv* e = NULL; 193 ScopedAttach attach(mNativeData->vm, &e); 194 if (e == NULL) 195 { 196 ALOGE ("jni env is null"); 197 return; 198 } 199 200 e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated); 201 if (e->ExceptionCheck()) 202 { 203 e->ExceptionClear(); 204 ALOGE ("fail notify"); 205 } 206} 207 208void RoutingManager::handleData (const UINT8* data, UINT8 dataLen) 209{ 210 if (dataLen <= 0) 211 { 212 ALOGE("no data"); 213 return; 214 } 215 216 JNIEnv* e = NULL; 217 ScopedAttach attach(mNativeData->vm, &e); 218 if (e == NULL) 219 { 220 ALOGE ("jni env is null"); 221 return; 222 } 223 224 ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(dataLen)); 225 if (dataJavaArray.get() == NULL) 226 { 227 ALOGE ("fail allocate array"); 228 return; 229 } 230 231 e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, dataLen, (jbyte *)data); 232 if (e->ExceptionCheck()) 233 { 234 e->ExceptionClear(); 235 ALOGE ("fail fill array"); 236 return; 237 } 238 239 e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData, dataJavaArray.get()); 240 if (e->ExceptionCheck()) 241 { 242 e->ExceptionClear(); 243 ALOGE ("fail notify"); 244 } 245} 246 247void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData) 248{ 249 static const char fn [] = "RoutingManager::stackCallback"; 250 ALOGD("%s: event=0x%X", fn, event); 251 RoutingManager& routingManager = RoutingManager::getInstance(); 252 253 switch (event) 254 { 255 case NFA_CE_REGISTERED_EVT: 256 { 257 tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered; 258 ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle); 259 } 260 break; 261 262 case NFA_CE_DEREGISTERED_EVT: 263 { 264 tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered; 265 ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle); 266 } 267 break; 268 269 case NFA_CE_ACTIVATED_EVT: 270 { 271 routingManager.notifyActivated(); 272 } 273 break; 274 case NFA_DEACTIVATED_EVT: 275 case NFA_CE_DEACTIVATED_EVT: 276 { 277 routingManager.notifyDeactivated(); 278 } 279 break; 280 case NFA_CE_DATA_EVT: 281 { 282 tNFA_CE_DATA& ce_data = eventData->ce_data; 283 ALOGD("%s: NFA_CE_DATA_EVT; h=0x%X; data len=%u", fn, ce_data.handle, ce_data.len); 284 getInstance().handleData(ce_data.p_data, ce_data.len); 285 } 286 break; 287 } 288} 289/******************************************************************************* 290** 291** Function: nfaEeCallback 292** 293** Description: Receive execution environment-related events from stack. 294** event: Event code. 295** eventData: Event data. 296** 297** Returns: None 298** 299*******************************************************************************/ 300void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData) 301{ 302 static const char fn [] = "RoutingManager::nfaEeCallback"; 303 304 RoutingManager& routingManager = RoutingManager::getInstance(); 305 306 switch (event) 307 { 308 case NFA_EE_REGISTER_EVT: 309 { 310 SyncEventGuard guard (routingManager.mEeRegisterEvent); 311 ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register); 312 routingManager.mEeRegisterEvent.notifyOne(); 313 } 314 break; 315 316 case NFA_EE_MODE_SET_EVT: 317 { 318 ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X handle: 0x%04X ", fn, 319 eventData->mode_set.status, eventData->mode_set.ee_handle); 320 } 321 break; 322 323 case NFA_EE_SET_TECH_CFG_EVT: 324 { 325 ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status); 326 SyncEventGuard guard(routingManager.mRoutingEvent); 327 routingManager.mRoutingEvent.notifyOne(); 328 } 329 break; 330 331 case NFA_EE_SET_PROTO_CFG_EVT: 332 { 333 ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status); 334 SyncEventGuard guard(routingManager.mRoutingEvent); 335 routingManager.mRoutingEvent.notifyOne(); 336 } 337 break; 338 339 case NFA_EE_ACTION_EVT: 340 { 341 tNFA_EE_ACTION& action = eventData->action; 342 if (action.trigger == NFC_EE_TRIG_SELECT) 343 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger); 344 else if (action.trigger == NFC_EE_TRIG_APP_INIT) 345 { 346 tNFC_APP_INIT& app_init = action.param.app_init; 347 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn, 348 action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data); 349 } 350 else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL) 351 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger); 352 else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY) 353 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger); 354 else 355 ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger); 356 } 357 break; 358 359 case NFA_EE_DISCOVER_REQ_EVT: 360 ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__, 361 eventData->discover_req.status, eventData->discover_req.num_ee); 362 break; 363 364 case NFA_EE_NO_CB_ERR_EVT: 365 ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT status=%u", fn, eventData->status); 366 break; 367 368 case NFA_EE_ADD_AID_EVT: 369 { 370 ALOGD ("%s: NFA_EE_ADD_AID_EVT status=%u", fn, eventData->status); 371 } 372 break; 373 374 case NFA_EE_REMOVE_AID_EVT: 375 { 376 ALOGD ("%s: NFA_EE_REMOVE_AID_EVT status=%u", fn, eventData->status); 377 } 378 break; 379 380 case NFA_EE_NEW_EE_EVT: 381 { 382 ALOGD ("%s: NFA_EE_NEW_EE_EVT h=0x%X; status=%u", fn, 383 eventData->new_ee.ee_handle, eventData->new_ee.ee_status); 384 } 385 break; 386 387 case NFA_EE_UPDATED_EVT: 388 { 389 ALOGD("%s: NFA_EE_UPDATED_EVT", fn); 390 SyncEventGuard guard(routingManager.mEeUpdateEvent); 391 routingManager.mEeUpdateEvent.notifyOne(); 392 } 393 break; 394 395 default: 396 ALOGE ("%s: unknown event=%u ????", fn, event); 397 break; 398 } 399} 400