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
28extern "C"
29{
30    #include "nfa_ee_api.h"
31    #include "nfa_ce_api.h"
32}
33extern bool gActivated;
34extern SyncEvent gDeactivatedEvent;
35
36
37const 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
44static const int MAX_NUM_EE = 5;
45
46RoutingManager::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
99RoutingManager::~RoutingManager ()
100{
101    NFA_EeDeregister (nfaEeCallback);
102}
103
104bool 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
192RoutingManager& RoutingManager::getInstance ()
193{
194    static RoutingManager manager;
195    return manager;
196}
197
198void 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
266void 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
328bool 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
344bool 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
360bool 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
376void 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
418void 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
436void 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
455void RoutingManager::handleData (UINT8 technology, const UINT8* data, UINT32 dataLen, tNFA_STATUS status)
456{
457    if (status == NFA_STATUS_CONTINUE)
458    {
459        if (dataLen > 0)
460        {
461            mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data; more to come
462        }
463        return; //expect another NFA_CE_DATA_EVT to come
464    }
465    else if (status == NFA_STATUS_OK)
466    {
467        if (dataLen > 0)
468        {
469            mRxDataBuffer.insert (mRxDataBuffer.end(), &data[0], &data[dataLen]); //append data
470        }
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    }
512TheEnd:
513    mRxDataBuffer.clear();
514}
515
516void 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*******************************************************************************/
575void 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
684int 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
721void 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
740void 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
791int 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
798int RoutingManager::com_android_nfc_cardemulation_doGetDefaultRouteDestination (JNIEnv*)
799{
800    return getInstance().mDefaultEe;
801}
802
803int RoutingManager::com_android_nfc_cardemulation_doGetDefaultOffHostRouteDestination (JNIEnv*)
804{
805    return getInstance().mOffHostEe;
806}
807
808int RoutingManager::com_android_nfc_cardemulation_doGetAidMatchingMode (JNIEnv*)
809{
810    return getInstance().mAidMatchingMode;
811}
812