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