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