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