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