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