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 LOG(DEBUG) << StringPrintf("%s: enter", fn);
239 tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
240
241 if (rfDetail.protocol != NFC_PROTOCOL_KOVIO) return false;
242
243 memcpy(&(mTechParams[0]), &(rfDetail.rf_tech_param),
244 sizeof(rfDetail.rf_tech_param));
245 if (mTechParams[0].mode != NFC_DISCOVERY_TYPE_POLL_KOVIO) return false;
246
247 struct timespec now;
248 clock_gettime(CLOCK_REALTIME, &now);
249
250 bool rVal = false;
251 if (mTechParams[0].param.pk.uid_len == mLastKovioUidLen) {
252 if (memcmp(mLastKovioUid, &mTechParams[0].param.pk.uid,
253 mTechParams[0].param.pk.uid_len) == 0) {
254 // same tag
255 if (TimeDiff(mLastKovioTime, now) < 500) {
256 // same tag within 500 ms, ignore activation
257 rVal = true;
258 }
259 }
260 }
261
262 // save Kovio tag info
263 if (!rVal) {
264 if ((mLastKovioUidLen = mTechParams[0].param.pk.uid_len) >
265 NFC_KOVIO_MAX_LEN)
266 mLastKovioUidLen = NFC_KOVIO_MAX_LEN;
267 memcpy(mLastKovioUid, mTechParams[0].param.pk.uid, mLastKovioUidLen);
268 }
269 mLastKovioTime = now;
270 LOG(DEBUG) << StringPrintf("%s: exit, is same Kovio=%d", fn, rVal);
271 return rVal;
272 }
273
274 /*******************************************************************************
275 **
276 ** Function: discoverTechnologies
277 **
278 ** Description: Discover the technologies that NFC service needs by
279 *interpreting
280 ** the data structures from the stack.
281 ** activationData: data from activation.
282 **
283 ** Returns: None
284 **
285 *******************************************************************************/
discoverTechnologies(tNFA_ACTIVATED & activationData)286 void NfcTag::discoverTechnologies(tNFA_ACTIVATED& activationData) {
287 static const char fn[] = "NfcTag::discoverTechnologies (activation)";
288 LOG(DEBUG) << StringPrintf("%s: enter", fn);
289 tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
290
291 if (mTechListTail < (MAX_NUM_TECHNOLOGY - 1)) {
292 mNumTechList = 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[mNumTechList] = rfDetail.rf_disc_id;
299 mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
300
301 // save the stack's data structure for interpretation later
302 memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
303 sizeof(rfDetail.rf_tech_param));
304
305 if (NFC_PROTOCOL_T1T == rfDetail.protocol) {
306 mTechList[mNumTechList] =
307 TARGET_TYPE_ISO14443_3A; // is TagTechnology.NFC_A by Java API
308 } else if (NFC_PROTOCOL_T2T == rfDetail.protocol) {
309 mTechList[mNumTechList] =
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 mNumTechList++;
324 mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
325 mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
326 // save the stack's data structure for interpretation later
327 memcpy(&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param),
328 sizeof(rfDetail.rf_tech_param));
329 mTechList[mNumTechList] =
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[mNumTechList] = 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[mNumTechList] =
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[mNumTechList], 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 mNumTechList++;
370 mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
371 mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
372 mTechList[mNumTechList] =
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[mNumTechList]), &(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 mNumTechList++;
384 mTechHandles[mNumTechList] = rfDetail.rf_disc_id;
385 mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
386 mTechList[mNumTechList] =
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[mNumTechList]), &(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[mNumTechList] = TARGET_TYPE_V;
395 } else if (NFC_PROTOCOL_KOVIO == rfDetail.protocol) {
396 LOG(DEBUG) << StringPrintf("%s: Kovio", fn);
397 mTechList[mNumTechList] = TARGET_TYPE_KOVIO_BARCODE;
398 } else if (NFC_PROTOCOL_MIFARE == rfDetail.protocol) {
399 LOG(DEBUG) << StringPrintf("%s: Mifare Classic", fn);
400 mTechList[mNumTechList] =
401 TARGET_TYPE_MIFARE_CLASSIC; // is TagTechnology.MIFARE_CLASSIC by Java
402 // 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),
408 sizeof(rfDetail.rf_tech_param));
409 mTechList[mNumTechList] =
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[mNumTechList] = rfDetail.rf_disc_id;
415 mTechLibNfcTypes[mNumTechList] = rfDetail.protocol;
416 LOG(DEBUG) << StringPrintf("%s; Tech type B, unknown ", fn);
417 mTechList[mNumTechList] =
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[mNumTechList]), &(rfDetail.rf_tech_param),
421 sizeof(rfDetail.rf_tech_param));
422 } else {
423 LOG(ERROR) << StringPrintf("%s; unknown protocol ????", fn);
424 mTechList[mNumTechList] = TARGET_TYPE_UNKNOWN;
425 }
426 }
427
428 mNumTechList++;
429 for (int i = 0; i < mNumTechList; 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 TheEnd:
437 LOG(DEBUG) << StringPrintf("%s: exit", fn);
438 }
439
440 /*******************************************************************************
441 **
442 ** Function: discoverTechnologies
443 **
444 ** Description: Discover the technologies that NFC service needs by
445 *interpreting
446 ** the data structures from the stack.
447 ** discoveryData: data from discovery events(s).
448 **
449 ** Returns: None
450 **
451 *******************************************************************************/
discoverTechnologies(tNFA_DISC_RESULT & discoveryData)452 void NfcTag::discoverTechnologies(tNFA_DISC_RESULT& discoveryData) {
453 static const char fn[] = "NfcTag::discoverTechnologies (discovery)";
454 tNFC_RESULT_DEVT& discovery_ntf = discoveryData.discovery_ntf;
455 uint8_t index = mNumDiscNtf;
456
457 LOG(DEBUG) << StringPrintf(
458 "%s: enter: rf disc. id=%u; protocol=0x%x, mNumTechList=%u", fn,
459 discovery_ntf.rf_disc_id, discovery_ntf.protocol, mNumTechList);
460 if (index >= MAX_NUM_TECHNOLOGY) {
461 LOG(ERROR) << StringPrintf("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);
462 goto TheEnd;
463 }
464 mTechHandlesDiscData[index] = discovery_ntf.rf_disc_id;
465 mTechLibNfcTypesDiscData[index] = discovery_ntf.protocol;
466 if (mNumDiscTechList < MAX_NUM_TECHNOLOGY) {
467 mNumDiscTechList++;
468 }
469 if (discovery_ntf.more != NCI_DISCOVER_NTF_MORE) {
470 for (int i = 0; i < mNumDiscTechList; i++) {
471 LOG(DEBUG) << StringPrintf("%s: index=%d; handle=%d; nfc type=0x%x", fn,
472 i, mTechHandlesDiscData[i],
473 mTechLibNfcTypesDiscData[i]);
474 }
475 }
476 LOG(DEBUG) << StringPrintf("%s; mNumDiscTechList=%x", fn, mNumDiscTechList);
477 mNumRfDiscId = discovery_ntf.rf_disc_id;
478 TheEnd:
479 LOG(DEBUG) << StringPrintf("%s: exit", fn);
480 }
481
482 /*******************************************************************************
483 **
484 ** Function: createNativeNfcTag
485 **
486 ** Description: Create a brand new Java NativeNfcTag object;
487 ** fill the objects's member variables with data;
488 ** notify NFC service;
489 ** activationData: data from activation.
490 **
491 ** Returns: None
492 **
493 *******************************************************************************/
createNativeNfcTag(tNFA_ACTIVATED & activationData)494 void NfcTag::createNativeNfcTag(tNFA_ACTIVATED& activationData) {
495 static const char fn[] = "NfcTag::createNativeNfcTag";
496 LOG(DEBUG) << StringPrintf("%s: enter", fn);
497
498 if (mNativeData == NULL) {
499 LOG(ERROR) << StringPrintf("%s: mNativeData is null", fn);
500 return;
501 }
502
503 JNIEnv* e = NULL;
504 ScopedAttach attach(mNativeData->vm, &e);
505 if (e == NULL) {
506 LOG(ERROR) << StringPrintf("%s: jni env is null", fn);
507 return;
508 }
509
510 ScopedLocalRef<jclass> tag_cls(e,
511 e->GetObjectClass(mNativeData->cached_NfcTag));
512 if (e->ExceptionCheck()) {
513 e->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 = e->GetMethodID(tag_cls.get(), "<init>", "()V");
520 ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor));
521
522 // fill NativeNfcTag's mProtocols, mTechList, mTechHandles, mTechLibNfcTypes
523 fillNativeNfcTagMembers1(e, tag_cls.get(), tag.get());
524
525 // fill NativeNfcTag's members: mHandle, mConnectedTechnology
526 fillNativeNfcTagMembers2(e, tag_cls.get(), tag.get(), activationData);
527
528 // fill NativeNfcTag's members: mTechPollBytes
529 fillNativeNfcTagMembers3(e, tag_cls.get(), tag.get(), activationData);
530
531 // fill NativeNfcTag's members: mTechActBytes
532 fillNativeNfcTagMembers4(e, tag_cls.get(), tag.get(), activationData);
533
534 // fill NativeNfcTag's members: mUid
535 fillNativeNfcTagMembers5(e, tag_cls.get(), tag.get(), activationData);
536
537 if (mNativeData->tag != NULL) {
538 e->DeleteGlobalRef(mNativeData->tag);
539 }
540 mNativeData->tag = e->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 e->CallVoidMethod(mNativeData->manager,
548 android::gCachedNfcManagerNotifyNdefMessageListeners,
549 tag.get());
550 if (e->ExceptionCheck()) {
551 e->ExceptionClear();
552 LOG(ERROR) << StringPrintf("%s: fail notify nfc service", fn);
553 }
554 deleteglobaldata(e);
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=%u", 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 LOG(ERROR) << StringPrintf("%s: tech unknown ????", fn);
780 pollBytes.reset(e->NewByteArray(0));
781 } // switch: every type of technology
782 e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get());
783 } // for: every technology in the array
784 if (sTechPollBytes != NULL && mTechListTail != 0) {
785 /* Save tech poll bytes of all activated tags of a multiprotocol tag in
786 * sTechPollBytes*/
787 e->DeleteGlobalRef(sTechPollBytes);
788 sTechPollBytes =
789 reinterpret_cast<jobjectArray>(e->NewGlobalRef(techPollBytes.get()));
790 }
791 jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B");
792 e->SetObjectField(tag, f, techPollBytes.get());
793 }
794
795 /*******************************************************************************
796 **
797 ** Function: fillNativeNfcTagMembers4
798 **
799 ** Description: Fill NativeNfcTag's members: mTechActBytes.
800 ** The original Google's implementation is in
801 *set_target_activationBytes()
802 ** in com_android_nfc_NativeNfcTag.cpp;
803 ** e: JVM environment.
804 ** tag_cls: Java NativeNfcTag class.
805 ** tag: Java NativeNfcTag object.
806 ** activationData: data from activation.
807 **
808 ** Returns: None
809 **
810 *******************************************************************************/
fillNativeNfcTagMembers4(JNIEnv * e,jclass tag_cls,jobject tag,tNFA_ACTIVATED & activationData)811 void NfcTag::fillNativeNfcTagMembers4(JNIEnv* e, jclass tag_cls, jobject tag,
812 tNFA_ACTIVATED& activationData) {
813 static const char fn[] = "NfcTag::fillNativeNfcTagMembers4";
814 ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0));
815 ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get()));
816 ScopedLocalRef<jobjectArray> techActBytes(
817 e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
818 jobject gtechActBytesObject;
819 // Restore previously selected tag information from the gtechActBytes to
820 // techActBytes.
821 for (int j = 0; j < mTechListTail; j++) {
822 gtechActBytesObject = e->GetObjectArrayElement(gtechActBytes, j);
823 e->SetObjectArrayElement(techActBytes.get(), j, gtechActBytesObject);
824 }
825
826 // merging sak for combi tag
827 if (activationData.activate_ntf.protocol &
828 (NFC_PROTOCOL_T1T | NFC_PROTOCOL_T2T | NFC_PROTOCOL_MIFARE |
829 NFC_PROTOCOL_ISO_DEP)) {
830 uint8_t merge_sak = 0;
831 for (int i = 0; i < mNumTechList; i++) {
832 merge_sak = (merge_sak | mTechParams[i].param.pa.sel_rsp);
833 }
834 for (int i = 0; i < mNumTechList; i++) {
835 if (TARGET_TYPE_ISO14443_3A == mTechList[i]) {
836 mTechParams[i].param.pa.sel_rsp = merge_sak;
837 actBytes.reset(e->NewByteArray(1));
838 e->SetByteArrayRegion(actBytes.get(), 0, 1,
839 (jbyte*)&mTechParams[i].param.pa.sel_rsp);
840 e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
841 }
842 }
843 }
844
845 if (mTechListTail == 0) {
846 // Keep the backup of the selected tag information to restore back with
847 // multi selection.
848 gtechActBytes =
849 reinterpret_cast<jobjectArray>(e->NewGlobalRef(techActBytes.get()));
850 } else {
851 for (int j = 0; j < mTechListTail; j++) {
852 if (gtechActBytes == NULL) {
853 gtechActBytes =
854 reinterpret_cast<jobjectArray>(e->NewGlobalRef(techActBytes.get()));
855 }
856 gtechActBytesObject = e->GetObjectArrayElement(gtechActBytes, j);
857 e->SetObjectArrayElement(techActBytes.get(), j, gtechActBytesObject);
858 }
859 }
860
861 for (int i = mTechListTail; i < mNumTechList; i++) {
862 LOG(DEBUG) << StringPrintf("%s: index=%d", fn, i);
863 if (NFC_PROTOCOL_T1T == mTechLibNfcTypes[i] ||
864 NFC_PROTOCOL_T2T == mTechLibNfcTypes[i]) {
865 if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T1T)
866 LOG(DEBUG) << StringPrintf("%s: T1T; tech A", fn);
867 else if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T2T)
868 LOG(DEBUG) << StringPrintf("%s: T2T; tech A", fn);
869 actBytes.reset(e->NewByteArray(1));
870 e->SetByteArrayRegion(actBytes.get(), 0, 1,
871 (jbyte*)&mTechParams[i].param.pa.sel_rsp);
872 } else if (NFC_PROTOCOL_T3T == mTechLibNfcTypes[i]) {
873 // felica
874 LOG(DEBUG) << StringPrintf("%s: T3T; felica; tech F", fn);
875 // really, there is no data
876 actBytes.reset(e->NewByteArray(0));
877 } else if (NFC_PROTOCOL_MIFARE == mTechLibNfcTypes[i]) {
878 LOG(DEBUG) << StringPrintf("%s: Mifare Classic; tech A", fn);
879 actBytes.reset(e->NewByteArray(1));
880 e->SetByteArrayRegion(actBytes.get(), 0, 1,
881 (jbyte*)&mTechParams[i].param.pa.sel_rsp);
882 } else if (NFC_PROTOCOL_ISO_DEP == mTechLibNfcTypes[i]) {
883 // t4t
884 if (mTechList[i] ==
885 TARGET_TYPE_ISO14443_4) // is TagTechnology.ISO_DEP by Java API
886 {
887 if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
888 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A)) {
889 // see NFC Forum Digital Protocol specification, section 11.6.2, "RATS
890 // Response"; search for "historical bytes"; copy historical bytes
891 // into Java object; the public API, IsoDep.getHistoricalBytes(),
892 // returns this data;
893 if (activationData.activate_ntf.intf_param.type ==
894 NFC_INTERFACE_ISO_DEP) {
895 tNFC_INTF_PA_ISO_DEP& pa_iso =
896 activationData.activate_ntf.intf_param.intf_param.pa_iso;
897 LOG(DEBUG) << StringPrintf(
898 "%s: T4T; ISO_DEP for tech A; copy historical bytes; len=%u",
899 fn, pa_iso.his_byte_len);
900 actBytes.reset(e->NewByteArray(pa_iso.his_byte_len));
901 if (pa_iso.his_byte_len > 0)
902 e->SetByteArrayRegion(actBytes.get(), 0, pa_iso.his_byte_len,
903 (jbyte*)(pa_iso.his_byte));
904 } else {
905 LOG(ERROR) << StringPrintf(
906 "%s: T4T; ISO_DEP for tech A; wrong interface=%u", fn,
907 activationData.activate_ntf.intf_param.type);
908 actBytes.reset(e->NewByteArray(0));
909 }
910 } else if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) ||
911 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
912 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
913 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME)) {
914 // see NFC Forum Digital Protocol specification, section 12.6.2,
915 // "ATTRIB Response"; copy higher-layer response bytes into Java
916 // object; the public API, IsoDep.getHiLayerResponse(), returns this
917 // data;
918 if (activationData.activate_ntf.intf_param.type ==
919 NFC_INTERFACE_ISO_DEP) {
920 tNFC_INTF_PB_ISO_DEP& pb_iso =
921 activationData.activate_ntf.intf_param.intf_param.pb_iso;
922 LOG(DEBUG) << StringPrintf(
923 "%s: T4T; ISO_DEP for tech B; copy response bytes; len=%u", fn,
924 pb_iso.hi_info_len);
925 actBytes.reset(e->NewByteArray(pb_iso.hi_info_len));
926 if (pb_iso.hi_info_len > 0)
927 e->SetByteArrayRegion(actBytes.get(), 0, pb_iso.hi_info_len,
928 (jbyte*)(pb_iso.hi_info));
929 } else {
930 LOG(ERROR) << StringPrintf(
931 "%s: T4T; ISO_DEP for tech B; wrong interface=%u", fn,
932 activationData.activate_ntf.intf_param.type);
933 actBytes.reset(e->NewByteArray(0));
934 }
935 }
936 } else if (mTechList[i] ==
937 TARGET_TYPE_ISO14443_3A) // is TagTechnology.NFC_A by Java API
938 {
939 LOG(DEBUG) << StringPrintf("%s: T4T; tech A", fn);
940 actBytes.reset(e->NewByteArray(1));
941 e->SetByteArrayRegion(actBytes.get(), 0, 1,
942 (jbyte*)&mTechParams[i].param.pa.sel_rsp);
943 } else {
944 actBytes.reset(e->NewByteArray(0));
945 }
946 } // case NFC_PROTOCOL_ISO_DEP: //t4t
947 else if (NFC_PROTOCOL_T5T == mTechLibNfcTypes[i]) {
948 LOG(DEBUG) << StringPrintf("%s: tech iso 15693", fn);
949 // iso 15693 response flags: 1 octet
950 // iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
951 // used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
952 uint8_t data[2] = {activationData.params.i93.afi,
953 activationData.params.i93.dsfid};
954 actBytes.reset(e->NewByteArray(2));
955 e->SetByteArrayRegion(actBytes.get(), 0, 2, (jbyte*)data);
956 } else {
957 if ((NCI_PROTOCOL_UNKNOWN == mTechLibNfcTypes[i]) &&
958 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B)) {
959 LOG(DEBUG) << StringPrintf("%s; Chinese Id Card - MBI = %02X", fn,
960 activationData.params.ci.mbi);
961 actBytes.reset(e->NewByteArray(1));
962 e->SetByteArrayRegion(actBytes.get(), 0, 1,
963 (jbyte*)&activationData.params.ci.mbi);
964 } else {
965 LOG(DEBUG) << StringPrintf("%s: tech unknown ????", fn);
966 actBytes.reset(e->NewByteArray(0));
967 }
968 }
969 e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
970 } // for: every technology in the array of current selected tag
971 if (gtechActBytes != NULL && mTechListTail != 0) {
972 e->DeleteGlobalRef(gtechActBytes);
973 gtechActBytes =
974 reinterpret_cast<jobjectArray>(e->NewGlobalRef(techActBytes.get()));
975 }
976 jfieldID f = e->GetFieldID(tag_cls, "mTechActBytes", "[[B");
977 e->SetObjectField(tag, f, techActBytes.get());
978 }
979
980 /*******************************************************************************
981 **
982 ** Function: fillNativeNfcTagMembers5
983 **
984 ** Description: Fill NativeNfcTag's members: mUid.
985 ** The original Google's implementation is in
986 *nfc_jni_Discovery_notification_callback()
987 ** in com_android_nfc_NativeNfcManager.cpp;
988 ** e: JVM environment.
989 ** tag_cls: Java NativeNfcTag class.
990 ** tag: Java NativeNfcTag object.
991 ** activationData: data from activation.
992 **
993 ** Returns: None
994 **
995 *******************************************************************************/
fillNativeNfcTagMembers5(JNIEnv * e,jclass tag_cls,jobject tag,tNFA_ACTIVATED & activationData)996 void NfcTag::fillNativeNfcTagMembers5(JNIEnv* e, jclass tag_cls, jobject tag,
997 tNFA_ACTIVATED& activationData) {
998 static const char fn[] = "NfcTag::fillNativeNfcTagMembers5";
999 int len = 0;
1000 ScopedLocalRef<jbyteArray> uid(e, NULL);
1001
1002 if (NFC_DISCOVERY_TYPE_POLL_KOVIO == mTechParams[0].mode) {
1003 LOG(DEBUG) << StringPrintf("%s: Kovio", fn);
1004 len = mTechParams[0].param.pk.uid_len;
1005 uid.reset(e->NewByteArray(len));
1006 e->SetByteArrayRegion(uid.get(), 0, len,
1007 (jbyte*)&mTechParams[0].param.pk.uid);
1008 } else if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams[0].mode ||
1009 NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams[0].mode) {
1010 LOG(DEBUG) << StringPrintf("%s: tech A", fn);
1011 len = mTechParams[0].param.pa.nfcid1_len;
1012 uid.reset(e->NewByteArray(len));
1013 e->SetByteArrayRegion(uid.get(), 0, len,
1014 (jbyte*)&mTechParams[0].param.pa.nfcid1);
1015 // a tag's NFCID1 can change dynamically at each activation;
1016 // only the first byte (0x08) is constant; a dynamic NFCID1's length
1017 // must be 4 bytes (see NFC Digitial Protocol,
1018 // section 4.7.2 SDD_RES Response, Requirements 20).
1019 mIsDynamicTagId = (mTechParams[0].param.pa.nfcid1_len == 4) &&
1020 (mTechParams[0].param.pa.nfcid1[0] == 0x08);
1021 } else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams[0].mode ||
1022 NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams[0].mode ||
1023 NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams[0].mode ||
1024 NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams[0].mode) {
1025 LOG(DEBUG) << StringPrintf("%s: tech B", fn);
1026 uid.reset(e->NewByteArray(NFC_NFCID0_MAX_LEN));
1027 e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID0_MAX_LEN,
1028 (jbyte*)&mTechParams[0].param.pb.nfcid0);
1029 } else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams[0].mode ||
1030 NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams[0].mode) {
1031 uid.reset(e->NewByteArray(NFC_NFCID2_LEN));
1032 e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID2_LEN,
1033 (jbyte*)&mTechParams[0].param.pf.nfcid2);
1034 LOG(DEBUG) << StringPrintf("%s: tech F", fn);
1035 } else if (NFC_DISCOVERY_TYPE_POLL_V == mTechParams[0].mode ||
1036 NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams[0].mode) {
1037 LOG(DEBUG) << StringPrintf("%s: tech iso 15693", fn);
1038 jbyte data[I93_UID_BYTE_LEN]; // 8 bytes
1039 for (int i = 0; i < I93_UID_BYTE_LEN; ++i) // reverse the ID
1040 data[i] = activationData.params.i93.uid[I93_UID_BYTE_LEN - i - 1];
1041 uid.reset(e->NewByteArray(I93_UID_BYTE_LEN));
1042 e->SetByteArrayRegion(uid.get(), 0, I93_UID_BYTE_LEN, data);
1043 } else {
1044 LOG(ERROR) << StringPrintf("%s: tech unknown ????", fn);
1045 uid.reset(e->NewByteArray(0));
1046 }
1047 jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B");
1048 e->SetObjectField(tag, f, uid.get());
1049 mTechListTail = mNumTechList;
1050 if (mNumDiscNtf == 0) mTechListTail = 0;
1051 LOG(DEBUG) << StringPrintf("%s;mTechListTail=%x", fn, mTechListTail);
1052 }
1053
1054 /*******************************************************************************
1055 **
1056 ** Function: resetTechnologies
1057 **
1058 ** Description: Clear all data related to the technology, protocol of the
1059 *tag.
1060 **
1061 ** Returns: None
1062 **
1063 *******************************************************************************/
resetTechnologies()1064 void NfcTag::resetTechnologies() {
1065 static const char fn[] = "NfcTag::resetTechnologies";
1066 LOG(DEBUG) << StringPrintf("%s", fn);
1067 mNumTechList = 0;
1068 mNumDiscNtf = 0;
1069 mNumDiscTechList = 0;
1070 mTechListTail = 0;
1071 mIsMultiProtocolTag = false;
1072 memset(mTechList, 0, sizeof(mTechList));
1073 memset(mTechHandles, 0, sizeof(mTechHandles));
1074 memset(mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
1075 memset(mTechParams, 0, sizeof(mTechParams));
1076 mIsDynamicTagId = false;
1077 mIsFelicaLite = false;
1078 resetAllTransceiveTimeouts();
1079 }
1080
1081 /*******************************************************************************
1082 **
1083 ** Function: selectFirstTag
1084 **
1085 ** Description: When multiple tags are discovered, just select the first one
1086 *to activate.
1087 **
1088 ** Returns: None
1089 **
1090 *******************************************************************************/
selectFirstTag()1091 void NfcTag::selectFirstTag() {
1092 static const char fn[] = "NfcTag::selectFirstTag";
1093 int foundIdx = -1;
1094 tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
1095
1096 for (int i = 0; i < mNumDiscTechList; i++) {
1097 LOG(DEBUG) << StringPrintf("%s: nfa target idx=%d h=0x%X; protocol=0x%X",
1098 fn, i, mTechHandlesDiscData[i],
1099 mTechLibNfcTypesDiscData[i]);
1100 if (mTechLibNfcTypesDiscData[i] != NFA_PROTOCOL_NFC_DEP) {
1101 sLastSelectedTagId = i;
1102 foundIdx = i;
1103 break;
1104 }
1105 }
1106
1107 if (foundIdx != -1) {
1108 if (mTechLibNfcTypesDiscData[foundIdx] == NFA_PROTOCOL_ISO_DEP) {
1109 rf_intf = NFA_INTERFACE_ISO_DEP;
1110 } else if (mTechLibNfcTypesDiscData[foundIdx] == NFC_PROTOCOL_MIFARE) {
1111 rf_intf = NFA_INTERFACE_MIFARE;
1112 } else
1113 rf_intf = NFA_INTERFACE_FRAME;
1114
1115 tNFA_STATUS stat = NFA_Select(mTechHandlesDiscData[foundIdx],
1116 mTechLibNfcTypesDiscData[foundIdx], rf_intf);
1117 if (stat != NFA_STATUS_OK)
1118 LOG(ERROR) << StringPrintf("%s: fail select; error=0x%X", fn, stat);
1119 } else
1120 LOG(ERROR) << StringPrintf("%s: only found NFC-DEP technology.", fn);
1121 }
1122
1123 /*******************************************************************************
1124 **
1125 ** Function: selectNextTagIfExists
1126 **
1127 ** Description: When multiple tags are discovered, selects the next tag to
1128 ** activate.
1129 **
1130 ** Returns: None
1131 **
1132 *******************************************************************************/
selectNextTagIfExists()1133 void NfcTag::selectNextTagIfExists() {
1134 static const char fn[] = "NfcTag::selectNextTagIfExists";
1135 int foundIdx = -1;
1136 tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
1137 tNFA_STATUS stat = NFA_STATUS_FAILED;
1138
1139 if (mNumDiscNtf == 0) {
1140 return;
1141 }
1142 mNumDiscNtf--;
1143 LOG(DEBUG) << StringPrintf("%s: enter, mNumDiscTechList=%x", fn,
1144 mNumDiscTechList);
1145 for (int i = 0; i < mNumDiscTechList; i++) {
1146 LOG(DEBUG) << StringPrintf("%s: nfa target idx=%d h=0x%X; protocol=0x%X",
1147 fn, i, mTechHandlesDiscData[i],
1148 mTechLibNfcTypesDiscData[i]);
1149 if (((mTechHandlesDiscData[sLastSelectedTagId] !=
1150 mTechHandlesDiscData[i]) ||
1151 (mTechLibNfcTypesDiscData[sLastSelectedTagId] !=
1152 mTechLibNfcTypesDiscData[i])) &&
1153 (mTechLibNfcTypesDiscData[i] != NFA_PROTOCOL_NFC_DEP)) {
1154 sLastSelectedTagId = i;
1155 foundIdx = i;
1156 break;
1157 }
1158 }
1159
1160 if (foundIdx != -1) {
1161 if (mTechLibNfcTypesDiscData[foundIdx] == NFA_PROTOCOL_ISO_DEP) {
1162 rf_intf = NFA_INTERFACE_ISO_DEP;
1163 } else if (mTechLibNfcTypesDiscData[foundIdx] == NFC_PROTOCOL_MIFARE) {
1164 rf_intf = NFA_INTERFACE_MIFARE;
1165 } else {
1166 rf_intf = NFA_INTERFACE_FRAME;
1167 }
1168
1169 stat = NFA_Select(mTechHandlesDiscData[foundIdx],
1170 mTechLibNfcTypesDiscData[foundIdx], rf_intf);
1171 if (stat == NFA_STATUS_OK) {
1172 LOG(ERROR) << StringPrintf("%s: Select Success, wait for activated ntf",
1173 fn);
1174 } else {
1175 LOG(ERROR) << StringPrintf("%s: fail select; error=0x%X", fn, stat);
1176 }
1177 } else {
1178 LOG(ERROR) << StringPrintf("%s: only found NFC-DEP technology.", fn);
1179 }
1180 }
1181
1182 /*******************************************************************************
1183 **
1184 ** Function: getT1tMaxMessageSize
1185 **
1186 ** Description: Get the maximum size (octet) that a T1T can store.
1187 **
1188 ** Returns: Maximum size in octets.
1189 **
1190 *******************************************************************************/
getT1tMaxMessageSize()1191 int NfcTag::getT1tMaxMessageSize() {
1192 static const char fn[] = "NfcTag::getT1tMaxMessageSize";
1193
1194 if (mProtocol != NFC_PROTOCOL_T1T) {
1195 LOG(ERROR) << StringPrintf("%s: wrong protocol %u", fn, mProtocol);
1196 return 0;
1197 }
1198 return mtT1tMaxMessageSize;
1199 }
1200
1201 /*******************************************************************************
1202 **
1203 ** Function: calculateT1tMaxMessageSize
1204 **
1205 ** Description: Calculate type-1 tag's max message size based on header ROM
1206 *bytes.
1207 ** activate: reference to activation data.
1208 **
1209 ** Returns: None
1210 **
1211 *******************************************************************************/
calculateT1tMaxMessageSize(tNFA_ACTIVATED & activate)1212 void NfcTag::calculateT1tMaxMessageSize(tNFA_ACTIVATED& activate) {
1213 static const char fn[] = "NfcTag::calculateT1tMaxMessageSize";
1214
1215 // make sure the tag is type-1
1216 if (activate.activate_ntf.protocol != NFC_PROTOCOL_T1T) {
1217 mtT1tMaxMessageSize = 0;
1218 return;
1219 }
1220
1221 // examine the first byte of header ROM bytes
1222 switch (activate.params.t1t.hr[0]) {
1223 case RW_T1T_IS_TOPAZ96:
1224 mtT1tMaxMessageSize = 90;
1225 break;
1226 case RW_T1T_IS_TOPAZ512:
1227 mtT1tMaxMessageSize = 462;
1228 break;
1229 default:
1230 LOG(ERROR) << StringPrintf("%s: unknown T1T HR0=%u", fn,
1231 activate.params.t1t.hr[0]);
1232 mtT1tMaxMessageSize = 0;
1233 break;
1234 }
1235 }
1236
1237 /*******************************************************************************
1238 **
1239 ** Function: isNfcForumT2T
1240 **
1241 ** Description: Whether tag is Nfc-Forum based and uses read command for
1242 ** presence check.
1243 **
1244 ** Returns: True if tag is isNfcForumT2T.
1245 **
1246 *******************************************************************************/
isNfcForumT2T()1247 bool NfcTag::isNfcForumT2T() {
1248 static const char fn[] = "NfcTag::isNfcForumT2T";
1249 bool retval = false;
1250
1251 for (int i = 0; i < mNumTechList; i++) {
1252 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
1253 if (mTechParams[i].param.pa.sel_rsp == 0) retval = true;
1254
1255 break;
1256 }
1257 }
1258 LOG(DEBUG) << StringPrintf("%s: return=%u", fn, retval);
1259 return retval;
1260 }
1261
1262 /*******************************************************************************
1263 **
1264 ** Function: isMifareUltralight
1265 **
1266 ** Description: Whether the currently activated tag is Mifare Ultralight.
1267 **
1268 ** Returns: True if tag is Mifare Ultralight.
1269 **
1270 *******************************************************************************/
isMifareUltralight()1271 bool NfcTag::isMifareUltralight() {
1272 static const char fn[] = "NfcTag::isMifareUltralight";
1273 bool retval = false;
1274
1275 for (int i = 0; i < mNumTechList; i++) {
1276 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
1277 // see NFC Digital Protocol, section 4.6.3 (SENS_RES); section 4.8.2
1278 // (SEL_RES). see "MF0ICU1 Functional specification MIFARE Ultralight",
1279 // Rev. 3.4 - 4 February 2008, section 6.7.
1280 if ((mTechParams[i].param.pa.sens_res[0] == 0x44) &&
1281 (mTechParams[i].param.pa.sens_res[1] == 0) &&
1282 ((mTechParams[i].param.pa.sel_rsp == 0) ||
1283 (mTechParams[i].param.pa.sel_rsp == 0x04)) &&
1284 (mTechParams[i].param.pa.nfcid1[0] == 0x04)) {
1285 retval = true;
1286 }
1287 break;
1288 }
1289 }
1290 LOG(DEBUG) << StringPrintf("%s: return=%u", fn, retval);
1291 return retval;
1292 }
1293
1294 /*******************************************************************************
1295 **
1296 ** Function: isMifareDESFire
1297 **
1298 ** Description: Whether the currently activated tag is Mifare DESFire.
1299 **
1300 ** Returns: True if tag is Mifare DESFire.
1301 **
1302 *******************************************************************************/
isMifareDESFire()1303 bool NfcTag::isMifareDESFire() {
1304 static const char fn[] = "NfcTag::isMifareDESFire";
1305 bool retval = false;
1306
1307 for (int i = 0; i < mNumTechList; i++) {
1308 if ((mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
1309 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A)) {
1310 /* DESfire has one sak byte and 2 ATQA bytes */
1311 if ((mTechParams[i].param.pa.sens_res[0] == 0x44) &&
1312 (mTechParams[i].param.pa.sens_res[1] == 0x03) &&
1313 (mTechParams[i].param.pa.sel_rsp == 0x20)) {
1314 retval = true;
1315 }
1316 break;
1317 }
1318 }
1319
1320 LOG(DEBUG) << StringPrintf("%s: return=%u", fn, retval);
1321 return retval;
1322 }
1323
1324 /*******************************************************************************
1325 **
1326 ** Function: isFelicaLite
1327 **
1328 ** Description: Whether the currently activated tag is Felica Lite.
1329 **
1330 ** Returns: True if tag is Felica Lite.
1331 **
1332 *******************************************************************************/
1333
isFelicaLite()1334 bool NfcTag::isFelicaLite() { return mIsFelicaLite; }
1335
1336 /*******************************************************************************
1337 **
1338 ** Function: isT2tNackResponse
1339 **
1340 ** Description: Whether the response is a T2T NACK response.
1341 ** See NFC Digital Protocol Technical Specification
1342 *(2010-11-17).
1343 ** Chapter 9 (Type 2 Tag Platform), section 9.6 (READ).
1344 ** response: buffer contains T2T response.
1345 ** responseLen: length of the response.
1346 **
1347 ** Returns: True if the response is NACK
1348 **
1349 *******************************************************************************/
isT2tNackResponse(const uint8_t * response,uint32_t responseLen)1350 bool NfcTag::isT2tNackResponse(const uint8_t* response, uint32_t responseLen) {
1351 static const char fn[] = "NfcTag::isT2tNackResponse";
1352 bool isNack = false;
1353
1354 if (responseLen == 1) {
1355 if (response[0] == 0xA)
1356 isNack = false; // an ACK response, so definitely not a NACK
1357 else
1358 isNack = true; // assume every value is a NACK
1359 }
1360 LOG(DEBUG) << StringPrintf("%s: return %u", fn, isNack);
1361 return isNack;
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() { return mNdefDetectionTimedOut; }
1374
1375 /*******************************************************************************
1376 **
1377 ** Function: notifyTagDiscovered
1378 **
1379 ** Description: Notify NFC service about tag discovery.
1380 ** discovered: true if tag is discovered, false if tag is lost.
1381 **
1382 ** Returns: None
1383 **
1384 *******************************************************************************/
notifyTagDiscovered(bool discovered)1385 void NfcTag::notifyTagDiscovered(bool discovered) {
1386 JNIEnv* e = NULL;
1387 ScopedAttach attach(mNativeData->vm, &e);
1388 if (e == NULL) {
1389 LOG(ERROR) << "jni env is null";
1390 return;
1391 }
1392 LOG(DEBUG) << StringPrintf("%s: %d", __func__, discovered);
1393 e->CallVoidMethod(mNativeData->manager,
1394 android::gCachedNfcManagerNotifyTagDiscovered,
1395 discovered);
1396 if (e->ExceptionCheck()) {
1397 e->ExceptionClear();
1398 LOG(ERROR) << StringPrintf("fail notify");
1399 }
1400 }
1401
1402 /*******************************************************************************
1403 **
1404 ** Function: connectionEventHandler
1405 **
1406 ** Description: Handle connection-related events.
1407 ** event: event code.
1408 ** data: pointer to event data.
1409 **
1410 ** Returns: None
1411 **
1412 *******************************************************************************/
connectionEventHandler(uint8_t event,tNFA_CONN_EVT_DATA * data)1413 void NfcTag::connectionEventHandler(uint8_t event, tNFA_CONN_EVT_DATA* data) {
1414 static const char fn[] = "NfcTag::connectionEventHandler";
1415
1416 switch (event) {
1417 case NFA_DISC_RESULT_EVT: {
1418 tNFA_DISC_RESULT& disc_result = data->disc_result;
1419 if ((disc_result.status == NFA_STATUS_OK) && !mIsReselecting) {
1420 notifyTagDiscovered(true);
1421 discoverTechnologies(disc_result);
1422 }
1423 } break;
1424
1425 case NFA_ACTIVATED_EVT:
1426 // Only do tag detection if we are polling and it is not 'EE Direct RF'
1427 // activation (which may happen when we are activated as a tag).
1428 if (data->activated.activate_ntf.rf_tech_param.mode <
1429 NCI_DISCOVERY_TYPE_LISTEN_A &&
1430 data->activated.activate_ntf.intf_param.type !=
1431 NFC_INTERFACE_EE_DIRECT_RF) {
1432 notifyTagDiscovered(true);
1433 tNFA_ACTIVATED& activated = data->activated;
1434 if (IsSameKovio(activated)) break;
1435 mIsActivated = true;
1436 mProtocol = activated.activate_ntf.protocol;
1437 calculateT1tMaxMessageSize(activated);
1438 if (!mIsReselecting) {
1439 discoverTechnologies(activated);
1440 }
1441 createNativeNfcTag(activated);
1442 }
1443 break;
1444
1445 case NFA_DEACTIVATED_EVT:
1446 mIsActivated = false;
1447 mProtocol = NFC_PROTOCOL_UNKNOWN;
1448 if (!mIsReselecting) {
1449 resetTechnologies();
1450 }
1451 notifyTagDiscovered(false);
1452 break;
1453
1454 case NFA_READ_CPLT_EVT: {
1455 SyncEventGuard g(mReadCompleteEvent);
1456 mReadCompletedStatus = data->status;
1457 mNdefDetectionTimedOut = data->status != NFA_STATUS_OK;
1458 if (mNdefDetectionTimedOut)
1459 LOG(ERROR) << StringPrintf("%s: NDEF detection timed out", fn);
1460 mReadCompleteEvent.notifyOne();
1461 } break;
1462
1463 case NFA_NDEF_DETECT_EVT: {
1464 tNFA_NDEF_DETECT& ndef_detect = data->ndef_detect;
1465 mNdefDetectionTimedOut = ndef_detect.status == NFA_STATUS_TIMEOUT;
1466 if (mNdefDetectionTimedOut)
1467 LOG(ERROR) << StringPrintf("%s: NDEF detection timed out", fn);
1468 }
1469 }
1470 }
1471
1472 /*******************************************************************************
1473 **
1474 ** Function setActive
1475 **
1476 ** Description Sets the active state for the object
1477 **
1478 ** Returns None.
1479 **
1480 *******************************************************************************/
setActive(bool active)1481 void NfcTag::setActive(bool active) { mIsActivated = active; }
1482
1483 /*******************************************************************************
1484 **
1485 ** Function: isDynamicTagId
1486 **
1487 ** Description: Whether a tag has a dynamic tag ID.
1488 **
1489 ** Returns: True if ID is dynamic.
1490 **
1491 *******************************************************************************/
isDynamicTagId()1492 bool NfcTag::isDynamicTagId() {
1493 return mIsDynamicTagId &&
1494 (mTechList[0] == TARGET_TYPE_ISO14443_4) && // type-4 tag
1495 (mTechList[1] == TARGET_TYPE_ISO14443_3A); // tech A
1496 }
1497
1498 /*******************************************************************************
1499 **
1500 ** Function: resetAllTransceiveTimeouts
1501 **
1502 ** Description: Reset all timeouts for all technologies to default values.
1503 **
1504 ** Returns: none
1505 **
1506 *******************************************************************************/
resetAllTransceiveTimeouts()1507 void NfcTag::resetAllTransceiveTimeouts() {
1508 mTechnologyTimeoutsTable[TARGET_TYPE_ISO14443_3A] = 618; // NfcA
1509 mTechnologyTimeoutsTable[TARGET_TYPE_ISO14443_3B] = 1000; // NfcB
1510 mTechnologyTimeoutsTable[TARGET_TYPE_ISO14443_4] = 618; // ISO-DEP
1511 mTechnologyTimeoutsTable[TARGET_TYPE_FELICA] = 255; // Felica
1512 mTechnologyTimeoutsTable[TARGET_TYPE_V] = 1000; // NfcV
1513 mTechnologyTimeoutsTable[TARGET_TYPE_NDEF] = 1000;
1514 mTechnologyTimeoutsTable[TARGET_TYPE_NDEF_FORMATABLE] = 1000;
1515 mTechnologyTimeoutsTable[TARGET_TYPE_MIFARE_CLASSIC] = 618; // MifareClassic
1516 mTechnologyTimeoutsTable[TARGET_TYPE_MIFARE_UL] = 618; // MifareUltralight
1517 mTechnologyTimeoutsTable[TARGET_TYPE_KOVIO_BARCODE] = 1000; // NfcBarcode
1518 }
1519
1520 /*******************************************************************************
1521 **
1522 ** Function: getTransceiveTimeout
1523 **
1524 ** Description: Get the timeout value for one technology.
1525 ** techId: one of the values in TARGET_TYPE_* defined in
1526 *NfcJniUtil.h
1527 **
1528 ** Returns: Timeout value in millisecond.
1529 **
1530 *******************************************************************************/
getTransceiveTimeout(int techId)1531 int NfcTag::getTransceiveTimeout(int techId) {
1532 static const char fn[] = "NfcTag::getTransceiveTimeout";
1533 int retval = 1000;
1534 if ((techId > 0) && (techId < (int)mTechnologyTimeoutsTable.size()))
1535 retval = mTechnologyTimeoutsTable[techId];
1536 else
1537 LOG(ERROR) << StringPrintf("%s: invalid tech=%d", fn, techId);
1538 return retval;
1539 }
1540
1541 /*******************************************************************************
1542 **
1543 ** Function: setTransceiveTimeout
1544 **
1545 ** Description: Set the timeout value for one technology.
1546 ** techId: one of the values in TARGET_TYPE_* defined in
1547 *NfcJniUtil.h
1548 ** timeout: timeout value in millisecond.
1549 **
1550 ** Returns: Timeout value.
1551 **
1552 *******************************************************************************/
setTransceiveTimeout(int techId,int timeout)1553 void NfcTag::setTransceiveTimeout(int techId, int timeout) {
1554 static const char fn[] = "NfcTag::setTransceiveTimeout";
1555 if ((techId >= 0) && (techId < (int)mTechnologyTimeoutsTable.size()))
1556 mTechnologyTimeoutsTable[techId] = timeout;
1557 else
1558 LOG(ERROR) << StringPrintf("%s: invalid tech=%d", fn, techId);
1559 }
1560
1561 /*******************************************************************************
1562 **
1563 ** Function: getPresenceCheckAlgorithm
1564 **
1565 ** Description: Get presence-check algorithm from .conf file.
1566 **
1567 ** Returns: Presence-check algorithm.
1568 **
1569 *******************************************************************************/
getPresenceCheckAlgorithm()1570 tNFA_RW_PRES_CHK_OPTION NfcTag::getPresenceCheckAlgorithm() {
1571 return mPresenceCheckAlgorithm;
1572 }
1573
1574 /*******************************************************************************
1575 **
1576 ** Function: isInfineonMyDMove
1577 **
1578 ** Description: Whether the currently activated tag is Infineon My-D Move.
1579 **
1580 ** Returns: True if tag is Infineon My-D Move.
1581 **
1582 *******************************************************************************/
isInfineonMyDMove()1583 bool NfcTag::isInfineonMyDMove() {
1584 static const char fn[] = "NfcTag::isInfineonMyDMove";
1585 bool retval = false;
1586
1587 for (int i = 0; i < mNumTechList; i++) {
1588 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
1589 // see Infineon my-d move, my-d move NFC, SLE 66R01P, SLE 66R01PN,
1590 // Short Product Information, 2011-11-24, section 3.5
1591 if (mTechParams[i].param.pa.nfcid1[0] == 0x05) {
1592 uint8_t highNibble = mTechParams[i].param.pa.nfcid1[1] & 0xF0;
1593 if (highNibble == 0x30) retval = true;
1594 }
1595 break;
1596 }
1597 }
1598 LOG(DEBUG) << StringPrintf("%s: return=%u", fn, retval);
1599 return retval;
1600 }
1601
1602 /*******************************************************************************
1603 **
1604 ** Function: isKovioType2Tag
1605 **
1606 ** Description: Whether the currently activated tag is Kovio Type-2 tag.
1607 **
1608 ** Returns: True if tag is Kovio Type-2 tag.
1609 **
1610 *******************************************************************************/
isKovioType2Tag()1611 bool NfcTag::isKovioType2Tag() {
1612 static const char fn[] = "NfcTag::isKovioType2Tag";
1613 bool retval = false;
1614
1615 for (int i = 0; i < mNumTechList; i++) {
1616 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) {
1617 // Kovio 2Kb RFID Tag, Functional Specification,
1618 // March 2, 2012, v2.0, section 8.3.
1619 if (mTechParams[i].param.pa.nfcid1[0] == 0x37) retval = true;
1620 break;
1621 }
1622 }
1623 LOG(DEBUG) << StringPrintf("%s: return=%u", fn, retval);
1624 return retval;
1625 }
1626
1627 /*******************************************************************************
1628 **
1629 ** Function: setMultiProtocolTagSupport
1630 **
1631 ** Description: Update mIsMultiProtocolTag
1632 **
1633 ** Returns: None
1634 **
1635 *******************************************************************************/
1636
setMultiProtocolTagSupport(bool isMultiProtocolSupported)1637 void NfcTag::setMultiProtocolTagSupport(bool isMultiProtocolSupported) {
1638 mIsMultiProtocolTag = isMultiProtocolSupported;
1639 }
1640
1641 /*******************************************************************************
1642 **
1643 ** Function: setNumDiscNtf
1644 **
1645 ** Description: Update number of Discovery NTF received
1646 **
1647 ** Returns: None
1648 **
1649 *******************************************************************************/
setNumDiscNtf(int numDiscNtfValue)1650 void NfcTag::setNumDiscNtf(int numDiscNtfValue) {
1651 if (numDiscNtfValue < MAX_NUM_TECHNOLOGY) {
1652 mNumDiscNtf = numDiscNtfValue;
1653 }
1654 }
1655
1656 /*******************************************************************************
1657 **
1658 ** Function: getNumDiscNtf
1659 **
1660 ** Description: number of discovery notifications received from NFCC after
1661 ** last RF DISCOVERY state
1662 **
1663 ** Returns: number of discovery notifications received from NFCC
1664 **
1665 *******************************************************************************/
getNumDiscNtf()1666 int NfcTag::getNumDiscNtf() { return mNumDiscNtf; }
1667
1668 /*******************************************************************************
1669 **
1670 ** Function: isReselecting
1671 **
1672 ** Description: used to check if a reSelect() procedure is ongoing
1673 **
1674 ** Returns: value of mIsReselecting variable
1675 **
1676 *******************************************************************************/
isReselecting()1677 bool NfcTag::isReselecting() { return mIsReselecting; }
1678
1679 /*******************************************************************************
1680 **
1681 ** Function: setReselect
1682 **
1683 ** Description: Called by JNI to indicate status of reSelect() procedure
1684 **
1685 ** Returns:
1686 **
1687 *******************************************************************************/
setReselect(bool isReselecting)1688 void NfcTag::setReselect(bool isReselecting) { mIsReselecting = isReselecting; }
1689