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