• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
RoutingManager()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 
~RoutingManager()98 RoutingManager::~RoutingManager() { NFA_EeDeregister(nfaEeCallback); }
99 
initialize(nfc_jni_native_data * native)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 
getInstance()213 RoutingManager& RoutingManager::getInstance() {
214   static RoutingManager manager;
215   return manager;
216 }
217 
enableRoutingToHost()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 
disableRoutingToHost()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 
addAidRouting(const uint8_t * aid,uint8_t aidLen,int route,int aidInfo)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 
removeAidRouting(const uint8_t * aid,uint8_t aidLen)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 
commitRouting()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 
onNfccShutdown()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 
notifyActivated(uint8_t technology)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 
notifyDeactivated(uint8_t technology)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 
handleData(uint8_t technology,const uint8_t * data,uint32_t dataLen,tNFA_STATUS status)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 
stackCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)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 *******************************************************************************/
nfaEeCallback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * eventData)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 
registerT3tIdentifier(uint8_t * t3tId,uint8_t t3tIdLen)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 
deregisterT3tIdentifier(int handle)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 
nfcFCeCallback(uint8_t event,tNFA_CONN_EVT_DATA * eventData)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 
registerJniFunctions(JNIEnv * e)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 
com_android_nfc_cardemulation_doGetDefaultRouteDestination(JNIEnv *)860 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination(
861     JNIEnv*) {
862   return getInstance().mDefaultEe;
863 }
864 
865 int RoutingManager::
com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv *)866     com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv*) {
867   return getInstance().mDefaultOffHostRoute;
868 }
869 
com_android_nfc_cardemulation_doGetAidMatchingMode(JNIEnv *)870 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode(
871     JNIEnv*) {
872   return getInstance().mAidMatchingMode;
873 }
874