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