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