Home | History | Annotate | Download | only in jni
      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 extern "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 *******************************************************************************/
     38 NfcTag::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 *******************************************************************************/
     65 NfcTag& 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 *******************************************************************************/
     82 void 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 *******************************************************************************/
    103 void 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 *******************************************************************************/
    119 NfcTag::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 *******************************************************************************/
    135 void 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 *******************************************************************************/
    155 void 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 *******************************************************************************/
    173 tNFC_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 *******************************************************************************/
    187 UINT32 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 *******************************************************************************/
    217 bool 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 *******************************************************************************/
    270 void 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 *******************************************************************************/
    382 void 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 
    473 TheEnd:
    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 *******************************************************************************/
    490 void 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 
    549 TheEnd:
    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 *******************************************************************************/
    567 void 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
    620 void 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 *******************************************************************************/
    646 void 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 *******************************************************************************/
    766 void 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 *******************************************************************************/
    907 void 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 *******************************************************************************/
    986 bool 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 *******************************************************************************/
   1015 void 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 *******************************************************************************/
   1065 void 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 *******************************************************************************/
   1086 void 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 *******************************************************************************/
   1117 int 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 *******************************************************************************/
   1140 void 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 *******************************************************************************/
   1177 bool 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 *******************************************************************************/
   1228 bool 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 *******************************************************************************/
   1254 bool 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 *******************************************************************************/
   1271 void 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