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 *  Tag-reading, tag-writing operations.
19 */
20#include "OverrideLog.h"
21#include "NfcTag.h"
22#include "JavaClassConstants.h"
23#include "config.h"
24#include <ScopedLocalRef.h>
25#include <ScopedPrimitiveArray.h>
26
27extern "C"
28{
29    #include "rw_int.h"
30}
31
32
33/*******************************************************************************
34**
35** Function:        NfcTag
36**
37** Description:     Initialize member variables.
38**
39** Returns:         None
40**
41*******************************************************************************/
42NfcTag::NfcTag ()
43:   mNumTechList (0),
44    mTechnologyTimeoutsTable (MAX_NUM_TECHNOLOGY),
45    mNativeData (NULL),
46    mIsActivated (false),
47    mActivationState (Idle),
48    mProtocol(NFC_PROTOCOL_UNKNOWN),
49    mtT1tMaxMessageSize (0),
50    mReadCompletedStatus (NFA_STATUS_OK),
51    mLastKovioUidLen (0),
52    mNdefDetectionTimedOut (false),
53    mIsDynamicTagId (false),
54    mPresenceCheckAlgorithm (NFA_RW_PRES_CHK_DEFAULT),
55    mIsFelicaLite(false)
56{
57    memset (mTechList, 0, sizeof(mTechList));
58    memset (mTechHandles, 0, sizeof(mTechHandles));
59    memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
60    memset (mTechParams, 0, sizeof(mTechParams));
61    memset(mLastKovioUid, 0, NFC_KOVIO_MAX_LEN);
62}
63
64
65/*******************************************************************************
66**
67** Function:        getInstance
68**
69** Description:     Get a reference to the singleton NfcTag object.
70**
71** Returns:         Reference to NfcTag object.
72**
73*******************************************************************************/
74NfcTag& NfcTag::getInstance ()
75{
76    static NfcTag tag;
77    return tag;
78}
79
80
81/*******************************************************************************
82**
83** Function:        initialize
84**
85** Description:     Reset member variables.
86**                  native: Native data.
87**
88** Returns:         None
89**
90*******************************************************************************/
91void NfcTag::initialize (nfc_jni_native_data* native)
92{
93    long num = 0;
94
95    mNativeData = native;
96    mIsActivated = false;
97    mActivationState = Idle;
98    mProtocol = NFC_PROTOCOL_UNKNOWN;
99    mNumTechList = 0;
100    mtT1tMaxMessageSize = 0;
101    mReadCompletedStatus = NFA_STATUS_OK;
102    resetTechnologies ();
103    if (GetNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num)))
104        mPresenceCheckAlgorithm = num;
105}
106
107
108/*******************************************************************************
109**
110** Function:        abort
111**
112** Description:     Unblock all operations.
113**
114** Returns:         None
115**
116*******************************************************************************/
117void NfcTag::abort ()
118{
119    SyncEventGuard g (mReadCompleteEvent);
120    mReadCompleteEvent.notifyOne ();
121}
122
123
124/*******************************************************************************
125**
126** Function:        getActivationState
127**
128** Description:     What is the current state: Idle, Sleep, or Activated.
129**
130** Returns:         Idle, Sleep, or Activated.
131**
132*******************************************************************************/
133NfcTag::ActivationState NfcTag::getActivationState ()
134{
135    return mActivationState;
136}
137
138
139/*******************************************************************************
140**
141** Function:        setDeactivationState
142**
143** Description:     Set the current state: Idle or Sleep.
144**                  deactivated: state of deactivation.
145**
146** Returns:         None.
147**
148*******************************************************************************/
149void NfcTag::setDeactivationState (tNFA_DEACTIVATED& deactivated)
150{
151    static const char fn [] = "NfcTag::setDeactivationState";
152    mActivationState = Idle;
153    mNdefDetectionTimedOut = false;
154    if (deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP)
155        mActivationState = Sleep;
156    ALOGD ("%s: state=%u", fn, mActivationState);
157}
158
159
160/*******************************************************************************
161**
162** Function:        setActivationState
163**
164** Description:     Set the current state to Active.
165**
166** Returns:         None.
167**
168*******************************************************************************/
169void NfcTag::setActivationState ()
170{
171    static const char fn [] = "NfcTag::setActivationState";
172    mNdefDetectionTimedOut = false;
173    mActivationState = Active;
174    ALOGD ("%s: state=%u", fn, mActivationState);
175}
176
177/*******************************************************************************
178**
179** Function:        isActivated
180**
181** Description:     Is tag activated?
182**
183** Returns:         True if tag is activated.
184**
185*******************************************************************************/
186bool NfcTag::isActivated ()
187{
188    return mIsActivated;
189}
190
191
192/*******************************************************************************
193**
194** Function:        getProtocol
195**
196** Description:     Get the protocol of the current tag.
197**
198** Returns:         Protocol number.
199**
200*******************************************************************************/
201tNFC_PROTOCOL NfcTag::getProtocol()
202{
203    return mProtocol;
204}
205
206/*******************************************************************************
207**
208** Function         TimeDiff
209**
210** Description      Computes time difference in milliseconds.
211**
212** Returns          Time difference in milliseconds
213**
214*******************************************************************************/
215UINT32 TimeDiff(timespec start, timespec end)
216{
217    timespec temp;
218    if ((end.tv_nsec-start.tv_nsec)<0)
219    {
220        temp.tv_sec = end.tv_sec-start.tv_sec-1;
221        temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
222    }
223    else
224    {
225        temp.tv_sec = end.tv_sec-start.tv_sec;
226        temp.tv_nsec = end.tv_nsec-start.tv_nsec;
227    }
228
229    return (temp.tv_sec * 1000) + (temp.tv_nsec / 1000000);
230}
231
232/*******************************************************************************
233**
234** Function:        IsSameKovio
235**
236** Description:     Checks if tag activate is the same (UID) Kovio tag previously
237**                  activated.  This is needed due to a problem with some Kovio
238**                  tags re-activating multiple times.
239**                  activationData: data from activation.
240**
241** Returns:         true if the activation is from the same tag previously
242**                  activated, false otherwise
243**
244*******************************************************************************/
245bool NfcTag::IsSameKovio(tNFA_ACTIVATED& activationData)
246{
247    static const char fn [] = "NfcTag::IsSameKovio";
248    ALOGD ("%s: enter", fn);
249    tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
250
251    if (rfDetail.protocol != NFC_PROTOCOL_KOVIO)
252        return false;
253
254    memcpy (&(mTechParams[0]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
255    if (mTechParams [0].mode != NFC_DISCOVERY_TYPE_POLL_KOVIO)
256        return false;
257
258    struct timespec now;
259    clock_gettime(CLOCK_REALTIME, &now);
260
261    bool rVal = false;
262    if (mTechParams[0].param.pk.uid_len == mLastKovioUidLen)
263    {
264        if (memcmp(mLastKovioUid, &mTechParams [0].param.pk.uid, mTechParams[0].param.pk.uid_len) == 0)
265        {
266            //same tag
267            if (TimeDiff(mLastKovioTime, now) < 500)
268            {
269                // same tag within 500 ms, ignore activation
270                rVal = true;
271            }
272        }
273    }
274
275    // save Kovio tag info
276    if (!rVal)
277    {
278        if ((mLastKovioUidLen = mTechParams[0].param.pk.uid_len) > NFC_KOVIO_MAX_LEN)
279            mLastKovioUidLen = NFC_KOVIO_MAX_LEN;
280        memcpy(mLastKovioUid, mTechParams[0].param.pk.uid, mLastKovioUidLen);
281    }
282    mLastKovioTime = now;
283    ALOGD ("%s: exit, is same Kovio=%d", fn, rVal);
284    return rVal;
285}
286
287/*******************************************************************************
288**
289** Function:        discoverTechnologies
290**
291** Description:     Discover the technologies that NFC service needs by interpreting
292**                  the data structures from the stack.
293**                  activationData: data from activation.
294**
295** Returns:         None
296**
297*******************************************************************************/
298void NfcTag::discoverTechnologies (tNFA_ACTIVATED& activationData)
299{
300    static const char fn [] = "NfcTag::discoverTechnologies (activation)";
301    ALOGD ("%s: enter", fn);
302    tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
303
304    mNumTechList = 0;
305    mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
306    mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
307
308    //save the stack's data structure for interpretation later
309    memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
310
311    switch (rfDetail.protocol)
312    {
313    case NFC_PROTOCOL_T1T:
314        mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
315        break;
316
317    case NFC_PROTOCOL_T2T:
318        mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A;  //is TagTechnology.NFC_A by Java API
319        // could be MifFare UL or Classic or Kovio
320        {
321            // need to look at first byte of uid to find Manufacture Byte
322            tNFC_RF_TECH_PARAMS tech_params;
323            memcpy (&tech_params, &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
324
325            if ((tech_params.param.pa.nfcid1[0] == 0x04 && rfDetail.rf_tech_param.param.pa.sel_rsp == 0) ||
326                rfDetail.rf_tech_param.param.pa.sel_rsp == 0x18 ||
327                rfDetail.rf_tech_param.param.pa.sel_rsp == 0x08)
328            {
329                if (rfDetail.rf_tech_param.param.pa.sel_rsp == 0)
330                {
331                    mNumTechList++;
332                    mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
333                    mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
334                    //save the stack's data structure for interpretation later
335                    memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
336                    mTechList [mNumTechList] = TARGET_TYPE_MIFARE_UL; //is TagTechnology.MIFARE_ULTRALIGHT by Java API
337                }
338            }
339        }
340        break;
341
342    case NFC_PROTOCOL_T3T:
343        {
344            UINT8 xx = 0;
345
346            mTechList [mNumTechList] = TARGET_TYPE_FELICA;
347
348            //see if it is Felica Lite.
349            while (xx < activationData.params.t3t.num_system_codes)
350            {
351                if (activationData.params.t3t.p_system_codes[xx++] == T3T_SYSTEM_CODE_FELICA_LITE)
352                {
353                    mIsFelicaLite = true;
354                    break;
355                }
356            }
357        }
358        break;
359
360    case NFC_PROTOCOL_ISO_DEP: //type-4 tag uses technology ISO-DEP and technology A or B
361        mTechList [mNumTechList] = TARGET_TYPE_ISO14443_4; //is TagTechnology.ISO_DEP by Java API
362        if ( (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
363                (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
364                (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
365                (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) )
366        {
367            mNumTechList++;
368            mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
369            mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
370            mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
371            //save the stack's data structure for interpretation later
372            memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
373        }
374        else if ( (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
375                (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
376                (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
377                (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) )
378        {
379            mNumTechList++;
380            mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
381            mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
382            mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API
383            //save the stack's data structure for interpretation later
384            memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
385        }
386        break;
387
388    case NFC_PROTOCOL_15693: //is TagTechnology.NFC_V by Java API
389        mTechList [mNumTechList] = TARGET_TYPE_ISO15693;
390        break;
391
392    case NFC_PROTOCOL_KOVIO:
393        ALOGD ("%s: Kovio", fn);
394        mTechList [mNumTechList] = TARGET_TYPE_KOVIO_BARCODE;
395        break;
396
397    default:
398        ALOGE ("%s: unknown protocol ????", fn);
399        mTechList [mNumTechList] = TARGET_TYPE_UNKNOWN;
400        break;
401    }
402
403    mNumTechList++;
404    for (int i=0; i < mNumTechList; i++)
405    {
406        ALOGD ("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn,
407                i, mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]);
408    }
409    ALOGD ("%s: exit", fn);
410}
411
412
413/*******************************************************************************
414**
415** Function:        discoverTechnologies
416**
417** Description:     Discover the technologies that NFC service needs by interpreting
418**                  the data structures from the stack.
419**                  discoveryData: data from discovery events(s).
420**
421** Returns:         None
422**
423*******************************************************************************/
424void NfcTag::discoverTechnologies (tNFA_DISC_RESULT& discoveryData)
425{
426    static const char fn [] = "NfcTag::discoverTechnologies (discovery)";
427    tNFC_RESULT_DEVT& discovery_ntf = discoveryData.discovery_ntf;
428
429    ALOGD ("%s: enter: rf disc. id=%u; protocol=%u, mNumTechList=%u", fn, discovery_ntf.rf_disc_id, discovery_ntf.protocol, mNumTechList);
430    if (mNumTechList >= MAX_NUM_TECHNOLOGY)
431    {
432        ALOGE ("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);
433        goto TheEnd;
434    }
435    mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
436    mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
437
438    //save the stack's data structure for interpretation later
439    memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
440
441    switch (discovery_ntf.protocol)
442    {
443    case NFC_PROTOCOL_T1T:
444        mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
445        break;
446
447    case NFC_PROTOCOL_T2T:
448        mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A;  //is TagTechnology.NFC_A by Java API
449        //type-2 tags are identical to Mifare Ultralight, so Ultralight is also discovered
450        if ((discovery_ntf.rf_tech_param.param.pa.sel_rsp == 0) &&
451                (mNumTechList < (MAX_NUM_TECHNOLOGY-1)))
452        {
453            // Mifare Ultralight
454            mNumTechList++;
455            mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
456            mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
457            mTechList [mNumTechList] = TARGET_TYPE_MIFARE_UL; //is TagTechnology.MIFARE_ULTRALIGHT by Java API
458        }
459
460        //save the stack's data structure for interpretation later
461        memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
462        break;
463
464    case NFC_PROTOCOL_T3T:
465        mTechList [mNumTechList] = TARGET_TYPE_FELICA;
466        break;
467
468    case NFC_PROTOCOL_ISO_DEP: //type-4 tag uses technology ISO-DEP and technology A or B
469        mTechList [mNumTechList] = TARGET_TYPE_ISO14443_4; //is TagTechnology.ISO_DEP by Java API
470        if ( (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
471                (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
472                (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
473                (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) )
474        {
475            if (mNumTechList < (MAX_NUM_TECHNOLOGY-1))
476            {
477                mNumTechList++;
478                mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
479                mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
480                mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
481                //save the stack's data structure for interpretation later
482                memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
483            }
484        }
485        else if ( (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
486                (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
487                (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
488                (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) )
489        {
490            if (mNumTechList < (MAX_NUM_TECHNOLOGY-1))
491            {
492                mNumTechList++;
493                mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
494                mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
495                mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API
496                //save the stack's data structure for interpretation later
497                memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
498            }
499        }
500        break;
501
502    case NFC_PROTOCOL_15693: //is TagTechnology.NFC_V by Java API
503        mTechList [mNumTechList] = TARGET_TYPE_ISO15693;
504        break;
505
506    default:
507        ALOGE ("%s: unknown protocol ????", fn);
508        mTechList [mNumTechList] = TARGET_TYPE_UNKNOWN;
509        break;
510    }
511
512    mNumTechList++;
513    if (discovery_ntf.more == FALSE)
514    {
515        for (int i=0; i < mNumTechList; i++)
516        {
517            ALOGD ("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn,
518                    i, mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]);
519        }
520    }
521
522TheEnd:
523    ALOGD ("%s: exit", fn);
524}
525
526
527/*******************************************************************************
528**
529** Function:        createNativeNfcTag
530**
531** Description:     Create a brand new Java NativeNfcTag object;
532**                  fill the objects's member variables with data;
533**                  notify NFC service;
534**                  activationData: data from activation.
535**
536** Returns:         None
537**
538*******************************************************************************/
539void NfcTag::createNativeNfcTag (tNFA_ACTIVATED& activationData)
540{
541    static const char fn [] = "NfcTag::createNativeNfcTag";
542    ALOGD ("%s: enter", fn);
543
544    JNIEnv* e = NULL;
545    ScopedAttach attach(mNativeData->vm, &e);
546    if (e == NULL)
547    {
548        ALOGE("%s: jni env is null", fn);
549        return;
550    }
551
552    ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(mNativeData->cached_NfcTag));
553    if (e->ExceptionCheck())
554    {
555        e->ExceptionClear();
556        ALOGE("%s: failed to get class", fn);
557        return;
558    }
559
560    //create a new Java NativeNfcTag object
561    jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
562    ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor));
563
564    //fill NativeNfcTag's mProtocols, mTechList, mTechHandles, mTechLibNfcTypes
565    fillNativeNfcTagMembers1(e, tag_cls.get(), tag.get());
566
567    //fill NativeNfcTag's members: mHandle, mConnectedTechnology
568    fillNativeNfcTagMembers2(e, tag_cls.get(), tag.get(), activationData);
569
570    //fill NativeNfcTag's members: mTechPollBytes
571    fillNativeNfcTagMembers3(e, tag_cls.get(), tag.get(), activationData);
572
573    //fill NativeNfcTag's members: mTechActBytes
574    fillNativeNfcTagMembers4(e, tag_cls.get(), tag.get(), activationData);
575
576    //fill NativeNfcTag's members: mUid
577    fillNativeNfcTagMembers5(e, tag_cls.get(), tag.get(), activationData);
578
579    if (mNativeData->tag != NULL)
580    {
581        e->DeleteGlobalRef(mNativeData->tag);
582    }
583    mNativeData->tag = e->NewGlobalRef(tag.get());
584
585    //notify NFC service about this new tag
586    ALOGD ("%s: try notify nfc service", fn);
587    e->CallVoidMethod(mNativeData->manager, android::gCachedNfcManagerNotifyNdefMessageListeners, tag.get());
588    if (e->ExceptionCheck())
589    {
590        e->ExceptionClear();
591        ALOGE ("%s: fail notify nfc service", fn);
592    }
593
594    ALOGD ("%s: exit", fn);
595}
596
597
598/*******************************************************************************
599**
600** Function:        fillNativeNfcTagMembers1
601**
602** Description:     Fill NativeNfcTag's members: mProtocols, mTechList, mTechHandles, mTechLibNfcTypes.
603**                  e: JVM environment.
604**                  tag_cls: Java NativeNfcTag class.
605**                  tag: Java NativeNfcTag object.
606**
607** Returns:         None
608**
609*******************************************************************************/
610void NfcTag::fillNativeNfcTagMembers1 (JNIEnv* e, jclass tag_cls, jobject tag)
611{
612    static const char fn [] = "NfcTag::fillNativeNfcTagMembers1";
613    ALOGD ("%s", fn);
614
615    //create objects that represent NativeNfcTag's member variables
616    ScopedLocalRef<jintArray> techList(e, e->NewIntArray(mNumTechList));
617    ScopedLocalRef<jintArray> handleList(e, e->NewIntArray(mNumTechList));
618    ScopedLocalRef<jintArray> typeList(e, e->NewIntArray(mNumTechList));
619
620    {
621        ScopedIntArrayRW technologies(e, techList.get());
622        ScopedIntArrayRW handles(e, handleList.get());
623        ScopedIntArrayRW types(e, typeList.get());
624        for (int i = 0; i < mNumTechList; i++) {
625            mNativeData->tProtocols [i] = mTechLibNfcTypes [i];
626            mNativeData->handles [i] = mTechHandles [i];
627            technologies [i] = mTechList [i];
628            handles [i]      = mTechHandles [i];
629            types [i]        = mTechLibNfcTypes [i];
630        }
631    }
632
633    jfieldID f = NULL;
634
635    f = e->GetFieldID(tag_cls, "mTechList", "[I");
636    e->SetObjectField(tag, f, techList.get());
637
638    f = e->GetFieldID(tag_cls, "mTechHandles", "[I");
639    e->SetObjectField(tag, f, handleList.get());
640
641    f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I");
642    e->SetObjectField(tag, f, typeList.get());
643}
644
645
646/*******************************************************************************
647**
648** Function:        fillNativeNfcTagMembers2
649**
650** Description:     Fill NativeNfcTag's members: mConnectedTechIndex or mConnectedTechnology.
651**                  The original Google's implementation is in set_target_pollBytes(
652**                  in com_android_nfc_NativeNfcTag.cpp;
653**                  e: JVM environment.
654**                  tag_cls: Java NativeNfcTag class.
655**                  tag: Java NativeNfcTag object.
656**                  activationData: data from activation.
657**
658** Returns:         None
659**
660*******************************************************************************/
661void NfcTag::fillNativeNfcTagMembers2 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& /*activationData*/)
662{
663    static const char fn [] = "NfcTag::fillNativeNfcTagMembers2";
664    ALOGD ("%s", fn);
665    jfieldID f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I");
666    e->SetIntField(tag, f, (jint) 0);
667}
668
669
670/*******************************************************************************
671**
672** Function:        fillNativeNfcTagMembers3
673**
674** Description:     Fill NativeNfcTag's members: mTechPollBytes.
675**                  The original Google's implementation is in set_target_pollBytes(
676**                  in com_android_nfc_NativeNfcTag.cpp;
677**                  e: JVM environment.
678**                  tag_cls: Java NativeNfcTag class.
679**                  tag: Java NativeNfcTag object.
680**                  activationData: data from activation.
681**
682** Returns:         None
683**
684*******************************************************************************/
685void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData)
686{
687    static const char fn [] = "NfcTag::fillNativeNfcTagMembers3";
688    ScopedLocalRef<jbyteArray> pollBytes(e, e->NewByteArray(0));
689    ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(pollBytes.get()));
690    ScopedLocalRef<jobjectArray> techPollBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
691    int len = 0;
692
693    for (int i = 0; i < mNumTechList; i++)
694    {
695        ALOGD ("%s: index=%d; rf tech params mode=%u", fn, i, mTechParams [i].mode);
696        switch (mTechParams [i].mode)
697        {
698        case NFC_DISCOVERY_TYPE_POLL_A:
699        case NFC_DISCOVERY_TYPE_POLL_A_ACTIVE:
700        case NFC_DISCOVERY_TYPE_LISTEN_A:
701        case NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE:
702            ALOGD ("%s: tech A", fn);
703            pollBytes.reset(e->NewByteArray(2));
704            e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte*) mTechParams [i].param.pa.sens_res);
705            break;
706
707        case NFC_DISCOVERY_TYPE_POLL_B:
708        case NFC_DISCOVERY_TYPE_POLL_B_PRIME:
709        case NFC_DISCOVERY_TYPE_LISTEN_B:
710        case NFC_DISCOVERY_TYPE_LISTEN_B_PRIME:
711            if (mTechList [i] == TARGET_TYPE_ISO14443_3B) //is TagTechnology.NFC_B by Java API
712            {
713                /*****************
714                see NFC Forum Digital Protocol specification; section 5.6.2;
715                in SENSB_RES response, byte 6 through 9 is Application Data, byte 10-12 or 13 is Protocol Info;
716                used by public API: NfcB.getApplicationData(), NfcB.getProtocolInfo();
717                *****************/
718                ALOGD ("%s: tech B; TARGET_TYPE_ISO14443_3B", fn);
719                len = mTechParams [i].param.pb.sensb_res_len;
720                len = len - 4; //subtract 4 bytes for NFCID0 at byte 2 through 5
721                pollBytes.reset(e->NewByteArray(len));
722                e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) (mTechParams [i].param.pb.sensb_res+4));
723            }
724            else
725            {
726                pollBytes.reset(e->NewByteArray(0));
727            }
728            break;
729
730        case NFC_DISCOVERY_TYPE_POLL_F:
731        case NFC_DISCOVERY_TYPE_POLL_F_ACTIVE:
732        case NFC_DISCOVERY_TYPE_LISTEN_F:
733        case NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
734            {
735                /****************
736                see NFC Forum Type 3 Tag Operation Specification; sections 2.3.2, 2.3.1.2;
737                see NFC Forum Digital Protocol Specification; sections 6.6.2;
738                PMm: manufacture parameter; 8 bytes;
739                System Code: 2 bytes;
740                ****************/
741                ALOGD ("%s: tech F", fn);
742                UINT8 result [10]; //return result to NFC service
743                memset (result, 0, sizeof(result));
744                len =  10;
745
746                /****
747                for (int ii = 0; ii < mTechParams [i].param.pf.sensf_res_len; ii++)
748                {
749                    ALOGD ("%s: tech F, sendf_res[%d]=%d (0x%x)",
750                          fn, ii, mTechParams [i].param.pf.sensf_res[ii],mTechParams [i].param.pf.sensf_res[ii]);
751                }
752                ***/
753                memcpy (result, mTechParams [i].param.pf.sensf_res + 8, 8); //copy PMm
754                if (activationData.params.t3t.num_system_codes > 0) //copy the first System Code
755                {
756                    UINT16 systemCode = *(activationData.params.t3t.p_system_codes);
757                    result [8] = (UINT8) (systemCode >> 8);
758                    result [9] = (UINT8) systemCode;
759                    ALOGD ("%s: tech F; sys code=0x%X 0x%X", fn, result [8], result [9]);
760                }
761                pollBytes.reset(e->NewByteArray(len));
762                e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) result);
763            }
764            break;
765
766        case NFC_DISCOVERY_TYPE_POLL_ISO15693:
767        case NFC_DISCOVERY_TYPE_LISTEN_ISO15693:
768            {
769                ALOGD ("%s: tech iso 15693", fn);
770                //iso 15693 response flags: 1 octet
771                //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
772                //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
773                uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid};
774                pollBytes.reset(e->NewByteArray(2));
775                e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte *) data);
776            }
777            break;
778
779        default:
780            ALOGE ("%s: tech unknown ????", fn);
781            pollBytes.reset(e->NewByteArray(0));
782            break;
783        } //switch: every type of technology
784        e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get());
785    } //for: every technology in the array
786    jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B");
787    e->SetObjectField(tag, f, techPollBytes.get());
788}
789
790
791/*******************************************************************************
792**
793** Function:        fillNativeNfcTagMembers4
794**
795** Description:     Fill NativeNfcTag's members: mTechActBytes.
796**                  The original Google's implementation is in set_target_activationBytes()
797**                  in com_android_nfc_NativeNfcTag.cpp;
798**                  e: JVM environment.
799**                  tag_cls: Java NativeNfcTag class.
800**                  tag: Java NativeNfcTag object.
801**                  activationData: data from activation.
802**
803** Returns:         None
804**
805*******************************************************************************/
806void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData)
807{
808    static const char fn [] = "NfcTag::fillNativeNfcTagMembers4";
809    ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0));
810    ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get()));
811    ScopedLocalRef<jobjectArray> techActBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
812
813    for (int i = 0; i < mNumTechList; i++)
814    {
815        ALOGD ("%s: index=%d", fn, i);
816        switch (mTechLibNfcTypes[i])
817        {
818        case NFC_PROTOCOL_T1T:
819        case NFC_PROTOCOL_T2T:
820            {
821                if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T1T)
822                    ALOGD ("%s: T1T; tech A", fn);
823                else if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T2T)
824                    ALOGD ("%s: T2T; tech A", fn);
825                actBytes.reset(e->NewByteArray(1));
826                e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp);
827            }
828            break;
829
830        case NFC_PROTOCOL_T3T: //felica
831            {
832                ALOGD ("%s: T3T; felica; tech F", fn);
833                //really, there is no data
834                actBytes.reset(e->NewByteArray(0));
835            }
836            break;
837
838        case NFC_PROTOCOL_ISO_DEP: //t4t
839            {
840                if (mTechList [i] == TARGET_TYPE_ISO14443_4) //is TagTechnology.ISO_DEP by Java API
841                {
842                    if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
843                            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
844                            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
845                            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) )
846                    {
847                        //see NFC Forum Digital Protocol specification, section 11.6.2, "RATS Response"; search for "historical bytes";
848                        //copy historical bytes into Java object;
849                        //the public API, IsoDep.getHistoricalBytes(), returns this data;
850                        if (activationData.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP)
851                        {
852                            tNFC_INTF_PA_ISO_DEP& pa_iso = activationData.activate_ntf.intf_param.intf_param.pa_iso;
853                            ALOGD ("%s: T4T; ISO_DEP for tech A; copy historical bytes; len=%u", fn, pa_iso.his_byte_len);
854                            actBytes.reset(e->NewByteArray(pa_iso.his_byte_len));
855                            if (pa_iso.his_byte_len > 0)
856                                e->SetByteArrayRegion(actBytes.get(), 0, pa_iso.his_byte_len, (jbyte*) (pa_iso.his_byte));
857                        }
858                        else
859                        {
860                            ALOGE ("%s: T4T; ISO_DEP for tech A; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type);
861                            actBytes.reset(e->NewByteArray(0));
862                        }
863                    }
864                    else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) ||
865                            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
866                            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
867                            (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) )
868                    {
869                        //see NFC Forum Digital Protocol specification, section 12.6.2, "ATTRIB Response";
870                        //copy higher-layer response bytes into Java object;
871                        //the public API, IsoDep.getHiLayerResponse(), returns this data;
872                        if (activationData.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP)
873                        {
874                            tNFC_INTF_PB_ISO_DEP& pb_iso = activationData.activate_ntf.intf_param.intf_param.pb_iso;
875                            ALOGD ("%s: T4T; ISO_DEP for tech B; copy response bytes; len=%u", fn, pb_iso.hi_info_len);
876                            actBytes.reset(e->NewByteArray(pb_iso.hi_info_len));
877                            if (pb_iso.hi_info_len > 0)
878                                e->SetByteArrayRegion(actBytes.get(), 0, pb_iso.hi_info_len, (jbyte*) (pb_iso.hi_info));
879                        }
880                        else
881                        {
882                            ALOGE ("%s: T4T; ISO_DEP for tech B; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type);
883                            actBytes.reset(e->NewByteArray(0));
884                        }
885                    }
886                }
887                else if (mTechList [i] == TARGET_TYPE_ISO14443_3A) //is TagTechnology.NFC_A by Java API
888                {
889                    ALOGD ("%s: T4T; tech A", fn);
890                    actBytes.reset(e->NewByteArray(1));
891                    e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp);
892                }
893                else
894                {
895                    actBytes.reset(e->NewByteArray(0));
896                }
897            } //case NFC_PROTOCOL_ISO_DEP: //t4t
898            break;
899
900        case NFC_PROTOCOL_15693:
901            {
902                ALOGD ("%s: tech iso 15693", fn);
903                //iso 15693 response flags: 1 octet
904                //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
905                //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
906                uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid};
907                actBytes.reset(e->NewByteArray(2));
908                e->SetByteArrayRegion(actBytes.get(), 0, 2, (jbyte *) data);
909            }
910            break;
911
912        default:
913            ALOGD ("%s: tech unknown ????", fn);
914            actBytes.reset(e->NewByteArray(0));
915            break;
916        }//switch
917        e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
918    } //for: every technology in the array
919    jfieldID f = e->GetFieldID (tag_cls, "mTechActBytes", "[[B");
920    e->SetObjectField(tag, f, techActBytes.get());
921}
922
923
924/*******************************************************************************
925**
926** Function:        fillNativeNfcTagMembers5
927**
928** Description:     Fill NativeNfcTag's members: mUid.
929**                  The original Google's implementation is in nfc_jni_Discovery_notification_callback()
930**                  in com_android_nfc_NativeNfcManager.cpp;
931**                  e: JVM environment.
932**                  tag_cls: Java NativeNfcTag class.
933**                  tag: Java NativeNfcTag object.
934**                  activationData: data from activation.
935**
936** Returns:         None
937**
938*******************************************************************************/
939void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData)
940{
941    static const char fn [] = "NfcTag::fillNativeNfcTagMembers5";
942    int len = 0;
943    ScopedLocalRef<jbyteArray> uid(e, NULL);
944
945    switch (mTechParams [0].mode)
946    {
947    case NFC_DISCOVERY_TYPE_POLL_KOVIO:
948        ALOGD ("%s: Kovio", fn);
949        len = mTechParams [0].param.pk.uid_len;
950        uid.reset(e->NewByteArray(len));
951        e->SetByteArrayRegion(uid.get(), 0, len,
952                (jbyte*) &mTechParams [0].param.pk.uid);
953        break;
954
955    case NFC_DISCOVERY_TYPE_POLL_A:
956    case NFC_DISCOVERY_TYPE_POLL_A_ACTIVE:
957    case NFC_DISCOVERY_TYPE_LISTEN_A:
958    case NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE:
959        ALOGD ("%s: tech A", fn);
960        len = mTechParams [0].param.pa.nfcid1_len;
961        uid.reset(e->NewByteArray(len));
962        e->SetByteArrayRegion(uid.get(), 0, len,
963                (jbyte*) &mTechParams [0].param.pa.nfcid1);
964        //a tag's NFCID1 can change dynamically at each activation;
965        //only the first byte (0x08) is constant; a dynamic NFCID1's length
966        //must be 4 bytes (see NFC Digitial Protocol,
967        //section 4.7.2 SDD_RES Response, Requirements 20).
968        mIsDynamicTagId = (mTechParams [0].param.pa.nfcid1_len == 4) &&
969                (mTechParams [0].param.pa.nfcid1 [0] == 0x08);
970        break;
971
972    case NFC_DISCOVERY_TYPE_POLL_B:
973    case NFC_DISCOVERY_TYPE_POLL_B_PRIME:
974    case NFC_DISCOVERY_TYPE_LISTEN_B:
975    case NFC_DISCOVERY_TYPE_LISTEN_B_PRIME:
976        ALOGD ("%s: tech B", fn);
977        uid.reset(e->NewByteArray(NFC_NFCID0_MAX_LEN));
978        e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID0_MAX_LEN,
979                (jbyte*) &mTechParams [0].param.pb.nfcid0);
980        break;
981
982    case NFC_DISCOVERY_TYPE_POLL_F:
983    case NFC_DISCOVERY_TYPE_POLL_F_ACTIVE:
984    case NFC_DISCOVERY_TYPE_LISTEN_F:
985    case NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE:
986        uid.reset(e->NewByteArray(NFC_NFCID2_LEN));
987        e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID2_LEN,
988                (jbyte*) &mTechParams [0].param.pf.nfcid2);
989        ALOGD ("%s: tech F", fn);
990        break;
991
992    case NFC_DISCOVERY_TYPE_POLL_ISO15693:
993    case NFC_DISCOVERY_TYPE_LISTEN_ISO15693:
994        {
995            ALOGD ("%s: tech iso 15693", fn);
996            jbyte data [I93_UID_BYTE_LEN];  //8 bytes
997            for (int i=0; i<I93_UID_BYTE_LEN; ++i) //reverse the ID
998                data[i] = activationData.params.i93.uid [I93_UID_BYTE_LEN - i - 1];
999            uid.reset(e->NewByteArray(I93_UID_BYTE_LEN));
1000            e->SetByteArrayRegion(uid.get(), 0, I93_UID_BYTE_LEN, data);
1001        }
1002        break;
1003
1004    default:
1005        ALOGE ("%s: tech unknown ????", fn);
1006        uid.reset(e->NewByteArray(0));
1007        break;
1008    }
1009    jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B");
1010    e->SetObjectField(tag, f, uid.get());
1011}
1012
1013
1014/*******************************************************************************
1015**
1016** Function:        isP2pDiscovered
1017**
1018** Description:     Does the peer support P2P?
1019**
1020** Returns:         True if the peer supports P2P.
1021**
1022*******************************************************************************/
1023bool NfcTag::isP2pDiscovered ()
1024{
1025    static const char fn [] = "NfcTag::isP2pDiscovered";
1026    bool retval = false;
1027
1028    for (int i = 0; i < mNumTechList; i++)
1029    {
1030        if (mTechLibNfcTypes[i] == NFA_PROTOCOL_NFC_DEP)
1031        {
1032            //if remote device supports P2P
1033            ALOGD ("%s: discovered P2P", fn);
1034            retval = true;
1035            break;
1036        }
1037    }
1038    ALOGD ("%s: return=%u", fn, retval);
1039    return retval;
1040}
1041
1042
1043/*******************************************************************************
1044**
1045** Function:        selectP2p
1046**
1047** Description:     Select the preferred P2P technology if there is a choice.
1048**
1049** Returns:         None
1050**
1051*******************************************************************************/
1052void NfcTag::selectP2p()
1053{
1054    static const char fn [] = "NfcTag::selectP2p";
1055    UINT8 rfDiscoveryId = 0;
1056
1057    for (int i = 0; i < mNumTechList; i++)
1058    {
1059        //if remote device does not support P2P, just skip it
1060        if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP)
1061            continue;
1062
1063        //if remote device supports tech F;
1064        //tech F is preferred because it is faster than tech A
1065        if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F) ||
1066             (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) )
1067        {
1068            rfDiscoveryId = mTechHandles[i];
1069            break; //no need to search further
1070        }
1071        else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
1072                (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) )
1073        {
1074            //only choose tech A if tech F is unavailable
1075            if (rfDiscoveryId == 0)
1076                rfDiscoveryId = mTechHandles[i];
1077        }
1078    }
1079
1080    if (rfDiscoveryId > 0)
1081    {
1082        ALOGD ("%s: select P2P; target rf discov id=0x%X", fn, rfDiscoveryId);
1083        tNFA_STATUS stat = NFA_Select (rfDiscoveryId, NFA_PROTOCOL_NFC_DEP, NFA_INTERFACE_NFC_DEP);
1084        if (stat != NFA_STATUS_OK)
1085            ALOGE ("%s: fail select P2P; error=0x%X", fn, stat);
1086    }
1087    else
1088        ALOGE ("%s: cannot find P2P", fn);
1089    resetTechnologies ();
1090}
1091
1092
1093/*******************************************************************************
1094**
1095** Function:        resetTechnologies
1096**
1097** Description:     Clear all data related to the technology, protocol of the tag.
1098**
1099** Returns:         None
1100**
1101*******************************************************************************/
1102void NfcTag::resetTechnologies ()
1103{
1104    static const char fn [] = "NfcTag::resetTechnologies";
1105    ALOGD ("%s", fn);
1106   	mNumTechList = 0;
1107    memset (mTechList, 0, sizeof(mTechList));
1108    memset (mTechHandles, 0, sizeof(mTechHandles));
1109    memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
1110    memset (mTechParams, 0, sizeof(mTechParams));
1111    mIsDynamicTagId = false;
1112    mIsFelicaLite = false;
1113    resetAllTransceiveTimeouts ();
1114}
1115
1116
1117/*******************************************************************************
1118**
1119** Function:        selectFirstTag
1120**
1121** Description:     When multiple tags are discovered, just select the first one to activate.
1122**
1123** Returns:         None
1124**
1125*******************************************************************************/
1126void NfcTag::selectFirstTag ()
1127{
1128    static const char fn [] = "NfcTag::selectFirstTag";
1129    int foundIdx = -1;
1130    tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
1131
1132    for (int i = 0; i < mNumTechList; i++)
1133    {
1134        ALOGD ("%s: nfa target idx=%d h=0x%X; protocol=0x%X",
1135                fn, i, mTechHandles [i], mTechLibNfcTypes [i]);
1136        if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP)
1137        {
1138            foundIdx = i;
1139            break;
1140        }
1141    }
1142
1143    if (foundIdx != -1)
1144    {
1145        if (mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_ISO_DEP)
1146        {
1147            rf_intf = NFA_INTERFACE_ISO_DEP;
1148        }
1149        else
1150            rf_intf = NFA_INTERFACE_FRAME;
1151
1152        tNFA_STATUS stat = NFA_Select (mTechHandles [foundIdx], mTechLibNfcTypes [foundIdx], rf_intf);
1153        if (stat != NFA_STATUS_OK)
1154            ALOGE ("%s: fail select; error=0x%X", fn, stat);
1155    }
1156    else
1157        ALOGE ("%s: only found NFC-DEP technology.", fn);
1158}
1159
1160
1161/*******************************************************************************
1162**
1163** Function:        getT1tMaxMessageSize
1164**
1165** Description:     Get the maximum size (octet) that a T1T can store.
1166**
1167** Returns:         Maximum size in octets.
1168**
1169*******************************************************************************/
1170int NfcTag::getT1tMaxMessageSize ()
1171{
1172    static const char fn [] = "NfcTag::getT1tMaxMessageSize";
1173
1174    if (mProtocol != NFC_PROTOCOL_T1T)
1175    {
1176        ALOGE ("%s: wrong protocol %u", fn, mProtocol);
1177        return 0;
1178    }
1179    return mtT1tMaxMessageSize;
1180}
1181
1182
1183/*******************************************************************************
1184**
1185** Function:        calculateT1tMaxMessageSize
1186**
1187** Description:     Calculate type-1 tag's max message size based on header ROM bytes.
1188**                  activate: reference to activation data.
1189**
1190** Returns:         None
1191**
1192*******************************************************************************/
1193void NfcTag::calculateT1tMaxMessageSize (tNFA_ACTIVATED& activate)
1194{
1195    static const char fn [] = "NfcTag::calculateT1tMaxMessageSize";
1196
1197    //make sure the tag is type-1
1198    if (activate.activate_ntf.protocol != NFC_PROTOCOL_T1T)
1199    {
1200        mtT1tMaxMessageSize = 0;
1201        return;
1202    }
1203
1204    //examine the first byte of header ROM bytes
1205    switch (activate.params.t1t.hr[0])
1206    {
1207    case RW_T1T_IS_TOPAZ96:
1208        mtT1tMaxMessageSize = 90;
1209        break;
1210    case RW_T1T_IS_TOPAZ512:
1211        mtT1tMaxMessageSize = 462;
1212        break;
1213    default:
1214        ALOGE ("%s: unknown T1T HR0=%u", fn, activate.params.t1t.hr[0]);
1215        mtT1tMaxMessageSize = 0;
1216        break;
1217    }
1218}
1219
1220
1221/*******************************************************************************
1222**
1223** Function:        isMifareUltralight
1224**
1225** Description:     Whether the currently activated tag is Mifare Ultralight.
1226**
1227** Returns:         True if tag is Mifare Ultralight.
1228**
1229*******************************************************************************/
1230bool NfcTag::isMifareUltralight ()
1231{
1232    static const char fn [] = "NfcTag::isMifareUltralight";
1233    bool retval = false;
1234
1235    for (int i =0; i < mNumTechList; i++)
1236    {
1237        if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A)
1238        {
1239            //see NFC Digital Protocol, section 4.6.3 (SENS_RES); section 4.8.2 (SEL_RES).
1240            //see "MF0ICU1 Functional specification MIFARE Ultralight", Rev. 3.4 - 4 February 2008,
1241            //section 6.7.
1242            if ( (mTechParams[i].param.pa.sens_res[0] == 0x44) &&
1243                 (mTechParams[i].param.pa.sens_res[1] == 0) &&
1244                 ( (mTechParams[i].param.pa.sel_rsp == 0) || (mTechParams[i].param.pa.sel_rsp == 0x04) ) &&
1245                 (mTechParams[i].param.pa.nfcid1[0] == 0x04) )
1246            {
1247                retval = true;
1248            }
1249            break;
1250        }
1251    }
1252    ALOGD ("%s: return=%u", fn, retval);
1253    return retval;
1254}
1255
1256
1257/*******************************************************************************
1258**
1259** Function:        isFelicaLite
1260**
1261** Description:     Whether the currently activated tag is Felica Lite.
1262**
1263** Returns:         True if tag is Felica Lite.
1264**
1265*******************************************************************************/
1266
1267bool NfcTag::isFelicaLite ()
1268{
1269    return mIsFelicaLite;
1270}
1271
1272
1273/*******************************************************************************
1274**
1275** Function:        isT2tNackResponse
1276**
1277** Description:     Whether the response is a T2T NACK response.
1278**                  See NFC Digital Protocol Technical Specification (2010-11-17).
1279**                  Chapter 9 (Type 2 Tag Platform), section 9.6 (READ).
1280**                  response: buffer contains T2T response.
1281**                  responseLen: length of the response.
1282**
1283** Returns:         True if the response is NACK
1284**
1285*******************************************************************************/
1286bool NfcTag::isT2tNackResponse (const UINT8* response, UINT32 responseLen)
1287{
1288    static const char fn [] = "NfcTag::isT2tNackResponse";
1289    bool isNack = false;
1290
1291    if (responseLen == 1)
1292    {
1293        if (response[0] == 0xA)
1294            isNack = false; //an ACK response, so definitely not a NACK
1295        else
1296            isNack = true; //assume every value is a NACK
1297    }
1298    ALOGD ("%s: return %u", fn, isNack);
1299    return isNack;
1300}
1301
1302
1303/*******************************************************************************
1304**
1305** Function:        isNdefDetectionTimedOut
1306**
1307** Description:     Whether NDEF-detection algorithm timed out.
1308**
1309** Returns:         True if NDEF-detection algorithm timed out.
1310**
1311*******************************************************************************/
1312bool NfcTag::isNdefDetectionTimedOut ()
1313{
1314    return mNdefDetectionTimedOut;
1315}
1316
1317
1318/*******************************************************************************
1319**
1320** Function:        connectionEventHandler
1321**
1322** Description:     Handle connection-related events.
1323**                  event: event code.
1324**                  data: pointer to event data.
1325**
1326** Returns:         None
1327**
1328*******************************************************************************/
1329void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data)
1330{
1331    static const char fn [] = "NfcTag::connectionEventHandler";
1332
1333    switch (event)
1334    {
1335    case NFA_DISC_RESULT_EVT:
1336        {
1337            tNFA_DISC_RESULT& disc_result = data->disc_result;
1338            if (disc_result.status == NFA_STATUS_OK)
1339            {
1340                discoverTechnologies (disc_result);
1341            }
1342        }
1343        break;
1344
1345    case NFA_ACTIVATED_EVT:
1346        // Only do tag detection if we are polling and it is not 'EE Direct RF' activation
1347        // (which may happen when we are activated as a tag).
1348        if (data->activated.activate_ntf.rf_tech_param.mode < NCI_DISCOVERY_TYPE_LISTEN_A
1349            && data->activated.activate_ntf.intf_param.type != NFC_INTERFACE_EE_DIRECT_RF)
1350        {
1351            tNFA_ACTIVATED& activated = data->activated;
1352            if (IsSameKovio(activated))
1353                break;
1354            mIsActivated = true;
1355            mProtocol = activated.activate_ntf.protocol;
1356            calculateT1tMaxMessageSize (activated);
1357            discoverTechnologies (activated);
1358            createNativeNfcTag (activated);
1359        }
1360        break;
1361
1362    case NFA_DEACTIVATED_EVT:
1363        mIsActivated = false;
1364        mProtocol = NFC_PROTOCOL_UNKNOWN;
1365        resetTechnologies ();
1366        break;
1367
1368    case NFA_READ_CPLT_EVT:
1369        {
1370            SyncEventGuard g (mReadCompleteEvent);
1371            mReadCompletedStatus = data->status;
1372            mReadCompleteEvent.notifyOne ();
1373        }
1374        break;
1375
1376    case NFA_NDEF_DETECT_EVT:
1377        {
1378            tNFA_NDEF_DETECT& ndef_detect = data->ndef_detect;
1379            mNdefDetectionTimedOut = ndef_detect.status == NFA_STATUS_TIMEOUT;
1380            if (mNdefDetectionTimedOut)
1381                ALOGE ("%s: NDEF detection timed out", fn);
1382        }
1383    }
1384}
1385
1386
1387/*******************************************************************************
1388**
1389** Function         setActive
1390**
1391** Description      Sets the active state for the object
1392**
1393** Returns          None.
1394**
1395*******************************************************************************/
1396void NfcTag::setActive(bool active)
1397{
1398    mIsActivated = active;
1399}
1400
1401
1402/*******************************************************************************
1403**
1404** Function:        isDynamicTagId
1405**
1406** Description:     Whether a tag has a dynamic tag ID.
1407**
1408** Returns:         True if ID is dynamic.
1409**
1410*******************************************************************************/
1411bool NfcTag::isDynamicTagId ()
1412{
1413    return mIsDynamicTagId &&
1414            (mTechList [0] == TARGET_TYPE_ISO14443_4) &&  //type-4 tag
1415            (mTechList [1] == TARGET_TYPE_ISO14443_3A);  //tech A
1416}
1417
1418
1419/*******************************************************************************
1420**
1421** Function:        resetAllTransceiveTimeouts
1422**
1423** Description:     Reset all timeouts for all technologies to default values.
1424**
1425** Returns:         none
1426**
1427*******************************************************************************/
1428void NfcTag::resetAllTransceiveTimeouts ()
1429{
1430    mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_3A] = 618; //NfcA
1431    mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_3B] = 1000; //NfcB
1432    mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_4] = 309; //ISO-DEP
1433    mTechnologyTimeoutsTable [TARGET_TYPE_FELICA] = 255; //Felica
1434    mTechnologyTimeoutsTable [TARGET_TYPE_ISO15693] = 1000;//NfcV
1435    mTechnologyTimeoutsTable [TARGET_TYPE_NDEF] = 1000;
1436    mTechnologyTimeoutsTable [TARGET_TYPE_NDEF_FORMATABLE] = 1000;
1437    mTechnologyTimeoutsTable [TARGET_TYPE_MIFARE_CLASSIC] = 618; //MifareClassic
1438    mTechnologyTimeoutsTable [TARGET_TYPE_MIFARE_UL] = 618; //MifareUltralight
1439    mTechnologyTimeoutsTable [TARGET_TYPE_KOVIO_BARCODE] = 1000; //NfcBarcode
1440}
1441
1442/*******************************************************************************
1443**
1444** Function:        getTransceiveTimeout
1445**
1446** Description:     Get the timeout value for one technology.
1447**                  techId: one of the values in TARGET_TYPE_* defined in NfcJniUtil.h
1448**
1449** Returns:         Timeout value in millisecond.
1450**
1451*******************************************************************************/
1452int NfcTag::getTransceiveTimeout (int techId)
1453{
1454    static const char fn [] = "NfcTag::getTransceiveTimeout";
1455    int retval = 1000;
1456    if ((techId > 0) && (techId < (int) mTechnologyTimeoutsTable.size()))
1457        retval = mTechnologyTimeoutsTable [techId];
1458    else
1459        ALOGE ("%s: invalid tech=%d", fn, techId);
1460    return retval;
1461}
1462
1463
1464/*******************************************************************************
1465**
1466** Function:        setTransceiveTimeout
1467**
1468** Description:     Set the timeout value for one technology.
1469**                  techId: one of the values in TARGET_TYPE_* defined in NfcJniUtil.h
1470**                  timeout: timeout value in millisecond.
1471**
1472** Returns:         Timeout value.
1473**
1474*******************************************************************************/
1475void NfcTag::setTransceiveTimeout (int techId, int timeout)
1476{
1477    static const char fn [] = "NfcTag::setTransceiveTimeout";
1478    if ((techId >= 0) && (techId < (int) mTechnologyTimeoutsTable.size()))
1479        mTechnologyTimeoutsTable [techId] = timeout;
1480    else
1481        ALOGE ("%s: invalid tech=%d", fn, techId);
1482}
1483
1484
1485/*******************************************************************************
1486**
1487** Function:        getPresenceCheckAlgorithm
1488**
1489** Description:     Get presence-check algorithm from .conf file.
1490**
1491** Returns:         Presence-check algorithm.
1492**
1493*******************************************************************************/
1494tNFA_RW_PRES_CHK_OPTION NfcTag::getPresenceCheckAlgorithm ()
1495{
1496    return mPresenceCheckAlgorithm;
1497}
1498
1499
1500/*******************************************************************************
1501**
1502** Function:        isInfineonMyDMove
1503**
1504** Description:     Whether the currently activated tag is Infineon My-D Move.
1505**
1506** Returns:         True if tag is Infineon My-D Move.
1507**
1508*******************************************************************************/
1509bool NfcTag::isInfineonMyDMove ()
1510{
1511    static const char fn [] = "NfcTag::isInfineonMyDMove";
1512    bool retval = false;
1513
1514    for (int i =0; i < mNumTechList; i++)
1515    {
1516        if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A)
1517        {
1518            //see Infineon my-d move, my-d move NFC, SLE 66R01P, SLE 66R01PN,
1519            //Short Product Information, 2011-11-24, section 3.5
1520            if (mTechParams[i].param.pa.nfcid1[0] == 0x05)
1521            {
1522                UINT8 highNibble = mTechParams[i].param.pa.nfcid1[1] & 0xF0;
1523                if (highNibble == 0x30)
1524                    retval = true;
1525            }
1526            break;
1527        }
1528    }
1529    ALOGD ("%s: return=%u", fn, retval);
1530    return retval;
1531}
1532
1533
1534/*******************************************************************************
1535**
1536** Function:        isKovioType2Tag
1537**
1538** Description:     Whether the currently activated tag is Kovio Type-2 tag.
1539**
1540** Returns:         True if tag is Kovio Type-2 tag.
1541**
1542*******************************************************************************/
1543bool NfcTag::isKovioType2Tag ()
1544{
1545    static const char fn [] = "NfcTag::isKovioType2Tag";
1546    bool retval = false;
1547
1548    for (int i =0; i < mNumTechList; i++)
1549    {
1550        if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A)
1551        {
1552            //Kovio 2Kb RFID Tag, Functional Specification,
1553            //March 2, 2012, v2.0, section 8.3.
1554            if (mTechParams[i].param.pa.nfcid1[0] == 0x37)
1555                retval = true;
1556            break;
1557        }
1558    }
1559    ALOGD ("%s: return=%u", fn, retval);
1560    return retval;
1561}
1562