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 
RoutingManager()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 active SE for Nfc-F
58     if (GetNumValue("ACTIVE_SE_NFCF", &num, sizeof(num)))
59         mActiveSeNfcF = num;
60     else
61         mActiveSeNfcF = 0x00;
62     ALOGD("%s: Active SE for Nfc-F is 0x%02X", fn, mActiveSeNfcF);
63 
64     // Get the "default" route
65     if (GetNumValue("DEFAULT_ISODEP_ROUTE", &num, sizeof(num)))
66         mDefaultEe = num;
67     else
68         mDefaultEe = 0x00;
69     ALOGD("%s: default route is 0x%02X", fn, mDefaultEe);
70 
71     // Get the "default" route for Nfc-F
72     if (GetNumValue("DEFAULT_NFCF_ROUTE", &num, sizeof(num)))
73         mDefaultEeNfcF = num;
74     else
75         mDefaultEeNfcF = 0x00;
76     ALOGD("%s: default route for Nfc-F is 0x%02X", fn, mDefaultEeNfcF);
77 
78     // Get the default "off-host" route.  This is hard-coded at the Java layer
79     // but we can override it here to avoid forcing Java changes.
80     if (GetNumValue("DEFAULT_OFFHOST_ROUTE", &num, sizeof(num)))
81         mOffHostEe = num;
82     else
83         mOffHostEe = 0xf4;
84 
85     if (GetNumValue("AID_MATCHING_MODE", &num, sizeof(num)))
86         mAidMatchingMode = num;
87     else
88         mAidMatchingMode = AID_MATCHING_EXACT_ONLY;
89 
90     ALOGD("%s: mOffHostEe=0x%02X", fn, mOffHostEe);
91 
92     memset (&mEeInfo, 0, sizeof(mEeInfo));
93     mReceivedEeInfo = false;
94     mSeTechMask = 0x00;
95 
96     mNfcFOnDhHandle = NFA_HANDLE_INVALID;
97 }
98 
~RoutingManager()99 RoutingManager::~RoutingManager ()
100 {
101     NFA_EeDeregister (nfaEeCallback);
102 }
103 
initialize(nfc_jni_native_data * native)104 bool RoutingManager::initialize (nfc_jni_native_data* native)
105 {
106     static const char fn [] = "RoutingManager::initialize()";
107     mNativeData = native;
108 
109     tNFA_STATUS nfaStat;
110     {
111         SyncEventGuard guard (mEeRegisterEvent);
112         ALOGD ("%s: try ee register", fn);
113         nfaStat = NFA_EeRegister (nfaEeCallback);
114         if (nfaStat != NFA_STATUS_OK)
115         {
116             ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat);
117             return false;
118         }
119         mEeRegisterEvent.wait ();
120     }
121 
122     mRxDataBuffer.clear ();
123 
124     if ((mActiveSe != 0) || (mActiveSeNfcF != 0))
125     {
126         ALOGD ("%s: Technology Routing (NfcASe:0x%02x, NfcFSe:0x%02x)", fn, mActiveSe, mActiveSeNfcF);
127         {
128             // Wait for EE info if needed
129             SyncEventGuard guard (mEeInfoEvent);
130             if (!mReceivedEeInfo)
131             {
132                 ALOGE("Waiting for EE info");
133                 mEeInfoEvent.wait();
134             }
135         }
136 
137         ALOGD ("%s: Number of EE is %d", fn, mEeInfo.num_ee);
138         for (UINT8 i = 0; i < mEeInfo.num_ee; i++)
139         {
140             tNFA_HANDLE eeHandle = mEeInfo.ee_disc_info[i].ee_handle;
141             tNFA_TECHNOLOGY_MASK seTechMask = 0;
142 
143             ALOGD ("%s   EE[%u] Handle: 0x%04x  techA: 0x%02x  techB: 0x%02x  techF: 0x%02x  techBprime: 0x%02x",
144                    fn, i, eeHandle,
145                    mEeInfo.ee_disc_info[i].la_protocol,
146                    mEeInfo.ee_disc_info[i].lb_protocol,
147                    mEeInfo.ee_disc_info[i].lf_protocol,
148                    mEeInfo.ee_disc_info[i].lbp_protocol);
149             if ((mActiveSe != 0) && (eeHandle == (mActiveSe | NFA_HANDLE_GROUP_EE)))
150             {
151                 if (mEeInfo.ee_disc_info[i].la_protocol != 0)
152                     seTechMask |= NFA_TECHNOLOGY_MASK_A;
153             }
154             if ((mActiveSeNfcF != 0) && (eeHandle == (mActiveSeNfcF | NFA_HANDLE_GROUP_EE)))
155             {
156                 if (mEeInfo.ee_disc_info[i].lf_protocol != 0)
157                     seTechMask |= NFA_TECHNOLOGY_MASK_F;
158             }
159 
160             ALOGD ("%s: seTechMask[%u]=0x%02x", fn, i, seTechMask);
161             if (seTechMask != 0x00)
162             {
163                 ALOGD("Configuring tech mask 0x%02x on EE 0x%04x", seTechMask, eeHandle);
164 
165                 nfaStat = NFA_CeConfigureUiccListenTech(eeHandle, seTechMask);
166                 if (nfaStat != NFA_STATUS_OK)
167                     ALOGE ("Failed to configure UICC listen technologies.");
168 
169                 // Set technology routes to UICC if it's there
170                 nfaStat = NFA_EeSetDefaultTechRouting(eeHandle, seTechMask, seTechMask, seTechMask);
171                 if (nfaStat != NFA_STATUS_OK)
172                     ALOGE ("Failed to configure UICC technology routing.");
173 
174                 mSeTechMask |= seTechMask;
175             }
176         }
177     }
178 
179     // Tell the host-routing to only listen on Nfc-A
180     nfaStat = NFA_CeSetIsoDepListenTech(NFA_TECHNOLOGY_MASK_A);
181     if (nfaStat != NFA_STATUS_OK)
182         ALOGE ("Failed to configure CE IsoDep technologies");
183 
184     // Register a wild-card for AIDs routed to the host
185     nfaStat = NFA_CeRegisterAidOnDH (NULL, 0, stackCallback);
186     if (nfaStat != NFA_STATUS_OK)
187         ALOGE("Failed to register wildcard AID for DH");
188 
189     return true;
190 }
191 
getInstance()192 RoutingManager& RoutingManager::getInstance ()
193 {
194     static RoutingManager manager;
195     return manager;
196 }
197 
enableRoutingToHost()198 void RoutingManager::enableRoutingToHost()
199 {
200     tNFA_STATUS nfaStat;
201     tNFA_TECHNOLOGY_MASK techMask;
202     tNFA_PROTOCOL_MASK protoMask;
203     SyncEventGuard guard (mRoutingEvent);
204 
205     // Set default routing at one time when the NFCEE IDs for Nfc-A and Nfc-F are same
206     if (mDefaultEe == mDefaultEeNfcF)
207     {
208         // Route Nfc-A/Nfc-F to host if we don't have a SE
209         techMask = (mSeTechMask ^ (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F));
210         if (techMask != 0)
211         {
212             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, techMask, 0, 0);
213             if (nfaStat == NFA_STATUS_OK)
214                 mRoutingEvent.wait ();
215             else
216                 ALOGE ("Fail to set default tech routing for Nfc-A/Nfc-F");
217         }
218         // Default routing for IsoDep and T3T protocol
219         protoMask = (NFA_PROTOCOL_MASK_ISO_DEP | NFA_PROTOCOL_MASK_T3T);
220         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, protoMask, 0, 0);
221         if (nfaStat == NFA_STATUS_OK)
222             mRoutingEvent.wait ();
223         else
224             ALOGE ("Fail to set default proto routing for IsoDep and T3T");
225     }
226     else
227     {
228         // Route Nfc-A to host if we don't have a SE
229         techMask = NFA_TECHNOLOGY_MASK_A;
230         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0)
231         {
232             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, techMask, 0, 0);
233             if (nfaStat == NFA_STATUS_OK)
234                 mRoutingEvent.wait ();
235             else
236                 ALOGE ("Fail to set default tech routing for Nfc-A");
237         }
238         // Default routing for IsoDep protocol
239         protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
240         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, protoMask, 0, 0);
241         if (nfaStat == NFA_STATUS_OK)
242             mRoutingEvent.wait ();
243         else
244             ALOGE ("Fail to set default proto routing for IsoDep");
245 
246         // Route Nfc-F to host if we don't have a SE
247         techMask = NFA_TECHNOLOGY_MASK_F;
248         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0)
249         {
250             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEeNfcF, techMask, 0, 0);
251             if (nfaStat == NFA_STATUS_OK)
252                 mRoutingEvent.wait ();
253             else
254                 ALOGE ("Fail to set default tech routing for Nfc-F");
255         }
256         // Default routing for T3T protocol
257         protoMask = NFA_PROTOCOL_MASK_T3T;
258         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEeNfcF, protoMask, 0, 0);
259         if (nfaStat == NFA_STATUS_OK)
260             mRoutingEvent.wait ();
261         else
262             ALOGE ("Fail to set default proto routing for T3T");
263     }
264 }
265 
disableRoutingToHost()266 void RoutingManager::disableRoutingToHost()
267 {
268     tNFA_STATUS nfaStat;
269     tNFA_TECHNOLOGY_MASK techMask;
270     SyncEventGuard guard (mRoutingEvent);
271 
272     // Set default routing at one time when the NFCEE IDs for Nfc-A and Nfc-F are same
273     if (mDefaultEe == mDefaultEeNfcF)
274     {
275         // Default routing for Nfc-A/Nfc-F technology if we don't have a SE
276         techMask = (mSeTechMask ^ (NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_F));
277         if (techMask != 0)
278         {
279             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0);
280             if (nfaStat == NFA_STATUS_OK)
281                 mRoutingEvent.wait ();
282             else
283                 ALOGE ("Fail to set default tech routing for Nfc-A/Nfc-F");
284         }
285         // Default routing for IsoDep and T3T protocol
286         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0);
287         if (nfaStat == NFA_STATUS_OK)
288             mRoutingEvent.wait ();
289         else
290             ALOGE ("Fail to set default proto routing for IsoDep and T3T");
291     }
292     else
293     {
294         // Default routing for Nfc-A technology if we don't have a SE
295         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_A) == 0)
296         {
297             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEe, 0, 0, 0);
298             if (nfaStat == NFA_STATUS_OK)
299                 mRoutingEvent.wait ();
300             else
301                 ALOGE ("Fail to set default tech routing for Nfc-A");
302         }
303         // Default routing for IsoDep protocol
304         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEe, 0, 0, 0);
305         if (nfaStat == NFA_STATUS_OK)
306             mRoutingEvent.wait ();
307         else
308             ALOGE ("Fail to set default proto routing for IsoDep");
309 
310         // Default routing for Nfc-F technology if we don't have a SE
311         if ((mSeTechMask & NFA_TECHNOLOGY_MASK_F) == 0)
312         {
313             nfaStat = NFA_EeSetDefaultTechRouting (mDefaultEeNfcF, 0, 0, 0);
314             if (nfaStat == NFA_STATUS_OK)
315                 mRoutingEvent.wait ();
316             else
317                 ALOGE ("Fail to set default tech routing for Nfc-F");
318         }
319         // Default routing for T3T protocol
320         nfaStat = NFA_EeSetDefaultProtoRouting(mDefaultEeNfcF, 0, 0, 0);
321         if (nfaStat == NFA_STATUS_OK)
322             mRoutingEvent.wait ();
323         else
324             ALOGE ("Fail to set default proto routing for T3T");
325     }
326 }
327 
addAidRouting(const UINT8 * aid,UINT8 aidLen,int route)328 bool RoutingManager::addAidRouting(const UINT8* aid, UINT8 aidLen, int route)
329 {
330     static const char fn [] = "RoutingManager::addAidRouting";
331     ALOGD ("%s: enter", fn);
332     tNFA_STATUS nfaStat = NFA_EeAddAidRouting(route, aidLen, (UINT8*) aid, 0x01);
333     if (nfaStat == NFA_STATUS_OK)
334     {
335         ALOGD ("%s: routed AID", fn);
336         return true;
337     } else
338     {
339         ALOGE ("%s: failed to route AID", fn);
340         return false;
341     }
342 }
343 
removeAidRouting(const UINT8 * aid,UINT8 aidLen)344 bool RoutingManager::removeAidRouting(const UINT8* aid, UINT8 aidLen)
345 {
346     static const char fn [] = "RoutingManager::removeAidRouting";
347     ALOGD ("%s: enter", fn);
348     tNFA_STATUS nfaStat = NFA_EeRemoveAidRouting(aidLen, (UINT8*) aid);
349     if (nfaStat == NFA_STATUS_OK)
350     {
351         ALOGD ("%s: removed AID", fn);
352         return true;
353     } else
354     {
355         ALOGE ("%s: failed to remove AID", fn);
356         return false;
357     }
358 }
359 
commitRouting()360 bool RoutingManager::commitRouting()
361 {
362     static const char fn [] = "RoutingManager::commitRouting";
363     tNFA_STATUS nfaStat = 0;
364     ALOGD ("%s", fn);
365     {
366         SyncEventGuard guard (mEeUpdateEvent);
367         nfaStat = NFA_EeUpdateNow();
368         if (nfaStat == NFA_STATUS_OK)
369         {
370             mEeUpdateEvent.wait (); //wait for NFA_EE_UPDATED_EVT
371         }
372     }
373     return (nfaStat == NFA_STATUS_OK);
374 }
375 
onNfccShutdown()376 void RoutingManager::onNfccShutdown ()
377 {
378     static const char fn [] = "RoutingManager:onNfccShutdown";
379     if (mActiveSe == 0x00) return;
380 
381     tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
382     UINT8 actualNumEe = MAX_NUM_EE;
383     tNFA_EE_INFO eeInfo[MAX_NUM_EE];
384 
385     memset (&eeInfo, 0, sizeof(eeInfo));
386     if ((nfaStat = NFA_EeGetInfo (&actualNumEe, eeInfo)) != NFA_STATUS_OK)
387     {
388         ALOGE ("%s: fail get info; error=0x%X", fn, nfaStat);
389         return;
390     }
391     if (actualNumEe != 0)
392     {
393         for (UINT8 xx = 0; xx < actualNumEe; xx++)
394         {
395             if ((eeInfo[xx].num_interface != 0)
396                 && (eeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS)
397                 && (eeInfo[xx].ee_status == NFA_EE_STATUS_ACTIVE))
398             {
399                 ALOGD ("%s: Handle: 0x%04x Change Status Active to Inactive", fn, eeInfo[xx].ee_handle);
400                 SyncEventGuard guard (mEeSetModeEvent);
401                 if ((nfaStat = NFA_EeModeSet (eeInfo[xx].ee_handle, NFA_EE_MD_DEACTIVATE)) == NFA_STATUS_OK)
402                 {
403                     mEeSetModeEvent.wait (); //wait for NFA_EE_MODE_SET_EVT
404                 }
405                 else
406                 {
407                     ALOGE ("Failed to set EE inactive");
408                 }
409             }
410         }
411     }
412     else
413     {
414         ALOGD ("%s: No active EEs found", fn);
415     }
416 }
417 
notifyActivated(UINT8 technology)418 void RoutingManager::notifyActivated (UINT8 technology)
419 {
420     JNIEnv* e = NULL;
421     ScopedAttach attach(mNativeData->vm, &e);
422     if (e == NULL)
423     {
424         ALOGE ("jni env is null");
425         return;
426     }
427 
428     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuActivated, (int)technology);
429     if (e->ExceptionCheck())
430     {
431         e->ExceptionClear();
432         ALOGE ("fail notify");
433     }
434 }
435 
notifyDeactivated(UINT8 technology)436 void RoutingManager::notifyDeactivated (UINT8 technology)
437 {
438     mRxDataBuffer.clear();
439     JNIEnv* e = NULL;
440     ScopedAttach attach(mNativeData->vm, &e);
441     if (e == NULL)
442     {
443         ALOGE ("jni env is null");
444         return;
445     }
446 
447     e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuDeactivated, (int)technology);
448     if (e->ExceptionCheck())
449     {
450         e->ExceptionClear();
451         ALOGE ("fail notify");
452     }
453 }
454 
handleData(UINT8 technology,const UINT8 * data,UINT32 dataLen,tNFA_STATUS status)455 void RoutingManager::handleData (UINT8 technology, const UINT8* data, UINT32 dataLen, tNFA_STATUS status)
456 {
457     if (dataLen <= 0)
458     {
459         ALOGE("no data");
460         goto TheEnd;
461     }
462 
463     if (status == NFA_STATUS_CONTINUE)
464     {
465         mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data; more to come
466         return; //expect another NFA_CE_DATA_EVT to come
467     }
468     else if (status == NFA_STATUS_OK)
469     {
470         mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data
471         //entire data packet has been received; no more NFA_CE_DATA_EVT
472     }
473     else if (status == NFA_STATUS_FAILED)
474     {
475         ALOGE("RoutingManager::handleData: read data fail");
476         goto TheEnd;
477     }
478 
479     {
480         JNIEnv* e = NULL;
481         ScopedAttach attach(mNativeData->vm, &e);
482         if (e == NULL)
483         {
484             ALOGE ("jni env is null");
485             goto TheEnd;
486         }
487 
488         ScopedLocalRef<jobject> dataJavaArray(e, e->NewByteArray(mRxDataBuffer.size()));
489         if (dataJavaArray.get() == NULL)
490         {
491             ALOGE ("fail allocate array");
492             goto TheEnd;
493         }
494 
495         e->SetByteArrayRegion ((jbyteArray)dataJavaArray.get(), 0, mRxDataBuffer.size(),
496                 (jbyte *)(&mRxDataBuffer[0]));
497         if (e->ExceptionCheck())
498         {
499             e->ExceptionClear();
500             ALOGE ("fail fill array");
501             goto TheEnd;
502         }
503 
504         e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyHostEmuData,
505                 (int)technology, dataJavaArray.get());
506         if (e->ExceptionCheck())
507         {
508             e->ExceptionClear();
509             ALOGE ("fail notify");
510         }
511     }
512 TheEnd:
513     mRxDataBuffer.clear();
514 }
515 
stackCallback(UINT8 event,tNFA_CONN_EVT_DATA * eventData)516 void RoutingManager::stackCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
517 {
518     static const char fn [] = "RoutingManager::stackCallback";
519     ALOGD("%s: event=0x%X", fn, event);
520     RoutingManager& routingManager = RoutingManager::getInstance();
521 
522     switch (event)
523     {
524     case NFA_CE_REGISTERED_EVT:
525         {
526             tNFA_CE_REGISTERED& ce_registered = eventData->ce_registered;
527             ALOGD("%s: NFA_CE_REGISTERED_EVT; status=0x%X; h=0x%X", fn, ce_registered.status, ce_registered.handle);
528         }
529         break;
530 
531     case NFA_CE_DEREGISTERED_EVT:
532         {
533             tNFA_CE_DEREGISTERED& ce_deregistered = eventData->ce_deregistered;
534             ALOGD("%s: NFA_CE_DEREGISTERED_EVT; h=0x%X", fn, ce_deregistered.handle);
535         }
536         break;
537 
538     case NFA_CE_ACTIVATED_EVT:
539         {
540             routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_A);
541         }
542         break;
543 
544     case NFA_DEACTIVATED_EVT:
545     case NFA_CE_DEACTIVATED_EVT:
546         {
547             ALOGD("%s: NFA_DEACTIVATED_EVT, NFA_CE_DEACTIVATED_EVT", fn);
548             routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_A);
549             SyncEventGuard g (gDeactivatedEvent);
550             gActivated = false; //guard this variable from multi-threaded access
551             gDeactivatedEvent.notifyOne ();
552         }
553         break;
554 
555     case NFA_CE_DATA_EVT:
556         {
557             tNFA_CE_DATA& ce_data = eventData->ce_data;
558             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);
559             getInstance().handleData(NFA_TECHNOLOGY_MASK_A, ce_data.p_data, ce_data.len, ce_data.status);
560         }
561         break;
562     }
563 }
564 /*******************************************************************************
565 **
566 ** Function:        nfaEeCallback
567 **
568 ** Description:     Receive execution environment-related events from stack.
569 **                  event: Event code.
570 **                  eventData: Event data.
571 **
572 ** Returns:         None
573 **
574 *******************************************************************************/
nfaEeCallback(tNFA_EE_EVT event,tNFA_EE_CBACK_DATA * eventData)575 void RoutingManager::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
576 {
577     static const char fn [] = "RoutingManager::nfaEeCallback";
578 
579     RoutingManager& routingManager = RoutingManager::getInstance();
580 
581     switch (event)
582     {
583     case NFA_EE_REGISTER_EVT:
584         {
585             SyncEventGuard guard (routingManager.mEeRegisterEvent);
586             ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
587             routingManager.mEeRegisterEvent.notifyOne();
588         }
589         break;
590 
591     case NFA_EE_MODE_SET_EVT:
592         {
593             SyncEventGuard guard (routingManager.mEeSetModeEvent);
594             ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  ", fn,
595                     eventData->mode_set.status, eventData->mode_set.ee_handle);
596             routingManager.mEeSetModeEvent.notifyOne();
597         }
598         break;
599 
600     case NFA_EE_SET_TECH_CFG_EVT:
601         {
602             ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
603             SyncEventGuard guard(routingManager.mRoutingEvent);
604             routingManager.mRoutingEvent.notifyOne();
605         }
606         break;
607 
608     case NFA_EE_SET_PROTO_CFG_EVT:
609         {
610             ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
611             SyncEventGuard guard(routingManager.mRoutingEvent);
612             routingManager.mRoutingEvent.notifyOne();
613         }
614         break;
615 
616     case NFA_EE_ACTION_EVT:
617         {
618             tNFA_EE_ACTION& action = eventData->action;
619             if (action.trigger == NFC_EE_TRIG_SELECT)
620                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger);
621             else if (action.trigger == NFC_EE_TRIG_APP_INIT)
622             {
623                 tNFC_APP_INIT& app_init = action.param.app_init;
624                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn,
625                         action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data);
626             }
627             else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
628                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger);
629             else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
630                 ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger);
631             else
632                 ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger);
633         }
634         break;
635 
636     case NFA_EE_DISCOVER_REQ_EVT:
637         {
638             ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__,
639                     eventData->discover_req.status, eventData->discover_req.num_ee);
640             SyncEventGuard guard (routingManager.mEeInfoEvent);
641             memcpy (&routingManager.mEeInfo, &eventData->discover_req, sizeof(routingManager.mEeInfo));
642             routingManager.mReceivedEeInfo = true;
643             routingManager.mEeInfoEvent.notifyOne();
644         }
645         break;
646 
647     case NFA_EE_NO_CB_ERR_EVT:
648         ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
649         break;
650 
651     case NFA_EE_ADD_AID_EVT:
652         {
653             ALOGD ("%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
654         }
655         break;
656 
657     case NFA_EE_REMOVE_AID_EVT:
658         {
659             ALOGD ("%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
660         }
661         break;
662 
663     case NFA_EE_NEW_EE_EVT:
664         {
665             ALOGD ("%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
666                 eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
667         }
668         break;
669 
670     case NFA_EE_UPDATED_EVT:
671         {
672             ALOGD("%s: NFA_EE_UPDATED_EVT", fn);
673             SyncEventGuard guard(routingManager.mEeUpdateEvent);
674             routingManager.mEeUpdateEvent.notifyOne();
675         }
676         break;
677 
678     default:
679         ALOGE ("%s: unknown event=%u ????", fn, event);
680         break;
681     }
682 }
683 
registerT3tIdentifier(UINT8 * t3tId,UINT8 t3tIdLen)684 int RoutingManager::registerT3tIdentifier(UINT8* t3tId, UINT8 t3tIdLen)
685 {
686     static const char fn [] = "RoutingManager::registerT3tIdentifier";
687 
688     ALOGD ("%s: Start to register NFC-F system on DH", fn);
689 
690     if (t3tIdLen != (2 + NCI_RF_F_UID_LEN))
691     {
692         ALOGE ("%s: Invalid length of T3T Identifier", fn);
693         return NFA_HANDLE_INVALID;
694     }
695 
696     SyncEventGuard guard (mRoutingEvent);
697     mNfcFOnDhHandle = NFA_HANDLE_INVALID;
698 
699     int systemCode;
700     UINT8 nfcid2[NCI_RF_F_UID_LEN];
701 
702     systemCode = (((int)t3tId[0] << 8) | ((int)t3tId[1] << 0));
703     memcpy(nfcid2, t3tId + 2, NCI_RF_F_UID_LEN);
704 
705     tNFA_STATUS nfaStat = NFA_CeRegisterFelicaSystemCodeOnDH (systemCode, nfcid2, nfcFCeCallback);
706     if (nfaStat == NFA_STATUS_OK)
707     {
708         mRoutingEvent.wait ();
709     }
710     else
711     {
712         ALOGE ("%s: Fail to register NFC-F system on DH", fn);
713         return NFA_HANDLE_INVALID;
714     }
715 
716     ALOGD ("%s: Succeed to register NFC-F system on DH", fn);
717 
718     return mNfcFOnDhHandle;
719 }
720 
deregisterT3tIdentifier(int handle)721 void RoutingManager::deregisterT3tIdentifier(int handle)
722 {
723     static const char fn [] = "RoutingManager::deregisterT3tIdentifier";
724 
725     ALOGD ("%s: Start to deregister NFC-F system on DH", fn);
726 
727     SyncEventGuard guard (mRoutingEvent);
728     tNFA_STATUS nfaStat = NFA_CeDeregisterFelicaSystemCodeOnDH (handle);
729     if (nfaStat == NFA_STATUS_OK)
730     {
731         mRoutingEvent.wait ();
732         ALOGD ("%s: Succeeded in deregistering NFC-F system on DH", fn);
733     }
734     else
735     {
736         ALOGE ("%s: Fail to deregister NFC-F system on DH", fn);
737     }
738 }
739 
nfcFCeCallback(UINT8 event,tNFA_CONN_EVT_DATA * eventData)740 void RoutingManager::nfcFCeCallback (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
741 {
742     static const char fn [] = "RoutingManager::nfcFCeCallback";
743     RoutingManager& routingManager = RoutingManager::getInstance();
744 
745     ALOGD("%s: 0x%x", __FUNCTION__, event);
746 
747     switch (event)
748     {
749     case NFA_CE_REGISTERED_EVT:
750         {
751             ALOGD ("%s: registerd event notified", fn);
752             routingManager.mNfcFOnDhHandle = eventData->ce_registered.handle;
753             SyncEventGuard guard(routingManager.mRoutingEvent);
754             routingManager.mRoutingEvent.notifyOne();
755         }
756         break;
757     case NFA_CE_DEREGISTERED_EVT:
758         {
759             ALOGD ("%s: deregisterd event notified", fn);
760             SyncEventGuard guard(routingManager.mRoutingEvent);
761             routingManager.mRoutingEvent.notifyOne();
762         }
763         break;
764     case NFA_CE_ACTIVATED_EVT:
765         {
766             ALOGD ("%s: activated event notified", fn);
767             routingManager.notifyActivated(NFA_TECHNOLOGY_MASK_F);
768         }
769         break;
770     case NFA_CE_DEACTIVATED_EVT:
771         {
772             ALOGD ("%s: deactivated event notified", fn);
773             routingManager.notifyDeactivated(NFA_TECHNOLOGY_MASK_F);
774         }
775         break;
776     case NFA_CE_DATA_EVT:
777         {
778             ALOGD ("%s: data event notified", fn);
779             tNFA_CE_DATA& ce_data = eventData->ce_data;
780             routingManager.handleData(NFA_TECHNOLOGY_MASK_F, ce_data.p_data, ce_data.len, ce_data.status);
781         }
782         break;
783     default:
784         {
785             ALOGE ("%s: unknown event=%u ????", fn, event);
786         }
787         break;
788     }
789 }
790 
registerJniFunctions(JNIEnv * e)791 int RoutingManager::registerJniFunctions (JNIEnv* e)
792 {
793     static const char fn [] = "RoutingManager::registerJniFunctions";
794     ALOGD ("%s", fn);
795     return jniRegisterNativeMethods (e, "com/android/nfc/cardemulation/AidRoutingManager", sMethods, NELEM(sMethods));
796 }
797 
com_android_nfc_cardemulation_doGetDefaultRouteDestination(JNIEnv *)798 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination (JNIEnv*)
799 {
800     return getInstance().mDefaultEe;
801 }
802 
com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination(JNIEnv *)803 int RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination (JNIEnv*)
804 {
805     return getInstance().mOffHostEe;
806 }
807 
com_android_nfc_cardemulation_doGetAidMatchingMode(JNIEnv *)808 int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode (JNIEnv*)
809 {
810     return getInstance().mAidMatchingMode;
811 }
812