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