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