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