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