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