blob: 4e5b192fa2f726b53c583be09f2b3f342bff71ea [file] [log] [blame]
nxpandroid64fd68c2015-09-23 16:45:15 +05301/*
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 * The original Work has been changed by NXP Semiconductors.
19 *
20 * Copyright (C) 2015 NXP Semiconductors
21 *
22 * Licensed under the Apache License, Version 2.0 (the "License");
23 * you may not use this file except in compliance with the License.
24 * You may obtain a copy of the License at
25 *
26 * http://www.apache.org/licenses/LICENSE-2.0
27 *
28 * Unless required by applicable law or agreed to in writing, software
29 * distributed under the License is distributed on an "AS IS" BASIS,
30 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 * See the License for the specific language governing permissions and
32 * limitations under the License.
33 *
34 ******************************************************************************/
35/*
36 * Tag-reading, tag-writing operations.
37 */
38#include "OverrideLog.h"
39#include "NfcTag.h"
40#include "JavaClassConstants.h"
41#include "config.h"
42#include <ScopedLocalRef.h>
43#include <ScopedPrimitiveArray.h>
nxpandroida9a68ba2016-01-14 21:12:17 +053044#include "IntervalTimer.h"
nxpandroid64fd68c2015-09-23 16:45:15 +053045extern "C"
46{
47 #include "rw_int.h"
nxpandroid34627bd2016-05-27 15:52:30 +053048 #include "nfc_brcm_defs.h"
nxpandroid64fd68c2015-09-23 16:45:15 +053049 #include "phNxpExtns.h"
50}
nxpandroida9a68ba2016-01-14 21:12:17 +053051#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +053052static void deleteglobaldata(JNIEnv* e);
nxpandroida9a68ba2016-01-14 21:12:17 +053053static void selectCompleteCallBack(union sigval);
nxpandroid64fd68c2015-09-23 16:45:15 +053054static jobjectArray techActBytes1;
55int selectedId = 0;
56static jobjectArray techPollBytes2;
nxpandroida9a68ba2016-01-14 21:12:17 +053057IntervalTimer gSelectCompleteTimer;
58#endif
nxpandroid64fd68c2015-09-23 16:45:15 +053059/*******************************************************************************
60**
61** Function: NfcTag
62**
63** Description: Initialize member variables.
64**
65** Returns: None
66**
67*******************************************************************************/
68NfcTag::NfcTag ()
69: mNumTechList (0),
70 mNumDiscNtf (0),
71 mNumDiscTechList (0),
72 mTechListIndex (0),
nxpandroid34627bd2016-05-27 15:52:30 +053073 mCashbeeDetected(false),
74 mEzLinkTypeTag(false),
75#if(NXP_EXTNS == TRUE)
76 mWaitingForSelect(false),
77#endif
nxpandroid64fd68c2015-09-23 16:45:15 +053078 mTechnologyTimeoutsTable (MAX_NUM_TECHNOLOGY),
79 mNativeData (NULL),
80 mIsActivated (false),
81 mActivationState (Idle),
82 mProtocol(NFC_PROTOCOL_UNKNOWN),
83 mtT1tMaxMessageSize (0),
84 mReadCompletedStatus (NFA_STATUS_OK),
85 mLastKovioUidLen (0),
86 mNdefDetectionTimedOut (false),
87 mIsDynamicTagId (false),
nxpandroid7d44e572016-08-01 19:11:04 +053088 mIsFelicaLite(false),
89 mPresenceCheckAlgorithm (NFA_RW_PRES_CHK_DEFAULT)
nxpandroid64fd68c2015-09-23 16:45:15 +053090{
91 memset (mTechList, 0, sizeof(mTechList));
92 memset (mTechHandles, 0, sizeof(mTechHandles));
93 memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
94 memset (mTechParams, 0, sizeof(mTechParams));
95 memset(mLastKovioUid, 0, NFC_KOVIO_MAX_LEN);
96 memset(&mLastKovioTime, 0, sizeof(mLastKovioTime));
97 memset(&mActivationParams_t, 0, sizeof(activationParams_t));
98}
99
100
101/*******************************************************************************
102**
103** Function: getInstance
104**
105** Description: Get a reference to the singleton NfcTag object.
106**
107** Returns: Reference to NfcTag object.
108**
109*******************************************************************************/
110NfcTag& NfcTag::getInstance ()
111{
112 static NfcTag tag;
113 return tag;
114}
115
116
117/*******************************************************************************
118**
119** Function: initialize
120**
121** Description: Reset member variables.
122** native: Native data.
123**
124** Returns: None
125**
126*******************************************************************************/
127void NfcTag::initialize (nfc_jni_native_data* native)
128{
129 long num = 0;
130
131 mNativeData = native;
132 mIsActivated = false;
133 mActivationState = Idle;
134 mProtocol = NFC_PROTOCOL_UNKNOWN;
135 mNumTechList = 0;
136 mNumDiscNtf = 0;
137 mNumDiscTechList = 0;
138 mTechListIndex = 0;
139 mtT1tMaxMessageSize = 0;
140 mReadCompletedStatus = NFA_STATUS_OK;
141 mNfcDisableinProgress = false;
142 resetTechnologies ();
143 if (GetNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num)))
144 mPresenceCheckAlgorithm = num;
145}
146
147
148/*******************************************************************************
149**
150** Function: abort
151**
152** Description: Unblock all operations.
153**
154** Returns: None
155**
156*******************************************************************************/
157void NfcTag::abort ()
158{
159 SyncEventGuard g (mReadCompleteEvent);
160 mReadCompleteEvent.notifyOne ();
161}
162
163
164/*******************************************************************************
165**
166** Function: getActivationState
167**
168** Description: What is the current state: Idle, Sleep, or Activated.
169**
170** Returns: Idle, Sleep, or Activated.
171**
172*******************************************************************************/
173NfcTag::ActivationState NfcTag::getActivationState ()
174{
175 return mActivationState;
176}
177
178
179/*******************************************************************************
180**
181** Function: setDeactivationState
182**
183** Description: Set the current state: Idle or Sleep.
184** deactivated: state of deactivation.
185**
186** Returns: None.
187**
188*******************************************************************************/
189void NfcTag::setDeactivationState (tNFA_DEACTIVATED& deactivated)
190{
191 static const char fn [] = "NfcTag::setDeactivationState";
192 mActivationState = Idle;
193 mNdefDetectionTimedOut = false;
194 if (deactivated.type == NFA_DEACTIVATE_TYPE_SLEEP)
195 mActivationState = Sleep;
196 ALOGD ("%s: state=%u", fn, mActivationState);
197}
198
199
200/*******************************************************************************
201**
202** Function: setActivationState
203**
204** Description: Set the current state to Active.
205**
206** Returns: None.
207**
208*******************************************************************************/
209void NfcTag::setActivationState ()
210{
211 static const char fn [] = "NfcTag::setActivationState";
212 mNdefDetectionTimedOut = false;
213 mActivationState = Active;
214 ALOGD ("%s: state=%u", fn, mActivationState);
215}
216
217/*******************************************************************************
218**
219** Function: isActivated
220**
221** Description: Is tag activated?
222**
223** Returns: True if tag is activated.
224**
225*******************************************************************************/
226bool NfcTag::isActivated ()
227{
228 return mIsActivated;
229}
230
231
232/*******************************************************************************
233**
234** Function: getProtocol
235**
236** Description: Get the protocol of the current tag.
237**
238** Returns: Protocol number.
239**
240*******************************************************************************/
241tNFC_PROTOCOL NfcTag::getProtocol()
242{
243 return mProtocol;
244}
245
246/*******************************************************************************
247**
248** Function TimeDiff
249**
250** Description Computes time difference in milliseconds.
251**
252** Returns Time difference in milliseconds
253**
254*******************************************************************************/
255UINT32 TimeDiff(timespec start, timespec end)
256{
257 timespec temp;
258 if ((end.tv_nsec-start.tv_nsec)<0)
259 {
260 temp.tv_sec = end.tv_sec-start.tv_sec-1;
261 temp.tv_nsec = 1000000000+end.tv_nsec-start.tv_nsec;
262 }
263 else
264 {
265 temp.tv_sec = end.tv_sec-start.tv_sec;
266 temp.tv_nsec = end.tv_nsec-start.tv_nsec;
267 }
268
269 return (temp.tv_sec * 1000) + (temp.tv_nsec / 1000000);
270}
271
272/*******************************************************************************
273**
274** Function: IsSameKovio
275**
276** Description: Checks if tag activate is the same (UID) Kovio tag previously
277** activated. This is needed due to a problem with some Kovio
278** tags re-activating multiple times.
279** activationData: data from activation.
280**
281** Returns: true if the activation is from the same tag previously
282** activated, false otherwise
283**
284*******************************************************************************/
285bool NfcTag::IsSameKovio(tNFA_ACTIVATED& activationData)
286{
287 static const char fn [] = "NfcTag::IsSameKovio";
288 ALOGD ("%s: enter", fn);
289 tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
290
291 if (rfDetail.protocol != NFC_PROTOCOL_KOVIO)
292 return false;
293
294 memcpy (&(mTechParams[0]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
295 if (mTechParams [0].mode != NFC_DISCOVERY_TYPE_POLL_KOVIO)
296 return false;
297
298 struct timespec now;
299 clock_gettime(CLOCK_REALTIME, &now);
300
301 bool rVal = false;
302 if (mTechParams[0].param.pk.uid_len == mLastKovioUidLen)
303 {
304 if (memcmp(mLastKovioUid, &mTechParams [0].param.pk.uid, mTechParams[0].param.pk.uid_len) == 0)
305 {
306 //same tag
307 if (TimeDiff(mLastKovioTime, now) < 500)
308 {
309 // same tag within 500 ms, ignore activation
310 rVal = true;
311 }
312 }
313 }
314
315 // save Kovio tag info
316 if (!rVal)
317 {
318 if ((mLastKovioUidLen = mTechParams[0].param.pk.uid_len) > NFC_KOVIO_MAX_LEN)
319 mLastKovioUidLen = NFC_KOVIO_MAX_LEN;
320 memcpy(mLastKovioUid, mTechParams[0].param.pk.uid, mLastKovioUidLen);
321 }
322 mLastKovioTime = now;
323 ALOGD ("%s: exit, is same Kovio=%d", fn, rVal);
324 return rVal;
325}
326
327/*******************************************************************************
328**
329** Function: discoverTechnologies
330**
331** Description: Discover the technologies that NFC service needs by interpreting
332** the data structures from the stack.
333** activationData: data from activation.
334**
335** Returns: None
336**
337*******************************************************************************/
338void NfcTag::discoverTechnologies (tNFA_ACTIVATED& activationData)
339{
340 static const char fn [] = "NfcTag::discoverTechnologies (activation)";
341 ALOGD ("%s: enter", fn);
342 tNFC_ACTIVATE_DEVT& rfDetail = activationData.activate_ntf;
343
344 mNumTechList = mTechListIndex;
345 ALOGE ("mNumTechList =%d, mTechListIndex=%d", mNumTechList, mTechListIndex);
nxpandroid1153eb32015-11-06 18:46:58 +0530346#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530347 if (mNumTechList >= MAX_NUM_TECHNOLOGY)
348 {
349 ALOGE ("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);
350 goto TheEnd;
351 }
352#endif
353 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
354 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
355
356 //save the stack's data structure for interpretation later
357 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
358
nxpandroid34627bd2016-05-27 15:52:30 +0530359 if(NFC_PROTOCOL_T1T == rfDetail.protocol)
nxpandroid64fd68c2015-09-23 16:45:15 +0530360 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530361 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
nxpandroid34627bd2016-05-27 15:52:30 +0530362 }
363 else if(NFC_PROTOCOL_T2T == rfDetail.protocol)
364 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530365 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
366 // could be MifFare UL or Classic or Kovio
367 {
368 // need to look at first byte of uid to find Manufacture Byte
369 tNFC_RF_TECH_PARAMS tech_params;
370 memcpy (&tech_params, &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
371
372 if ((tech_params.param.pa.nfcid1[0] == 0x04 && rfDetail.rf_tech_param.param.pa.sel_rsp == 0) ||
373 rfDetail.rf_tech_param.param.pa.sel_rsp == 0x18 ||
374 rfDetail.rf_tech_param.param.pa.sel_rsp == 0x08 ||
375 rfDetail.rf_tech_param.param.pa.sel_rsp == 0x01)
376 {
nxpandroid1153eb32015-11-06 18:46:58 +0530377#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530378 if ((rfDetail.rf_tech_param.param.pa.sel_rsp == 0) &&
379 (mNumTechList < (MAX_NUM_TECHNOLOGY-1)))
380#else
381 if (rfDetail.rf_tech_param.param.pa.sel_rsp == 0)
382#endif
383 {
384 mNumTechList++;
385 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
386 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
387 //save the stack's data structure for interpretation later
388 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
389 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_UL; //is TagTechnology.MIFARE_ULTRALIGHT by Java API
390 }
nxpandroid1153eb32015-11-06 18:46:58 +0530391#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530392 //To support skylander tag.
393 else if (rfDetail.rf_tech_param.param.pa.sel_rsp == 0x01)
394 {
395 mTechLibNfcTypes [mNumTechList] = NFC_PROTOCOL_MIFARE;
396 rfDetail.rf_tech_param.param.pa.sel_rsp = 0x08;
397 memcpy (&tech_params, &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
398 if(mNumTechList < (MAX_NUM_TECHNOLOGY-1))
399 {
400 mNumTechList++;
401 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
402 mTechLibNfcTypes [mNumTechList] = NFC_PROTOCOL_MIFARE;
403 //save the stack's data structure for interpretation later
404 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
405 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC; //is TagTechnology.MIFARE_CLASSIC by Java API
406 }
407 EXTNS_MfcInit(activationData);
408 }
409#endif
410 }
411 }
nxpandroid34627bd2016-05-27 15:52:30 +0530412 }
413 else if(NFC_PROTOCOL_T3BT == rfDetail.protocol)
414 {
415 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
416 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
417 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API
418 //save the stack's data structure for interpretation later
419 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
420 }
421 else if(NFC_PROTOCOL_T3T == rfDetail.protocol)
422 {
423 UINT8 xx = 0;
nxpandroid64fd68c2015-09-23 16:45:15 +0530424
nxpandroid34627bd2016-05-27 15:52:30 +0530425 mTechList [mNumTechList] = TARGET_TYPE_FELICA;
426
427 //see if it is Felica Lite.
428 while (xx < activationData.params.t3t.num_system_codes)
nxpandroid64fd68c2015-09-23 16:45:15 +0530429 {
nxpandroid34627bd2016-05-27 15:52:30 +0530430 if (activationData.params.t3t.p_system_codes[xx++] == T3T_SYSTEM_CODE_FELICA_LITE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530431 {
nxpandroid34627bd2016-05-27 15:52:30 +0530432 mIsFelicaLite = true;
433 break;
nxpandroid64fd68c2015-09-23 16:45:15 +0530434 }
435 }
nxpandroid34627bd2016-05-27 15:52:30 +0530436 }
437 else if(NFC_PROTOCOL_ISO_DEP == rfDetail.protocol)
438 {
439 //type-4 tag uses technology ISO-DEP and technology A or B
nxpandroid64fd68c2015-09-23 16:45:15 +0530440 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_4; //is TagTechnology.ISO_DEP by Java API
nxpandroid1153eb32015-11-06 18:46:58 +0530441#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530442 if ( ( (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
nxpandroid34627bd2016-05-27 15:52:30 +0530443 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
444 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
445 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) ) && mNumTechList < (MAX_NUM_TECHNOLOGY-1))
446#else
447 if ( (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
nxpandroid64fd68c2015-09-23 16:45:15 +0530448 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
449 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
nxpandroid34627bd2016-05-27 15:52:30 +0530450 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE))
nxpandroid64fd68c2015-09-23 16:45:15 +0530451#endif
452 {
453 mNumTechList++;
454 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
455 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
456 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
457 //save the stack's data structure for interpretation later
458 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
459 }
nxpandroid1153eb32015-11-06 18:46:58 +0530460#if(NXP_EXTNS == TRUE)
nxpandroid34627bd2016-05-27 15:52:30 +0530461 else if ( ((rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
462 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
463 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
464 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) ) && mNumTechList < (MAX_NUM_TECHNOLOGY-1))
nxpandroid64fd68c2015-09-23 16:45:15 +0530465#else
nxpandroid34627bd2016-05-27 15:52:30 +0530466 else if ((rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
467 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
468 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
469 (rfDetail.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME))
nxpandroid64fd68c2015-09-23 16:45:15 +0530470#endif
471 {
472 mNumTechList++;
473 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
474 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
475 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API
476 //save the stack's data structure for interpretation later
477 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
478 }
nxpandroid34627bd2016-05-27 15:52:30 +0530479 }
480 else if(NFC_PROTOCOL_15693 == rfDetail.protocol)
481 {
482 //is TagTechnology.NFC_V by Java API
483 mTechList [mNumTechList] = TARGET_TYPE_ISO15693;
484 }
485 else if(NFC_PROTOCOL_KOVIO == rfDetail.protocol)
486 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530487 ALOGD ("%s: Kovio", fn);
488 mTechList [mNumTechList] = TARGET_TYPE_KOVIO_BARCODE;
nxpandroid34627bd2016-05-27 15:52:30 +0530489 }
490 else if(NFC_PROTOCOL_MIFARE == rfDetail.protocol)
491 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530492 ALOGE ("Mifare Classic detected");
493 EXTNS_MfcInit(activationData);
494 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
495 // could be MifFare UL or Classic or Kovio
496 {
497 // need to look at first byte of uid to find manuf.
498 tNFC_RF_TECH_PARAMS tech_params;
499 memcpy (&tech_params, &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
500 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1))
501 {
502 mNumTechList++;
503 mTechHandles [mNumTechList] = rfDetail.rf_disc_id;
504 mTechLibNfcTypes [mNumTechList] = rfDetail.protocol;
505 //save the stack's data structure for interpretation later
506 memcpy (&(mTechParams[mNumTechList]), &(rfDetail.rf_tech_param), sizeof(rfDetail.rf_tech_param));
507 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC; //is TagTechnology.MIFARE_ULTRALIGHT by Java API
508 }
509 }
nxpandroid34627bd2016-05-27 15:52:30 +0530510 }
511 else
512 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530513 ALOGE ("%s: unknown protocol ????", fn);
514 mTechList [mNumTechList] = TARGET_TYPE_UNKNOWN;
nxpandroid64fd68c2015-09-23 16:45:15 +0530515 }
516
517 mNumTechList++;
nxpandroid1153eb32015-11-06 18:46:58 +0530518#if (NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530519 for (int i=0; (i < mNumTechList) && (mNumTechList < MAX_NUM_TECHNOLOGY); i++)
520#else
521 for (int i=0; i < mNumTechList; i++)
522#endif
523 {
524 ALOGD ("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn,
525 i, mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]);
526 }
nxpandroid1153eb32015-11-06 18:46:58 +0530527#if (NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530528TheEnd:
529#endif
530 ALOGD ("%s: exit", fn);
531}
532
533
534/*******************************************************************************
535**
536** Function: discoverTechnologies
537**
538** Description: Discover the technologies that NFC service needs by interpreting
539** the data structures from the stack.
540** discoveryData: data from discovery events(s).
541**
542** Returns: None
543**
544*******************************************************************************/
545void NfcTag::discoverTechnologies (tNFA_DISC_RESULT& discoveryData)
546{
547 static const char fn [] = "NfcTag::discoverTechnologies (discovery)";
548 tNFC_RESULT_DEVT& discovery_ntf = discoveryData.discovery_ntf;
549
550 ALOGD ("%s: enter: rf disc. id=%u; protocol=%u, mNumTechList=%u", fn, discovery_ntf.rf_disc_id, discovery_ntf.protocol, mNumTechList);
551 if (mNumTechList >= MAX_NUM_TECHNOLOGY)
552 {
553 ALOGE ("%s: exceed max=%d", fn, MAX_NUM_TECHNOLOGY);
554 goto TheEnd;
555 }
556 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
557 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
558
559 //save the stack's data structure for interpretation later
560 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
561
nxpandroid34627bd2016-05-27 15:52:30 +0530562 if(NFC_PROTOCOL_T1T == discovery_ntf.protocol)
nxpandroid64fd68c2015-09-23 16:45:15 +0530563 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530564 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
nxpandroid34627bd2016-05-27 15:52:30 +0530565 }
566 else if(NFC_PROTOCOL_T2T == discovery_ntf.protocol)
567 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530568 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
569 //type-2 tags are identical to Mifare Ultralight, so Ultralight is also discovered
570 if ((discovery_ntf.rf_tech_param.param.pa.sel_rsp == 0) &&
571 (mNumTechList < (MAX_NUM_TECHNOLOGY-1)))
572 {
573 // Mifare Ultralight
574 mNumTechList++;
575 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
576 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
577 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_UL; //is TagTechnology.MIFARE_ULTRALIGHT by Java API
578 }
579
580 //save the stack's data structure for interpretation later
581 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
nxpandroid34627bd2016-05-27 15:52:30 +0530582 }
583 else if(NFC_PROTOCOL_T3T == discovery_ntf.protocol)
584 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530585 mTechList [mNumTechList] = TARGET_TYPE_FELICA;
nxpandroid34627bd2016-05-27 15:52:30 +0530586 }
587 else if(NFC_PROTOCOL_ISO_DEP == discovery_ntf.protocol)
588 {
589 //type-4 tag uses technology ISO-DEP and technology A or B
nxpandroid64fd68c2015-09-23 16:45:15 +0530590 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_4; //is TagTechnology.ISO_DEP by Java API
591 if ( (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A) ||
592 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
593 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
594 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) )
595 {
596 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1))
597 {
598 mNumTechList++;
599 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
600 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
601 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A; //is TagTechnology.NFC_A by Java API
602 //save the stack's data structure for interpretation later
603 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
604 }
605 }
606 else if ( (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B) ||
607 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
608 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
609 (discovery_ntf.rf_tech_param.mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) )
610 {
611 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1))
612 {
613 mNumTechList++;
614 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
615 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
616 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3B; //is TagTechnology.NFC_B by Java API
617 //save the stack's data structure for interpretation later
618 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
619 }
620 }
nxpandroid34627bd2016-05-27 15:52:30 +0530621 }
622 else if(NFC_PROTOCOL_15693 == discovery_ntf.protocol)
623 {
624 //is TagTechnology.NFC_V by Java API
nxpandroid64fd68c2015-09-23 16:45:15 +0530625 mTechList [mNumTechList] = TARGET_TYPE_ISO15693;
nxpandroid34627bd2016-05-27 15:52:30 +0530626 }
627 else if (NFC_PROTOCOL_MIFARE == discovery_ntf.protocol)
628 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530629 mTechList [mNumTechList] = TARGET_TYPE_MIFARE_CLASSIC;
nxpandroid34627bd2016-05-27 15:52:30 +0530630 if (mNumTechList < (MAX_NUM_TECHNOLOGY-1))
nxpandroid64fd68c2015-09-23 16:45:15 +0530631 {
nxpandroid34627bd2016-05-27 15:52:30 +0530632 mNumTechList++;
633 mTechHandles [mNumTechList] = discovery_ntf.rf_disc_id;
634 mTechLibNfcTypes [mNumTechList] = discovery_ntf.protocol;
nxpandroid64fd68c2015-09-23 16:45:15 +0530635 mTechList [mNumTechList] = TARGET_TYPE_ISO14443_3A;
nxpandroid34627bd2016-05-27 15:52:30 +0530636 //save the stack's data structure for interpretation later
637 memcpy (&(mTechParams[mNumTechList]), &(discovery_ntf.rf_tech_param), sizeof(discovery_ntf.rf_tech_param));
nxpandroid64fd68c2015-09-23 16:45:15 +0530638 }
nxpandroid34627bd2016-05-27 15:52:30 +0530639 }
640 else
641 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530642 ALOGE ("%s: unknown protocol ????", fn);
643 mTechList [mNumTechList] = TARGET_TYPE_UNKNOWN;
nxpandroid64fd68c2015-09-23 16:45:15 +0530644 }
645
646 mNumTechList++;
647
nxpandroid64fd68c2015-09-23 16:45:15 +0530648 if(discovery_ntf.more != NCI_DISCOVER_NTF_MORE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530649 {
nxpandroid1153eb32015-11-06 18:46:58 +0530650#if (NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530651 for (int i=0; (i < mNumTechList) && (mNumTechList < MAX_NUM_TECHNOLOGY); i++)
652#else
653 for (int i=0; i < mNumTechList; i++)
654#endif
655 {
656 ALOGD ("%s: index=%d; tech=%d; handle=%d; nfc type=%d", fn,
657 i, mTechList[i], mTechHandles[i], mTechLibNfcTypes[i]);
658 }
659 }
660 mNumDiscTechList = mNumTechList;
661 ALOGD("%s; mNumDiscTechList=%x", fn, mNumDiscTechList);
662
663TheEnd:
664 ALOGD ("%s: exit", fn);
665}
666
nxpandroid64fd68c2015-09-23 16:45:15 +0530667/*******************************************************************************
668**
669** Function: createNativeNfcTag
670**
671** Description: Create a brand new Java NativeNfcTag object;
672** fill the objects's member variables with data;
673** notify NFC service;
674** activationData: data from activation.
675**
676** Returns: None
677**
678*******************************************************************************/
679void NfcTag::createNativeNfcTag (tNFA_ACTIVATED& activationData)
680{
681 static const char fn [] = "NfcTag::createNativeNfcTag";
682 ALOGD ("%s: enter", fn);
683
684 JNIEnv* e = NULL;
685 ScopedAttach attach(mNativeData->vm, &e);
686 if (e == NULL)
687 {
688 ALOGE("%s: jni env is null", fn);
689 return;
690 }
691
692 ScopedLocalRef<jclass> tag_cls(e, e->GetObjectClass(mNativeData->cached_NfcTag));
693 if (e->ExceptionCheck())
694 {
695 e->ExceptionClear();
696 ALOGE("%s: failed to get class", fn);
697 return;
698 }
699
700 //create a new Java NativeNfcTag object
701 jmethodID ctor = e->GetMethodID(tag_cls.get(), "<init>", "()V");
702 ScopedLocalRef<jobject> tag(e, e->NewObject(tag_cls.get(), ctor));
703
704 //fill NativeNfcTag's mProtocols, mTechList, mTechHandles, mTechLibNfcTypes
705 fillNativeNfcTagMembers1(e, tag_cls.get(), tag.get());
706
707 //fill NativeNfcTag's members: mHandle, mConnectedTechnology
708 fillNativeNfcTagMembers2(e, tag_cls.get(), tag.get(), activationData);
709
710 //fill NativeNfcTag's members: mTechPollBytes
711 fillNativeNfcTagMembers3(e, tag_cls.get(), tag.get(), activationData);
712
713 //fill NativeNfcTag's members: mTechActBytes
714 fillNativeNfcTagMembers4(e, tag_cls.get(), tag.get(), activationData);
715
716 //fill NativeNfcTag's members: mUid
717 fillNativeNfcTagMembers5(e, tag_cls.get(), tag.get(), activationData);
718
719 if (mNativeData->tag != NULL)
720 {
721 e->DeleteGlobalRef(mNativeData->tag);
722 }
723 mNativeData->tag = e->NewGlobalRef(tag.get());
724
725 ALOGE("%s; mNumDiscNtf=%x", fn,mNumDiscNtf);
726 if(!mNumDiscNtf || NfcTag::getInstance().checkNextValidProtocol() == -1)
727 {
728 //notify NFC service about this new tag
729 mNumDiscNtf = 0;
730 ALOGD ("%s: try notify nfc service", fn);
731 storeActivationParams();
732 e->CallVoidMethod(mNativeData->manager, android::gCachedNfcManagerNotifyNdefMessageListeners, tag.get());
733 if (e->ExceptionCheck())
734 {
735 e->ExceptionClear();
736 ALOGE ("%s: fail notify nfc service", fn);
737 }
738 deleteglobaldata(e);
739 }
740 else
741 {
742 ALOGE("%s: Selecting next tag", fn);
743 }
744
745 ALOGD ("%s: exit", fn);
746}
747
748/*******************************************************************************
749**
750** Function: deleteglobaldata
751**
752** Description: Deletes the global data reference after notifying to service
753** e: JVM environment.
754**
755** Returns: None
756**
757*******************************************************************************/
758static void deleteglobaldata(JNIEnv* e)
759{
760 static const char fn [] = "deleteglobaldata";
761 ALOGD ("%s: enter", fn);
762 if( techActBytes1 != NULL)
763 {
764 e->DeleteGlobalRef(techActBytes1);
765 }
766 if(techPollBytes2 != NULL)
767 {
768 e->DeleteGlobalRef(techPollBytes2);
769 }
770 ALOGD ("%s: exit", fn);
771}
772
773
774/*******************************************************************************
775**
776** Function: fillNativeNfcTagMembers1
777**
778** Description: Fill NativeNfcTag's members: mProtocols, mTechList, mTechHandles, mTechLibNfcTypes.
779** e: JVM environment.
780** tag_cls: Java NativeNfcTag class.
781** tag: Java NativeNfcTag object.
782**
783** Returns: None
784**
785*******************************************************************************/
786void NfcTag::fillNativeNfcTagMembers1 (JNIEnv* e, jclass tag_cls, jobject tag)
787{
788 static const char fn [] = "NfcTag::fillNativeNfcTagMembers1";
789 ALOGD ("%s", fn);
790
791 //create objects that represent NativeNfcTag's member variables
792 ScopedLocalRef<jintArray> techList(e, e->NewIntArray(mNumTechList));
793 ScopedLocalRef<jintArray> handleList(e, e->NewIntArray(mNumTechList));
794 ScopedLocalRef<jintArray> typeList(e, e->NewIntArray(mNumTechList));
795
796 {
797 ScopedIntArrayRW technologies(e, techList.get());
798 ScopedIntArrayRW handles(e, handleList.get());
799 ScopedIntArrayRW types(e, typeList.get());
800 for (int i = 0; i < mNumTechList; i++) {
801 mNativeData->tProtocols [i] = mTechLibNfcTypes [i];
802 mNativeData->handles [i] = mTechHandles [i];
803 technologies [i] = mTechList [i];
804 handles [i] = mTechHandles [i];
805 types [i] = mTechLibNfcTypes [i];
806 }
807 }
808
809 jfieldID f = NULL;
810
811 f = e->GetFieldID(tag_cls, "mTechList", "[I");
812 e->SetObjectField(tag, f, techList.get());
813
814 f = e->GetFieldID(tag_cls, "mTechHandles", "[I");
815 e->SetObjectField(tag, f, handleList.get());
816
817 f = e->GetFieldID(tag_cls, "mTechLibNfcTypes", "[I");
818 e->SetObjectField(tag, f, typeList.get());
819}
820
821
822/*******************************************************************************
823**
824** Function: fillNativeNfcTagMembers2
825**
826** Description: Fill NativeNfcTag's members: mConnectedTechIndex or mConnectedTechnology.
827** The original Google's implementation is in set_target_pollBytes(
828** in com_android_nfc_NativeNfcTag.cpp;
829** e: JVM environment.
830** tag_cls: Java NativeNfcTag class.
831** tag: Java NativeNfcTag object.
832** activationData: data from activation.
833**
834** Returns: None
835**
836*******************************************************************************/
837//fill NativeNfcTag's members: mHandle, mConnectedTechnology
838void NfcTag::fillNativeNfcTagMembers2 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& /*activationData*/)
839{
840 static const char fn [] = "NfcTag::fillNativeNfcTagMembers2";
841 ALOGD ("%s", fn);
842 jfieldID f = e->GetFieldID(tag_cls, "mConnectedTechIndex", "I");
843 e->SetIntField(tag, f, (jint) 0);
844}
845
846
847/*******************************************************************************
848**
849** Function: fillNativeNfcTagMembers3
850**
851** Description: Fill NativeNfcTag's members: mTechPollBytes.
852** The original Google's implementation is in set_target_pollBytes(
853** in com_android_nfc_NativeNfcTag.cpp;
854** e: JVM environment.
855** tag_cls: Java NativeNfcTag class.
856** tag: Java NativeNfcTag object.
857** activationData: data from activation.
858**
859** Returns: None
860**
861*******************************************************************************/
862void NfcTag::fillNativeNfcTagMembers3 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData)
863{
864 static const char fn [] = "NfcTag::fillNativeNfcTagMembers3";
865 ScopedLocalRef<jbyteArray> pollBytes(e, e->NewByteArray(0));
866 ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(pollBytes.get()));
867 ScopedLocalRef<jobjectArray> techPollBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
868 int len = 0;
nxpandroid34627bd2016-05-27 15:52:30 +0530869 jobject obj1;
nxpandroid64fd68c2015-09-23 16:45:15 +0530870 if(mTechListIndex == 0)
871 {
872 techPollBytes2= reinterpret_cast<jobjectArray>(e->NewGlobalRef(techPollBytes.get()));
873 }
874 else
875 {
876 for(int j=0;j<mTechListIndex;j++)
877 {
nxpandroid34627bd2016-05-27 15:52:30 +0530878 obj1 = e->GetObjectArrayElement(techPollBytes2,j);
879 e->SetObjectArrayElement(techPollBytes.get(),j,obj1);
nxpandroid64fd68c2015-09-23 16:45:15 +0530880 }
881 }
882
nxpandroid64fd68c2015-09-23 16:45:15 +0530883 for (int i = mTechListIndex; i < mNumTechList; i++)
884
885 {
886 ALOGD ("%s: index=%d; rf tech params mode=%u", fn, i, mTechParams [i].mode);
nxpandroid34627bd2016-05-27 15:52:30 +0530887 if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams [i].mode
888 || NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == mTechParams [i].mode
889 || NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams [i].mode
890 || NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == mTechParams [i].mode)
nxpandroid64fd68c2015-09-23 16:45:15 +0530891 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530892 ALOGD ("%s: tech A", fn);
893 pollBytes.reset(e->NewByteArray(2));
894 e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte*) mTechParams [i].param.pa.sens_res);
nxpandroid34627bd2016-05-27 15:52:30 +0530895 }
896 else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams [i].mode
897 || NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams [i].mode
898 || NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams [i].mode
899 || NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams [i].mode)
900 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530901 if (mTechList [i] == TARGET_TYPE_ISO14443_3B) //is TagTechnology.NFC_B by Java API
902 {
903 /*****************
904 see NFC Forum Digital Protocol specification; section 5.6.2;
905 in SENSB_RES response, byte 6 through 9 is Application Data, byte 10-12 or 13 is Protocol Info;
906 used by public API: NfcB.getApplicationData(), NfcB.getProtocolInfo();
907 *****************/
908 ALOGD ("%s: tech B; TARGET_TYPE_ISO14443_3B", fn);
909 len = mTechParams [i].param.pb.sensb_res_len;
910 len = len - 4; //subtract 4 bytes for NFCID0 at byte 2 through 5
911 if(len > 0)
912 {
913 pollBytes.reset(e->NewByteArray(len));
914 e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) (mTechParams [i].param.pb.sensb_res+4));
915 }
916 else
917 {
918 ALOGD ("%s: tech B; Activation param missing", fn);
919 }
920 }
921 else
922 {
923 pollBytes.reset(e->NewByteArray(0));
924 }
nxpandroid34627bd2016-05-27 15:52:30 +0530925 }
926 else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams [i].mode
927 || NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == mTechParams [i].mode
928 || NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams [i].mode
929 || NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == mTechParams [i].mode)
930 {
931 /****************
932 see NFC Forum Type 3 Tag Operation Specification; sections 2.3.2, 2.3.1.2;
933 see NFC Forum Digital Protocol Specification; sections 6.6.2;
934 PMm: manufacture parameter; 8 bytes;
935 System Code: 2 bytes;
936 ****************/
937 ALOGD ("%s: tech F", fn);
938 UINT8 result [10]; //return result to NFC service
939 memset (result, 0, sizeof(result));
940 len = 10;
nxpandroid64fd68c2015-09-23 16:45:15 +0530941
nxpandroid34627bd2016-05-27 15:52:30 +0530942 /****
943 for (int ii = 0; ii < mTechParams [i].param.pf.sensf_res_len; ii++)
nxpandroid64fd68c2015-09-23 16:45:15 +0530944 {
nxpandroid34627bd2016-05-27 15:52:30 +0530945 ALOGD ("%s: tech F, sendf_res[%d]=%d (0x%x)",
946 fn, ii, mTechParams [i].param.pf.sensf_res[ii],mTechParams [i].param.pf.sensf_res[ii]);
nxpandroid64fd68c2015-09-23 16:45:15 +0530947 }
nxpandroid34627bd2016-05-27 15:52:30 +0530948 ***/
949 memcpy (result, mTechParams [i].param.pf.sensf_res + 8, 8); //copy PMm
950 if (activationData.params.t3t.num_system_codes > 0) //copy the first System Code
nxpandroid64fd68c2015-09-23 16:45:15 +0530951 {
nxpandroid34627bd2016-05-27 15:52:30 +0530952 UINT16 systemCode = *(activationData.params.t3t.p_system_codes);
953 result [8] = (UINT8) (systemCode >> 8);
954 result [9] = (UINT8) systemCode;
955 ALOGD ("%s: tech F; sys code=0x%X 0x%X", fn, result [8], result [9]);
nxpandroid64fd68c2015-09-23 16:45:15 +0530956 }
nxpandroid34627bd2016-05-27 15:52:30 +0530957 pollBytes.reset(e->NewByteArray(len));
958 e->SetByteArrayRegion(pollBytes.get(), 0, len, (jbyte*) result);
959 }
960 else if (NFC_DISCOVERY_TYPE_POLL_ISO15693 == mTechParams [i].mode
961 || NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams [i].mode)
962 {
963 ALOGD ("%s: tech iso 15693", fn);
964 //iso 15693 response flags: 1 octet
965 //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
966 //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
967 uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid};
968 pollBytes.reset(e->NewByteArray(2));
969 e->SetByteArrayRegion(pollBytes.get(), 0, 2, (jbyte *) data);
970 }
nxpandroid64fd68c2015-09-23 16:45:15 +0530971
nxpandroid34627bd2016-05-27 15:52:30 +0530972 else if (NFC_DISCOVERY_TYPE_POLL_KOVIO == mTechParams [i].mode)
973 {
974 ALOGD ("%s: tech Kovio", fn);
975 pollBytes.reset(e->NewByteArray(0));
976 }
977 else
978 {
nxpandroid64fd68c2015-09-23 16:45:15 +0530979 ALOGE ("%s: tech unknown ????", fn);
980 pollBytes.reset(e->NewByteArray(0));
nxpandroid34627bd2016-05-27 15:52:30 +0530981
nxpandroid64fd68c2015-09-23 16:45:15 +0530982 } //switch: every type of technology
983 e->SetObjectArrayElement(techPollBytes.get(), i, pollBytes.get());
984 }
985 if (techPollBytes2 != NULL && mTechListIndex != 0 )
986 {
987 e->DeleteGlobalRef(techPollBytes2);
988
989 techPollBytes2= reinterpret_cast<jobjectArray>(e->NewGlobalRef(techPollBytes.get()));
990 }
991 //for: every technology in the array
992 jfieldID f = e->GetFieldID(tag_cls, "mTechPollBytes", "[[B");
993 e->SetObjectField(tag, f, techPollBytes.get());
994}
995
nxpandroid64fd68c2015-09-23 16:45:15 +0530996/*******************************************************************************
997**
998** Function: fillNativeNfcTagMembers4
999**
1000** Description: Fill NativeNfcTag's members: mTechActBytes.
1001** The original Google's implementation is in set_target_activationBytes()
1002** in com_android_nfc_NativeNfcTag.cpp;
1003** e: JVM environment.
1004** tag_cls: Java NativeNfcTag class.
1005** tag: Java NativeNfcTag object.
1006** activationData: data from activation.
1007**
1008** Returns: None
1009**
1010*******************************************************************************/
1011void NfcTag::fillNativeNfcTagMembers4 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData)
1012{
1013 static const char fn [] = "NfcTag::fillNativeNfcTagMembers4";
1014 ScopedLocalRef<jbyteArray> actBytes(e, e->NewByteArray(0));
1015 ScopedLocalRef<jclass> byteArrayClass(e, e->GetObjectClass(actBytes.get()));
1016 ScopedLocalRef<jobjectArray> techActBytes(e, e->NewObjectArray(mNumTechList, byteArrayClass.get(), 0));
nxpandroid34627bd2016-05-27 15:52:30 +05301017 jobject obj1;
nxpandroid64fd68c2015-09-23 16:45:15 +05301018 if(mTechListIndex == 0)
1019 {
1020 techActBytes1 = reinterpret_cast<jobjectArray>(e->NewGlobalRef(techActBytes.get()));
1021 }
1022 else
1023 {
1024 for(int j=0;j < mTechListIndex;j++)
1025 {
nxpandroid34627bd2016-05-27 15:52:30 +05301026 obj1 = e->GetObjectArrayElement(techActBytes1,j);
1027 e->SetObjectArrayElement(techActBytes.get(), j, obj1);
nxpandroid64fd68c2015-09-23 16:45:15 +05301028 }
1029 }
1030
nxpandroid64fd68c2015-09-23 16:45:15 +05301031 for (int i = mTechListIndex; i < mNumTechList; i++)
1032
1033 {
1034 ALOGD ("%s: index=%d", fn, i);
nxpandroid34627bd2016-05-27 15:52:30 +05301035 if (NFC_PROTOCOL_T1T == mTechLibNfcTypes[i] || NFC_PROTOCOL_T2T == mTechLibNfcTypes[i])
nxpandroid64fd68c2015-09-23 16:45:15 +05301036 {
nxpandroid34627bd2016-05-27 15:52:30 +05301037 if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T1T)
1038 ALOGD ("%s: T1T; tech A", fn);
1039 else if (mTechLibNfcTypes[i] == NFC_PROTOCOL_T2T)
1040 ALOGD ("%s: T2T; tech A", fn);
1041 actBytes.reset(e->NewByteArray(1));
1042 e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp);
1043 }
1044 else if (NFC_PROTOCOL_T3T == mTechLibNfcTypes[i])
1045 {
1046 //felica
1047 ALOGD ("%s: T3T; felica; tech F", fn);
1048 //really, there is no data
1049 actBytes.reset(e->NewByteArray(0));
1050 }
1051 else if (NFC_PROTOCOL_MIFARE == mTechLibNfcTypes[i])
1052 {
1053 ALOGD ("%s: Mifare Classic; tech A", fn);
1054 actBytes.reset (e->NewByteArray(1));
1055 e->SetByteArrayRegion (actBytes.get(), 0, 1,
1056 (jbyte*) &mTechParams [i].param.pa.sel_rsp);
1057 }
1058 else if (NFC_PROTOCOL_T3BT == mTechLibNfcTypes[i])
1059 {
1060 ALOGD ("%s: tech T3BT; chinaId card", fn);
1061 actBytes.reset(e->NewByteArray(0));
1062 }
1063 else if (NFC_PROTOCOL_ISO_DEP == mTechLibNfcTypes[i])
1064 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301065 if (mTechList [i] == TARGET_TYPE_ISO14443_4) //is TagTechnology.ISO_DEP by Java API
1066 {
1067 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
1068 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) ||
1069 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
1070 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) )
1071 {
1072 //see NFC Forum Digital Protocol specification, section 11.6.2, "RATS Response"; search for "historical bytes";
1073 //copy historical bytes into Java object;
1074 //the public API, IsoDep.getHistoricalBytes(), returns this data;
1075 if (activationData.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP)
1076 {
1077 tNFC_INTF_PA_ISO_DEP& pa_iso = activationData.activate_ntf.intf_param.intf_param.pa_iso;
1078 ALOGD ("%s: T4T; ISO_DEP for tech A; copy historical bytes; len=%u", fn, pa_iso.his_byte_len);
1079 actBytes.reset(e->NewByteArray(pa_iso.his_byte_len));
1080 if (pa_iso.his_byte_len > 0)
1081 e->SetByteArrayRegion(actBytes.get(), 0, pa_iso.his_byte_len, (jbyte*) (pa_iso.his_byte));
1082 }
1083 else
1084 {
1085 ALOGE ("%s: T4T; ISO_DEP for tech A; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type);
1086 actBytes.reset(e->NewByteArray(0));
1087 }
1088 }
1089 else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) ||
1090 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B_PRIME) ||
1091 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B) ||
1092 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B_PRIME) )
1093 {
1094 //see NFC Forum Digital Protocol specification, section 12.6.2, "ATTRIB Response";
1095 //copy higher-layer response bytes into Java object;
1096 //the public API, IsoDep.getHiLayerResponse(), returns this data;
1097 if (activationData.activate_ntf.intf_param.type == NFC_INTERFACE_ISO_DEP)
1098 {
1099 tNFC_INTF_PB_ISO_DEP& pb_iso = activationData.activate_ntf.intf_param.intf_param.pb_iso;
1100 ALOGD ("%s: T4T; ISO_DEP for tech B; copy response bytes; len=%u", fn, pb_iso.hi_info_len);
1101 actBytes.reset(e->NewByteArray(pb_iso.hi_info_len));
1102 if (pb_iso.hi_info_len > 0)
1103 e->SetByteArrayRegion(actBytes.get(), 0, pb_iso.hi_info_len, (jbyte*) (pb_iso.hi_info));
1104 }
1105 else
1106 {
1107 ALOGE ("%s: T4T; ISO_DEP for tech B; wrong interface=%u", fn, activationData.activate_ntf.intf_param.type);
1108 actBytes.reset(e->NewByteArray(0));
1109 }
1110 }
1111 }
1112 else if (mTechList [i] == TARGET_TYPE_ISO14443_3A) //is TagTechnology.NFC_A by Java API
1113 {
1114 ALOGD ("%s: T4T; tech A", fn);
1115 actBytes.reset(e->NewByteArray(1));
1116 e->SetByteArrayRegion(actBytes.get(), 0, 1, (jbyte*) &mTechParams [i].param.pa.sel_rsp);
1117 }
1118 else
1119 {
1120 actBytes.reset(e->NewByteArray(0));
1121 }
nxpandroid34627bd2016-05-27 15:52:30 +05301122 } //case NFC_PROTOCOL_ISO_DEP: //t4t
1123 else if (NFC_PROTOCOL_15693 == mTechLibNfcTypes[i])
1124 {
1125 ALOGD ("%s: tech iso 15693", fn);
1126 //iso 15693 response flags: 1 octet
1127 //iso 15693 Data Structure Format Identifier (DSF ID): 1 octet
1128 //used by public API: NfcV.getDsfId(), NfcV.getResponseFlags();
1129 uint8_t data [2]= {activationData.params.i93.afi, activationData.params.i93.dsfid};
1130 actBytes.reset(e->NewByteArray(2));
1131 e->SetByteArrayRegion(actBytes.get(), 0, 2, (jbyte *) data);
1132 }
1133 else if (NFC_PROTOCOL_KOVIO == mTechLibNfcTypes[i])
1134 {
1135 ALOGD ("%s: tech Kovio", fn);
1136 actBytes.reset(e->NewByteArray(0));
1137 }
1138 else
1139 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301140 ALOGD ("%s: tech unknown ????", fn);
1141 actBytes.reset(e->NewByteArray(0));
nxpandroid64fd68c2015-09-23 16:45:15 +05301142 }//switch
1143 e->SetObjectArrayElement(techActBytes.get(), i, actBytes.get());
1144 }
1145 if (techActBytes1 != NULL && mTechListIndex !=0 )
1146 {
1147 e->DeleteGlobalRef(techActBytes1);
1148 techActBytes1 = reinterpret_cast<jobjectArray>(e->NewGlobalRef(techActBytes.get()));
1149 }
1150 //for: every technology in the array
1151 jfieldID f = e->GetFieldID (tag_cls, "mTechActBytes", "[[B");
1152 e->SetObjectField(tag, f, techActBytes.get());
1153}
1154
nxpandroid64fd68c2015-09-23 16:45:15 +05301155/*******************************************************************************
1156**
1157** Function: fillNativeNfcTagMembers5
1158**
1159** Description: Fill NativeNfcTag's members: mUid.
1160** The original Google's implementation is in nfc_jni_Discovery_notification_callback()
1161** in com_android_nfc_NativeNfcManager.cpp;
1162** e: JVM environment.
1163** tag_cls: Java NativeNfcTag class.
1164** tag: Java NativeNfcTag object.
1165** activationData: data from activation.
1166**
1167** Returns: None
1168**
1169*******************************************************************************/
1170void NfcTag::fillNativeNfcTagMembers5 (JNIEnv* e, jclass tag_cls, jobject tag, tNFA_ACTIVATED& activationData)
1171{
1172 static const char fn [] = "NfcTag::fillNativeNfcTagMembers5";
1173 int len = 0;
1174 ScopedLocalRef<jbyteArray> uid(e, NULL);
1175
nxpandroid34627bd2016-05-27 15:52:30 +05301176 if (NFC_DISCOVERY_TYPE_POLL_KOVIO == mTechParams [0].mode)
nxpandroid64fd68c2015-09-23 16:45:15 +05301177 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301178 ALOGD ("%s: Kovio", fn);
1179 len = mTechParams [0].param.pk.uid_len;
1180 uid.reset(e->NewByteArray(len));
1181 e->SetByteArrayRegion(uid.get(), 0, len,
1182 (jbyte*) &mTechParams [0].param.pk.uid);
nxpandroid34627bd2016-05-27 15:52:30 +05301183 }
1184 else if (NFC_DISCOVERY_TYPE_POLL_A == mTechParams [0].mode
1185 || NFC_DISCOVERY_TYPE_POLL_A_ACTIVE == mTechParams [0].mode
1186 || NFC_DISCOVERY_TYPE_LISTEN_A == mTechParams [0].mode
1187 || NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE == mTechParams [0].mode)
1188 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301189 ALOGD ("%s: tech A", fn);
1190 len = mTechParams [0].param.pa.nfcid1_len;
1191 uid.reset(e->NewByteArray(len));
1192 e->SetByteArrayRegion(uid.get(), 0, len,
1193 (jbyte*) &mTechParams [0].param.pa.nfcid1);
1194 //a tag's NFCID1 can change dynamically at each activation;
1195 //only the first byte (0x08) is constant; a dynamic NFCID1's length
1196 //must be 4 bytes (see NFC Digitial Protocol,
1197 //section 4.7.2 SDD_RES Response, Requirements 20).
1198 mIsDynamicTagId = (mTechParams [0].param.pa.nfcid1_len == 4) &&
1199 (mTechParams [0].param.pa.nfcid1 [0] == 0x08);
nxpandroid34627bd2016-05-27 15:52:30 +05301200 }
1201 else if (NFC_DISCOVERY_TYPE_POLL_B == mTechParams [0].mode
1202 || NFC_DISCOVERY_TYPE_POLL_B_PRIME == mTechParams [0].mode
1203 || NFC_DISCOVERY_TYPE_LISTEN_B == mTechParams [0].mode
1204 || NFC_DISCOVERY_TYPE_LISTEN_B_PRIME == mTechParams [0].mode)
1205 {
nxpandroid1153eb32015-11-06 18:46:58 +05301206#if (NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301207 if(activationData.activate_ntf.protocol != NFA_PROTOCOL_T3BT)
1208#endif
1209 {
1210 ALOGD ("%s: tech B", fn);
1211 uid.reset(e->NewByteArray(NFC_NFCID0_MAX_LEN));
1212 e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID0_MAX_LEN,
1213 (jbyte*) &mTechParams [0].param.pb.nfcid0);
1214 }
nxpandroid1153eb32015-11-06 18:46:58 +05301215#if (NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301216 else
1217 {
1218 ALOGD ("%s: chinaId card", fn);
1219 ALOGD ("%s: pipi_id[0]=%x", fn, mTechParams [0].param.pb.pupiid[0]);
1220 uid.reset(e->NewByteArray(NFC_PUPIID_MAX_LEN));
1221 e->SetByteArrayRegion(uid.get(), 0, NFC_PUPIID_MAX_LEN,
1222 (jbyte*) &mTechParams [0].param.pb.pupiid);
1223 }
1224#endif
nxpandroid34627bd2016-05-27 15:52:30 +05301225 }
1226 else if (NFC_DISCOVERY_TYPE_POLL_F == mTechParams [0].mode
1227 || NFC_DISCOVERY_TYPE_POLL_F_ACTIVE == mTechParams [0].mode
1228 || NFC_DISCOVERY_TYPE_LISTEN_F == mTechParams [0].mode
1229 || NFC_DISCOVERY_TYPE_LISTEN_F_ACTIVE == mTechParams [0].mode)
1230 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301231 uid.reset(e->NewByteArray(NFC_NFCID2_LEN));
1232 e->SetByteArrayRegion(uid.get(), 0, NFC_NFCID2_LEN,
1233 (jbyte*) &mTechParams [0].param.pf.nfcid2);
1234 ALOGD ("%s: tech F", fn);
nxpandroid34627bd2016-05-27 15:52:30 +05301235 }
1236 else if (NFC_DISCOVERY_TYPE_POLL_ISO15693 == mTechParams [0].mode
1237 || NFC_DISCOVERY_TYPE_LISTEN_ISO15693 == mTechParams [0].mode)
1238 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301239 ALOGD ("%s: tech iso 15693", fn);
1240 jbyte data [I93_UID_BYTE_LEN]; //8 bytes
1241 for (int i=0; i<I93_UID_BYTE_LEN; ++i) //reverse the ID
1242 data[i] = activationData.params.i93.uid [I93_UID_BYTE_LEN - i - 1];
1243 uid.reset(e->NewByteArray(I93_UID_BYTE_LEN));
1244 e->SetByteArrayRegion(uid.get(), 0, I93_UID_BYTE_LEN, data);
nxpandroid34627bd2016-05-27 15:52:30 +05301245 }
1246 else
1247 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301248 ALOGE ("%s: tech unknown ????", fn);
1249 uid.reset(e->NewByteArray(0));
nxpandroid64fd68c2015-09-23 16:45:15 +05301250 }
1251 jfieldID f = e->GetFieldID(tag_cls, "mUid", "[B");
1252 e->SetObjectField(tag, f, uid.get());
1253 mTechListIndex = mNumTechList;
1254 if(!mNumDiscNtf)
1255 mTechListIndex = 0;
1256 ALOGD("%s;mTechListIndex=%x",fn,mTechListIndex);
1257}
1258
nxpandroid64fd68c2015-09-23 16:45:15 +05301259/*******************************************************************************
1260**
1261** Function: isP2pDiscovered
1262**
1263** Description: Does the peer support P2P?
1264**
1265** Returns: True if the peer supports P2P.
1266**
1267*******************************************************************************/
1268bool NfcTag::isP2pDiscovered ()
1269{
1270 static const char fn [] = "NfcTag::isP2pDiscovered";
1271 bool retval = false;
1272
1273 for (int i = 0; i < mNumTechList; i++)
1274 {
1275 if (mTechLibNfcTypes[i] == NFA_PROTOCOL_NFC_DEP)
1276 {
1277 //if remote device supports P2P
1278 ALOGD ("%s: discovered P2P", fn);
1279 retval = true;
1280 break;
1281 }
1282 }
1283 ALOGD ("%s: return=%u", fn, retval);
1284 return retval;
1285}
1286
1287/*******************************************************************************
1288**
1289** Function: storeActivationParams
1290**
1291** Description: stores tag activation parameters for backup
1292**
1293** Returns: None
1294**
1295*******************************************************************************/
1296void NfcTag::storeActivationParams()
1297{
1298 static const char fn [] = "NfcTag::storeActivationParams";
1299 mActivationParams_t.mTechParams = mTechParams[0].mode;
1300 mActivationParams_t.mTechLibNfcTypes = mTechLibNfcTypes [0];
1301}
1302/*******************************************************************************
1303**
1304** Function: selectP2p
1305**
1306** Description: Select the preferred P2P technology if there is a choice.
1307**
1308** Returns: None
1309**
1310*******************************************************************************/
1311void NfcTag::selectP2p()
1312{
1313 static const char fn [] = "NfcTag::selectP2p";
1314 UINT8 rfDiscoveryId = 0;
1315
1316 for (int i = 0; i < mNumTechList; i++)
1317 {
1318 //if remote device does not support P2P, just skip it
1319 if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP)
1320 continue;
1321
1322 //if remote device supports tech F;
1323 //tech F is preferred because it is faster than tech A
1324 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F) ||
1325 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_F_ACTIVE) )
1326 {
1327 rfDiscoveryId = mTechHandles[i];
1328 break; //no need to search further
1329 }
1330 else if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
1331 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A_ACTIVE) )
1332 {
1333 //only choose tech A if tech F is unavailable
1334 if (rfDiscoveryId == 0)
1335 rfDiscoveryId = mTechHandles[i];
1336 }
1337 }
1338
1339 if (rfDiscoveryId > 0)
1340 {
1341 ALOGD ("%s: select P2P; target rf discov id=0x%X", fn, rfDiscoveryId);
1342 tNFA_STATUS stat = NFA_Select (rfDiscoveryId, NFA_PROTOCOL_NFC_DEP, NFA_INTERFACE_NFC_DEP);
1343 if (stat != NFA_STATUS_OK)
1344 ALOGE ("%s: fail select P2P; error=0x%X", fn, stat);
nxpandroida9a68ba2016-01-14 21:12:17 +05301345#if(NXP_EXTNS == TRUE)
1346 else
1347 {
1348 mWaitingForSelect = true;
1349 ALOGE ("%s: starting timer", fn);
1350 gSelectCompleteTimer.set(1000, selectCompleteCallBack);
1351 }
1352#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301353 }
1354 else
1355 ALOGE ("%s: cannot find P2P", fn);
1356 resetTechnologies ();
1357}
1358
1359
1360/*******************************************************************************
1361**
1362** Function: resetTechnologies
1363**
1364** Description: Clear all data related to the technology, protocol of the tag.
1365**
1366** Returns: None
1367**
1368*******************************************************************************/
1369void NfcTag::resetTechnologies ()
1370{
1371 static const char fn [] = "NfcTag::resetTechnologies";
1372 ALOGD ("%s", fn);
1373 mNumTechList = 0;
1374 mTechListIndex = 0;
1375 memset (mTechList, 0, sizeof(mTechList));
1376 memset (mTechHandles, 0, sizeof(mTechHandles));
1377 memset (mTechLibNfcTypes, 0, sizeof(mTechLibNfcTypes));
1378 memset (mTechParams, 0, sizeof(mTechParams));
1379 mIsDynamicTagId = false;
1380 mIsFelicaLite = false;
1381 resetAllTransceiveTimeouts ();
nxpandroida9a68ba2016-01-14 21:12:17 +05301382#if(NXP_EXTNS == TRUE)
1383 mNumDiscNtf = 0;
1384#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301385}
1386
1387
1388/*******************************************************************************
1389**
1390** Function: selectFirstTag
1391**
1392** Description: When multiple tags are discovered, just select the first one to activate.
1393**
1394** Returns: None
1395**
1396*******************************************************************************/
1397void NfcTag::selectFirstTag ()
1398{
1399 static const char fn [] = "NfcTag::selectFirstTag";
1400 int foundIdx = -1;
1401 tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
1402
1403 for (int i = 0; i < mNumTechList; i++)
1404 {
1405 ALOGD ("%s: nfa target idx=%d h=0x%X; protocol=0x%X",
1406 fn, i, mTechHandles [i], mTechLibNfcTypes [i]);
1407 if (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP)
1408 {
1409 foundIdx = i;
1410 selectedId = i;
1411 break;
1412 }
1413 }
1414
1415 if (foundIdx != -1)
1416 {
1417 if (mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_ISO_DEP)
1418 {
1419 rf_intf = NFA_INTERFACE_ISO_DEP;
1420 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301421 else if(mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_MIFARE)
1422 {
1423 rf_intf = NFA_INTERFACE_MIFARE;
1424 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301425 else
1426 rf_intf = NFA_INTERFACE_FRAME;
1427
1428 tNFA_STATUS stat = NFA_Select (mTechHandles [foundIdx], mTechLibNfcTypes [foundIdx], rf_intf);
1429 if (stat != NFA_STATUS_OK)
1430 ALOGE ("%s: fail select; error=0x%X", fn, stat);
nxpandroida9a68ba2016-01-14 21:12:17 +05301431#if(NXP_EXTNS == TRUE)
1432 else
1433 {
1434 mWaitingForSelect = true;
1435 gSelectCompleteTimer.set(1000, selectCompleteCallBack);
1436 ALOGE ("%s:starting timer", fn);
1437 }
1438#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301439 }
1440 else
1441 ALOGE ("%s: only found NFC-DEP technology.", fn);
1442}
1443
1444/*******************************************************************************
1445**
1446** Function: checkNextValidProtocol
1447**
1448** Description: When multiple tags are discovered, check next valid protocol
1449**
1450** Returns: id
1451**
1452*******************************************************************************/
1453int NfcTag::checkNextValidProtocol(void)
1454{
1455 static const char fn [] = "NfcTag::checkNextValidProtocol";
1456 ALOGD("%s: enter, mNumDiscTechList=%x", fn, mNumDiscTechList);
1457 int foundIdx = -1;
1458 ALOGD("%s: enter,selectedId=%x", fn, selectedId);
1459 for (int i = 0; i < mNumDiscTechList; i++)
1460 {
1461 ALOGD ("%s: nfa target idx=%d h=0x%X; protocol=0x%X",
1462 fn, i, mTechHandles [i], mTechLibNfcTypes [i]);
1463 if ((mTechHandles[selectedId] != mTechHandles [i]) &&
1464 (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP))
1465 {
1466 foundIdx = i;
1467 break;
1468 }
1469 }
1470 return foundIdx;
1471}
1472
1473 /*******************************************************************************
1474**
1475** Function: selectNextTag
1476**
1477** Description: When multiple tags are discovered, selects the Nex one to activate.
1478**
1479** Returns: None
1480**
1481*******************************************************************************/
1482void NfcTag::selectNextTag ()
1483{
1484 static const char fn [] = "NfcTag::selectNextTag";
1485 int foundIdx = -1;
1486 tNFA_INTF_TYPE rf_intf = NFA_INTERFACE_FRAME;
1487 tNFA_STATUS stat = NFA_STATUS_FAILED;
1488
1489 ALOGD("%s: enter, mNumDiscTechList=%x", fn, mNumDiscTechList);
1490 for (int i = 0; i < mNumDiscTechList; i++)
1491 {
1492 ALOGD ("%s: nfa target idx=%d h=0x%X; protocol=0x%X",
1493 fn, i, mTechHandles [i], mTechLibNfcTypes [i]);
1494 if ((mTechHandles[selectedId] != mTechHandles [i]) &&
1495 (mTechLibNfcTypes[i] != NFA_PROTOCOL_NFC_DEP))
1496 {
1497 selectedId = i;
1498 foundIdx = i;
1499 break;
1500 }
1501 }
1502
1503 if (foundIdx != -1)
1504 {
1505 if (mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_ISO_DEP)
1506 {
1507 rf_intf = NFA_INTERFACE_ISO_DEP;
1508 }
1509 else if(mTechLibNfcTypes [foundIdx] == NFA_PROTOCOL_MIFARE)
1510 {
1511 rf_intf = NFA_INTERFACE_MIFARE;
1512 }
1513 else
1514 rf_intf = NFA_INTERFACE_FRAME;
1515
1516 stat = NFA_Select (mTechHandles [foundIdx], mTechLibNfcTypes [foundIdx], rf_intf);
1517 if (stat == NFA_STATUS_OK)
1518 {
1519 ALOGE ("%s: stat=%x; wait for activated ntf", fn, stat);
nxpandroida9a68ba2016-01-14 21:12:17 +05301520#if(NXP_EXTNS == TRUE)
1521 {
1522 mWaitingForSelect = true;
1523 ALOGE ("%s:starting timer", fn);
1524 gSelectCompleteTimer.set(1000, selectCompleteCallBack);
1525 }
1526#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301527 }
1528 else
1529 ALOGE ("%s: fail select; error=0x%X", fn, stat);
1530 }
1531 else
1532 ALOGE ("%s: only found NFC-DEP technology.", fn);
1533}
1534
1535
1536/*******************************************************************************
1537**
1538** Function: getT1tMaxMessageSize
1539**
1540** Description: Get the maximum size (octet) that a T1T can store.
1541**
1542** Returns: Maximum size in octets.
1543**
1544*******************************************************************************/
1545int NfcTag::getT1tMaxMessageSize ()
1546{
1547 static const char fn [] = "NfcTag::getT1tMaxMessageSize";
1548
1549 if (mProtocol != NFC_PROTOCOL_T1T)
1550 {
1551 ALOGE ("%s: wrong protocol %u", fn, mProtocol);
1552 return 0;
1553 }
1554 return mtT1tMaxMessageSize;
1555}
1556
1557
1558/*******************************************************************************
1559**
1560** Function: calculateT1tMaxMessageSize
1561**
1562** Description: Calculate type-1 tag's max message size based on header ROM bytes.
1563** activate: reference to activation data.
1564**
1565** Returns: None
1566**
1567*******************************************************************************/
1568void NfcTag::calculateT1tMaxMessageSize (tNFA_ACTIVATED& activate)
1569{
1570 static const char fn [] = "NfcTag::calculateT1tMaxMessageSize";
1571
1572 //make sure the tag is type-1
1573 if (activate.activate_ntf.protocol != NFC_PROTOCOL_T1T)
1574 {
1575 mtT1tMaxMessageSize = 0;
1576 return;
1577 }
1578
1579 //examine the first byte of header ROM bytes
1580 switch (activate.params.t1t.hr[0])
1581 {
1582 case RW_T1T_IS_TOPAZ96:
1583 mtT1tMaxMessageSize = 90;
1584 break;
1585 case RW_T1T_IS_TOPAZ512:
1586 mtT1tMaxMessageSize = 462;
1587 break;
1588 default:
1589 ALOGE ("%s: unknown T1T HR0=%u", fn, activate.params.t1t.hr[0]);
1590 mtT1tMaxMessageSize = 0;
1591 break;
1592 }
1593}
1594
1595
1596/*******************************************************************************
1597**
1598** Function: isMifareUltralight
1599**
1600** Description: Whether the currently activated tag is Mifare Ultralight.
1601**
1602** Returns: True if tag is Mifare Ultralight.
1603**
1604*******************************************************************************/
1605bool NfcTag::isMifareUltralight ()
1606{
1607 static const char fn [] = "NfcTag::isMifareUltralight";
1608 bool retval = false;
1609
1610 for (int i =0; i < mNumTechList; i++)
1611 {
1612 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A)
1613 {
1614 //see NFC Digital Protocol, section 4.6.3 (SENS_RES); section 4.8.2 (SEL_RES).
1615 //see "MF0ICU1 Functional specification MIFARE Ultralight", Rev. 3.4 - 4 February 2008,
1616 //section 6.7.
1617 if ( (mTechParams[i].param.pa.sens_res[0] == 0x44) &&
1618 (mTechParams[i].param.pa.sens_res[1] == 0) &&
1619 ( (mTechParams[i].param.pa.sel_rsp == 0) || (mTechParams[i].param.pa.sel_rsp == 0x04) ) &&
1620 (mTechParams[i].param.pa.nfcid1[0] == 0x04) )
1621 {
1622 retval = true;
1623 }
1624 break;
1625 }
1626 }
1627 ALOGD ("%s: return=%u", fn, retval);
1628 return retval;
1629}
1630
1631
1632/*******************************************************************************
1633**
1634** Function: isMifareDESFire
1635**
1636** Description: Whether the currently activated tag is Mifare DESFire.
1637**
1638** Returns: True if tag is Mifare DESFire.
1639**
1640*******************************************************************************/
1641bool NfcTag::isMifareDESFire ()
1642{
1643 static const char fn [] = "NfcTag::isMifareDESFire";
1644 bool retval = false;
1645
1646 for (int i =0; i < mNumTechList; i++)
1647 {
1648 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
1649 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) ||
1650 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A_ACTIVE) )
1651 {
1652 /* DESfire has one sak byte and 2 ATQA bytes */
1653 if ( (mTechParams[i].param.pa.sens_res[0] == 0x44) &&
1654 (mTechParams[i].param.pa.sens_res[1] == 3) &&
1655 (mTechParams[i].param.pa.sel_rsp == 0x20))
1656 {
1657 retval = true;
1658 }
1659 break;
1660 }
1661 }
1662 ALOGD ("%s: return=%u", fn, retval);
1663 return retval;
1664}
1665
1666
1667/*******************************************************************************
1668**
1669** Function: isFelicaLite
1670**
1671** Description: Whether the currently activated tag is Felica Lite.
1672**
1673** Returns: True if tag is Felica Lite.
1674**
1675*******************************************************************************/
1676
1677bool NfcTag::isFelicaLite ()
1678{
1679 return mIsFelicaLite;
1680}
1681
1682
1683/*******************************************************************************
1684**
1685** Function: isT2tNackResponse
1686**
1687** Description: Whether the response is a T2T NACK response.
1688** See NFC Digital Protocol Technical Specification (2010-11-17).
1689** Chapter 9 (Type 2 Tag Platform), section 9.6 (READ).
1690** response: buffer contains T2T response.
1691** responseLen: length of the response.
1692**
1693** Returns: True if the response is NACK
1694**
1695*******************************************************************************/
1696bool NfcTag::isT2tNackResponse (const UINT8* response, UINT32 responseLen)
1697{
1698 static const char fn [] = "NfcTag::isT2tNackResponse";
1699 bool isNack = false;
1700
1701 if (responseLen == 1)
1702 {
1703 if (response[0] == 0xA)
1704 isNack = false; //an ACK response, so definitely not a NACK
1705 else
1706 isNack = true; //assume every value is a NACK
1707 }
1708 ALOGD ("%s: return %u", fn, isNack);
1709 return isNack;
1710}
1711
1712
1713/*******************************************************************************
1714**
1715** Function: isNdefDetectionTimedOut
1716**
1717** Description: Whether NDEF-detection algorithm timed out.
1718**
1719** Returns: True if NDEF-detection algorithm timed out.
1720**
1721*******************************************************************************/
1722bool NfcTag::isNdefDetectionTimedOut ()
1723{
1724 return mNdefDetectionTimedOut;
1725}
1726
1727
1728/*******************************************************************************
1729**
1730** Function: connectionEventHandler
1731**
1732** Description: Handle connection-related events.
1733** event: event code.
1734** data: pointer to event data.
1735**
1736** Returns: None
1737**
1738*******************************************************************************/
1739void NfcTag::connectionEventHandler (UINT8 event, tNFA_CONN_EVT_DATA* data)
1740{
1741 static const char fn [] = "NfcTag::connectionEventHandler";
1742
1743 switch (event)
1744 {
1745 case NFA_DISC_RESULT_EVT:
1746 {
1747 tNFA_DISC_RESULT& disc_result = data->disc_result;
1748 if (disc_result.status == NFA_STATUS_OK)
1749 {
1750 discoverTechnologies (disc_result);
1751 }
1752 }
1753 break;
1754
1755 case NFA_ACTIVATED_EVT:
1756 // Only do tag detection if we are polling and it is not 'EE Direct RF' activation
1757 // (which may happen when we are activated as a tag).
1758 if (data->activated.activate_ntf.rf_tech_param.mode < NCI_DISCOVERY_TYPE_LISTEN_A
1759 && data->activated.activate_ntf.intf_param.type != NFC_INTERFACE_EE_DIRECT_RF)
1760 {
1761 tNFA_ACTIVATED& activated = data->activated;
1762 if (IsSameKovio(activated))
1763 break;
1764 mIsActivated = true;
1765 mProtocol = activated.activate_ntf.protocol;
1766 calculateT1tMaxMessageSize (activated);
1767 discoverTechnologies (activated);
1768 createNativeNfcTag (activated);
1769 }
1770 break;
1771
1772 case NFA_DEACTIVATED_EVT:
1773 mIsActivated = false;
1774 mProtocol = NFC_PROTOCOL_UNKNOWN;
1775 resetTechnologies ();
1776 break;
1777
1778 case NFA_READ_CPLT_EVT:
1779 {
1780 SyncEventGuard g (mReadCompleteEvent);
1781 mReadCompletedStatus = data->status;
1782 mReadCompleteEvent.notifyOne ();
1783 }
1784 break;
1785
1786 case NFA_NDEF_DETECT_EVT:
1787 {
1788 tNFA_NDEF_DETECT& ndef_detect = data->ndef_detect;
1789 mNdefDetectionTimedOut = ndef_detect.status == NFA_STATUS_TIMEOUT;
1790 if (mNdefDetectionTimedOut)
1791 ALOGE ("%s: NDEF detection timed out", fn);
1792 }
1793 break;
1794
1795 case NFA_ACTIVATED_UPDATE_EVT:
1796 {
1797 tNFA_ACTIVATED& activated = data->activated;
1798 mIsActivated = true;
1799 mProtocol = activated.activate_ntf.protocol;
1800 discoverTechnologies (activated);
1801 }
1802 break;
1803 }
1804}
1805
1806
1807/*******************************************************************************
1808**
1809** Function setActive
1810**
1811** Description Sets the active state for the object
1812**
1813** Returns None.
1814**
1815*******************************************************************************/
1816void NfcTag::setActive(bool active)
1817{
1818 mIsActivated = active;
1819}
1820
1821
1822/*******************************************************************************
1823**
1824** Function: isDynamicTagId
1825**
1826** Description: Whether a tag has a dynamic tag ID.
1827**
1828** Returns: True if ID is dynamic.
1829**
1830*******************************************************************************/
1831bool NfcTag::isDynamicTagId ()
1832{
1833 return mIsDynamicTagId &&
1834 (mTechList [0] == TARGET_TYPE_ISO14443_4) && //type-4 tag
1835 (mTechList [1] == TARGET_TYPE_ISO14443_3A); //tech A
1836}
1837
1838
1839/*******************************************************************************
1840**
1841** Function: resetAllTransceiveTimeouts
1842**
1843** Description: Reset all timeouts for all technologies to default values.
1844**
1845** Returns: none
1846**
1847*******************************************************************************/
1848void NfcTag::resetAllTransceiveTimeouts ()
1849{
1850 mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_3A] = 618; //NfcA
1851 mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_3B] = 1000; //NfcB
nxpandroid34627bd2016-05-27 15:52:30 +05301852 mTechnologyTimeoutsTable [TARGET_TYPE_ISO14443_4] = 618; //ISO-DEP
nxpandroid64fd68c2015-09-23 16:45:15 +05301853 mTechnologyTimeoutsTable [TARGET_TYPE_FELICA] = 255; //Felica
1854 mTechnologyTimeoutsTable [TARGET_TYPE_ISO15693] = 1000;//NfcV
1855 mTechnologyTimeoutsTable [TARGET_TYPE_NDEF] = 1000;
1856 mTechnologyTimeoutsTable [TARGET_TYPE_NDEF_FORMATABLE] = 1000;
1857 mTechnologyTimeoutsTable [TARGET_TYPE_MIFARE_CLASSIC] = 618; //MifareClassic
1858 mTechnologyTimeoutsTable [TARGET_TYPE_MIFARE_UL] = 618; //MifareUltralight
1859 mTechnologyTimeoutsTable [TARGET_TYPE_KOVIO_BARCODE] = 1000; //NfcBarcode
1860}
1861
1862/*******************************************************************************
1863**
1864** Function: getTransceiveTimeout
1865**
1866** Description: Get the timeout value for one technology.
1867** techId: one of the values in TARGET_TYPE_* defined in NfcJniUtil.h
1868**
1869** Returns: Timeout value in millisecond.
1870**
1871*******************************************************************************/
1872int NfcTag::getTransceiveTimeout (int techId)
1873{
1874 static const char fn [] = "NfcTag::getTransceiveTimeout";
1875 int retval = 1000;
1876 if ((techId > 0) && (techId < (int) mTechnologyTimeoutsTable.size()))
1877 retval = mTechnologyTimeoutsTable [techId];
1878 else
1879 ALOGE ("%s: invalid tech=%d", fn, techId);
1880 return retval;
1881}
1882
1883
1884/*******************************************************************************
1885**
1886** Function: setTransceiveTimeout
1887**
1888** Description: Set the timeout value for one technology.
1889** techId: one of the values in TARGET_TYPE_* defined in NfcJniUtil.h
1890** timeout: timeout value in millisecond.
1891**
1892** Returns: Timeout value.
1893**
1894*******************************************************************************/
1895void NfcTag::setTransceiveTimeout (int techId, int timeout)
1896{
1897 static const char fn [] = "NfcTag::setTransceiveTimeout";
1898 if ((techId >= 0) && (techId < (int) mTechnologyTimeoutsTable.size()))
1899 mTechnologyTimeoutsTable [techId] = timeout;
1900 else
1901 ALOGE ("%s: invalid tech=%d", fn, techId);
1902}
1903
1904/*******************************************************************************
1905**
1906** Function: isEzLinkTagActivated
1907**
1908** Description: checks if EzLinkTag tag is detected
1909**
1910** Returns: True if tag is activated.
1911**
1912*******************************************************************************/
1913bool NfcTag::isEzLinkTagActivated ()
1914{
1915 static const char fn [] = "NfcTag::isEzLinkTagActivated";
1916 return mEzLinkTypeTag;
1917}
1918
1919/*******************************************************************************
1920**
1921** Function: isCashBeeActivated
1922**
1923** Description: checks if cashbee tag is detected
1924**
1925** Returns: True if tag is activated.
1926**
1927*******************************************************************************/
1928bool NfcTag::isCashBeeActivated ()
1929{
1930 static const char fn [] = "NfcTag::isCashBeeActivated";
1931 return mCashbeeDetected;
1932}
1933
1934/*******************************************************************************
1935**
1936** Function: isTypeBTag
1937**
1938** Description: Whether the currently activated tag is Type B.
1939**
1940** Returns: True if tag is Type B.
1941**
1942*******************************************************************************/
1943bool NfcTag::isTypeBTag ()
1944{
1945 static const char fn [] = "NfcTag::isTypeBTag";
1946 bool retval = false;
1947
1948 for (int i =0; i < mNumTechList; i++)
1949 {
1950 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_B) ||
1951 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_B) )
1952 {
1953 retval = true;
1954 break;
1955 }
1956 }
1957 ALOGD ("%s: return=%u", fn, retval);
1958 return retval;
1959}
1960
1961
1962/*******************************************************************************
1963**
1964** Function: getPresenceCheckAlgorithm
1965**
1966** Description: Get presence-check algorithm from .conf file.
1967**
1968** Returns: Presence-check algorithm.
1969**
1970*******************************************************************************/
1971tNFA_RW_PRES_CHK_OPTION NfcTag::getPresenceCheckAlgorithm ()
1972{
1973 return mPresenceCheckAlgorithm;
1974}
1975
1976
1977/*******************************************************************************
1978**
1979** Function: isInfineonMyDMove
1980**
1981** Description: Whether the currently activated tag is Infineon My-D Move.
1982**
1983** Returns: True if tag is Infineon My-D Move.
1984**
1985*******************************************************************************/
1986bool NfcTag::isInfineonMyDMove ()
1987{
1988 static const char fn [] = "NfcTag::isInfineonMyDMove";
1989 bool retval = false;
1990
1991 for (int i =0; i < mNumTechList; i++)
1992 {
1993 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A)
1994 {
1995 //see Infineon my-d move, my-d move NFC, SLE 66R01P, SLE 66R01PN,
1996 //Short Product Information, 2011-11-24, section 3.5
1997 if (mTechParams[i].param.pa.nfcid1[0] == 0x05)
1998 {
1999 UINT8 highNibble = mTechParams[i].param.pa.nfcid1[1] & 0xF0;
2000 if (highNibble == 0x30)
2001 retval = true;
2002 }
2003 break;
2004 }
2005 }
2006 ALOGD ("%s: return=%u", fn, retval);
2007 return retval;
2008}
2009
2010
2011/*******************************************************************************
2012**
2013** Function: isKovioType2Tag
2014**
2015** Description: Whether the currently activated tag is Kovio Type-2 tag.
2016**
2017** Returns: True if tag is Kovio Type-2 tag.
2018**
2019*******************************************************************************/
2020bool NfcTag::isKovioType2Tag ()
2021{
2022 static const char fn [] = "NfcTag::isKovioType2Tag";
2023 bool retval = false;
2024
2025 for (int i =0; i < mNumTechList; i++)
2026 {
2027 if (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A)
2028 {
2029 //Kovio 2Kb RFID Tag, Functional Specification,
2030 //March 2, 2012, v2.0, section 8.3.
2031 if (mTechParams[i].param.pa.nfcid1[0] == 0x37)
2032 retval = true;
2033 break;
2034 }
2035 }
2036 ALOGD ("%s: return=%u", fn, retval);
2037 return retval;
2038}
2039
2040
2041void NfcTag::getTypeATagUID(UINT8 **uid, UINT32 *len)
2042{
2043 for (int i =0; i < mNumTechList; i++)
2044 {
2045 if ( (mTechParams[i].mode == NFC_DISCOVERY_TYPE_POLL_A) ||
2046 (mTechParams[i].mode == NFC_DISCOVERY_TYPE_LISTEN_A) )
2047 {
2048 *len = mTechParams [i].param.pa.nfcid1_len;
2049 *uid = mTechParams [0].param.pa.nfcid1;
2050 return;
2051 }
2052 }
2053
2054 *len = 0;
2055 *uid = NULL;
2056}
nxpandroida9a68ba2016-01-14 21:12:17 +05302057#if(NXP_EXTNS == TRUE)
2058/*******************************************************************************
2059**
2060** Function: selectCompleteStatus
2061**
2062** Description: Notify whether tag select is success/failure
2063**
2064** Returns: None
2065**
2066*******************************************************************************/
2067void NfcTag::selectCompleteStatus(bool status)
2068{
2069
2070 if(mWaitingForSelect == true)
2071 {
2072 ALOGD ("selectCompleteStatus=%u", status);
2073 gSelectCompleteTimer.kill();
2074 mWaitingForSelect = false;
2075 }
2076}
2077
2078/*******************************************************************************
2079**
2080** Function: selectCompleteCallBack
2081**
2082** Description: CallBack called when tag select is timed out.
2083**
2084** Returns: None
2085**
2086*******************************************************************************/
2087void selectCompleteCallBack(union sigval)
2088{
2089
2090 if(NfcTag::getInstance().mWaitingForSelect == true)
2091 {
2092 ALOGD ("selectCompleteCallBack");
2093 NfcTag::getInstance().mWaitingForSelect = false;
2094 NFA_Deactivate (FALSE);
2095 }
2096}
2097#endif