SecureElement.cpp revision 525c260303268a83da4c3413b953d13c9084e834
1/*
2 * Copyright (C) 2012 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 *  Communicate with secure elements that are attached to the NFC
19 *  controller.
20 */
21#include <semaphore.h>
22#include <errno.h>
23#include "OverrideLog.h"
24#include "SecureElement.h"
25#include "config.h"
26#include "PowerSwitch.h"
27#include "HostAidRouter.h"
28#include "JavaClassConstants.h"
29
30
31/*****************************************************************************
32**
33** public variables
34**
35*****************************************************************************/
36int gSEId = -1;     // secure element ID to use in connectEE(), -1 means not set
37int gGatePipe = -1; // gate id or static pipe id to use in connectEE(), -1 means not set
38bool gUseStaticPipe = false;    // if true, use gGatePipe as static pipe id.  if false, use as gate id
39
40namespace android
41{
42    extern void startRfDiscovery (bool isStart);
43}
44
45//////////////////////////////////////////////
46//////////////////////////////////////////////
47
48
49SecureElement SecureElement::sSecElem;
50const char* SecureElement::APP_NAME = "nfc_jni";
51
52
53/*******************************************************************************
54**
55** Function:        SecureElement
56**
57** Description:     Initialize member variables.
58**
59** Returns:         None
60**
61*******************************************************************************/
62SecureElement::SecureElement ()
63:   mActiveEeHandle (NFA_HANDLE_INVALID),
64    mDestinationGate (4), //loopback gate
65    mNfaHciHandle (NFA_HANDLE_INVALID),
66    mNativeData (NULL),
67    mIsInit (false),
68    mActualNumEe (0),
69    mNumEePresent(0),
70    mbNewEE (true),   // by default we start w/thinking there are new EE
71    mNewPipeId (0),
72    mNewSourceGate (0),
73    mActiveSeOverride(0),
74    mCommandStatus (NFA_STATUS_OK),
75    mIsPiping (false),
76    mCurrentRouteSelection (NoRoute),
77    mActualResponseSize(0),
78    mUseOberthurWarmReset (false),
79    mActivatedInListenMode (false),
80    mOberthurWarmResetCommand (3),
81    mRfFieldIsOn(false)
82{
83    memset (&mEeInfo, 0, sizeof(mEeInfo));
84    memset (&mUiccInfo, 0, sizeof(mUiccInfo));
85    memset (&mHciCfg, 0, sizeof(mHciCfg));
86    memset (mResponseData, 0, sizeof(mResponseData));
87    memset (mAidForEmptySelect, 0, sizeof(mAidForEmptySelect));
88    memset (&mLastRfFieldToggle, 0, sizeof(mLastRfFieldToggle));
89}
90
91
92/*******************************************************************************
93**
94** Function:        ~SecureElement
95**
96** Description:     Release all resources.
97**
98** Returns:         None
99**
100*******************************************************************************/
101SecureElement::~SecureElement ()
102{
103}
104
105
106/*******************************************************************************
107**
108** Function:        getInstance
109**
110** Description:     Get the SecureElement singleton object.
111**
112** Returns:         SecureElement object.
113**
114*******************************************************************************/
115SecureElement& SecureElement::getInstance()
116{
117    return sSecElem;
118}
119
120
121/*******************************************************************************
122**
123** Function:        setActiveSeOverride
124**
125** Description:     Specify which secure element to turn on.
126**                  activeSeOverride: ID of secure element
127**
128** Returns:         None
129**
130*******************************************************************************/
131void SecureElement::setActiveSeOverride(UINT8 activeSeOverride)
132{
133    ALOGD ("SecureElement::setActiveSeOverride, seid=0x%X", activeSeOverride);
134    mActiveSeOverride = activeSeOverride;
135}
136
137
138/*******************************************************************************
139**
140** Function:        initialize
141**
142** Description:     Initialize all member variables.
143**                  native: Native data.
144**
145** Returns:         True if ok.
146**
147*******************************************************************************/
148bool SecureElement::initialize (nfc_jni_native_data* native)
149{
150    static const char fn [] = "SecureElement::initialize";
151    tNFA_STATUS nfaStat;
152    UINT8 xx = 0, yy = 0;
153    unsigned long num = 0;
154
155    ALOGD ("%s: enter", fn);
156
157    if (GetNumValue("NFA_HCI_DEFAULT_DEST_GATE", &num, sizeof(num)))
158        mDestinationGate = num;
159    ALOGD ("%s: Default destination gate: %d", fn, mDestinationGate);
160
161    // active SE, if not set active all SEs
162    if (GetNumValue("ACTIVE_SE", &num, sizeof(num)))
163        mActiveSeOverride = num;
164    ALOGD ("%s: Active SE override: %d", fn, mActiveSeOverride);
165
166    if (GetNumValue("OBERTHUR_WARM_RESET_COMMAND", &num, sizeof(num)))
167    {
168        mUseOberthurWarmReset = true;
169        mOberthurWarmResetCommand = (UINT8) num;
170    }
171
172    mActiveEeHandle = NFA_HANDLE_INVALID;
173    mNfaHciHandle = NFA_HANDLE_INVALID;
174
175    mNativeData     = native;
176    mActualNumEe    = MAX_NUM_EE;
177    mbNewEE         = true;
178    mNewPipeId      = 0;
179    mNewSourceGate  = 0;
180    mCurrentRouteSelection = NoRoute;
181    memset (mEeInfo, 0, sizeof(mEeInfo));
182    memset (&mUiccInfo, 0, sizeof(mUiccInfo));
183    memset (&mHciCfg, 0, sizeof(mHciCfg));
184    mUsedAids.clear ();
185    memset(mAidForEmptySelect, 0, sizeof(mAidForEmptySelect));
186
187    // Get Fresh EE info.
188    if (! getEeInfo())
189        return (false);
190
191    {
192        SyncEventGuard guard (mEeRegisterEvent);
193        ALOGD ("%s: try ee register", fn);
194        nfaStat = NFA_EeRegister (nfaEeCallback);
195        if (nfaStat != NFA_STATUS_OK)
196        {
197            ALOGE ("%s: fail ee register; error=0x%X", fn, nfaStat);
198            return (false);
199        }
200        mEeRegisterEvent.wait ();
201    }
202
203    // If the controller has an HCI Network, register for that
204    for (xx = 0; xx < mActualNumEe; xx++)
205    {
206        if ((mEeInfo[xx].num_interface > 0) && (mEeInfo[xx].ee_interface[0] == NCI_NFCEE_INTERFACE_HCI_ACCESS) )
207        {
208            ALOGD ("%s: Found HCI network, try hci register", fn);
209
210            SyncEventGuard guard (mHciRegisterEvent);
211
212            nfaStat = NFA_HciRegister (const_cast<char*>(APP_NAME), nfaHciCallback, TRUE);
213            if (nfaStat != NFA_STATUS_OK)
214            {
215                ALOGE ("%s: fail hci register; error=0x%X", fn, nfaStat);
216                return (false);
217            }
218            mHciRegisterEvent.wait();
219            break;
220        }
221    }
222
223    mRouteDataSet.initialize ();
224    mRouteDataSet.import (); //read XML file
225    HostAidRouter::getInstance().initialize ();
226
227    GetStrValue(NAME_AID_FOR_EMPTY_SELECT, (char*)&mAidForEmptySelect[0], sizeof(mAidForEmptySelect));
228
229    mIsInit = true;
230    ALOGD ("%s: exit", fn);
231    return (true);
232}
233
234
235/*******************************************************************************
236**
237** Function:        finalize
238**
239** Description:     Release all resources.
240**
241** Returns:         None
242**
243*******************************************************************************/
244void SecureElement::finalize ()
245{
246    static const char fn [] = "SecureElement::finalize";
247    ALOGD ("%s: enter", fn);
248    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
249
250    NFA_EeDeregister (nfaEeCallback);
251
252    if (mNfaHciHandle != NFA_HANDLE_INVALID)
253        NFA_HciDeregister (const_cast<char*>(APP_NAME));
254
255    mNfaHciHandle = NFA_HANDLE_INVALID;
256    mNativeData   = NULL;
257    mIsInit       = false;
258    mActualNumEe  = 0;
259    mNumEePresent = 0;
260    mNewPipeId    = 0;
261    mNewSourceGate = 0;
262    mIsPiping = false;
263    memset (mEeInfo, 0, sizeof(mEeInfo));
264    memset (&mUiccInfo, 0, sizeof(mUiccInfo));
265
266    ALOGD ("%s: exit", fn);
267}
268
269
270/*******************************************************************************
271**
272** Function:        getEeInfo
273**
274** Description:     Get latest information about execution environments from stack.
275**
276** Returns:         True if at least 1 EE is available.
277**
278*******************************************************************************/
279bool SecureElement::getEeInfo()
280{
281    static const char fn [] = "SecureElement::getEeInfo";
282    ALOGD ("%s: enter; mbNewEE=%d, mActualNumEe=%d", fn, mbNewEE, mActualNumEe);
283    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
284    UINT8 xx = 0, yy = 0;
285
286    // If mbNewEE is true then there is new EE info.
287    if (mbNewEE)
288    {
289        mActualNumEe = MAX_NUM_EE;
290
291        if ((nfaStat = NFA_EeGetInfo (&mActualNumEe, mEeInfo)) != NFA_STATUS_OK)
292        {
293            ALOGE ("%s: fail get info; error=0x%X", fn, nfaStat);
294            mActualNumEe = 0;
295        }
296        else
297        {
298            mbNewEE = false;
299
300            ALOGD ("%s: num EEs discovered: %u", fn, mActualNumEe);
301            if (mActualNumEe != 0)
302            {
303                for (UINT8 xx = 0; xx < mActualNumEe; xx++)
304                {
305                    if ((mEeInfo[xx].num_interface != 0) && (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) )
306                        mNumEePresent++;
307
308                    ALOGD ("%s: EE[%u] Handle: 0x%04x  Status: %s  Num I/f: %u: (0x%02x, 0x%02x)  Num TLVs: %u",
309                          fn, xx, mEeInfo[xx].ee_handle, eeStatusToString(mEeInfo[xx].ee_status), mEeInfo[xx].num_interface,
310                          mEeInfo[xx].ee_interface[0], mEeInfo[xx].ee_interface[1], mEeInfo[xx].num_tlvs);
311
312                    for (yy = 0; yy < mEeInfo[xx].num_tlvs; yy++)
313                    {
314                        ALOGD ("%s: EE[%u] TLV[%u]  Tag: 0x%02x  Len: %u  Values[]: 0x%02x  0x%02x  0x%02x ...",
315                              fn, xx, yy, mEeInfo[xx].ee_tlv[yy].tag, mEeInfo[xx].ee_tlv[yy].len, mEeInfo[xx].ee_tlv[yy].info[0],
316                              mEeInfo[xx].ee_tlv[yy].info[1], mEeInfo[xx].ee_tlv[yy].info[2]);
317                    }
318                }
319            }
320        }
321    }
322    ALOGD ("%s: exit; mActualNumEe=%d, mNumEePresent=%d", fn, mActualNumEe,mNumEePresent);
323    return (mActualNumEe != 0);
324}
325
326
327/*******************************************************************************
328**
329** Function         TimeDiff
330**
331** Description      Computes time difference in milliseconds.
332**
333** Returns          Time difference in milliseconds
334**
335*******************************************************************************/
336static UINT32 TimeDiff(timespec start, timespec end)
337{
338    end.tv_sec -= start.tv_sec;
339    end.tv_nsec -= start.tv_nsec;
340
341    if (end.tv_nsec < 0) {
342        end.tv_nsec += 10e8;
343        end.tv_sec -=1;
344    }
345
346    return (end.tv_sec * 1000) + (end.tv_nsec / 10e5);
347}
348
349/*******************************************************************************
350**
351** Function:        isRfFieldOn
352**
353** Description:     Can be used to determine if the SE is in an RF field
354**
355** Returns:         True if the SE is activated in an RF field
356**
357*******************************************************************************/
358bool SecureElement::isRfFieldOn() {
359    AutoMutex mutex(mMutex);
360    if (mRfFieldIsOn) {
361        return true;
362    }
363    struct timespec now;
364    int ret = clock_gettime(CLOCK_MONOTONIC, &now);
365    if (ret == -1) {
366        ALOGE("isRfFieldOn(): clock_gettime failed");
367        return false;
368    }
369    if (TimeDiff(mLastRfFieldToggle, now) < 50) {
370        // If it was less than 50ms ago that RF field
371        // was turned off, still return ON.
372        return true;
373    } else {
374        return false;
375    }
376}
377
378/*******************************************************************************
379**
380** Function:        isActivatedInListenMode
381**
382** Description:     Can be used to determine if the SE is activated in listen mode
383**
384** Returns:         True if the SE is activated in listen mode
385**
386*******************************************************************************/
387bool SecureElement::isActivatedInListenMode() {
388    return mActivatedInListenMode;
389}
390
391/*******************************************************************************
392**
393** Function:        getListOfEeHandles
394**
395** Description:     Get the list of handles of all execution environments.
396**                  e: Java Virtual Machine.
397**
398** Returns:         List of handles of all execution environments.
399**
400*******************************************************************************/
401jintArray SecureElement::getListOfEeHandles (JNIEnv* e)
402{
403    static const char fn [] = "SecureElement::getListOfEeHandles";
404    ALOGD ("%s: enter", fn);
405    if (mNumEePresent == 0)
406        return NULL;
407    jintArray list = NULL;
408
409    if (!mIsInit)
410    {
411        ALOGE ("%s: not init", fn);
412        return (NULL);
413    }
414
415    // Get Fresh EE info.
416    if (! getEeInfo())
417        return (NULL);
418
419    list = e->NewIntArray (mNumEePresent); //allocate array
420    jint jj = 0;
421    int cnt = 0;
422    for (int ii = 0; ii < mActualNumEe && cnt < mNumEePresent; ii++)
423    {
424        ALOGD ("%s: %u = 0x%X", fn, ii, mEeInfo[ii].ee_handle);
425        if ((mEeInfo[ii].num_interface == 0) || (mEeInfo[ii].ee_interface[0] == NCI_NFCEE_INTERFACE_HCI_ACCESS) )
426        {
427            continue;
428        }
429
430        jj = mEeInfo[ii].ee_handle & ~NFA_HANDLE_GROUP_EE;
431        e->SetIntArrayRegion (list, cnt++, 1, &jj);
432    }
433    //e->DeleteLocalRef (list);
434
435    ALOGD("%s: exit", fn);
436    return list;
437}
438
439
440/*******************************************************************************
441**
442** Function:        activate
443**
444** Description:     Turn on the secure element.
445**                  seID: ID of secure element.
446**
447** Returns:         True if ok.
448**
449*******************************************************************************/
450bool SecureElement::activate (jint seID)
451{
452    static const char fn [] = "SecureElement::activate";
453    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
454    int numActivatedEe = 0;
455
456    ALOGD ("%s: enter; seID=0x%X", fn, seID);
457
458    if (!mIsInit)
459    {
460        ALOGE ("%s: not init", fn);
461        return false;
462    }
463
464    if (mActiveEeHandle != NFA_HANDLE_INVALID)
465    {
466        ALOGD ("%s: already active", fn);
467        return true;
468    }
469
470    // Get Fresh EE info if needed.
471    if (! getEeInfo())
472    {
473        ALOGE ("%s: no EE info", fn);
474        return false;
475    }
476
477    mActiveEeHandle = getDefaultEeHandle();
478    ALOGD ("%s: active ee h=0x%X, override se=0x%X", fn, mActiveEeHandle, mActiveSeOverride);
479    if (mActiveEeHandle == NFA_HANDLE_INVALID)
480    {
481        ALOGE ("%s: ee not found", fn);
482        return false;
483    }
484
485    UINT16 override_se = 0;
486    if (mActiveSeOverride)
487        override_se = NFA_HANDLE_GROUP_EE | mActiveSeOverride;
488
489    if (mRfFieldIsOn) {
490        ALOGE("%s: RF field indication still on, resetting", fn);
491        mRfFieldIsOn = false;
492    }
493
494    ALOGD ("%s: override seid=0x%X", fn, override_se );
495    //activate every discovered secure element
496    for (int index=0; index < mActualNumEe; index++)
497    {
498        tNFA_EE_INFO& eeItem = mEeInfo[index];
499
500        if ((eeItem.ee_handle == EE_HANDLE_0xF3) || (eeItem.ee_handle == EE_HANDLE_0xF4))
501        {
502            if (override_se && (override_se != eeItem.ee_handle) )
503                continue;   // do not enable all SEs; only the override one
504
505            if (eeItem.ee_status != NFC_NFCEE_STATUS_INACTIVE)
506            {
507                ALOGD ("%s: h=0x%X already activated", fn, eeItem.ee_handle);
508                numActivatedEe++;
509                continue;
510            }
511
512            {
513                SyncEventGuard guard (mEeSetModeEvent);
514                ALOGD ("%s: set EE mode activate; h=0x%X", fn, eeItem.ee_handle);
515                if ((nfaStat = NFA_EeModeSet (eeItem.ee_handle, NFA_EE_MD_ACTIVATE)) == NFA_STATUS_OK)
516                {
517                    mEeSetModeEvent.wait (); //wait for NFA_EE_MODE_SET_EVT
518                    if (eeItem.ee_status == NFC_NFCEE_STATUS_ACTIVE)
519                        numActivatedEe++;
520                }
521                else
522                    ALOGE ("%s: NFA_EeModeSet failed; error=0x%X", fn, nfaStat);
523            }
524        }
525    } //for
526
527    for (UINT8 xx = 0; xx < mActualNumEe; xx++)
528    {
529        if ((mEeInfo[xx].num_interface != 0) && (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) &&
530            (mEeInfo[xx].ee_status != NFC_NFCEE_STATUS_INACTIVE))
531        {
532            mActiveEeHandle = mEeInfo[xx].ee_handle;
533            break;
534        }
535    }
536
537    ALOGD ("%s: exit; ok=%u", fn, numActivatedEe > 0);
538    return numActivatedEe > 0;
539}
540
541
542/*******************************************************************************
543**
544** Function:        deactivate
545**
546** Description:     Turn off the secure element.
547**                  seID: ID of secure element.
548**
549** Returns:         True if ok.
550**
551*******************************************************************************/
552bool SecureElement::deactivate (jint seID)
553{
554    static const char fn [] = "SecureElement::deactivate";
555    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
556    int numDeactivatedEe = 0;
557    bool retval = false;
558
559    ALOGD ("%s: enter; seID=0x%X, mActiveEeHandle=0x%X", fn, seID, mActiveEeHandle);
560
561    if (!mIsInit)
562    {
563        ALOGE ("%s: not init", fn);
564        goto TheEnd;
565    }
566
567    //if the controller is routing to sec elems or piping,
568    //then the secure element cannot be deactivated
569    if ((mCurrentRouteSelection == SecElemRoute) || mIsPiping)
570    {
571        ALOGE ("%s: still busy", fn);
572        goto TheEnd;
573    }
574
575    if (mActiveEeHandle == NFA_HANDLE_INVALID)
576    {
577        ALOGE ("%s: invalid EE handle", fn);
578        goto TheEnd;
579    }
580
581    mActiveEeHandle = NFA_HANDLE_INVALID;
582    retval = true;
583
584TheEnd:
585    ALOGD ("%s: exit; ok=%u", fn, retval);
586    return retval;
587}
588
589
590/*******************************************************************************
591**
592** Function:        notifyTransactionListenersOfAid
593**
594** Description:     Notify the NFC service about a transaction event from secure element.
595**                  aid: Buffer contains application ID.
596**                  aidLen: Length of application ID.
597**
598** Returns:         None
599**
600*******************************************************************************/
601void SecureElement::notifyTransactionListenersOfAid (const UINT8* aidBuffer, UINT8 aidBufferLen)
602{
603    static const char fn [] = "SecureElement::notifyTransactionListenersOfAid";
604    ALOGD ("%s: enter; aid len=%u", fn, aidBufferLen);
605
606    if (aidBufferLen == 0)
607    	return;
608
609    jobject tlvJavaArray = NULL;
610    JNIEnv* e = NULL;
611    UINT8* tlv = 0;
612    const UINT16 tlvMaxLen = aidBufferLen + 10;
613    UINT16 tlvActualLen = 0;
614    bool stat = false;
615
616    mNativeData->vm->AttachCurrentThread (&e, NULL);
617    if (e == NULL)
618    {
619        ALOGE ("%s: jni env is null", fn);
620        return;
621    }
622
623    tlv = new UINT8 [tlvMaxLen];
624    if (tlv == NULL)
625    {
626        ALOGE ("%s: fail allocate tlv", fn);
627        goto TheEnd;
628    }
629
630    memcpy (tlv, aidBuffer, aidBufferLen);
631    tlvActualLen = aidBufferLen;
632
633    tlvJavaArray = e->NewByteArray (tlvActualLen);
634    if (tlvJavaArray == NULL)
635    {
636        ALOGE ("%s: fail allocate array", fn);
637        goto TheEnd;
638    }
639
640    e->SetByteArrayRegion ((jbyteArray)tlvJavaArray, 0, tlvActualLen, (jbyte *)tlv);
641    if (e->ExceptionCheck())
642    {
643        e->ExceptionClear();
644        ALOGE ("%s: fail fill array", fn);
645        goto TheEnd;
646    }
647
648    e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifyTransactionListeners, tlvJavaArray);
649    if (e->ExceptionCheck())
650    {
651        e->ExceptionClear();
652        ALOGE ("%s: fail notify", fn);
653        goto TheEnd;
654    }
655
656TheEnd:
657    if (tlvJavaArray)
658        e->DeleteLocalRef (tlvJavaArray);
659    mNativeData->vm->DetachCurrentThread ();
660    delete [] tlv;
661    ALOGD ("%s: exit", fn);
662}
663
664
665/*******************************************************************************
666**
667** Function:        connectEE
668**
669** Description:     Connect to the execution environment.
670**
671** Returns:         True if ok.
672**
673*******************************************************************************/
674bool SecureElement::connectEE ()
675{
676    static const char fn [] = "SecureElement::connectEE";
677    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
678    bool        retVal = false;
679    UINT8       destHost = 0;
680    unsigned long num = 0;
681    char pipeConfName[40];
682    tNFA_HANDLE  eeHandle = mActiveEeHandle;
683
684    ALOGD ("%s: enter, mActiveEeHandle: 0x%04x, SEID: 0x%x, pipe_gate_num=%d, use pipe=%d",
685        fn, mActiveEeHandle, gSEId, gGatePipe, gUseStaticPipe);
686
687    if (!mIsInit)
688    {
689        ALOGE ("%s: not init", fn);
690        return (false);
691    }
692
693    if (gSEId != -1)
694    {
695        eeHandle = gSEId | NFA_HANDLE_GROUP_EE;
696        ALOGD ("%s: Using SEID: 0x%x", fn, eeHandle );
697    }
698
699    if (eeHandle == NFA_HANDLE_INVALID)
700    {
701        ALOGE ("%s: invalid handle 0x%X", fn, eeHandle);
702        return (false);
703    }
704
705    tNFA_EE_INFO *pEE = findEeByHandle (eeHandle);
706
707    if (pEE == NULL)
708    {
709        ALOGE ("%s: Handle 0x%04x  NOT FOUND !!", fn, eeHandle);
710        return (false);
711    }
712
713    // Disable RF discovery completely while the DH is connected
714    android::startRfDiscovery(false);
715
716    mNewSourceGate = 0;
717
718    if (gGatePipe == -1)
719    {
720        // pipe/gate num was not specifed by app, get from config file
721        mNewPipeId     = 0;
722
723        // Construct the PIPE name based on the EE handle (e.g. NFA_HCI_STATIC_PIPE_ID_F3 for UICC0).
724        snprintf (pipeConfName, sizeof(pipeConfName), "NFA_HCI_STATIC_PIPE_ID_%02X", eeHandle & NFA_HANDLE_MASK);
725
726        if (GetNumValue(pipeConfName, &num, sizeof(num)) && (num != 0))
727        {
728            mNewPipeId = num;
729            ALOGD ("%s: Using static pipe id: 0x%X", __FUNCTION__, mNewPipeId);
730        }
731        else
732        {
733            ALOGD ("%s: Did not find value '%s' defined in the .conf", __FUNCTION__, pipeConfName);
734        }
735    }
736    else
737    {
738        if (gUseStaticPipe)
739        {
740            mNewPipeId     = gGatePipe;
741        }
742        else
743        {
744            mNewPipeId      = 0;
745            mDestinationGate= gGatePipe;
746        }
747    }
748
749    // If the .conf file had a static pipe to use, just use it.
750    if (mNewPipeId != 0)
751    {
752        UINT8 host = (mNewPipeId == STATIC_PIPE_0x70) ? 0x02 : 0x03;
753        UINT8 gate = (mNewPipeId == STATIC_PIPE_0x70) ? 0xF0 : 0xF1;
754        nfaStat = NFA_HciAddStaticPipe(mNfaHciHandle, host, gate, mNewPipeId);
755        if (nfaStat != NFA_STATUS_OK)
756        {
757            ALOGE ("%s: fail create static pipe; error=0x%X", fn, nfaStat);
758            retVal = false;
759            goto TheEnd;
760        }
761    }
762    else
763    {
764        if ( (pEE->num_tlvs >= 1) && (pEE->ee_tlv[0].tag == NFA_EE_TAG_HCI_HOST_ID) )
765            destHost = pEE->ee_tlv[0].info[0];
766        else
767            destHost = 2;
768
769        // Get a list of existing gates and pipes
770        {
771            ALOGD ("%s: get gate, pipe list", fn);
772            SyncEventGuard guard (mPipeListEvent);
773            nfaStat = NFA_HciGetGateAndPipeList (mNfaHciHandle);
774            if (nfaStat == NFA_STATUS_OK)
775            {
776                mPipeListEvent.wait();
777                if (mHciCfg.status == NFA_STATUS_OK)
778                {
779                    for (UINT8 xx = 0; xx < mHciCfg.num_pipes; xx++)
780                    {
781                        if ( (mHciCfg.pipe[xx].dest_host == destHost)
782                         &&  (mHciCfg.pipe[xx].dest_gate == mDestinationGate) )
783                        {
784                            mNewSourceGate = mHciCfg.pipe[xx].local_gate;
785                            mNewPipeId     = mHciCfg.pipe[xx].pipe_id;
786
787                            ALOGD ("%s: found configured gate: 0x%02x  pipe: 0x%02x", fn, mNewSourceGate, mNewPipeId);
788                            break;
789                        }
790                    }
791                }
792            }
793        }
794
795        if (mNewSourceGate == 0)
796        {
797            ALOGD ("%s: allocate gate", fn);
798            //allocate a source gate and store in mNewSourceGate
799            SyncEventGuard guard (mAllocateGateEvent);
800            if ((nfaStat = NFA_HciAllocGate (mNfaHciHandle)) != NFA_STATUS_OK)
801            {
802                ALOGE ("%s: fail allocate source gate; error=0x%X", fn, nfaStat);
803                goto TheEnd;
804            }
805            mAllocateGateEvent.wait ();
806            if (mCommandStatus != NFA_STATUS_OK)
807               goto TheEnd;
808        }
809
810        if (mNewPipeId == 0)
811        {
812            ALOGD ("%s: create pipe", fn);
813            SyncEventGuard guard (mCreatePipeEvent);
814            nfaStat = NFA_HciCreatePipe (mNfaHciHandle, mNewSourceGate, destHost, mDestinationGate);
815            if (nfaStat != NFA_STATUS_OK)
816            {
817                ALOGE ("%s: fail create pipe; error=0x%X", fn, nfaStat);
818                goto TheEnd;
819            }
820            mCreatePipeEvent.wait ();
821            if (mCommandStatus != NFA_STATUS_OK)
822               goto TheEnd;
823        }
824
825        {
826            ALOGD ("%s: open pipe", fn);
827            SyncEventGuard guard (mPipeOpenedEvent);
828            nfaStat = NFA_HciOpenPipe (mNfaHciHandle, mNewPipeId);
829            if (nfaStat != NFA_STATUS_OK)
830            {
831                ALOGE ("%s: fail open pipe; error=0x%X", fn, nfaStat);
832                goto TheEnd;
833            }
834            mPipeOpenedEvent.wait ();
835            if (mCommandStatus != NFA_STATUS_OK)
836               goto TheEnd;
837        }
838    }
839
840    retVal = true;
841
842TheEnd:
843    mIsPiping = retVal;
844    if (!retVal)
845    {
846        // if open failed we need to de-allocate the gate
847        disconnectEE(0);
848    }
849
850    ALOGD ("%s: exit; ok=%u", fn, retVal);
851    return retVal;
852}
853
854
855/*******************************************************************************
856**
857** Function:        disconnectEE
858**
859** Description:     Disconnect from the execution environment.
860**                  seID: ID of secure element.
861**
862** Returns:         True if ok.
863**
864*******************************************************************************/
865bool SecureElement::disconnectEE (jint seID)
866{
867    static const char fn [] = "SecureElement::disconnectEE";
868    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
869    tNFA_HANDLE eeHandle = seID;
870
871    ALOGD("%s: seID=0x%X; handle=0x%04x", fn, seID, eeHandle);
872
873    if (mUseOberthurWarmReset)
874    {
875        //send warm-reset command to Oberthur secure element which deselects the applet;
876        //this is an Oberthur-specific command;
877        ALOGD("%s: try warm-reset on pipe id 0x%X; cmd=0x%X", fn, mNewPipeId, mOberthurWarmResetCommand);
878        SyncEventGuard guard (mRegistryEvent);
879        nfaStat = NFA_HciSetRegistry (mNfaHciHandle, mNewPipeId,
880                1, 1, &mOberthurWarmResetCommand);
881        if (nfaStat == NFA_STATUS_OK)
882        {
883            mRegistryEvent.wait ();
884            ALOGD("%s: completed warm-reset on pipe 0x%X", fn, mNewPipeId);
885        }
886    }
887
888    if (mNewSourceGate)
889    {
890        SyncEventGuard guard (mDeallocateGateEvent);
891        if ((nfaStat = NFA_HciDeallocGate (mNfaHciHandle, mNewSourceGate)) == NFA_STATUS_OK)
892            mDeallocateGateEvent.wait ();
893        else
894            ALOGE ("%s: fail dealloc gate; error=0x%X", fn, nfaStat);
895    }
896    mIsPiping = false;
897    // Re-enable RF discovery
898    // Note that it only effactuates the current configuration,
899    // so if polling/listening were configured OFF (forex because
900    // the screen was off), they will stay OFF with this call.
901    android::startRfDiscovery(true);
902    return true;
903}
904
905
906/*******************************************************************************
907**
908** Function:        transceive
909**
910** Description:     Send data to the secure element; read it's response.
911**                  xmitBuffer: Data to transmit.
912**                  xmitBufferSize: Length of data.
913**                  recvBuffer: Buffer to receive response.
914**                  recvBufferMaxSize: Maximum size of buffer.
915**                  recvBufferActualSize: Actual length of response.
916**                  timeoutMillisec: timeout in millisecond.
917**
918** Returns:         True if ok.
919**
920*******************************************************************************/
921bool SecureElement::transceive (UINT8* xmitBuffer, INT32 xmitBufferSize, UINT8* recvBuffer,
922        INT32 recvBufferMaxSize, INT32& recvBufferActualSize, INT32 timeoutMillisec)
923{
924    static const char fn [] = "SecureElement::transceive";
925    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
926    bool isSuccess = false;
927    bool waitOk = false;
928    UINT8 newSelectCmd[NCI_MAX_AID_LEN + 10];
929
930    ALOGD ("%s: enter; xmitBufferSize=%ld; recvBufferMaxSize=%ld; timeout=%ld", fn, xmitBufferSize, recvBufferMaxSize, timeoutMillisec);
931
932    // Check if we need to replace an "empty" SELECT command.
933    // 1. Has there been a AID configured, and
934    // 2. Is that AID a valid length (i.e 16 bytes max), and
935    // 3. Is the APDU at least 4 bytes (for header), and
936    // 4. Is INS == 0xA4 (SELECT command), and
937    // 5. Is P1 == 0x04 (SELECT by AID), and
938    // 6. Is the APDU len 4 or 5 bytes.
939    //
940    // Note, the length of the configured AID is in the first
941    //   byte, and AID starts from the 2nd byte.
942    if (mAidForEmptySelect[0]                           // 1
943        && (mAidForEmptySelect[0] <= NCI_MAX_AID_LEN)   // 2
944        && (xmitBufferSize >= 4)                        // 3
945        && (xmitBuffer[1] == 0xA4)                      // 4
946        && (xmitBuffer[2] == 0x04)                      // 5
947        && (xmitBufferSize <= 5))                       // 6
948    {
949        UINT8 idx = 0;
950
951        // Copy APDU command header from the input buffer.
952        memcpy(&newSelectCmd[0], &xmitBuffer[0], 4);
953        idx = 4;
954
955        // Set the Lc value to length of the new AID
956        newSelectCmd[idx++] = mAidForEmptySelect[0];
957
958        // Copy the AID
959        memcpy(&newSelectCmd[idx], &mAidForEmptySelect[1], mAidForEmptySelect[0]);
960        idx += mAidForEmptySelect[0];
961
962        // If there is an Le (5th byte of APDU), add it to the end.
963        if (xmitBufferSize == 5)
964            newSelectCmd[idx++] = xmitBuffer[4];
965
966        // Point to the new APDU
967        xmitBuffer = &newSelectCmd[0];
968        xmitBufferSize = idx;
969
970        ALOGD ("%s: Empty AID SELECT cmd detected, substituting AID from config file, new length=%d", fn, idx);
971    }
972
973    {
974        SyncEventGuard guard (mTransceiveEvent);
975        mActualResponseSize = 0;
976        memset (mResponseData, 0, sizeof(mResponseData));
977        if ((mNewPipeId == STATIC_PIPE_0x70) || (mNewPipeId == STATIC_PIPE_0x71))
978            nfaStat = NFA_HciSendEvent (mNfaHciHandle, mNewPipeId, EVT_SEND_DATA, xmitBufferSize, xmitBuffer, sizeof(mResponseData), mResponseData, 0);
979        else
980            nfaStat = NFA_HciSendEvent (mNfaHciHandle, mNewPipeId, NFA_HCI_EVT_POST_DATA, xmitBufferSize, xmitBuffer, sizeof(mResponseData), mResponseData, 0);
981
982        if (nfaStat == NFA_STATUS_OK)
983        {
984            waitOk = mTransceiveEvent.wait (timeoutMillisec);
985            if (waitOk == false) //timeout occurs
986            {
987                ALOGE ("%s: wait response timeout", fn);
988                goto TheEnd;
989            }
990        }
991        else
992        {
993            ALOGE ("%s: fail send data; error=0x%X", fn, nfaStat);
994            goto TheEnd;
995        }
996    }
997
998    if (mActualResponseSize > recvBufferMaxSize)
999        recvBufferActualSize = recvBufferMaxSize;
1000    else
1001        recvBufferActualSize = mActualResponseSize;
1002
1003    memcpy (recvBuffer, mResponseData, recvBufferActualSize);
1004    isSuccess = true;
1005
1006TheEnd:
1007    ALOGD ("%s: exit; isSuccess: %d; recvBufferActualSize: %ld", fn, isSuccess, recvBufferActualSize);
1008    return (isSuccess);
1009}
1010
1011
1012/*******************************************************************************
1013**
1014** Function:        notifyListenModeState
1015**
1016** Description:     Notify the NFC service about whether the SE was activated
1017**                  in listen mode.
1018**                  isActive: Whether the secure element is activated.
1019**
1020** Returns:         None
1021**
1022*******************************************************************************/
1023void SecureElement::notifyListenModeState (bool isActivated) {
1024    static const char fn [] = "SecureElement::notifyListenMode";
1025    JNIEnv *e = NULL;
1026
1027    ALOGD ("%s: enter; listen mode active=%u", fn, isActivated);
1028    mNativeData->vm->AttachCurrentThread (&e, NULL);
1029
1030    if (e == NULL)
1031    {
1032        ALOGE ("%s: jni env is null", fn);
1033        return;
1034    }
1035
1036    mActivatedInListenMode = isActivated;
1037    if (isActivated) {
1038        e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifySeListenActivated);
1039    }
1040    else {
1041        e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifySeListenDeactivated);
1042    }
1043
1044    if (e->ExceptionCheck())
1045    {
1046        e->ExceptionClear();
1047        ALOGE ("%s: fail notify", fn);
1048    }
1049
1050    mNativeData->vm->DetachCurrentThread ();
1051    ALOGD ("%s: exit", fn);
1052}
1053
1054/*******************************************************************************
1055**
1056** Function:        notifyRfFieldEvent
1057**
1058** Description:     Notify the NFC service about RF field events from the stack.
1059**                  isActive: Whether any secure element is activated.
1060**
1061** Returns:         None
1062**
1063*******************************************************************************/
1064void SecureElement::notifyRfFieldEvent (bool isActive)
1065{
1066    static const char fn [] = "SecureElement::notifyRfFieldEvent";
1067    JNIEnv *e = NULL;
1068
1069    ALOGD ("%s: enter; is active=%u", fn, isActive);
1070    mNativeData->vm->AttachCurrentThread (&e, NULL);
1071
1072    if (e == NULL)
1073    {
1074        ALOGE ("%s: jni env is null", fn);
1075        return;
1076    }
1077
1078    mMutex.lock();
1079    int ret = clock_gettime (CLOCK_MONOTONIC, &mLastRfFieldToggle);
1080    if (ret == -1) {
1081        ALOGE("%s: clock_gettime failed", fn);
1082        // There is no good choice here...
1083    }
1084    if (isActive) {
1085        mRfFieldIsOn = true;
1086        e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifySeFieldActivated);
1087    }
1088    else {
1089        mRfFieldIsOn = false;
1090        e->CallVoidMethod (mNativeData->manager, android::gCachedNfcManagerNotifySeFieldDeactivated);
1091    }
1092    mMutex.unlock();
1093
1094    if (e->ExceptionCheck())
1095    {
1096        e->ExceptionClear();
1097        ALOGE ("%s: fail notify", fn);
1098    }
1099    mNativeData->vm->DetachCurrentThread ();
1100    ALOGD ("%s: exit", fn);
1101}
1102
1103
1104/*******************************************************************************
1105**
1106** Function:        storeUiccInfo
1107**
1108** Description:     Store a copy of the execution environment information from the stack.
1109**                  info: execution environment information.
1110**
1111** Returns:         None
1112**
1113*******************************************************************************/
1114void SecureElement::storeUiccInfo (tNFA_EE_DISCOVER_REQ& info)
1115{
1116    static const char fn [] = "SecureElement::storeUiccInfo";
1117    ALOGD ("%s:  Status: %u   Num EE: %u", fn, info.status, info.num_ee);
1118
1119    SyncEventGuard guard (mUiccInfoEvent);
1120    memcpy (&mUiccInfo, &info, sizeof(mUiccInfo));
1121    for (UINT8 xx = 0; xx < info.num_ee; xx++)
1122    {
1123        //for each technology (A, B, F, B'), print the bit field that shows
1124        //what protocol(s) is support by that technology
1125        ALOGD ("%s   EE[%u] Handle: 0x%04x  techA: 0x%02x  techB: 0x%02x  techF: 0x%02x  techBprime: 0x%02x",
1126                fn, xx, info.ee_disc_info[xx].ee_handle,
1127                info.ee_disc_info[xx].la_protocol,
1128                info.ee_disc_info[xx].lb_protocol,
1129                info.ee_disc_info[xx].lf_protocol,
1130                info.ee_disc_info[xx].lbp_protocol);
1131    }
1132    mUiccInfoEvent.notifyOne ();
1133}
1134
1135
1136/*******************************************************************************
1137**
1138** Function:        getUiccId
1139**
1140** Description:     Get the ID of the secure element.
1141**                  eeHandle: Handle to the secure element.
1142**                  uid: Array to receive the ID.
1143**
1144** Returns:         True if ok.
1145**
1146*******************************************************************************/
1147bool SecureElement::getUiccId (tNFA_HANDLE eeHandle, jbyteArray& uid)
1148{
1149    static const char fn [] = "SecureElement::getUiccId";
1150    ALOGD ("%s: ee h=0x%X", fn, eeHandle);
1151    bool retval = false;
1152    JNIEnv* e = NULL;
1153
1154    mNativeData->vm->AttachCurrentThread (&e, NULL);
1155    if (e == NULL)
1156    {
1157        ALOGE ("%s: jni env is null", fn);
1158        return false;
1159    }
1160
1161    findUiccByHandle (eeHandle);
1162    //cannot get UID from the stack; nothing to do
1163
1164TheEnd:
1165    mNativeData->vm->DetachCurrentThread ();
1166    ALOGD ("%s: exit; ret=%u", fn, retval);
1167    return retval;
1168}
1169
1170
1171/*******************************************************************************
1172**
1173** Function:        getTechnologyList
1174**
1175** Description:     Get all the technologies supported by a secure element.
1176**                  eeHandle: Handle of secure element.
1177**                  techList: List to receive the technologies.
1178**
1179** Returns:         True if ok.
1180**
1181*******************************************************************************/
1182bool SecureElement::getTechnologyList (tNFA_HANDLE eeHandle, jintArray& techList)
1183{
1184    static const char fn [] = "SecureElement::getTechnologyList";
1185    ALOGD ("%s: ee h=0x%X", fn, eeHandle);
1186    bool retval = false;
1187    JNIEnv* e = NULL;
1188    jint theList = 0;
1189
1190    mNativeData->vm->AttachCurrentThread (&e, NULL);
1191    if (e == NULL)
1192    {
1193        ALOGE ("%s: jni env is null", fn);
1194        return false;
1195    }
1196
1197    tNFA_EE_DISCOVER_INFO *pUICC = findUiccByHandle (eeHandle);
1198
1199    if (pUICC->la_protocol != 0)
1200        theList = TARGET_TYPE_ISO14443_3A;
1201    else if (pUICC->lb_protocol != 0)
1202        theList = TARGET_TYPE_ISO14443_3B;
1203    else if (pUICC->lf_protocol != 0)
1204        theList = TARGET_TYPE_FELICA;
1205    else if (pUICC->lbp_protocol != 0)
1206        theList = TARGET_TYPE_ISO14443_3B;
1207    else
1208        theList = TARGET_TYPE_UNKNOWN;
1209
1210TheEnd:
1211    mNativeData->vm->DetachCurrentThread ();
1212    ALOGD ("%s: exit; ret=%u", fn, retval);
1213    return retval;
1214}
1215
1216
1217/*******************************************************************************
1218**
1219** Function:        adjustRoutes
1220**
1221** Description:     Adjust routes in the controller's listen-mode routing table.
1222**                  selection: which set of routes to configure the controller.
1223**
1224** Returns:         None
1225**
1226*******************************************************************************/
1227void SecureElement::adjustRoutes (RouteSelection selection)
1228{
1229    static const char fn [] = "SecureElement::adjustRoutes";
1230    ALOGD ("%s: enter; selection=%u", fn, selection);
1231    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
1232    RouteDataSet::Database* db = mRouteDataSet.getDatabase (RouteDataSet::DefaultRouteDatabase);
1233
1234    if (selection == SecElemRoute)
1235        db = mRouteDataSet.getDatabase (RouteDataSet::SecElemRouteDatabase);
1236
1237    mCurrentRouteSelection = selection;
1238    adjustProtocolRoutes (db, selection);
1239    adjustTechnologyRoutes (db, selection);
1240    HostAidRouter::getInstance ().deleteAllRoutes (); //stop all AID routes to host
1241
1242    if (db->empty())
1243    {
1244        ALOGD ("%s: no route configuration", fn);
1245        goto TheEnd;
1246    }
1247
1248
1249TheEnd:
1250    NFA_EeUpdateNow (); //apply new routes now
1251    ALOGD ("%s: exit", fn);
1252}
1253
1254
1255/*******************************************************************************
1256**
1257** Function:        applyRoutes
1258**
1259** Description:     Read route data from file and apply them again.
1260**
1261** Returns:         None
1262**
1263*******************************************************************************/
1264void SecureElement::applyRoutes ()
1265{
1266    static const char fn [] = "SecureElement::applyRoutes";
1267    ALOGD ("%s: enter", fn);
1268    if (mCurrentRouteSelection != NoRoute)
1269    {
1270        mRouteDataSet.import (); //read XML file
1271        adjustRoutes (mCurrentRouteSelection);
1272    }
1273    ALOGD ("%s: exit", fn);
1274}
1275
1276
1277/*******************************************************************************
1278**
1279** Function:        adjustProtocolRoutes
1280**
1281** Description:     Adjust default routing based on protocol in NFC listen mode.
1282**                  isRouteToEe: Whether routing to EE (true) or host (false).
1283**
1284** Returns:         None
1285**
1286*******************************************************************************/
1287void SecureElement::adjustProtocolRoutes (RouteDataSet::Database* db, RouteSelection routeSelection)
1288{
1289    static const char fn [] = "SecureElement::adjustProtocolRoutes";
1290    ALOGD ("%s: enter", fn);
1291    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
1292    const tNFA_PROTOCOL_MASK protoMask = NFA_PROTOCOL_MASK_ISO_DEP;
1293
1294    ///////////////////////
1295    // delete route to host
1296    ///////////////////////
1297    {
1298        ALOGD ("%s: delete route to host", fn);
1299        SyncEventGuard guard (mRoutingEvent);
1300        if ((nfaStat = NFA_EeSetDefaultProtoRouting (NFA_EE_HANDLE_DH, 0, 0, 0)) == NFA_STATUS_OK)
1301            mRoutingEvent.wait ();
1302        else
1303            ALOGE ("%s: fail delete route to host; error=0x%X", fn, nfaStat);
1304    }
1305
1306    ///////////////////////
1307    // delete route to every sec elem
1308    ///////////////////////
1309    for (int i=0; i < mActualNumEe; i++)
1310    {
1311        if ((mEeInfo[i].num_interface != 0) &&
1312                (mEeInfo[i].ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) &&
1313                (mEeInfo[i].ee_status == NFA_EE_STATUS_ACTIVE))
1314        {
1315            ALOGD ("%s: delete route to EE h=0x%X", fn, mEeInfo[i].ee_handle);
1316            SyncEventGuard guard (mRoutingEvent);
1317            if ((nfaStat = NFA_EeSetDefaultProtoRouting (mEeInfo[i].ee_handle, 0, 0, 0)) == NFA_STATUS_OK)
1318                mRoutingEvent.wait ();
1319            else
1320                ALOGE ("%s: fail delete route to EE; error=0x%X", fn, nfaStat);
1321        }
1322    }
1323
1324    //////////////////////
1325    // configure route for every discovered sec elem
1326    //////////////////////
1327    for (int i=0; i < mActualNumEe; i++)
1328    {
1329        //if sec elem is active
1330        if ((mEeInfo[i].num_interface != 0) &&
1331                (mEeInfo[i].ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) &&
1332                (mEeInfo[i].ee_status == NFA_EE_STATUS_ACTIVE))
1333        {
1334            tNFA_PROTOCOL_MASK protocolsSwitchOn = 0; //all protocols that are active at full power
1335            tNFA_PROTOCOL_MASK protocolsSwitchOff = 0; //all protocols that are active when phone is turned off
1336            tNFA_PROTOCOL_MASK protocolsBatteryOff = 0; //all protocols that are active when there is no power
1337
1338            //for every route in XML, look for protocol route;
1339            //collect every protocol according to it's desired power mode
1340            for (RouteDataSet::Database::iterator iter = db->begin(); iter != db->end(); iter++)
1341            {
1342                RouteData* routeData = *iter;
1343                RouteDataForProtocol* route = NULL;
1344                if (routeData->mRouteType != RouteData::ProtocolRoute)
1345                    continue; //skip other kinds of routing data
1346                route = (RouteDataForProtocol*) (*iter);
1347                if (route->mNfaEeHandle == mEeInfo[i].ee_handle)
1348                {
1349                    if (route->mSwitchOn)
1350                        protocolsSwitchOn |= route->mProtocol;
1351                    if (route->mSwitchOff)
1352                        protocolsSwitchOff |= route->mProtocol;
1353                    if (route->mBatteryOff)
1354                        protocolsBatteryOff |= route->mProtocol;
1355                }
1356            }
1357
1358            if (protocolsSwitchOn | protocolsSwitchOff | protocolsBatteryOff)
1359            {
1360                ALOGD ("%s: route to EE h=0x%X", fn, mEeInfo[i].ee_handle);
1361                SyncEventGuard guard (mRoutingEvent);
1362                nfaStat = NFA_EeSetDefaultProtoRouting (mEeInfo[i].ee_handle,
1363                        protocolsSwitchOn, protocolsSwitchOff, protocolsBatteryOff);
1364                if (nfaStat == NFA_STATUS_OK)
1365                    mRoutingEvent.wait ();
1366                else
1367                    ALOGE ("%s: fail route to EE; error=0x%X", fn, nfaStat);
1368            }
1369        } //if sec elem is active
1370    } //for every discovered sec elem
1371
1372    //////////////////////
1373    // configure route to host
1374    //////////////////////
1375    {
1376        tNFA_PROTOCOL_MASK protocolsSwitchOn = 0; //all protocols that are active at full power
1377        tNFA_PROTOCOL_MASK protocolsSwitchOff = 0; //all protocols that are active when phone is turned off
1378        tNFA_PROTOCOL_MASK protocolsBatteryOff = 0; //all protocols that are active when there is no power
1379
1380        //for every route in XML, look for protocol route;
1381        //collect every protocol according to it's desired power mode
1382        for (RouteDataSet::Database::iterator iter = db->begin(); iter != db->end(); iter++)
1383        {
1384            RouteData* routeData = *iter;
1385            RouteDataForProtocol* route = NULL;
1386            if (routeData->mRouteType != RouteData::ProtocolRoute)
1387                continue; //skip other kinds of routing data
1388            route = (RouteDataForProtocol*) (*iter);
1389            if (route->mNfaEeHandle == NFA_EE_HANDLE_DH)
1390            {
1391                if (route->mSwitchOn)
1392                    protocolsSwitchOn |= route->mProtocol;
1393                if (route->mSwitchOff)
1394                    protocolsSwitchOff |= route->mProtocol;
1395                if (route->mBatteryOff)
1396                    protocolsBatteryOff |= route->mProtocol;
1397            }
1398        }
1399
1400        if (protocolsSwitchOn | protocolsSwitchOff | protocolsBatteryOff)
1401        {
1402            ALOGD ("%s: route to EE h=0x%X", fn, NFA_EE_HANDLE_DH);
1403            SyncEventGuard guard (mRoutingEvent);
1404            nfaStat = NFA_EeSetDefaultProtoRouting (NFA_EE_HANDLE_DH,
1405                    protocolsSwitchOn, protocolsSwitchOff, protocolsBatteryOff);
1406            if (nfaStat == NFA_STATUS_OK)
1407                mRoutingEvent.wait ();
1408            else
1409                ALOGE ("%s: fail route to EE; error=0x%X", fn, nfaStat);
1410        }
1411    }
1412
1413    //////////////////////
1414    // if route database is empty, setup a default route
1415    //////////////////////
1416    if (db->empty())
1417    {
1418        tNFA_HANDLE eeHandle = NFA_EE_HANDLE_DH;
1419        if (routeSelection == SecElemRoute)
1420            eeHandle = getDefaultEeHandle ();
1421        ALOGD ("%s: route to default EE h=0x%X", fn, eeHandle);
1422        SyncEventGuard guard (mRoutingEvent);
1423        nfaStat = NFA_EeSetDefaultProtoRouting (eeHandle, protoMask, 0, 0);
1424        if (nfaStat == NFA_STATUS_OK)
1425            mRoutingEvent.wait ();
1426        else
1427            ALOGE ("%s: fail route to EE; error=0x%X", fn, nfaStat);
1428    }
1429    ALOGD ("%s: exit", fn);
1430}
1431
1432
1433/*******************************************************************************
1434**
1435** Function:        adjustTechnologyRoutes
1436**
1437** Description:     Adjust default routing based on technology in NFC listen mode.
1438**                  isRouteToEe: Whether routing to EE (true) or host (false).
1439**
1440** Returns:         None
1441**
1442*******************************************************************************/
1443void SecureElement::adjustTechnologyRoutes (RouteDataSet::Database* db, RouteSelection routeSelection)
1444{
1445    static const char fn [] = "SecureElement::adjustTechnologyRoutes";
1446    ALOGD ("%s: enter", fn);
1447    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
1448    const tNFA_TECHNOLOGY_MASK techMask = NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B;
1449
1450    ///////////////////////
1451    // delete route to host
1452    ///////////////////////
1453    {
1454        ALOGD ("%s: delete route to host", fn);
1455        SyncEventGuard guard (mRoutingEvent);
1456        if ((nfaStat = NFA_EeSetDefaultTechRouting (NFA_EE_HANDLE_DH, 0, 0, 0)) == NFA_STATUS_OK)
1457            mRoutingEvent.wait ();
1458        else
1459            ALOGE ("%s: fail delete route to host; error=0x%X", fn, nfaStat);
1460    }
1461
1462    ///////////////////////
1463    // delete route to every sec elem
1464    ///////////////////////
1465    for (int i=0; i < mActualNumEe; i++)
1466    {
1467        if ((mEeInfo[i].num_interface != 0) &&
1468                (mEeInfo[i].ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) &&
1469                (mEeInfo[i].ee_status == NFA_EE_STATUS_ACTIVE))
1470        {
1471            ALOGD ("%s: delete route to EE h=0x%X", fn, mEeInfo[i].ee_handle);
1472            SyncEventGuard guard (mRoutingEvent);
1473            if ((nfaStat = NFA_EeSetDefaultTechRouting (mEeInfo[i].ee_handle, 0, 0, 0)) == NFA_STATUS_OK)
1474                mRoutingEvent.wait ();
1475            else
1476                ALOGE ("%s: fail delete route to EE; error=0x%X", fn, nfaStat);
1477        }
1478    }
1479
1480    //////////////////////
1481    // configure route for every discovered sec elem
1482    //////////////////////
1483    for (int i=0; i < mActualNumEe; i++)
1484    {
1485        //if sec elem is active
1486        if ((mEeInfo[i].num_interface != 0) &&
1487                (mEeInfo[i].ee_interface[0] != NFC_NFCEE_INTERFACE_HCI_ACCESS) &&
1488                (mEeInfo[i].ee_status == NFA_EE_STATUS_ACTIVE))
1489        {
1490            tNFA_TECHNOLOGY_MASK techsSwitchOn = 0; //all techs that are active at full power
1491            tNFA_TECHNOLOGY_MASK techsSwitchOff = 0; //all techs that are active when phone is turned off
1492            tNFA_TECHNOLOGY_MASK techsBatteryOff = 0; //all techs that are active when there is no power
1493
1494            //for every route in XML, look for tech route;
1495            //collect every tech according to it's desired power mode
1496            for (RouteDataSet::Database::iterator iter = db->begin(); iter != db->end(); iter++)
1497            {
1498                RouteData* routeData = *iter;
1499                RouteDataForTechnology* route = NULL;
1500                if (routeData->mRouteType != RouteData::TechnologyRoute)
1501                    continue; //skip other kinds of routing data
1502                route = (RouteDataForTechnology*) (*iter);
1503                if (route->mNfaEeHandle == mEeInfo[i].ee_handle)
1504                {
1505                    if (route->mSwitchOn)
1506                        techsSwitchOn |= route->mTechnology;
1507                    if (route->mSwitchOff)
1508                        techsSwitchOff |= route->mTechnology;
1509                    if (route->mBatteryOff)
1510                        techsBatteryOff |= route->mTechnology;
1511                }
1512            }
1513
1514            if (techsSwitchOn | techsSwitchOff | techsBatteryOff)
1515            {
1516                ALOGD ("%s: route to EE h=0x%X", fn, mEeInfo[i].ee_handle);
1517                SyncEventGuard guard (mRoutingEvent);
1518                nfaStat = NFA_EeSetDefaultTechRouting (mEeInfo[i].ee_handle,
1519                        techsSwitchOn, techsSwitchOff, techsBatteryOff);
1520                if (nfaStat == NFA_STATUS_OK)
1521                    mRoutingEvent.wait ();
1522                else
1523                    ALOGE ("%s: fail route to EE; error=0x%X", fn, nfaStat);
1524            }
1525        } //if sec elem is active
1526    } //for every discovered sec elem
1527
1528    //////////////////////
1529    // configure route to host
1530    //////////////////////
1531    {
1532        tNFA_TECHNOLOGY_MASK techsSwitchOn = 0; //all techs that are active at full power
1533        tNFA_TECHNOLOGY_MASK techsSwitchOff = 0; //all techs that are active when phone is turned off
1534        tNFA_TECHNOLOGY_MASK techsBatteryOff = 0; //all techs that are active when there is no power
1535
1536        //for every route in XML, look for protocol route;
1537        //collect every protocol according to it's desired power mode
1538        for (RouteDataSet::Database::iterator iter = db->begin(); iter != db->end(); iter++)
1539        {
1540            RouteData* routeData = *iter;
1541            RouteDataForTechnology * route = NULL;
1542            if (routeData->mRouteType != RouteData::TechnologyRoute)
1543                continue; //skip other kinds of routing data
1544            route = (RouteDataForTechnology*) (*iter);
1545            if (route->mNfaEeHandle == NFA_EE_HANDLE_DH)
1546            {
1547                if (route->mSwitchOn)
1548                    techsSwitchOn |= route->mTechnology;
1549                if (route->mSwitchOff)
1550                    techsSwitchOff |= route->mTechnology;
1551                if (route->mBatteryOff)
1552                    techsBatteryOff |= route->mTechnology;
1553            }
1554        }
1555
1556        if (techsSwitchOn | techsSwitchOff | techsBatteryOff)
1557        {
1558            ALOGD ("%s: route to EE h=0x%X", fn, NFA_EE_HANDLE_DH);
1559            SyncEventGuard guard (mRoutingEvent);
1560            nfaStat = NFA_EeSetDefaultTechRouting (NFA_EE_HANDLE_DH,
1561                    techsSwitchOn, techsSwitchOff, techsBatteryOff);
1562            if (nfaStat == NFA_STATUS_OK)
1563                mRoutingEvent.wait ();
1564            else
1565                ALOGE ("%s: fail route to EE; error=0x%X", fn, nfaStat);
1566        }
1567    }
1568
1569    //////////////////////
1570    // if route database is empty, setup a default route
1571    //////////////////////
1572    if (db->empty())
1573    {
1574        tNFA_HANDLE eeHandle = NFA_EE_HANDLE_DH;
1575        if (routeSelection == SecElemRoute)
1576            eeHandle = getDefaultEeHandle ();
1577        ALOGD ("%s: route to default EE h=0x%X", fn, eeHandle);
1578        SyncEventGuard guard (mRoutingEvent);
1579        nfaStat = NFA_EeSetDefaultTechRouting (eeHandle, techMask, 0, 0);
1580        if (nfaStat == NFA_STATUS_OK)
1581            mRoutingEvent.wait ();
1582        else
1583            ALOGE ("%s: fail route to EE; error=0x%X", fn, nfaStat);
1584    }
1585    ALOGD ("%s: exit", fn);
1586}
1587
1588
1589/*******************************************************************************
1590**
1591** Function:        nfaEeCallback
1592**
1593** Description:     Receive execution environment-related events from stack.
1594**                  event: Event code.
1595**                  eventData: Event data.
1596**
1597** Returns:         None
1598**
1599*******************************************************************************/
1600void SecureElement::nfaEeCallback (tNFA_EE_EVT event, tNFA_EE_CBACK_DATA* eventData)
1601{
1602    static const char fn [] = "SecureElement::nfaEeCallback";
1603
1604    switch (event)
1605    {
1606    case NFA_EE_REGISTER_EVT:
1607        {
1608            SyncEventGuard guard (sSecElem.mEeRegisterEvent);
1609            ALOGD ("%s: NFA_EE_REGISTER_EVT; status=%u", fn, eventData->ee_register);
1610            sSecElem.mEeRegisterEvent.notifyOne();
1611        }
1612        break;
1613
1614    case NFA_EE_MODE_SET_EVT:
1615        {
1616            ALOGD ("%s: NFA_EE_MODE_SET_EVT; status: 0x%04X  handle: 0x%04X  mActiveEeHandle: 0x%04X", fn,
1617                    eventData->mode_set.status, eventData->mode_set.ee_handle, sSecElem.mActiveEeHandle);
1618
1619            if (eventData->mode_set.status == NFA_STATUS_OK)
1620            {
1621                tNFA_EE_INFO *pEE = sSecElem.findEeByHandle (eventData->mode_set.ee_handle);
1622                if (pEE)
1623                {
1624                    pEE->ee_status ^= 1;
1625                    ALOGD ("%s: NFA_EE_MODE_SET_EVT; pEE->ee_status: %s (0x%04x)", fn, SecureElement::eeStatusToString(pEE->ee_status), pEE->ee_status);
1626                }
1627                else
1628                    ALOGE ("%s: NFA_EE_MODE_SET_EVT; EE: 0x%04x not found.  mActiveEeHandle: 0x%04x", fn, eventData->mode_set.ee_handle, sSecElem.mActiveEeHandle);
1629            }
1630            SyncEventGuard guard (sSecElem.mEeSetModeEvent);
1631            sSecElem.mEeSetModeEvent.notifyOne();
1632        }
1633        break;
1634
1635    case NFA_EE_SET_TECH_CFG_EVT:
1636        {
1637            ALOGD ("%s: NFA_EE_SET_TECH_CFG_EVT; status=0x%X", fn, eventData->status);
1638            SyncEventGuard guard (sSecElem.mRoutingEvent);
1639            sSecElem.mRoutingEvent.notifyOne ();
1640        }
1641        break;
1642
1643    case NFA_EE_SET_PROTO_CFG_EVT:
1644        {
1645            ALOGD ("%s: NFA_EE_SET_PROTO_CFG_EVT; status=0x%X", fn, eventData->status);
1646            SyncEventGuard guard (sSecElem.mRoutingEvent);
1647            sSecElem.mRoutingEvent.notifyOne ();
1648        }
1649        break;
1650
1651    case NFA_EE_ACTION_EVT:
1652        {
1653            tNFA_EE_ACTION& action = eventData->action;
1654            if (action.trigger == NFC_EE_TRIG_SELECT)
1655                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=select (0x%X)", fn, action.ee_handle, action.trigger);
1656            else if (action.trigger == NFC_EE_TRIG_APP_INIT)
1657            {
1658                tNFC_APP_INIT& app_init = action.param.app_init;
1659                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=app-init (0x%X); aid len=%u; data len=%u", fn,
1660                        action.ee_handle, action.trigger, app_init.len_aid, app_init.len_data);
1661                //if app-init operation is successful;
1662                //app_init.data[] contains two bytes, which are the status codes of the event;
1663                //app_init.data[] does not contain an APDU response;
1664                //see EMV Contactless Specification for Payment Systems; Book B; Entry Point Specification;
1665                //version 2.1; March 2011; section 3.3.3.5;
1666                if ( (app_init.len_data > 1) &&
1667                     (app_init.data[0] == 0x90) &&
1668                     (app_init.data[1] == 0x00) )
1669                {
1670                    sSecElem.notifyTransactionListenersOfAid (app_init.aid, app_init.len_aid);
1671                }
1672            }
1673            else if (action.trigger == NFC_EE_TRIG_RF_PROTOCOL)
1674                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf protocol (0x%X)", fn, action.ee_handle, action.trigger);
1675            else if (action.trigger == NFC_EE_TRIG_RF_TECHNOLOGY)
1676                ALOGD ("%s: NFA_EE_ACTION_EVT; h=0x%X; trigger=rf tech (0x%X)", fn, action.ee_handle, action.trigger);
1677            else
1678                ALOGE ("%s: NFA_EE_ACTION_EVT; h=0x%X; unknown trigger (0x%X)", fn, action.ee_handle, action.trigger);
1679        }
1680        break;
1681
1682    case NFA_EE_DISCOVER_REQ_EVT:
1683        ALOGD ("%s: NFA_EE_DISCOVER_REQ_EVT; status=0x%X; num ee=%u", __FUNCTION__,
1684                eventData->discover_req.status, eventData->discover_req.num_ee);
1685        sSecElem.storeUiccInfo (eventData->discover_req);
1686        break;
1687
1688    case NFA_EE_NO_CB_ERR_EVT:
1689        ALOGD ("%s: NFA_EE_NO_CB_ERR_EVT  status=%u", fn, eventData->status);
1690        break;
1691
1692    case NFA_EE_ADD_AID_EVT:
1693        {
1694            ALOGD ("%s: NFA_EE_ADD_AID_EVT  status=%u", fn, eventData->status);
1695            SyncEventGuard guard (sSecElem.mAidAddRemoveEvent);
1696            sSecElem.mAidAddRemoveEvent.notifyOne ();
1697        }
1698        break;
1699
1700    case NFA_EE_REMOVE_AID_EVT:
1701        {
1702            ALOGD ("%s: NFA_EE_REMOVE_AID_EVT  status=%u", fn, eventData->status);
1703            SyncEventGuard guard (sSecElem.mAidAddRemoveEvent);
1704            sSecElem.mAidAddRemoveEvent.notifyOne ();
1705        }
1706        break;
1707
1708    case NFA_EE_NEW_EE_EVT:
1709        {
1710            ALOGD ("%s: NFA_EE_NEW_EE_EVT  h=0x%X; status=%u", fn,
1711                eventData->new_ee.ee_handle, eventData->new_ee.ee_status);
1712            // Indicate there are new EE
1713            sSecElem.mbNewEE = true;
1714        }
1715        break;
1716
1717    default:
1718        ALOGE ("%s: unknown event=%u ????", fn, event);
1719        break;
1720    }
1721}
1722
1723/*******************************************************************************
1724**
1725** Function         getSeVerInfo
1726**
1727** Description      Gets version information and id for a secure element.  The
1728**                  seIndex parmeter is the zero based index of the secure
1729**                  element to get verion info for.  The version infommation
1730**                  is returned as a string int the verInfo parameter.
1731**
1732** Returns          ture on success, false on failure
1733**
1734*******************************************************************************/
1735bool SecureElement::getSeVerInfo(int seIndex, char * verInfo, int verInfoSz, UINT8 * seid)
1736{
1737    ALOGD("%s: enter, seIndex=%d", __FUNCTION__, seIndex);
1738
1739    if (seIndex > (mActualNumEe-1))
1740    {
1741        ALOGE("%s: invalid se index: %d, only %d SEs in system", __FUNCTION__, seIndex, mActualNumEe);
1742        return false;
1743    }
1744
1745    *seid = mEeInfo[seIndex].ee_handle;
1746
1747    if ((mEeInfo[seIndex].num_interface == 0) || (mEeInfo[seIndex].ee_interface[0] == NCI_NFCEE_INTERFACE_HCI_ACCESS) )
1748    {
1749        return false;
1750    }
1751
1752    strncpy(verInfo, "Version info not available", verInfoSz-1);
1753    verInfo[verInfoSz-1] = '\0';
1754
1755    UINT8 pipe = (mEeInfo[seIndex].ee_handle == EE_HANDLE_0xF3) ? 0x70 : 0x71;
1756    UINT8 host = (pipe == STATIC_PIPE_0x70) ? 0x02 : 0x03;
1757    UINT8 gate = (pipe == STATIC_PIPE_0x70) ? 0xF0 : 0xF1;
1758
1759    tNFA_STATUS nfaStat = NFA_HciAddStaticPipe(mNfaHciHandle, host, gate, pipe);
1760    if (nfaStat != NFA_STATUS_OK)
1761    {
1762        ALOGE ("%s: NFA_HciAddStaticPipe() failed, pipe = 0x%x, error=0x%X", __FUNCTION__, pipe, nfaStat);
1763        return true;
1764    }
1765
1766    SyncEventGuard guard (mVerInfoEvent);
1767    if (NFA_STATUS_OK == (nfaStat = NFA_HciGetRegistry (mNfaHciHandle, pipe, 0x02)))
1768    {
1769        if (false == mVerInfoEvent.wait(200))
1770        {
1771            ALOGE ("%s: wait response timeout", __FUNCTION__);
1772        }
1773        else
1774        {
1775            snprintf(verInfo, verInfoSz-1, "Oberthur OS S/N: 0x%02x%02x%02x", mVerInfo[0], mVerInfo[1], mVerInfo[2]);
1776            verInfo[verInfoSz-1] = '\0';
1777        }
1778    }
1779    else
1780    {
1781        ALOGE ("%s: NFA_HciGetRegistry () failed: 0x%X", __FUNCTION__, nfaStat);
1782    }
1783    return true;
1784}
1785
1786/*******************************************************************************
1787**
1788** Function         getActualNumEe
1789**
1790** Description      Returns number of secure elements we know about.
1791**
1792** Returns          Number of secure elements we know about.
1793**
1794*******************************************************************************/
1795UINT8 SecureElement::getActualNumEe()
1796{
1797    return mActualNumEe;
1798}
1799
1800/*******************************************************************************
1801**
1802** Function:        nfaHciCallback
1803**
1804** Description:     Receive Host Controller Interface-related events from stack.
1805**                  event: Event code.
1806**                  eventData: Event data.
1807**
1808** Returns:         None
1809**
1810*******************************************************************************/
1811void SecureElement::nfaHciCallback (tNFA_HCI_EVT event, tNFA_HCI_EVT_DATA* eventData)
1812{
1813    static const char fn [] = "SecureElement::nfaHciCallback";
1814    ALOGD ("%s: event=0x%X", fn, event);
1815
1816    switch (event)
1817    {
1818    case NFA_HCI_REGISTER_EVT:
1819        {
1820            ALOGD ("%s: NFA_HCI_REGISTER_EVT; status=0x%X; handle=0x%X", fn,
1821                    eventData->hci_register.status, eventData->hci_register.hci_handle);
1822            SyncEventGuard guard (sSecElem.mHciRegisterEvent);
1823            sSecElem.mNfaHciHandle = eventData->hci_register.hci_handle;
1824            sSecElem.mHciRegisterEvent.notifyOne();
1825        }
1826        break;
1827
1828    case NFA_HCI_ALLOCATE_GATE_EVT:
1829        {
1830            ALOGD ("%s: NFA_HCI_ALLOCATE_GATE_EVT; status=0x%X; gate=0x%X", fn, eventData->status, eventData->allocated.gate);
1831            SyncEventGuard guard (sSecElem.mAllocateGateEvent);
1832            sSecElem.mCommandStatus = eventData->status;
1833            sSecElem.mNewSourceGate = (eventData->allocated.status == NFA_STATUS_OK) ? eventData->allocated.gate : 0;
1834            sSecElem.mAllocateGateEvent.notifyOne();
1835        }
1836        break;
1837
1838    case NFA_HCI_DEALLOCATE_GATE_EVT:
1839        {
1840            tNFA_HCI_DEALLOCATE_GATE& deallocated = eventData->deallocated;
1841            ALOGD ("%s: NFA_HCI_DEALLOCATE_GATE_EVT; status=0x%X; gate=0x%X", fn, deallocated.status, deallocated.gate);
1842            SyncEventGuard guard (sSecElem.mDeallocateGateEvent);
1843            sSecElem.mDeallocateGateEvent.notifyOne();
1844        }
1845        break;
1846
1847    case NFA_HCI_GET_GATE_PIPE_LIST_EVT:
1848        {
1849            ALOGD ("%s: NFA_HCI_GET_GATE_PIPE_LIST_EVT; status=0x%X; num_pipes: %u  num_gates: %u", fn,
1850                    eventData->gates_pipes.status, eventData->gates_pipes.num_pipes, eventData->gates_pipes.num_gates);
1851            SyncEventGuard guard (sSecElem.mPipeListEvent);
1852            sSecElem.mCommandStatus = eventData->gates_pipes.status;
1853            sSecElem.mHciCfg = eventData->gates_pipes;
1854            sSecElem.mPipeListEvent.notifyOne();
1855        }
1856        break;
1857
1858    case NFA_HCI_CREATE_PIPE_EVT:
1859        {
1860            ALOGD ("%s: NFA_HCI_CREATE_PIPE_EVT; status=0x%X; pipe=0x%X; src gate=0x%X; dest host=0x%X; dest gate=0x%X", fn,
1861                    eventData->created.status, eventData->created.pipe, eventData->created.source_gate, eventData->created.dest_host, eventData->created.dest_gate);
1862            SyncEventGuard guard (sSecElem.mCreatePipeEvent);
1863            sSecElem.mCommandStatus = eventData->created.status;
1864            sSecElem.mNewPipeId = eventData->created.pipe;
1865            sSecElem.mCreatePipeEvent.notifyOne();
1866        }
1867        break;
1868
1869    case NFA_HCI_OPEN_PIPE_EVT:
1870        {
1871            ALOGD ("%s: NFA_HCI_OPEN_PIPE_EVT; status=0x%X; pipe=0x%X", fn, eventData->opened.status, eventData->opened.pipe);
1872            SyncEventGuard guard (sSecElem.mPipeOpenedEvent);
1873            sSecElem.mCommandStatus = eventData->opened.status;
1874            sSecElem.mPipeOpenedEvent.notifyOne();
1875        }
1876        break;
1877
1878    case NFA_HCI_EVENT_SENT_EVT:
1879        ALOGD ("%s: NFA_HCI_EVENT_SENT_EVT; status=0x%X", fn, eventData->evt_sent.status);
1880        break;
1881
1882    case NFA_HCI_RSP_RCVD_EVT: //response received from secure element
1883        {
1884            tNFA_HCI_RSP_RCVD& rsp_rcvd = eventData->rsp_rcvd;
1885            ALOGD ("%s: NFA_HCI_RSP_RCVD_EVT; status: 0x%X; code: 0x%X; pipe: 0x%X; len: %u", fn,
1886                    rsp_rcvd.status, rsp_rcvd.rsp_code, rsp_rcvd.pipe, rsp_rcvd.rsp_len);
1887        }
1888        break;
1889
1890    case NFA_HCI_GET_REG_RSP_EVT :
1891        ALOGD ("%s: NFA_HCI_GET_REG_RSP_EVT; status: 0x%X; pipe: 0x%X, len: %d", fn,
1892                eventData->registry.status, eventData->registry.pipe, eventData->registry.data_len);
1893        if (eventData->registry.data_len >= 19 && ((eventData->registry.pipe == STATIC_PIPE_0x70) || (eventData->registry.pipe == STATIC_PIPE_0x71)))
1894        {
1895            SyncEventGuard guard (sSecElem.mVerInfoEvent);
1896            // Oberthur OS version is in bytes 16,17, and 18
1897            sSecElem.mVerInfo[0] = eventData->registry.reg_data[16];
1898            sSecElem.mVerInfo[1] = eventData->registry.reg_data[17];
1899            sSecElem.mVerInfo[2] = eventData->registry.reg_data[18];
1900            sSecElem.mVerInfoEvent.notifyOne ();
1901        }
1902        break;
1903
1904    case NFA_HCI_EVENT_RCVD_EVT:
1905        ALOGD ("%s: NFA_HCI_EVENT_RCVD_EVT; code: 0x%X; pipe: 0x%X; data len: %u", fn,
1906                eventData->rcvd_evt.evt_code, eventData->rcvd_evt.pipe, eventData->rcvd_evt.evt_len);
1907        if ((eventData->rcvd_evt.pipe == STATIC_PIPE_0x70) || (eventData->rcvd_evt.pipe == STATIC_PIPE_0x71))
1908        {
1909            ALOGD ("%s: NFA_HCI_EVENT_RCVD_EVT; data from static pipe", fn);
1910            SyncEventGuard guard (sSecElem.mTransceiveEvent);
1911            sSecElem.mActualResponseSize = (eventData->rcvd_evt.evt_len > MAX_RESPONSE_SIZE) ? MAX_RESPONSE_SIZE : eventData->rcvd_evt.evt_len;
1912            sSecElem.mTransceiveEvent.notifyOne ();
1913        }
1914        else if (eventData->rcvd_evt.evt_code == NFA_HCI_EVT_POST_DATA)
1915        {
1916            ALOGD ("%s: NFA_HCI_EVENT_RCVD_EVT; NFA_HCI_EVT_POST_DATA", fn);
1917            SyncEventGuard guard (sSecElem.mTransceiveEvent);
1918            sSecElem.mActualResponseSize = (eventData->rcvd_evt.evt_len > MAX_RESPONSE_SIZE) ? MAX_RESPONSE_SIZE : eventData->rcvd_evt.evt_len;
1919            sSecElem.mTransceiveEvent.notifyOne ();
1920        }
1921        else if (eventData->rcvd_evt.evt_code == NFA_HCI_EVT_TRANSACTION)
1922        {
1923            ALOGD ("%s: NFA_HCI_EVENT_RCVD_EVT; NFA_HCI_EVT_TRANSACTION", fn);
1924            // If we got an AID, notify any listeners
1925            if ((eventData->rcvd_evt.evt_len > 3) && (eventData->rcvd_evt.p_evt_buf[0] == 0x81) )
1926                sSecElem.notifyTransactionListenersOfAid (&eventData->rcvd_evt.p_evt_buf[2], eventData->rcvd_evt.p_evt_buf[1]);
1927        }
1928        break;
1929
1930    case NFA_HCI_SET_REG_RSP_EVT: //received response to write registry command
1931        {
1932            tNFA_HCI_REGISTRY& registry = eventData->registry;
1933            ALOGD ("%s: NFA_HCI_SET_REG_RSP_EVT; status=0x%X; pipe=0x%X", fn, registry.status, registry.pipe);
1934            SyncEventGuard guard (sSecElem.mRegistryEvent);
1935            sSecElem.mRegistryEvent.notifyOne ();
1936            break;
1937        }
1938
1939    default:
1940        ALOGE ("%s: unknown event code=0x%X ????", fn, event);
1941        break;
1942    }
1943}
1944
1945
1946/*******************************************************************************
1947**
1948** Function:        findEeByHandle
1949**
1950** Description:     Find information about an execution environment.
1951**                  eeHandle: Handle to execution environment.
1952**
1953** Returns:         Information about an execution environment.
1954**
1955*******************************************************************************/
1956tNFA_EE_INFO *SecureElement::findEeByHandle (tNFA_HANDLE eeHandle)
1957{
1958    for (UINT8 xx = 0; xx < mActualNumEe; xx++)
1959    {
1960        if (mEeInfo[xx].ee_handle == eeHandle)
1961            return (&mEeInfo[xx]);
1962    }
1963    return (NULL);
1964}
1965
1966
1967/*******************************************************************************
1968**
1969** Function:        getDefaultEeHandle
1970**
1971** Description:     Get the handle to the execution environment.
1972**
1973** Returns:         Handle to the execution environment.
1974**
1975*******************************************************************************/
1976tNFA_HANDLE SecureElement::getDefaultEeHandle ()
1977{
1978    // Find the first EE that is not the HCI Access i/f.
1979    for (UINT8 xx = 0; xx < mActualNumEe; xx++)
1980    {
1981        if ((mEeInfo[xx].num_interface != 0) && (mEeInfo[xx].ee_interface[0] != NCI_NFCEE_INTERFACE_HCI_ACCESS) )
1982            return (mEeInfo[xx].ee_handle);
1983    }
1984    return NFA_HANDLE_INVALID;
1985}
1986
1987
1988    /*******************************************************************************
1989    **
1990    ** Function:        findUiccByHandle
1991    **
1992    ** Description:     Find information about an execution environment.
1993    **                  eeHandle: Handle of the execution environment.
1994    **
1995    ** Returns:         Information about the execution environment.
1996    **
1997    *******************************************************************************/
1998tNFA_EE_DISCOVER_INFO *SecureElement::findUiccByHandle (tNFA_HANDLE eeHandle)
1999{
2000    for (UINT8 index = 0; index < mUiccInfo.num_ee; index++)
2001    {
2002        if (mUiccInfo.ee_disc_info[index].ee_handle == eeHandle)
2003        {
2004            return (&mUiccInfo.ee_disc_info[index]);
2005        }
2006    }
2007    ALOGE ("SecureElement::findUiccByHandle:  ee h=0x%4x not found", eeHandle);
2008    return NULL;
2009}
2010
2011
2012/*******************************************************************************
2013**
2014** Function:        eeStatusToString
2015**
2016** Description:     Convert status code to status text.
2017**                  status: Status code
2018**
2019** Returns:         None
2020**
2021*******************************************************************************/
2022const char* SecureElement::eeStatusToString (UINT8 status)
2023{
2024    switch (status)
2025    {
2026    case NFC_NFCEE_STATUS_ACTIVE:
2027        return("Connected/Active");
2028    case NFC_NFCEE_STATUS_INACTIVE:
2029        return("Connected/Inactive");
2030    case NFC_NFCEE_STATUS_REMOVED:
2031        return("Removed");
2032    }
2033    return("?? Unknown ??");
2034}
2035
2036
2037/*******************************************************************************
2038**
2039** Function:        connectionEventHandler
2040**
2041** Description:     Receive card-emulation related events from stack.
2042**                  event: Event code.
2043**                  eventData: Event data.
2044**
2045** Returns:         None
2046**
2047*******************************************************************************/
2048void SecureElement::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* eventData)
2049{
2050    switch (event)
2051    {
2052    case NFA_CE_UICC_LISTEN_CONFIGURED_EVT:
2053        {
2054            SyncEventGuard guard (mUiccListenEvent);
2055            mUiccListenEvent.notifyOne ();
2056        }
2057        break;
2058    }
2059}
2060
2061
2062/*******************************************************************************
2063**
2064** Function:        routeToSecureElement
2065**
2066** Description:     Adjust controller's listen-mode routing table so transactions
2067**                  are routed to the secure elements.
2068**
2069** Returns:         True if ok.
2070**
2071*******************************************************************************/
2072bool SecureElement::routeToSecureElement ()
2073{
2074    static const char fn [] = "SecureElement::routeToSecureElement";
2075    ALOGD ("%s: enter", fn);
2076    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
2077    tNFA_TECHNOLOGY_MASK tech_mask = NFA_TECHNOLOGY_MASK_A | NFA_TECHNOLOGY_MASK_B;
2078    bool retval = false;
2079
2080    if (! mIsInit)
2081    {
2082        ALOGE ("%s: not init", fn);
2083        return false;
2084    }
2085
2086    if (mCurrentRouteSelection == SecElemRoute)
2087    {
2088        ALOGE ("%s: already sec elem route", fn);
2089        return true;
2090    }
2091
2092    if (mActiveEeHandle == NFA_HANDLE_INVALID)
2093    {
2094        ALOGE ("%s: invalid EE handle", fn);
2095        return false;
2096    }
2097
2098    adjustRoutes (SecElemRoute);
2099
2100    {
2101        unsigned long num = 0;
2102        if (GetNumValue("UICC_LISTEN_TECH_MASK", &num, sizeof(num)))
2103            tech_mask = num;
2104        ALOGD ("%s: start UICC listen; h=0x%X; tech mask=0x%X", fn, mActiveEeHandle, tech_mask);
2105        SyncEventGuard guard (mUiccListenEvent);
2106        nfaStat = NFA_CeConfigureUiccListenTech (mActiveEeHandle, tech_mask);
2107        if (nfaStat == NFA_STATUS_OK)
2108        {
2109            mUiccListenEvent.wait ();
2110            retval = true;
2111        }
2112        else
2113            ALOGE ("%s: fail to start UICC listen", fn);
2114    }
2115
2116    ALOGD ("%s: exit; ok=%u", fn, retval);
2117    return retval;
2118}
2119
2120
2121/*******************************************************************************
2122**
2123** Function:        routeToDefault
2124**
2125** Description:     Adjust controller's listen-mode routing table so transactions
2126**                  are routed to the default destination.
2127**
2128** Returns:         True if ok.
2129**
2130*******************************************************************************/
2131bool SecureElement::routeToDefault ()
2132{
2133    static const char fn [] = "SecureElement::routeToDefault";
2134    tNFA_STATUS nfaStat = NFA_STATUS_FAILED;
2135    bool retval = false;
2136
2137    ALOGD ("%s: enter", fn);
2138    if (! mIsInit)
2139    {
2140        ALOGE ("%s: not init", fn);
2141        return false;
2142    }
2143
2144    if (mCurrentRouteSelection == DefaultRoute)
2145    {
2146        ALOGD ("%s: already default route", fn);
2147        return true;
2148    }
2149
2150    if (mActiveEeHandle != NFA_HANDLE_INVALID)
2151    {
2152        ALOGD ("%s: stop UICC listen; EE h=0x%X", fn, mActiveEeHandle);
2153        SyncEventGuard guard (mUiccListenEvent);
2154        nfaStat = NFA_CeConfigureUiccListenTech (mActiveEeHandle, 0);
2155        if (nfaStat == NFA_STATUS_OK)
2156        {
2157            mUiccListenEvent.wait ();
2158            retval = true;
2159        }
2160        else
2161            ALOGE ("%s: fail to stop UICC listen", fn);
2162    }
2163    else
2164        retval = true;
2165
2166    adjustRoutes (DefaultRoute);
2167
2168    ALOGD ("%s: exit; ok=%u", fn, retval);
2169    return retval;
2170}
2171
2172
2173/*******************************************************************************
2174**
2175** Function:        isBusy
2176**
2177** Description:     Whether controller is routing listen-mode events to
2178**                  secure elements or a pipe is connected.
2179**
2180** Returns:         True if either case is true.
2181**
2182*******************************************************************************/
2183bool SecureElement::isBusy ()
2184{
2185    bool retval = (mCurrentRouteSelection == SecElemRoute) || mIsPiping;
2186    ALOGD ("SecureElement::isBusy: %u", retval);
2187    return retval;
2188}
2189
2190