blob: 357558e4c6fbe10669a0175160137e53ad8f4fc9 [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#include <semaphore.h>
37#include <errno.h>
38#include <time.h>
39#include <signal.h>
40#include "OverrideLog.h"
41#include "NfcJniUtil.h"
42#include "NfcTag.h"
43#include "config.h"
44#include "Mutex.h"
45#include "IntervalTimer.h"
46#include "JavaClassConstants.h"
47#include "Pn544Interop.h"
48#include <ScopedLocalRef.h>
49#include <ScopedPrimitiveArray.h>
50#include <string>
51
52extern "C"
53{
54 #include "nfa_api.h"
55 #include "nfa_rw_api.h"
nxpandroid34627bd2016-05-27 15:52:30 +053056 #include "nfc_brcm_defs.h"
nxpandroid64fd68c2015-09-23 16:45:15 +053057 #include "ndef_utils.h"
58 #include "rw_api.h"
59 #include "phNxpExtns.h"
60}
61namespace android
62{
63 extern nfc_jni_native_data* getNative(JNIEnv *e, jobject o);
64 extern bool nfcManager_isNfcActive();
nxpandroid64fd68c2015-09-23 16:45:15 +053065 extern UINT16 getrfDiscoveryDuration();
66}
67
68extern bool gActivated;
69extern SyncEvent gDeactivatedEvent;
70
71/*****************************************************************************
72**
73** public variables and functions
74**
75*****************************************************************************/
76namespace android
77{
78 bool gIsTagDeactivating = false; // flag for nfa callback indicating we are deactivating for RF interface switch
79 bool gIsSelectingRfInterface = false; // flag for nfa callback indicating we are selecting for RF interface switch
80 bool fNeedToSwitchBack = false;
81 void acquireRfInterfaceMutexLock();
82 void releaseRfInterfaceMutexLock();
83}
84
85
86/*****************************************************************************
87**
88** private variables and functions
89**
90*****************************************************************************/
91namespace android
92{
93
94
95// Pre-defined tag type values. These must match the values in
96// framework Ndef.java for Google public NFC API.
nxpandroid7d44e572016-08-01 19:11:04 +053097#define NDEF_UNKNOWN_TYPE (-1)
nxpandroid64fd68c2015-09-23 16:45:15 +053098#define NDEF_TYPE1_TAG 1
99#define NDEF_TYPE2_TAG 2
100#define NDEF_TYPE3_TAG 3
101#define NDEF_TYPE4_TAG 4
102#define NDEF_MIFARE_CLASSIC_TAG 101
103
104/*Below #defines are made to make libnfc-nci as AOSP*/
105#ifndef NCI_INTERFACE_MIFARE
106#define NCI_INTERFACE_MIFARE 0x80
107#endif
108#undef NCI_PROTOCOL_MIFARE
109#define NCI_PROTOCOL_MIFARE 0x80
110
111
112#define STATUS_CODE_TARGET_LOST 146 // this error code comes from the service
113
114static uint32_t sCheckNdefCurrentSize = 0;
115static tNFA_STATUS sCheckNdefStatus = 0; //whether tag already contains a NDEF message
116static bool sCheckNdefCapable = false; //whether tag has NDEF capability
117static tNFA_HANDLE sNdefTypeHandlerHandle = NFA_HANDLE_INVALID;
118tNFA_INTF_TYPE sCurrentRfInterface = NFA_INTERFACE_ISO_DEP;
119static std::basic_string<UINT8> sRxDataBuffer;
120static tNFA_STATUS sRxDataStatus = NFA_STATUS_OK;
121static bool sWaitingForTransceive = false;
122static bool sTransceiveRfTimeout = false;
123static Mutex sRfInterfaceMutex;
124static uint32_t sReadDataLen = 0;
125static tNFA_STATUS sReadStatus;
126static uint8_t* sReadData = NULL;
127static bool sIsReadingNdefMessage = false;
128static SyncEvent sReadEvent;
129static sem_t sWriteSem;
130static sem_t sFormatSem;
131static SyncEvent sTransceiveEvent;
132static SyncEvent sReconnectEvent;
133static sem_t sCheckNdefSem;
134static SyncEvent sPresenceCheckEvent;
135static sem_t sMakeReadonlySem;
136static IntervalTimer sSwitchBackTimer; // timer used to tell us to switch back to ISO_DEP frame interface
137static IntervalTimer sPresenceCheckTimer; // timer used for presence cmd notification timeout.
138static IntervalTimer sReconnectNtfTimer ;
139static jboolean sWriteOk = JNI_FALSE;
140static jboolean sWriteWaitingForComplete = JNI_FALSE;
141static bool sFormatOk = false;
142static bool sReadOnlyOk = false;
nxpandroid1153eb32015-11-06 18:46:58 +0530143#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530144static bool sNeedToSwitchRf = false;
145#endif
146static jboolean sConnectOk = JNI_FALSE;
147static jboolean sConnectWaitingForComplete = JNI_FALSE;
148static bool sGotDeactivate = false;
149static uint32_t sCheckNdefMaxSize = 0;
150static bool sCheckNdefCardReadOnly = false;
151static jboolean sCheckNdefWaitingForComplete = JNI_FALSE;
152static bool sIsTagPresent = true;
153static tNFA_STATUS sMakeReadonlyStatus = NFA_STATUS_FAILED;
154static jboolean sMakeReadonlyWaitingForComplete = JNI_FALSE;
155static int sCurrentConnectedTargetType = TARGET_TYPE_UNKNOWN;
nxpandroid34627bd2016-05-27 15:52:30 +0530156static int sCurrentConnectedTargetProtocol = NFC_PROTOCOL_UNKNOWN;
nxpandroid64fd68c2015-09-23 16:45:15 +0530157static int sCurrentConnectedHandle;
158static SyncEvent sNfaVSCResponseEvent;
159static SyncEvent sNfaVSCNotificationEvent;
160static bool sIsTagInField;
161static bool sVSCRsp;
162static bool sReconnectFlag = false;
163static int reSelect (tNFA_INTF_TYPE rfInterface, bool fSwitchIfNeeded);
164static bool switchRfInterface(tNFA_INTF_TYPE rfInterface);
165static bool setNdefDetectionTimeoutIfTagAbsent (JNIEnv *e, jobject o, tNFC_PROTOCOL protocol);
166static void setNdefDetectionTimeout ();
167static jboolean nativeNfcTag_doPresenceCheck (JNIEnv*, jobject);
nxpandroid1153eb32015-11-06 18:46:58 +0530168#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530169uint8_t key1[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
170uint8_t key2[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
171bool isMifare = false;
172static uint8_t Presence_check_TypeB[] = {0xB2};
173#if(NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid1153eb32015-11-06 18:46:58 +0530174static UINT16 NON_NCI_CARD_TIMER_OFFSET =700;
nxpandroid64fd68c2015-09-23 16:45:15 +0530175static IntervalTimer sNonNciCardDetectionTimer;
176static IntervalTimer sNonNciMultiCardDetectionTimer;
177struct sNonNciCard{
178 bool chinaTransp_Card;
179 bool Changan_Card;
180 UINT8 sProtocolType;
181 UINT8 srfInterfaceType;
182 UINT32 uidlen;
183 UINT8 uid[12];
184} sNonNciCard_t;
185bool scoreGenericNtf = false;
186void nativeNfcTag_cacheNonNciCardDetection();
187void nativeNfcTag_handleNonNciCardDetection(tNFA_CONN_EVT_DATA* eventData);
188void nativeNfcTag_handleNonNciMultiCardDetection(UINT8 connEvent, tNFA_CONN_EVT_DATA* eventData);
189static void nonNciCardTimerProc(union sigval);
190static void nonNciMultiCardTimerProc(union sigval);
191uint8_t checkTagNtf = 0;
192uint8_t checkCmdSent = 0;
193#endif
194#endif
195static bool sIsReconnecting = false;
196static int doReconnectFlag = 0x00;
197static bool sIsCheckingNDef = false;
198
199static void nfaVSCCallback(UINT8 event, UINT16 param_len, UINT8 *p_param);
200static void nfaVSCNtfCallback(UINT8 event, UINT16 param_len, UINT8 *p_param);
201static void presenceCheckTimerProc (union sigval);
202static void sReconnectTimerProc(union sigval);
203
204static void nfaVSCNtfCallback(UINT8 event, UINT16 param_len, UINT8 *p_param)
205{
206 (void)event;
207 ALOGD ("%s", __FUNCTION__);
208 if(param_len == 4 && p_param[3] == 0x01)
209 {
210 sIsTagInField = true;
211 }
212 else
213 {
214 sIsTagInField = false;
215 }
216
217 ALOGD ("%s is Tag in Field = %d", __FUNCTION__, sIsTagInField);
218 usleep(100*1000);
219 SyncEventGuard guard (sNfaVSCNotificationEvent);
220 sNfaVSCNotificationEvent.notifyOne ();
221}
222
223static void nfaVSCCallback(UINT8 event, UINT16 param_len, UINT8 *p_param)
224{
225 (void)event;
226 ALOGD ("%s", __FUNCTION__);
227 ALOGD ("%s param_len = %d ", __FUNCTION__, param_len);
228 ALOGD ("%s p_param = %d ", __FUNCTION__, *p_param);
229
230 if(param_len == 4 && p_param[3] == 0x00)
231 {
232 ALOGD ("%s sVSCRsp = true", __FUNCTION__);
233
234 sVSCRsp = true;
235 }
236 else
237 {
238 ALOGD ("%s sVSCRsp = false", __FUNCTION__);
239
240 sVSCRsp = false;
241 }
242
243 ALOGD ("%s sVSCRsp = %d", __FUNCTION__, sVSCRsp);
244
245
246 SyncEventGuard guard (sNfaVSCResponseEvent);
247 sNfaVSCResponseEvent.notifyOne ();
248}
249
250/*******************************************************************************
251**
252** Function: nativeNfcTag_abortWaits
253**
254** Description: Unblock all thread synchronization objects.
255**
256** Returns: None
257**
258*******************************************************************************/
259void nativeNfcTag_abortWaits ()
260{
261 ALOGD ("%s", __FUNCTION__);
262 {
263 SyncEventGuard g (sReadEvent);
264 sReadEvent.notifyOne ();
265 }
266 sem_post (&sWriteSem);
267 sem_post (&sFormatSem);
268 {
269 SyncEventGuard g (sTransceiveEvent);
270 sTransceiveEvent.notifyOne ();
271 }
272 {
273 SyncEventGuard g (sReconnectEvent);
274 sReconnectEvent.notifyOne ();
275 }
276
277 sem_post (&sCheckNdefSem);
278 {
279 SyncEventGuard guard (sPresenceCheckEvent);
280 sPresenceCheckEvent.notifyOne ();
281 }
282 sem_post (&sMakeReadonlySem);
283 sCurrentRfInterface = NFA_INTERFACE_ISO_DEP;
284 sCurrentConnectedTargetType = TARGET_TYPE_UNKNOWN;
nxpandroid34627bd2016-05-27 15:52:30 +0530285 sCurrentConnectedTargetProtocol = NFC_PROTOCOL_UNKNOWN;
nxpandroid64fd68c2015-09-23 16:45:15 +0530286}
287
288
289/*******************************************************************************
290**
291** Function: nativeNfcTag_doReadCompleted
292**
293** Description: Receive the completion status of read operation. Called by
294** NFA_READ_CPLT_EVT.
295** status: Status of operation.
296**
297** Returns: None
298**
299*******************************************************************************/
300void nativeNfcTag_doReadCompleted (tNFA_STATUS status)
301{
302 ALOGD ("%s: status=0x%X; is reading=%u", __FUNCTION__, status, sIsReadingNdefMessage);
303
304 if (sIsReadingNdefMessage == false)
305 return; //not reading NDEF message right now, so just return
306
307 sReadStatus = status;
308 if (status != NFA_STATUS_OK)
309 {
310 sReadDataLen = 0;
311 if (sReadData)
312 free (sReadData);
313 sReadData = NULL;
314 }
315 SyncEventGuard g (sReadEvent);
316 sReadEvent.notifyOne ();
317}
318
nxpandroid34627bd2016-05-27 15:52:30 +0530319/*******************************************************************************
320 **
321** Function: nativeNfcTag_setRfInterface
322**
323** Description: Set rf interface.
324**
325** Returns: void
326**
327*******************************************************************************/
328void nativeNfcTag_setRfInterface (tNFA_INTF_TYPE rfInterface)
329{
330 sCurrentRfInterface = rfInterface;
331}
nxpandroid64fd68c2015-09-23 16:45:15 +0530332
333/*******************************************************************************
334**
335** Function: ndefHandlerCallback
336**
337** Description: Receive NDEF-message related events from stack.
338** event: Event code.
339** p_data: Event data.
340**
341** Returns: None
342**
343*******************************************************************************/
344static void ndefHandlerCallback (tNFA_NDEF_EVT event, tNFA_NDEF_EVT_DATA *eventData)
345{
346 ALOGD ("%s: event=%u, eventData=%p", __FUNCTION__, event, eventData);
347
348 switch (event)
349 {
350 case NFA_NDEF_REGISTER_EVT:
351 {
352 tNFA_NDEF_REGISTER& ndef_reg = eventData->ndef_reg;
353 ALOGD ("%s: NFA_NDEF_REGISTER_EVT; status=0x%X; h=0x%X", __FUNCTION__, ndef_reg.status, ndef_reg.ndef_type_handle);
354 sNdefTypeHandlerHandle = ndef_reg.ndef_type_handle;
355 }
356 break;
357
358 case NFA_NDEF_DATA_EVT:
359 {
360 ALOGD ("%s: NFA_NDEF_DATA_EVT; data_len = %lu", __FUNCTION__, eventData->ndef_data.len);
361 sReadDataLen = eventData->ndef_data.len;
362 sReadData = (uint8_t*) malloc (sReadDataLen);
nxpandroida9a68ba2016-01-14 21:12:17 +0530363 if(sReadData != NULL)
nxpandroid64fd68c2015-09-23 16:45:15 +0530364 memcpy (sReadData, eventData->ndef_data.p_data, eventData->ndef_data.len);
365 }
366 break;
367
368 default:
369 ALOGE ("%s: Unknown event %u ????", __FUNCTION__, event);
370 break;
371 }
372}
373
374
375/*******************************************************************************
376**
377** Function: nativeNfcTag_doRead
378**
379** Description: Read the NDEF message on the tag.
380** e: JVM environment.
381** o: Java object.
382**
383** Returns: NDEF message.
384**
385*******************************************************************************/
386static jbyteArray nativeNfcTag_doRead (JNIEnv* e, jobject o)
387{
388 ALOGD ("%s: enter", __FUNCTION__);
389 tNFA_STATUS status = NFA_STATUS_FAILED;
390 jbyteArray buf = NULL;
nxpandroid64fd68c2015-09-23 16:45:15 +0530391
392 sReadStatus = NFA_STATUS_OK;
393 sReadDataLen = 0;
394 if (sReadData != NULL)
395 {
396 free (sReadData);
397 sReadData = NULL;
398 }
399
400 if (sCheckNdefCurrentSize > 0)
401 {
402 {
403 SyncEventGuard g (sReadEvent);
404 sIsReadingNdefMessage = true;
nxpandroid34627bd2016-05-27 15:52:30 +0530405 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530406 {
nxpandroid34627bd2016-05-27 15:52:30 +0530407 status = EXTNS_MfcReadNDef ();
nxpandroid64fd68c2015-09-23 16:45:15 +0530408 }
409 else
410 {
411 status = NFA_RwReadNDef ();
412 }
413 sReadEvent.wait (); //wait for NFA_READ_CPLT_EVT
414 }
415 sIsReadingNdefMessage = false;
416
417 if (sReadDataLen > 0) //if stack actually read data from the tag
418 {
419 ALOGD ("%s: read %u bytes", __FUNCTION__, sReadDataLen);
420 buf = e->NewByteArray (sReadDataLen);
421 e->SetByteArrayRegion (buf, 0, sReadDataLen, (jbyte*) sReadData);
422 }
423 if (sReadStatus == NFA_STATUS_TIMEOUT)
424 setNdefDetectionTimeout();
425 else if (sReadStatus == NFA_STATUS_FAILED)
426 (void)setNdefDetectionTimeoutIfTagAbsent(e, o, NFA_PROTOCOL_ISO15693);
427 }
428 else
429 {
430 ALOGD ("%s: create empty buffer", __FUNCTION__);
431 sReadDataLen = 0;
432 sReadData = (uint8_t*) malloc (1);
433 buf = e->NewByteArray (sReadDataLen);
434 e->SetByteArrayRegion (buf, 0, sReadDataLen, (jbyte*) sReadData);
435 }
436
437 if (sReadData)
438 {
439 free (sReadData);
440 sReadData = NULL;
441 }
442 sReadDataLen = 0;
443
444 ALOGD ("%s: exit", __FUNCTION__);
445 return buf;
446}
447
448
449/*******************************************************************************
450**
451** Function: nativeNfcTag_doWriteStatus
452**
453** Description: Receive the completion status of write operation. Called
454** by NFA_WRITE_CPLT_EVT.
455** isWriteOk: Status of operation.
456**
457** Returns: None
458**
459*******************************************************************************/
460void nativeNfcTag_doWriteStatus (jboolean isWriteOk)
461{
462 if (sWriteWaitingForComplete != JNI_FALSE)
463 {
464 sWriteWaitingForComplete = JNI_FALSE;
465 sWriteOk = isWriteOk;
466 sem_post (&sWriteSem);
467 }
468}
nxpandroid1153eb32015-11-06 18:46:58 +0530469#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530470/*******************************************************************************
471**
472** Function: nonNciCardTimerProc
473**
474** Description: CallBack timer for Non nci card detection.
475**
476**
477**
478** Returns: None
479**
480*******************************************************************************/
481void nonNciCardTimerProc(union sigval)
482{
483 ALOGD ("%s: enter ", __FUNCTION__);
484 memset(&sNonNciCard_t,0,sizeof(sNonNciCard));
485 scoreGenericNtf = false;
486}
487
488/*******************************************************************************
489**
490** Function: nonNciMultiCardTimerProc
491**
492** Description: CallBack timer for Non nci Multi card detection.
493**
494**
495**
496** Returns: None
497**
498*******************************************************************************/
499void nonNciMultiCardTimerProc(union sigval)
500{
501 ALOGD ("%s: enter ", __FUNCTION__);
502 checkTagNtf = 0;
503 checkCmdSent = 0;
504}
505
506/*******************************************************************************
507**
508** Function: nativeNfcTag_cacheChinaBeijingCardDetection
509**
510** Description: Store the China Beijing Card detection parameters
511**
512** Returns: None
513**
514*******************************************************************************/
515void nativeNfcTag_cacheNonNciCardDetection()
516{
517 NfcTag& natTag = NfcTag::getInstance ();
518 static UINT32 cardDetectTimeout = 0;
519 static UINT8 *uid;
520 scoreGenericNtf = true;
521 NfcTag::getInstance().getTypeATagUID(&uid ,&sNonNciCard_t.uidlen);
522 memcpy(sNonNciCard_t.uid ,uid ,sNonNciCard_t.uidlen);
523 sNonNciCard_t.sProtocolType = natTag.mTechLibNfcTypes[sCurrentConnectedHandle];
524 sNonNciCard_t.srfInterfaceType = sCurrentRfInterface;
525 cardDetectTimeout = NON_NCI_CARD_TIMER_OFFSET + android::getrfDiscoveryDuration();
526 ALOGD ("%s: cardDetectTimeout = %d", __FUNCTION__,cardDetectTimeout);
527 sNonNciCardDetectionTimer.set(cardDetectTimeout, nonNciCardTimerProc);
528 ALOGD ("%s: sNonNciCard_t.sProtocolType=0x%x sNonNciCard_t.srfInterfaceType =0x%x ", __FUNCTION__,sNonNciCard_t.sProtocolType, sNonNciCard_t.srfInterfaceType);
529}
530/*******************************************************************************
531**
532** Function: nativeNfcTag_handleChinaBeijingCardDetection
533**
534** Description: China Beijing Card activation
535**
536** Returns: None
537**
538*******************************************************************************/
539void nativeNfcTag_handleNonNciCardDetection(tNFA_CONN_EVT_DATA* eventData)
540{
541 ALOGD ("%s: enter ", __FUNCTION__);
542 sNonNciCardDetectionTimer.kill();
543 static UINT32 tempUidLen = 0x00;
544 static UINT8 *tempUid;
545 NfcTag::getInstance().getTypeATagUID(&tempUid, &tempUidLen);
546 if((eventData->activated.activate_ntf.intf_param.type == sNonNciCard_t.srfInterfaceType) && ( eventData->activated.activate_ntf.protocol == sNonNciCard_t.sProtocolType))
547 {
548 if((tempUidLen == sNonNciCard_t.uidlen) && (memcmp(tempUid, sNonNciCard_t.uid, tempUidLen) == 0x00) )
549 {
550 sNonNciCard_t.chinaTransp_Card = true;
551 ALOGD ("%s: sNonNciCard_t.chinaTransp_Card = true", __FUNCTION__);
552 }
553 }
554 else if((sNonNciCard_t.srfInterfaceType == NFC_INTERFACE_FRAME) && ( eventData->activated.activate_ntf.protocol == sNonNciCard_t.sProtocolType))
555 {
556 if((tempUidLen == sNonNciCard_t.uidlen) && (memcmp(tempUid, sNonNciCard_t.uid, tempUidLen) == 0x00) )
557 {
558 sNonNciCard_t.Changan_Card = true;
559 ALOGD ("%s: sNonNciCard_t.Changan_Card = true", __FUNCTION__);
560 }
561 }
562 ALOGD ("%s: eventData->activated.activate_ntf.protocol =0x%x eventData->activated.activate_ntf.intf_param.type =0x%x", __FUNCTION__,eventData->activated.activate_ntf.protocol, eventData->activated.activate_ntf.intf_param.type);
563}
564
565/*******************************************************************************
566**
567** Function: nativeNfcTag_handleChinaMultiCardDetection
568**
569** Description: Multiprotocol Card activation
570**
571** Returns: None
572**
573*******************************************************************************/
574void nativeNfcTag_handleNonNciMultiCardDetection(UINT8 connEvent, tNFA_CONN_EVT_DATA* eventData)
575{
576 ALOGD ("%s: enter ", __FUNCTION__);
577 if(NfcTag::getInstance ().mNumDiscNtf)
578 {
579 ALOGD("%s: check_tag_ntf = %d, check_cmd_sent = %d", __FUNCTION__ ,checkTagNtf,checkCmdSent);
580 if(checkTagNtf == 0)
581 {
582 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
583 NFA_Deactivate (TRUE);
584 checkCmdSent = 1;
585 sNonNciMultiCardDetectionTimer.set(NON_NCI_CARD_TIMER_OFFSET, nonNciCardTimerProc);
586 }
587 else if(checkTagNtf == 1)
588 {
589 NfcTag::getInstance ().mNumDiscNtf = 0;
590 checkTagNtf = 0;
591 checkCmdSent = 0;
592 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
593 }
594 }
595 else
596 {
597 NfcTag::getInstance().connectionEventHandler (connEvent, eventData);
598 }
599}
600/*******************************************************************************
601**
602** Function: switchBackTimerProc
603**
604** Description: Callback function for interval timer.
605**
606** Returns: None
607**
608*******************************************************************************/
609static void switchBackTimerProc (union sigval)
610{
611 ALOGD ("%s", __FUNCTION__);
612 switchRfInterface(NFA_INTERFACE_ISO_DEP);
613}
614#endif
615
616/*******************************************************************************
617**
618** Function: nativeNfcTag_formatStatus
619**
620** Description: Receive the completion status of format operation. Called
621** by NFA_FORMAT_CPLT_EVT.
622** isOk: Status of operation.
623**
624** Returns: None
625**
626*******************************************************************************/
627void nativeNfcTag_formatStatus (bool isOk)
628{
629 sFormatOk = isOk;
630 sem_post (&sFormatSem);
631}
632
633
634/*******************************************************************************
635**
636** Function: nativeNfcTag_doWrite
637**
638** Description: Write a NDEF message to the tag.
639** e: JVM environment.
640** o: Java object.
641** buf: Contains a NDEF message.
642**
643** Returns: True if ok.
644**
645*******************************************************************************/
646static jboolean nativeNfcTag_doWrite (JNIEnv* e, jobject, jbyteArray buf)
647{
648 jboolean result = JNI_FALSE;
649 tNFA_STATUS status = 0;
650 const int maxBufferSize = 1024;
651 UINT8 buffer[maxBufferSize] = { 0 };
652 UINT32 curDataSize = 0;
653 int handle = sCurrentConnectedHandle;
654
655 ScopedByteArrayRO bytes(e, buf);
656 UINT8* p_data = const_cast<UINT8*>(reinterpret_cast<const UINT8*>(&bytes[0])); // TODO: const-ness API bug in NFA_RwWriteNDef!
657
658 ALOGD ("%s: enter; len = %zu", __FUNCTION__, bytes.size());
659
660 /* Create the write semaphore */
661 if (sem_init (&sWriteSem, 0, 0) == -1)
662 {
663 ALOGE ("%s: semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno);
664 return JNI_FALSE;
665 }
666
667 sWriteWaitingForComplete = JNI_TRUE;
668 if (sCheckNdefStatus == NFA_STATUS_FAILED)
669 {
670 //if tag does not contain a NDEF message
671 //and tag is capable of storing NDEF message
672 if (sCheckNdefCapable)
673 {
nxpandroid1153eb32015-11-06 18:46:58 +0530674#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530675 isMifare = false;
676#endif
677 ALOGD ("%s: try format", __FUNCTION__);
678 sem_init (&sFormatSem, 0, 0);
679 sFormatOk = false;
nxpandroid34627bd2016-05-27 15:52:30 +0530680 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530681 {
nxpandroid1153eb32015-11-06 18:46:58 +0530682#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530683 isMifare = true;
684 status = EXTNS_MfcFormatTag(key1,sizeof(key1));
685#endif
686 }
687 else
688 {
689 status = NFA_RwFormatTag ();
690 }
691 sem_wait (&sFormatSem);
692 sem_destroy (&sFormatSem);
693
nxpandroid1153eb32015-11-06 18:46:58 +0530694#if(NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530695 if(isMifare == true && sFormatOk != true)
696 {
697 sem_init (&sFormatSem, 0, 0);
698
699 status = EXTNS_MfcFormatTag(key2,sizeof(key2));
700 sem_wait (&sFormatSem);
701 sem_destroy (&sFormatSem);
702 }
703#endif
704
705 if (sFormatOk == false) //if format operation failed
706 goto TheEnd;
707 }
708 ALOGD ("%s: try write", __FUNCTION__);
709 status = NFA_RwWriteNDef (p_data, bytes.size());
710 }
711 else if (bytes.size() == 0)
712 {
713 //if (NXP TagWriter wants to erase tag) then create and write an empty ndef message
714 NDEF_MsgInit (buffer, maxBufferSize, &curDataSize);
715 status = NDEF_MsgAddRec (buffer, maxBufferSize, &curDataSize, NDEF_TNF_EMPTY, NULL, 0, NULL, 0, NULL, 0);
716 ALOGD ("%s: create empty ndef msg; status=%u; size=%lu", __FUNCTION__, status, curDataSize);
nxpandroid34627bd2016-05-27 15:52:30 +0530717 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530718 {
nxpandroid34627bd2016-05-27 15:52:30 +0530719 status = EXTNS_MfcWriteNDef (buffer, curDataSize);
nxpandroid64fd68c2015-09-23 16:45:15 +0530720 }
721 else
722 {
723 status = NFA_RwWriteNDef (buffer, curDataSize);
724 }
725 }
726 else
727 {
728 ALOGD ("%s: NFA_RwWriteNDef", __FUNCTION__);
nxpandroid34627bd2016-05-27 15:52:30 +0530729 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530730 {
nxpandroid34627bd2016-05-27 15:52:30 +0530731 status = EXTNS_MfcWriteNDef (p_data, bytes.size());
nxpandroid64fd68c2015-09-23 16:45:15 +0530732 }
733 else
734 {
735 status = NFA_RwWriteNDef (p_data, bytes.size());
736 }
737 }
738
739 if (status != NFA_STATUS_OK)
740 {
741 ALOGE ("%s: write/format error=%d", __FUNCTION__, status);
742 goto TheEnd;
743 }
744
745 /* Wait for write completion status */
746 sWriteOk = false;
747 if (sem_wait (&sWriteSem))
748 {
749 ALOGE ("%s: wait semaphore (errno=0x%08x)", __FUNCTION__, errno);
750 goto TheEnd;
751 }
752
753 result = sWriteOk;
754
755TheEnd:
756 /* Destroy semaphore */
757 if (sem_destroy (&sWriteSem))
758 {
759 ALOGE ("%s: failed destroy semaphore (errno=0x%08x)", __FUNCTION__, errno);
760 }
761 sWriteWaitingForComplete = JNI_FALSE;
762 ALOGD ("%s: exit; result=%d", __FUNCTION__, result);
763 return result;
764}
765
766/*******************************************************************************
767**
768** Function: setNdefDetectionTimeoutIfTagAbsent
769**
770** Description: Check protocol / presence of a tag which cannot detect tag lost during
771** NDEF check. If it is absent, set NDEF detection timed out state.
772**
773** Returns: True if a tag is absent and a current protocol matches the given protocols.
774**
775*******************************************************************************/
776static bool setNdefDetectionTimeoutIfTagAbsent (JNIEnv *e, jobject o, tNFC_PROTOCOL protocol)
777{
778 if (!(NfcTag::getInstance().getProtocol() & protocol))
779 return false;
780
781 if (nativeNfcTag_doPresenceCheck(e, o))
782 return false;
783
784 ALOGD ("%s: tag is not present. set NDEF detection timed out", __FUNCTION__);
785 setNdefDetectionTimeout();
786 return true;
787}
788
789/*******************************************************************************
790**
791** Function: setNdefDetectionTimeout
792**
793** Description: Set the flag which indicates whether NDEF detection algorithm
794** timed out so that the tag is regarded as lost.
795**
796** Returns: None
797**
798*******************************************************************************/
799static void setNdefDetectionTimeout ()
800{
801 tNFA_CONN_EVT_DATA conn_evt_data;
802
803 conn_evt_data.status = NFA_STATUS_TIMEOUT;
804 conn_evt_data.ndef_detect.cur_size = 0;
805 conn_evt_data.ndef_detect.max_size = 0;
806 conn_evt_data.ndef_detect.flags = RW_NDEF_FL_UNKNOWN;
807
808 NfcTag::getInstance().connectionEventHandler(NFA_NDEF_DETECT_EVT, &conn_evt_data);
809}
810
811/*******************************************************************************
812**
813** Function: nativeNfcTag_doConnectStatus
814**
815** Description: Receive the completion status of connect operation.
816** isConnectOk: Status of the operation.
817**
818** Returns: None
819**
820*******************************************************************************/
821void nativeNfcTag_doConnectStatus (jboolean isConnectOk)
822{
823 if (EXTNS_GetConnectFlag() == TRUE)
824 {
nxpandroid34627bd2016-05-27 15:52:30 +0530825 EXTNS_MfcActivated ();
nxpandroid64fd68c2015-09-23 16:45:15 +0530826 EXTNS_SetConnectFlag (FALSE);
827 return;
828 }
829
830 if (sConnectWaitingForComplete != JNI_FALSE)
831 {
832 sConnectWaitingForComplete = JNI_FALSE;
833 sConnectOk = isConnectOk;
834 SyncEventGuard g (sReconnectEvent);
835 sReconnectEvent.notifyOne ();
836 }
837}
838
839
840/*******************************************************************************
841**
842** Function: nativeNfcTag_doDeactivateStatus
843**
844** Description: Receive the completion status of deactivate operation.
845**
846** Returns: None
847**
848*******************************************************************************/
849void nativeNfcTag_doDeactivateStatus (int status)
850{
851 if(EXTNS_GetDeactivateFlag() == TRUE)
852 {
nxpandroid34627bd2016-05-27 15:52:30 +0530853 EXTNS_MfcDisconnect ();
854 EXTNS_SetDeactivateFlag (FALSE);
nxpandroid64fd68c2015-09-23 16:45:15 +0530855 return;
856 }
857
858 sGotDeactivate = (status == 0);
859
860 SyncEventGuard g (sReconnectEvent);
861 sReconnectEvent.notifyOne ();
862}
863
864
865/*******************************************************************************
866**
867** Function: nativeNfcTag_doConnect
868**
869** Description: Connect to the tag in RF field.
870** e: JVM environment.
871** o: Java object.
872** targetHandle: Handle of the tag.
873**
874** Returns: Must return NXP status code, which NFC service expects.
875**
876*******************************************************************************/
877static jint nativeNfcTag_doConnect (JNIEnv*, jobject, jint targetHandle)
878{
879 ALOGD ("%s: targetHandle = %d", __FUNCTION__, targetHandle);
880 int i = targetHandle;
881 NfcTag& natTag = NfcTag::getInstance ();
882 int retCode = NFCSTATUS_SUCCESS;
nxpandroid34627bd2016-05-27 15:52:30 +0530883 sCurrentConnectedTargetType = natTag.mTechList[i];
884 sCurrentConnectedTargetProtocol = natTag.mTechLibNfcTypes[i];
nxpandroid64fd68c2015-09-23 16:45:15 +0530885
886 if (i >= NfcTag::MAX_NUM_TECHNOLOGY)
887 {
888 ALOGE ("%s: Handle not found", __FUNCTION__);
889 retCode = NFCSTATUS_FAILED;
890 goto TheEnd;
891 }
nxpandroid1153eb32015-11-06 18:46:58 +0530892#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530893 sNeedToSwitchRf = false;
894#endif
895 if (natTag.getActivationState() != NfcTag::Active)
896 {
897 ALOGE ("%s: tag already deactivated", __FUNCTION__);
898 retCode = NFCSTATUS_FAILED;
899 goto TheEnd;
900 }
nxpandroid1153eb32015-11-06 18:46:58 +0530901#if(NXP_EXTNS == TRUE)
nxpandroida9a68ba2016-01-14 21:12:17 +0530902 sCurrentConnectedHandle = targetHandle;
nxpandroid34627bd2016-05-27 15:52:30 +0530903 if(sCurrentConnectedTargetProtocol == NFC_PROTOCOL_T3BT)
nxpandroid64fd68c2015-09-23 16:45:15 +0530904 {
905 goto TheEnd;
906 }
907#endif
nxpandroid34627bd2016-05-27 15:52:30 +0530908
909 if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP)
nxpandroid64fd68c2015-09-23 16:45:15 +0530910 {
nxpandroid34627bd2016-05-27 15:52:30 +0530911 ALOGD ("%s() Nfc type = %d, do nothing for non ISO_DEP", __FUNCTION__, sCurrentConnectedTargetProtocol);
nxpandroid64fd68c2015-09-23 16:45:15 +0530912 retCode = NFCSTATUS_SUCCESS;
913 goto TheEnd;
914 }
915 /* Switching is required for CTS protocol paramter test case.*/
nxpandroid34627bd2016-05-27 15:52:30 +0530916 if (sCurrentConnectedTargetType == TARGET_TYPE_ISO14443_3A || sCurrentConnectedTargetType == TARGET_TYPE_ISO14443_3B)
nxpandroid64fd68c2015-09-23 16:45:15 +0530917 {
nxpandroid34627bd2016-05-27 15:52:30 +0530918 ALOGD ("%s: switching to tech: %d need to switch rf intf to frame", __FUNCTION__, sCurrentConnectedTargetType);
nxpandroid1153eb32015-11-06 18:46:58 +0530919#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530920 if(sNonNciCard_t.Changan_Card == true)
921 sNeedToSwitchRf = true;
922 else
923#endif
924 retCode = switchRfInterface(NFA_INTERFACE_FRAME) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
925 }
926 else
927 {
928 retCode = switchRfInterface(NFA_INTERFACE_ISO_DEP) ? NFA_STATUS_OK : NFA_STATUS_FAILED;
929 }
930
931TheEnd:
932 ALOGD ("%s: exit 0x%X", __FUNCTION__, retCode);
933 return retCode;
934}
935void setReconnectState(bool flag)
936{
937 sReconnectFlag = flag;
nxpandroid281eb922016-08-25 20:27:46 +0530938 ALOGD ("setReconnectState = 0x%x",sReconnectFlag );
nxpandroid64fd68c2015-09-23 16:45:15 +0530939}
940bool getReconnectState(void)
941{
nxpandroid281eb922016-08-25 20:27:46 +0530942 ALOGD ("getReconnectState = 0x%x",sReconnectFlag );
nxpandroid64fd68c2015-09-23 16:45:15 +0530943 return sReconnectFlag;
944}
945/*******************************************************************************
946**
947** Function: reSelect
948**
949** Description: Deactivates the tag and re-selects it with the specified
950** rf interface.
951**
952** Returns: status code, 0 on success, 1 on failure,
953** 146 (defined in service) on tag lost
954**
955*******************************************************************************/
956static int reSelect (tNFA_INTF_TYPE rfInterface, bool fSwitchIfNeeded)
957{
958 int handle = sCurrentConnectedHandle;
959 ALOGD ("%s: enter; rf intf = %d, current intf = %d", __FUNCTION__, rfInterface, sCurrentRfInterface);
960
961 sRfInterfaceMutex.lock ();
962
963 if (fSwitchIfNeeded && (rfInterface == sCurrentRfInterface))
964 {
965 // already in the requested interface
966 sRfInterfaceMutex.unlock ();
967 return 0; // success
968 }
969
970 NfcTag& natTag = NfcTag::getInstance ();
971
972 tNFA_STATUS status;
973 int rVal = 1;
nxpandroida9a68ba2016-01-14 21:12:17 +0530974#if(NFC_NXP_NON_STD_CARD == TRUE)
975 unsigned char retry_cnt = 1;
976#endif
nxpandroid64fd68c2015-09-23 16:45:15 +0530977 do
978 {
979 //if tag has shutdown, abort this method
980 if (NfcTag::getInstance ().isNdefDetectionTimedOut())
981 {
982 ALOGD ("%s: ndef detection timeout; break", __FUNCTION__);
983 rVal = STATUS_CODE_TARGET_LOST;
984 break;
985 }
nxpandroida9a68ba2016-01-14 21:12:17 +0530986#if(NFC_NXP_NON_STD_CARD == TRUE)
987 if(!retry_cnt && (natTag.mTechLibNfcTypes[handle] != NFA_PROTOCOL_MIFARE))
988 NfcTag::getInstance ().mCashbeeDetected = true;
989#endif
nxpandroid64fd68c2015-09-23 16:45:15 +0530990 {
991 SyncEventGuard g (sReconnectEvent);
992 gIsTagDeactivating = true;
993 sGotDeactivate = false;
994 setReconnectState(false);
995 NFA_SetReconnectState(TRUE);
996 if (NfcTag::getInstance ().isCashBeeActivated() == true || NfcTag::getInstance ().isEzLinkTagActivated() == true
nxpandroid1153eb32015-11-06 18:46:58 +0530997#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +0530998 || sNonNciCard_t.chinaTransp_Card == true
999#endif
1000 )
1001 {
1002 setReconnectState(true);
1003 /* send deactivate to Idle command */
1004 ALOGD ("%s: deactivate to Idle", __FUNCTION__);
1005 if (NFA_STATUS_OK != (status = NFA_StopRfDiscovery ())) //deactivate to sleep state
1006 {
1007 ALOGE ("%s: deactivate failed, status = %d", __FUNCTION__, status);
1008 break;
1009 }
1010 }
1011 else
1012 {
1013 ALOGD ("%s: deactivate to sleep", __FUNCTION__);
1014 if (NFA_STATUS_OK != (status = NFA_Deactivate (TRUE))) //deactivate to sleep state
1015 {
1016 ALOGE ("%s: deactivate failed, status = %d", __FUNCTION__, status);
1017 break;
1018 }
1019 }
1020 if (sReconnectEvent.wait (1000) == false) //if timeout occurred
1021 {
1022 ALOGE ("%s: timeout waiting for deactivate", __FUNCTION__);
1023 }
1024 }
1025
1026 /* if (!sGotDeactivate)
1027 {
1028 rVal = STATUS_CODE_TARGET_LOST;
1029 break;
1030 }*/
1031 if(NfcTag::getInstance().getActivationState() == NfcTag::Idle)
1032 {
1033 ALOGD("%s:tag is in idle", __FUNCTION__);
1034 if((NfcTag::getInstance().mActivationParams_t.mTechLibNfcTypes == NFC_PROTOCOL_ISO_DEP))
1035 {
1036 if(NfcTag::getInstance().mActivationParams_t.mTechParams == NFC_DISCOVERY_TYPE_POLL_A)
1037 {
1038 NfcTag::getInstance ().mCashbeeDetected = true;
1039 }
1040 else if(NfcTag::getInstance().mActivationParams_t.mTechParams == NFC_DISCOVERY_TYPE_POLL_B)
1041 {
1042 NfcTag::getInstance ().mEzLinkTypeTag = true;
1043 }
1044 }
1045 }
1046
1047
1048 if (!(NfcTag::getInstance ().isCashBeeActivated() == true || NfcTag::getInstance ().isEzLinkTagActivated() == true
nxpandroid1153eb32015-11-06 18:46:58 +05301049#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301050 || sNonNciCard_t.chinaTransp_Card == true
1051#endif
1052 ))
1053 {
1054 if (NfcTag::getInstance ().getActivationState () != NfcTag::Sleep)
1055 {
1056 ALOGD ("%s: tag is not in sleep", __FUNCTION__);
1057 rVal = STATUS_CODE_TARGET_LOST;
nxpandroida9a68ba2016-01-14 21:12:17 +05301058#if(NFC_NXP_NON_STD_CARD == TRUE)
1059 if(!retry_cnt)
1060#endif
1061 break;
1062#if(NFC_NXP_NON_STD_CARD == TRUE)
1063 else continue;
1064#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301065 }
1066 }
1067 else
1068 {
1069 setReconnectState(false);
1070 }
1071 gIsTagDeactivating = false;
1072
1073 {
1074 SyncEventGuard g2 (sReconnectEvent);
1075 gIsSelectingRfInterface = true;
1076 sConnectWaitingForComplete = JNI_TRUE;
1077 if (NfcTag::getInstance ().isCashBeeActivated() == true || NfcTag::getInstance ().isEzLinkTagActivated() == true
nxpandroid1153eb32015-11-06 18:46:58 +05301078#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301079 || sNonNciCard_t.chinaTransp_Card == true
1080#endif
1081 )
1082 {
1083 setReconnectState(true);
1084 ALOGD ("%s: Discover map cmd", __FUNCTION__);
1085 if (NFA_STATUS_OK != (status = NFA_StartRfDiscovery ())) //deactivate to sleep state
1086 {
1087 ALOGE ("%s: deactivate failed, status = %d", __FUNCTION__, status);
1088 break;
1089 }
1090 }
1091 else
1092 {
1093 ALOGD ("%s: select interface %u", __FUNCTION__, rfInterface);
1094
1095 if (NFA_STATUS_OK != (status = NFA_Select (natTag.mTechHandles[handle], natTag.mTechLibNfcTypes[handle], rfInterface)))
1096 {
1097 ALOGE ("%s: NFA_Select failed, status = %d", __FUNCTION__, status);
1098 break;
1099 }
1100 }
1101 sConnectOk = false;
1102 if (sReconnectEvent.wait (1000) == false) //if timeout occured
1103 {
1104 ALOGE ("%s: timeout waiting for select", __FUNCTION__);
nxpandroida9a68ba2016-01-14 21:12:17 +05301105#if(NXP_EXTNS == TRUE)
1106 if (!(NfcTag::getInstance ().isCashBeeActivated() == true || NfcTag::getInstance ().isEzLinkTagActivated() == true
1107 #if(NFC_NXP_NON_STD_CARD == TRUE)
1108 || sNonNciCard_t.chinaTransp_Card == true
1109 #endif
1110 ))
1111 {
1112 status = NFA_Deactivate (FALSE);
1113 if (status != NFA_STATUS_OK)
1114 ALOGE ("%s: deactivate failed; error=0x%X", __FUNCTION__, status);
1115 }
nxpandroid64fd68c2015-09-23 16:45:15 +05301116 break;
nxpandroida9a68ba2016-01-14 21:12:17 +05301117#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301118 }
1119 }
1120
1121 ALOGD("%s: select completed; sConnectOk=%d", __FUNCTION__, sConnectOk);
1122 if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
1123 {
1124 ALOGD("%s: tag is not active", __FUNCTION__);
1125 rVal = STATUS_CODE_TARGET_LOST;
nxpandroida9a68ba2016-01-14 21:12:17 +05301126#if(NFC_NXP_NON_STD_CARD == TRUE)
1127 if(!retry_cnt)
1128#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301129 break;
1130 }
1131 if(NfcTag::getInstance ().isEzLinkTagActivated() == true)
1132 {
1133 NfcTag::getInstance ().mEzLinkTypeTag = false;
1134 }
nxpandroida9a68ba2016-01-14 21:12:17 +05301135#if(NFC_NXP_NON_STD_CARD == TRUE)
1136 if(NfcTag::getInstance ().isCashBeeActivated() == true)
1137 {
1138 NfcTag::getInstance ().mCashbeeDetected = false;
1139 }
1140#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301141 if (sConnectOk)
1142 {
1143 rVal = 0; // success
1144 sCurrentRfInterface = rfInterface;
nxpandroida9a68ba2016-01-14 21:12:17 +05301145#if(NFC_NXP_NON_STD_CARD == TRUE)
1146 break;
1147#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301148 }
1149 else
1150 {
1151 rVal = 1;
1152 }
nxpandroida9a68ba2016-01-14 21:12:17 +05301153 }
1154#if(NFC_NXP_NON_STD_CARD == TRUE)
1155 while (retry_cnt--);
1156#else
1157 while(0);
1158#endif
nxpandroid64fd68c2015-09-23 16:45:15 +05301159 setReconnectState(false);
1160 NFA_SetReconnectState(FALSE);
1161 sConnectWaitingForComplete = JNI_FALSE;
1162 gIsTagDeactivating = false;
1163 gIsSelectingRfInterface = false;
1164 sRfInterfaceMutex.unlock ();
1165 ALOGD ("%s: exit; status=%d", __FUNCTION__, rVal);
1166 return rVal;
1167}
1168
1169/*******************************************************************************
1170**
1171** Function: switchRfInterface
1172**
1173** Description: Switch controller's RF interface to frame, ISO-DEP, or NFC-DEP.
1174** rfInterface: Type of RF interface.
1175**
1176** Returns: True if ok.
1177**
1178*******************************************************************************/
1179static bool switchRfInterface (tNFA_INTF_TYPE rfInterface)
1180{
nxpandroid64fd68c2015-09-23 16:45:15 +05301181 ALOGD ("%s: rf intf = %d", __FUNCTION__, rfInterface);
1182 NfcTag& natTag = NfcTag::getInstance ();
1183
nxpandroid34627bd2016-05-27 15:52:30 +05301184 if (sCurrentConnectedTargetProtocol != NFC_PROTOCOL_ISO_DEP)
nxpandroid64fd68c2015-09-23 16:45:15 +05301185 {
nxpandroid34627bd2016-05-27 15:52:30 +05301186 ALOGD ("%s: protocol: %d not ISO_DEP, do nothing", __FUNCTION__, sCurrentConnectedTargetProtocol);
nxpandroid64fd68c2015-09-23 16:45:15 +05301187 return true;
1188 }
1189
1190 ALOGD ("%s: new rf intf = %d, cur rf intf = %d", __FUNCTION__, rfInterface, sCurrentRfInterface);
1191
1192 bool rVal = true;
1193 if (rfInterface != sCurrentRfInterface)
1194 {
nxpandroid34627bd2016-05-27 15:52:30 +05301195 if (0 == reSelect(rfInterface, true))
nxpandroid64fd68c2015-09-23 16:45:15 +05301196 {
1197 sCurrentRfInterface = rfInterface;
nxpandroid34627bd2016-05-27 15:52:30 +05301198 rVal = true;
1199 }
1200 else
1201 {
1202 rVal = false;
nxpandroid64fd68c2015-09-23 16:45:15 +05301203 }
1204 }
1205
1206 return rVal;
1207}
1208
1209
1210/*******************************************************************************
1211**
1212** Function: nativeNfcTag_doReconnect
1213**
1214** Description: Re-connect to the tag in RF field.
1215** e: JVM environment.
1216** o: Java object.
1217**
1218** Returns: Status code.
1219**
1220*******************************************************************************/
1221static jint nativeNfcTag_doReconnect (JNIEnv*, jobject)
1222{
1223 ALOGD ("%s: enter", __FUNCTION__);
1224 int retCode = NFCSTATUS_SUCCESS;
1225 NfcTag& natTag = NfcTag::getInstance ();
1226 int handle = sCurrentConnectedHandle;
1227
1228 UINT8* uid;
1229 UINT32 uid_len;
1230 ALOGD ("%s: enter; handle=%x", __FUNCTION__, handle);
1231 natTag.getTypeATagUID(&uid,&uid_len);
1232
1233 if(natTag.mNfcDisableinProgress)
1234 {
1235 ALOGE ("%s: NFC disabling in progress", __FUNCTION__);
1236 retCode = NFCSTATUS_FAILED;
1237 goto TheEnd;
1238 }
1239
1240 if (natTag.getActivationState() != NfcTag::Active)
1241 {
1242 ALOGE ("%s: tag already deactivated", __FUNCTION__);
1243 retCode = NFCSTATUS_FAILED;
1244 goto TheEnd;
1245 }
1246
1247 // special case for Kovio
nxpandroid34627bd2016-05-27 15:52:30 +05301248 if (sCurrentConnectedTargetType == TARGET_TYPE_KOVIO_BARCODE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301249 {
1250 ALOGD ("%s: fake out reconnect for Kovio", __FUNCTION__);
1251 goto TheEnd;
1252 }
1253
1254 if (natTag.isNdefDetectionTimedOut())
1255 {
1256 ALOGD ("%s: ndef detection timeout", __FUNCTION__);
1257 retCode = STATUS_CODE_TARGET_LOST;
1258 goto TheEnd;
1259 }
1260
1261 //special case for TypeB and TypeA random UID
1262 if ( (sCurrentRfInterface != NCI_INTERFACE_FRAME) &&
1263 ((natTag.mTechLibNfcTypes[handle] == NFA_PROTOCOL_ISO_DEP &&
1264 true == natTag.isTypeBTag() ) ||
1265 ( NfcTag::getInstance ().mTechLibNfcTypes[handle] == NFA_PROTOCOL_ISO_DEP &&
1266 uid_len > 0 && uid[0] == 0x08))
1267 )
1268 {
1269 ALOGD ("%s: reconnect for TypeB / TypeA random uid", __FUNCTION__);
1270 sReconnectNtfTimer.set(500, sReconnectTimerProc);
1271
1272 tNFC_STATUS stat = NFA_RegVSCback (true,nfaVSCNtfCallback); //Register CallBack for VS NTF
1273 if(NFA_STATUS_OK != stat)
1274 {
1275 retCode = 0x01;
1276 goto TheEnd;
1277 }
1278
1279 SyncEventGuard guard (sNfaVSCResponseEvent);
1280 stat = NFA_SendVsCommand (0x11,0x00,NULL,nfaVSCCallback);
1281 if(NFA_STATUS_OK == stat)
1282 {
1283 sIsReconnecting = true;
1284 ALOGD ("%s: reconnect for TypeB - wait for NFA VS command to finish", __FUNCTION__);
1285 sNfaVSCResponseEvent.wait(); //wait for NFA VS command to finish
1286 ALOGD ("%s: reconnect for TypeB - Got RSP", __FUNCTION__);
1287 }
1288
1289 if(false == sVSCRsp)
1290 {
1291 retCode = 0x01;
1292 sIsReconnecting = false;
1293 }
1294 else
1295 {
1296 {
1297 ALOGD ("%s: reconnect for TypeB - wait for NFA VS NTF to come", __FUNCTION__);
1298 SyncEventGuard guard (sNfaVSCNotificationEvent);
1299 sNfaVSCNotificationEvent.wait(); //wait for NFA VS NTF to come
1300 ALOGD ("%s: reconnect for TypeB - GOT NFA VS NTF", __FUNCTION__);
1301 sReconnectNtfTimer.kill();
1302 sIsReconnecting = false;
1303 }
1304
1305 if(false == sIsTagInField)
1306 {
1307 ALOGD ("%s: NxpNci: TAG OUT OF FIELD", __FUNCTION__);
1308 retCode = STATUS_CODE_TARGET_LOST;
1309
1310 SyncEventGuard g (gDeactivatedEvent);
1311
1312 //Tag not present, deactivate the TAG.
1313 stat = NFA_Deactivate (FALSE);
1314 if (stat == NFA_STATUS_OK)
1315 {
1316 gDeactivatedEvent.wait ();
1317 }
1318 else
1319 {
1320 ALOGE ("%s: deactivate failed; error=0x%X", __FUNCTION__, stat);
1321 }
1322 }
1323
1324 else
1325 {
1326 retCode = 0x00;
1327 }
1328 }
1329
1330 stat = NFA_RegVSCback (false,nfaVSCNtfCallback); //DeRegister CallBack for VS NTF
1331 if(NFA_STATUS_OK != stat)
1332 {
1333 retCode = 0x01;
1334 }
1335 ALOGD ("%s: reconnect for TypeB - return", __FUNCTION__);
1336
1337 goto TheEnd;
1338 }
1339 // this is only supported for type 2 or 4 (ISO_DEP) tags
nxpandroid34627bd2016-05-27 15:52:30 +05301340 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_ISO_DEP)
nxpandroid64fd68c2015-09-23 16:45:15 +05301341 retCode = reSelect(NFA_INTERFACE_ISO_DEP, false);
nxpandroid34627bd2016-05-27 15:52:30 +05301342 else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_T2T)
nxpandroid64fd68c2015-09-23 16:45:15 +05301343 retCode = reSelect(NFA_INTERFACE_FRAME, false);
nxpandroid34627bd2016-05-27 15:52:30 +05301344 else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301345 retCode = reSelect(NFA_INTERFACE_MIFARE, false);
1346
1347TheEnd:
1348 ALOGD ("%s: exit 0x%X", __FUNCTION__, retCode);
1349 return retCode;
1350}
1351
1352
1353/*******************************************************************************
1354**
1355** Function: nativeNfcTag_doHandleReconnect
1356**
1357** Description: Re-connect to the tag in RF field.
1358** e: JVM environment.
1359** o: Java object.
1360** targetHandle: Handle of the tag.
1361**
1362** Returns: Status code.
1363**
1364*******************************************************************************/
1365static jint nativeNfcTag_doHandleReconnect (JNIEnv *e, jobject o, jint targetHandle)
1366{
1367 ALOGD ("%s: targetHandle = %d", __FUNCTION__, targetHandle);
1368 if(NfcTag::getInstance ().mNfcDisableinProgress)
1369 return STATUS_CODE_TARGET_LOST;
1370 return nativeNfcTag_doConnect (e, o, targetHandle);
1371}
1372
1373
1374/*******************************************************************************
1375**
1376** Function: nativeNfcTag_doDisconnect
1377**
1378** Description: Deactivate the RF field.
1379** e: JVM environment.
1380** o: Java object.
1381**
1382** Returns: True if ok.
1383**
1384*******************************************************************************/
1385static jboolean nativeNfcTag_doDisconnect (JNIEnv*, jobject)
1386{
1387 ALOGD ("%s: enter", __FUNCTION__);
1388 tNFA_STATUS nfaStat = NFA_STATUS_OK;
1389
1390 NfcTag::getInstance().resetAllTransceiveTimeouts ();
nxpandroid1153eb32015-11-06 18:46:58 +05301391#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301392 if(sNonNciCard_t.Changan_Card == true || sNonNciCard_t.chinaTransp_Card == true)
1393 {
1394 memset(&sNonNciCard_t,0,sizeof(sNonNciCard));
1395 scoreGenericNtf = false;
1396 }
1397#endif
1398 if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
1399 {
1400 ALOGE ("%s: tag already deactivated", __FUNCTION__);
1401 goto TheEnd;
1402 }
1403
1404 nfaStat = NFA_Deactivate (FALSE);
1405 if (nfaStat != NFA_STATUS_OK)
1406 ALOGE ("%s: deactivate failed; error=0x%X", __FUNCTION__, nfaStat);
1407
1408TheEnd:
1409 ALOGD ("%s: exit", __FUNCTION__);
1410 return (nfaStat == NFA_STATUS_OK) ? JNI_TRUE : JNI_FALSE;
1411}
1412
1413
1414/*******************************************************************************
1415**
1416** Function: nativeNfcTag_doTransceiveStatus
1417**
1418** Description: Receive the completion status of transceive operation.
1419** status: operation status.
1420** buf: Contains tag's response.
1421** bufLen: Length of buffer.
1422**
1423** Returns: None
1424**
1425*******************************************************************************/
1426void nativeNfcTag_doTransceiveStatus (tNFA_STATUS status, uint8_t* buf, uint32_t bufLen)
1427{
1428 int handle = sCurrentConnectedHandle;
1429 SyncEventGuard g (sTransceiveEvent);
1430 ALOGD ("%s: data len=%d", __FUNCTION__, bufLen);
1431
nxpandroid34627bd2016-05-27 15:52:30 +05301432 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301433 {
nxpandroid34627bd2016-05-27 15:52:30 +05301434 if (EXTNS_GetCallBackFlag () == FALSE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301435 {
nxpandroid34627bd2016-05-27 15:52:30 +05301436 EXTNS_MfcCallBack (buf, bufLen);
nxpandroid64fd68c2015-09-23 16:45:15 +05301437 return;
1438 }
1439 }
1440
1441 if (!sWaitingForTransceive)
1442 {
1443 ALOGE ("%s: drop data", __FUNCTION__);
1444 return;
1445 }
1446 sRxDataStatus = status;
1447 if (sRxDataStatus == NFA_STATUS_OK || sRxDataStatus == NFA_STATUS_CONTINUE)
1448 sRxDataBuffer.append (buf, bufLen);
1449
1450 if (sRxDataStatus == NFA_STATUS_OK)
1451 sTransceiveEvent.notifyOne ();
1452}
1453
1454
1455void nativeNfcTag_notifyRfTimeout ()
1456{
1457 SyncEventGuard g (sTransceiveEvent);
1458 ALOGD ("%s: waiting for transceive: %d", __FUNCTION__, sWaitingForTransceive);
1459 if (!sWaitingForTransceive)
1460 return;
1461
1462 sTransceiveRfTimeout = true;
1463
1464 sTransceiveEvent.notifyOne ();
1465}
1466
1467
1468/*******************************************************************************
1469**
1470** Function: nativeNfcTag_doTransceive
1471**
1472** Description: Send raw data to the tag; receive tag's response.
1473** e: JVM environment.
1474** o: Java object.
1475** raw: Not used.
1476** statusTargetLost: Whether tag responds or times out.
1477**
1478** Returns: Response from tag.
1479**
1480*******************************************************************************/
1481static jbyteArray nativeNfcTag_doTransceive (JNIEnv* e, jobject o, jbyteArray data, jboolean raw, jintArray statusTargetLost)
1482{
1483 int timeout = NfcTag::getInstance ().getTransceiveTimeout (sCurrentConnectedTargetType);
1484 ALOGD ("%s: enter; raw=%u; timeout = %d", __FUNCTION__, raw, timeout);
1485
1486 int handle = sCurrentConnectedHandle;
1487 bool waitOk = false;
1488 bool isNack = false;
1489 jint *targetLost = NULL;
1490 tNFA_STATUS status;
nxpandroid1153eb32015-11-06 18:46:58 +05301491#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301492 bool fNeedToSwitchBack = false;
1493#endif
nxpandroid34627bd2016-05-27 15:52:30 +05301494 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301495 {
1496 if( doReconnectFlag == 0)
1497 {
1498 int retCode = NFCSTATUS_SUCCESS;
1499 retCode = nativeNfcTag_doReconnect (e, o);
1500 doReconnectFlag = 0x01;
1501 }
1502 }
1503
1504 if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
1505 {
1506 if (statusTargetLost)
1507 {
1508 targetLost = e->GetIntArrayElements (statusTargetLost, 0);
1509 if (targetLost)
1510 *targetLost = 1; //causes NFC service to throw TagLostException
1511 e->ReleaseIntArrayElements (statusTargetLost, targetLost, 0);
1512 }
1513 ALOGD ("%s: tag not active", __FUNCTION__);
1514 return NULL;
1515 }
1516
1517 NfcTag& natTag = NfcTag::getInstance ();
1518
1519 // get input buffer and length from java call
1520 ScopedByteArrayRO bytes(e, data);
1521 uint8_t* buf = const_cast<uint8_t*>(reinterpret_cast<const uint8_t*>(&bytes[0])); // TODO: API bug; NFA_SendRawFrame should take const*!
1522 size_t bufLen = bytes.size();
1523
1524 if (statusTargetLost)
1525 {
1526 targetLost = e->GetIntArrayElements (statusTargetLost, 0);
1527 if (targetLost)
1528 *targetLost = 0; //success, tag is still present
1529 }
1530
1531 sSwitchBackTimer.kill ();
1532 ScopedLocalRef<jbyteArray> result(e, NULL);
1533 do
1534 {
nxpandroid1153eb32015-11-06 18:46:58 +05301535#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301536 if (sNeedToSwitchRf)
1537 {
1538 if (!switchRfInterface (NFA_INTERFACE_FRAME)) //NFA_INTERFACE_ISO_DEP
1539 {
1540 break;
1541 }
1542 fNeedToSwitchBack = true;
1543 }
1544#endif
1545 {
1546 SyncEventGuard g (sTransceiveEvent);
1547 sTransceiveRfTimeout = false;
1548 sWaitingForTransceive = true;
1549 sRxDataStatus = NFA_STATUS_OK;
1550 sRxDataBuffer.clear ();
nxpandroid34627bd2016-05-27 15:52:30 +05301551 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301552 {
nxpandroid34627bd2016-05-27 15:52:30 +05301553 status = EXTNS_MfcTransceive (buf, bufLen);
nxpandroid64fd68c2015-09-23 16:45:15 +05301554 }
1555 else
1556 {
1557 status = NFA_SendRawFrame (buf, bufLen,
1558 NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY);
1559 }
1560
1561 if (status != NFA_STATUS_OK)
1562 {
1563 ALOGE ("%s: fail send; error=%d", __FUNCTION__, status);
1564 break;
1565 }
nxpandroid281eb922016-08-25 20:27:46 +05301566 waitOk = sTransceiveEvent.wait (timeout);
nxpandroid64fd68c2015-09-23 16:45:15 +05301567 }
1568
1569 if (waitOk == false || sTransceiveRfTimeout) //if timeout occurred
1570 {
1571 ALOGE ("%s: wait response timeout", __FUNCTION__);
1572 if (targetLost)
1573 *targetLost = 1; //causes NFC service to throw TagLostException
1574 break;
1575 }
1576
1577 if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
1578 {
1579 ALOGE ("%s: already deactivated", __FUNCTION__);
1580 if (targetLost)
1581 *targetLost = 1; //causes NFC service to throw TagLostException
1582 break;
1583 }
1584
nxpandroid34627bd2016-05-27 15:52:30 +05301585 ALOGD ("%s: response %zu bytes", __FUNCTION__, sRxDataBuffer.size());
nxpandroid64fd68c2015-09-23 16:45:15 +05301586
1587 if ((natTag.getProtocol () == NFA_PROTOCOL_T2T) &&
1588 natTag.isT2tNackResponse (sRxDataBuffer.data(), sRxDataBuffer.size()))
1589 {
1590 isNack = true;
1591 }
1592
1593 if (sRxDataBuffer.size() > 0)
1594 {
1595 if (isNack)
1596 {
1597 //Some Mifare Ultralight C tags enter the HALT state after it
1598 //responds with a NACK. Need to perform a "reconnect" operation
1599 //to wake it.
1600 ALOGD ("%s: try reconnect", __FUNCTION__);
1601 nativeNfcTag_doReconnect (NULL, NULL);
1602 ALOGD ("%s: reconnect finish", __FUNCTION__);
1603 }
nxpandroid34627bd2016-05-27 15:52:30 +05301604 else if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301605 {
nxpandroid34627bd2016-05-27 15:52:30 +05301606 uint32_t transDataLen = sRxDataBuffer.size ();
1607 uint8_t *transData = (uint8_t *)sRxDataBuffer.data ();
1608 if (EXTNS_CheckMfcResponse (&transData, &transDataLen) == NFCSTATUS_FAILED)
nxpandroid64fd68c2015-09-23 16:45:15 +05301609 {
nxpandroid34627bd2016-05-27 15:52:30 +05301610 nativeNfcTag_doReconnect (e, o);
nxpandroid64fd68c2015-09-23 16:45:15 +05301611 }
1612 else
1613 {
nxpandroid34627bd2016-05-27 15:52:30 +05301614 if (transDataLen != 0)
nxpandroid64fd68c2015-09-23 16:45:15 +05301615 {
nxpandroid34627bd2016-05-27 15:52:30 +05301616 result.reset (e->NewByteArray(transDataLen));
nxpandroid64fd68c2015-09-23 16:45:15 +05301617 }
nxpandroid34627bd2016-05-27 15:52:30 +05301618 if (result.get () != NULL)
nxpandroid64fd68c2015-09-23 16:45:15 +05301619 {
nxpandroid34627bd2016-05-27 15:52:30 +05301620 e->SetByteArrayRegion (result.get (), 0, transDataLen, (const jbyte *) transData);
nxpandroid64fd68c2015-09-23 16:45:15 +05301621 }
1622 else
1623 ALOGE ("%s: Failed to allocate java byte array", __FUNCTION__);
1624 }
1625 }
1626 else
1627 {
1628 // marshall data to java for return
1629 result.reset(e->NewByteArray(sRxDataBuffer.size()));
1630 if (result.get() != NULL)
1631 {
1632 e->SetByteArrayRegion(result.get(), 0, sRxDataBuffer.size(), (const jbyte *) sRxDataBuffer.data());
1633 }
1634 else
1635 ALOGE ("%s: Failed to allocate java byte array", __FUNCTION__);
1636 } // else a nack is treated as a transceive failure to the upper layers
1637
1638 sRxDataBuffer.clear();
1639 }
1640 } while (0);
1641
1642 sWaitingForTransceive = false;
1643 if (targetLost)
1644 e->ReleaseIntArrayElements (statusTargetLost, targetLost, 0);
nxpandroid1153eb32015-11-06 18:46:58 +05301645#if(NXP_EXTNS == TRUE && NFC_NXP_NON_STD_CARD == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301646 if (fNeedToSwitchBack)
1647 {
1648 sSwitchBackTimer.set (1500, switchBackTimerProc);
1649 }
1650#endif
1651 ALOGD ("%s: exit", __FUNCTION__);
1652 return result.release();
1653}
1654
1655
1656/*******************************************************************************
1657**
1658** Function: nativeNfcTag_doGetNdefType
1659**
1660** Description: Retrieve the type of tag.
1661** e: JVM environment.
1662** o: Java object.
1663** libnfcType: Type of tag represented by JNI.
1664** javaType: Not used.
1665**
1666** Returns: Type of tag represented by NFC Service.
1667**
1668*******************************************************************************/
1669static jint nativeNfcTag_doGetNdefType (JNIEnv*, jobject, jint libnfcType, jint javaType)
1670{
1671 ALOGD ("%s: enter; libnfc type=%d; java type=%d", __FUNCTION__, libnfcType, javaType);
1672 jint ndefType = NDEF_UNKNOWN_TYPE;
1673
1674 // For NFA, libnfcType is mapped to the protocol value received
1675 // in the NFA_ACTIVATED_EVT and NFA_DISC_RESULT_EVT event.
nxpandroid34627bd2016-05-27 15:52:30 +05301676 if(NFA_PROTOCOL_T1T == libnfcType)
1677 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301678 ndefType = NDEF_TYPE1_TAG;
nxpandroid64fd68c2015-09-23 16:45:15 +05301679 }
nxpandroid34627bd2016-05-27 15:52:30 +05301680 else if(NFA_PROTOCOL_T2T == libnfcType)
1681 {
1682 ndefType = NDEF_TYPE2_TAG;
1683 }
1684 else if(NFA_PROTOCOL_T3T == libnfcType)
1685 {
1686 ndefType = NDEF_TYPE3_TAG;
1687 }
1688 else if(NFA_PROTOCOL_ISO_DEP == libnfcType)
1689 {
1690 ndefType = NDEF_TYPE4_TAG;
1691 }
1692 else if(NFA_PROTOCOL_MIFARE == libnfcType)
1693 {
1694 ndefType = NDEF_MIFARE_CLASSIC_TAG;
1695 }
1696 else
1697 {
1698 /* NFA_PROTOCOL_ISO15693 and others */
1699 ndefType = NDEF_UNKNOWN_TYPE;
1700 }
1701
nxpandroid64fd68c2015-09-23 16:45:15 +05301702 ALOGD ("%s: exit; ndef type=%d", __FUNCTION__, ndefType);
1703 return ndefType;
1704}
1705
1706
1707/*******************************************************************************
1708**
1709** Function: nativeNfcTag_doCheckNdefResult
1710**
1711** Description: Receive the result of checking whether the tag contains a NDEF
1712** message. Called by the NFA_NDEF_DETECT_EVT.
1713** status: Status of the operation.
1714** maxSize: Maximum size of NDEF message.
1715** currentSize: Current size of NDEF message.
1716** flags: Indicate various states.
1717**
1718** Returns: None
1719**
1720*******************************************************************************/
1721void nativeNfcTag_doCheckNdefResult (tNFA_STATUS status, uint32_t maxSize, uint32_t currentSize, uint8_t flags)
1722{
1723 //this function's flags parameter is defined using the following macros
1724 //in nfc/include/rw_api.h;
1725 //#define RW_NDEF_FL_READ_ONLY 0x01 /* Tag is read only */
1726 //#define RW_NDEF_FL_FORMATED 0x02 /* Tag formated for NDEF */
1727 //#define RW_NDEF_FL_SUPPORTED 0x04 /* NDEF supported by the tag */
1728 //#define RW_NDEF_FL_UNKNOWN 0x08 /* Unable to find if tag is ndef capable/formated/read only */
1729 //#define RW_NDEF_FL_FORMATABLE 0x10 /* Tag supports format operation */
1730
1731 if (!sCheckNdefWaitingForComplete)
1732 {
1733 ALOGE ("%s: not waiting", __FUNCTION__);
1734 return;
1735 }
1736
1737 if (flags & RW_NDEF_FL_READ_ONLY)
1738 ALOGD ("%s: flag read-only", __FUNCTION__);
1739 if (flags & RW_NDEF_FL_FORMATED)
1740 ALOGD ("%s: flag formatted for ndef", __FUNCTION__);
1741 if (flags & RW_NDEF_FL_SUPPORTED)
1742 ALOGD ("%s: flag ndef supported", __FUNCTION__);
1743 if (flags & RW_NDEF_FL_UNKNOWN)
1744 ALOGD ("%s: flag all unknown", __FUNCTION__);
1745 if (flags & RW_NDEF_FL_FORMATABLE)
1746 ALOGD ("%s: flag formattable", __FUNCTION__);
1747
1748 sCheckNdefWaitingForComplete = JNI_FALSE;
1749 sCheckNdefStatus = status;
1750 if (sCheckNdefStatus != NFA_STATUS_OK && sCheckNdefStatus != NFA_STATUS_TIMEOUT)
1751 sCheckNdefStatus = NFA_STATUS_FAILED;
1752 sCheckNdefCapable = false; //assume tag is NOT ndef capable
1753 if (sCheckNdefStatus == NFA_STATUS_OK)
1754 {
1755 //NDEF content is on the tag
1756 sCheckNdefMaxSize = maxSize;
1757 sCheckNdefCurrentSize = currentSize;
1758 sCheckNdefCardReadOnly = flags & RW_NDEF_FL_READ_ONLY;
1759 sCheckNdefCapable = true;
1760 }
1761 else if (sCheckNdefStatus == NFA_STATUS_FAILED)
1762 {
1763 //no NDEF content on the tag
1764 sCheckNdefMaxSize = 0;
1765 sCheckNdefCurrentSize = 0;
1766 sCheckNdefCardReadOnly = flags & RW_NDEF_FL_READ_ONLY;
1767 if ((flags & RW_NDEF_FL_UNKNOWN) == 0) //if stack understands the tag
1768 {
1769 if (flags & RW_NDEF_FL_SUPPORTED) //if tag is ndef capable
1770 sCheckNdefCapable = true;
1771 }
1772 }
1773 else if (sCheckNdefStatus == NFA_STATUS_TIMEOUT)
1774 {
1775 ALOGE("%s: timeout", __FUNCTION__);
1776
1777 sCheckNdefMaxSize = 0;
1778 sCheckNdefCurrentSize = 0;
1779 sCheckNdefCardReadOnly = false;
1780 }
1781 else
1782 {
1783 ALOGE ("%s: unknown status=0x%X", __FUNCTION__, status);
1784 sCheckNdefMaxSize = 0;
1785 sCheckNdefCurrentSize = 0;
1786 sCheckNdefCardReadOnly = false;
1787 }
1788 sem_post (&sCheckNdefSem);
1789}
1790
1791
1792/*******************************************************************************
1793**
1794** Function: nativeNfcTag_doCheckNdef
1795**
1796** Description: Does the tag contain a NDEF message?
1797** e: JVM environment.
1798** o: Java object.
1799** ndefInfo: NDEF info.
1800**
1801** Returns: Status code; 0 is success.
1802**
1803*******************************************************************************/
1804static jint nativeNfcTag_doCheckNdef (JNIEnv* e, jobject o, jintArray ndefInfo)
1805{
1806 tNFA_STATUS status = NFA_STATUS_FAILED;
1807 jint* ndef = NULL;
1808 int handle = sCurrentConnectedHandle;
1809 ALOGD ("%s: enter; handle=%x", __FUNCTION__, handle);
1810
1811 ALOGD ("%s: enter", __FUNCTION__);
1812 sIsCheckingNDef = true;
nxpandroid1153eb32015-11-06 18:46:58 +05301813#if (NXP_EXTNS == TRUE)
nxpandroid34627bd2016-05-27 15:52:30 +05301814 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_T3BT)
nxpandroid64fd68c2015-09-23 16:45:15 +05301815 {
1816 ndef = e->GetIntArrayElements (ndefInfo, 0);
1817 ndef[0] = 0;
1818 ndef[1] = NDEF_MODE_READ_ONLY;
1819 e->ReleaseIntArrayElements (ndefInfo, ndef, 0);
1820 sIsCheckingNDef = false;
1821 return NFA_STATUS_FAILED;
1822 }
1823#endif
1824
1825 // special case for Kovio
nxpandroid34627bd2016-05-27 15:52:30 +05301826 if (sCurrentConnectedTargetProtocol == TARGET_TYPE_KOVIO_BARCODE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301827 {
1828 ALOGD ("%s: Kovio tag, no NDEF", __FUNCTION__);
1829 ndef = e->GetIntArrayElements (ndefInfo, 0);
1830 ndef[0] = 0;
1831 ndef[1] = NDEF_MODE_READ_ONLY;
1832 e->ReleaseIntArrayElements (ndefInfo, ndef, 0);
1833 sIsCheckingNDef = false;
1834 return NFA_STATUS_FAILED;
1835 }
nxpandroid34627bd2016-05-27 15:52:30 +05301836 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301837 {
nxpandroid34627bd2016-05-27 15:52:30 +05301838 nativeNfcTag_doReconnect (e, o);
nxpandroid64fd68c2015-09-23 16:45:15 +05301839 }
1840
1841 doReconnectFlag = 0;
1842
1843 /* Create the write semaphore */
1844 if (sem_init (&sCheckNdefSem, 0, 0) == -1)
1845 {
1846 ALOGE ("%s: Check NDEF semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno);
1847 sIsCheckingNDef = false;
1848 return JNI_FALSE;
1849 }
1850
1851 if (NfcTag::getInstance ().getActivationState () != NfcTag::Active)
1852 {
1853 ALOGE ("%s: tag already deactivated", __FUNCTION__);
1854 goto TheEnd;
1855 }
1856
1857 ALOGD ("%s: try NFA_RwDetectNDef", __FUNCTION__);
1858 sCheckNdefWaitingForComplete = JNI_TRUE;
1859
1860 ALOGD ("%s: NfcTag::getInstance ().mTechLibNfcTypes[%d]=%d", __FUNCTION__, NfcTag::getInstance ().mTechLibNfcTypes[handle]);
1861
nxpandroid34627bd2016-05-27 15:52:30 +05301862 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05301863 {
1864 status = EXTNS_MfcCheckNDef ();
nxpandroid34627bd2016-05-27 15:52:30 +05301865 }
1866 else
1867 {
nxpandroid64fd68c2015-09-23 16:45:15 +05301868 status = NFA_RwDetectNDef ();
1869 }
1870
1871 if (status != NFA_STATUS_OK)
1872 {
1873 ALOGE ("%s: NFA_RwDetectNDef failed, status = 0x%X", __FUNCTION__, status);
1874 goto TheEnd;
1875 }
1876
1877 /* Wait for check NDEF completion status */
1878 if (sem_wait (&sCheckNdefSem))
1879 {
1880 ALOGE ("%s: Failed to wait for check NDEF semaphore (errno=0x%08x)", __FUNCTION__, errno);
1881 goto TheEnd;
1882 }
1883
1884 if (sCheckNdefStatus == NFA_STATUS_OK)
1885 {
1886 //stack found a NDEF message on the tag
1887 ndef = e->GetIntArrayElements (ndefInfo, 0);
1888 if (NfcTag::getInstance ().getProtocol () == NFA_PROTOCOL_T1T)
1889 ndef[0] = NfcTag::getInstance ().getT1tMaxMessageSize ();
1890 else
1891 ndef[0] = sCheckNdefMaxSize;
1892 if (sCheckNdefCardReadOnly)
1893 ndef[1] = NDEF_MODE_READ_ONLY;
1894 else
1895 ndef[1] = NDEF_MODE_READ_WRITE;
1896 e->ReleaseIntArrayElements (ndefInfo, ndef, 0);
1897 status = NFA_STATUS_OK;
1898 }
1899 else if (sCheckNdefStatus == NFA_STATUS_FAILED)
1900 {
1901 //stack did not find a NDEF message on the tag;
1902 ndef = e->GetIntArrayElements (ndefInfo, 0);
1903 if (NfcTag::getInstance ().getProtocol () == NFA_PROTOCOL_T1T)
1904 ndef[0] = NfcTag::getInstance ().getT1tMaxMessageSize ();
1905 else
1906 ndef[0] = sCheckNdefMaxSize;
1907 if (sCheckNdefCardReadOnly)
1908 ndef[1] = NDEF_MODE_READ_ONLY;
1909 else
1910 ndef[1] = NDEF_MODE_READ_WRITE;
1911 e->ReleaseIntArrayElements (ndefInfo, ndef, 0);
1912 status = NFA_STATUS_FAILED;
1913 if (setNdefDetectionTimeoutIfTagAbsent(e, o, NFA_PROTOCOL_T3T | NFA_PROTOCOL_ISO15693))
1914 status = STATUS_CODE_TARGET_LOST;
1915 }
1916 else if ((sCheckNdefStatus == NFA_STATUS_TIMEOUT) && (NfcTag::getInstance ().getProtocol() == NFC_PROTOCOL_ISO_DEP))
1917 {
1918 pn544InteropStopPolling ();
1919 status = STATUS_CODE_TARGET_LOST;
1920 }
1921 else
1922 {
1923 ALOGD ("%s: unknown status 0x%X", __FUNCTION__, sCheckNdefStatus);
1924 status = sCheckNdefStatus;
1925 }
1926
nxpandroid34627bd2016-05-27 15:52:30 +05301927 /* Reconnect Mifare Classic Tag for furture use */
1928 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
1929 {
1930 nativeNfcTag_doReconnect (e, o);
1931 }
1932
nxpandroid64fd68c2015-09-23 16:45:15 +05301933TheEnd:
1934 /* Destroy semaphore */
1935 if (sem_destroy (&sCheckNdefSem))
1936 {
1937 ALOGE ("%s: Failed to destroy check NDEF semaphore (errno=0x%08x)", __FUNCTION__, errno);
1938 }
1939 sCheckNdefWaitingForComplete = JNI_FALSE;
1940 sIsCheckingNDef = false;
1941 ALOGD ("%s: exit; status=0x%X", __FUNCTION__, status);
1942 return status;
1943}
1944
1945
1946/*******************************************************************************
1947**
1948** Function: nativeNfcTag_resetPresenceCheck
1949**
1950** Description: Reset variables related to presence-check.
1951**
1952** Returns: None
1953**
1954*******************************************************************************/
1955void nativeNfcTag_resetPresenceCheck ()
1956{
1957 sIsTagPresent = true;
1958 NfcTag::getInstance ().mCashbeeDetected = false;
1959 NfcTag::getInstance ().mEzLinkTypeTag = false;
1960 MfcResetPresenceCheckStatus();
1961}
1962
1963
1964/*******************************************************************************
1965**
1966** Function: nativeNfcTag_doPresenceCheckResult
1967**
1968** Description: Receive the result of presence-check.
1969** status: Result of presence-check.
1970**
1971** Returns: None
1972**
1973*******************************************************************************/
1974void nativeNfcTag_doPresenceCheckResult (tNFA_STATUS status)
1975{
1976 SyncEventGuard guard (sPresenceCheckEvent);
1977 sIsTagPresent = status == NFA_STATUS_OK;
1978 sPresenceCheckEvent.notifyOne ();
1979}
1980
1981
1982/*******************************************************************************
1983**
1984** Function: nativeNfcTag_doPresenceCheck
1985**
1986** Description: Check if the tag is in the RF field.
1987** e: JVM environment.
1988** o: Java object.
1989**
1990** Returns: True if tag is in RF field.
1991**
1992*******************************************************************************/
1993static jboolean nativeNfcTag_doPresenceCheck (JNIEnv*, jobject)
1994{
1995 ALOGD ("%s", __FUNCTION__);
1996 tNFA_STATUS status = NFA_STATUS_OK;
1997 jboolean isPresent = JNI_FALSE;
1998 UINT8* uid;
1999 UINT32 uid_len;
2000 NfcTag::getInstance ().getTypeATagUID(&uid,&uid_len);
2001 int handle = sCurrentConnectedHandle;
2002
2003 if(NfcTag::getInstance().mNfcDisableinProgress)
2004 {
2005 ALOGD("%s, Nfc disable in progress",__FUNCTION__);
2006 return JNI_FALSE;
2007 }
2008
2009 if (sIsCheckingNDef == true)
2010 {
2011 ALOGD("%s: Ndef is being checked", __FUNCTION__);
2012 return JNI_TRUE;
2013 }
2014 if (fNeedToSwitchBack)
2015 {
2016 sSwitchBackTimer.kill ();
2017 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302018 if (nfcManager_isNfcActive() == false)
2019 {
2020 ALOGD ("%s: NFC is no longer active.", __FUNCTION__);
2021 return JNI_FALSE;
2022 }
2023
2024 if (!sRfInterfaceMutex.tryLock())
2025 {
2026 ALOGD ("%s: tag is being reSelected assume it is present", __FUNCTION__);
2027 return JNI_TRUE;
2028 }
2029
2030 sRfInterfaceMutex.unlock();
2031
2032 if (NfcTag::getInstance ().isActivated () == false)
2033 {
2034 ALOGD ("%s: tag already deactivated", __FUNCTION__);
2035 return JNI_FALSE;
2036 }
2037
nxpandroida9a68ba2016-01-14 21:12:17 +05302038 /*Presence check for Kovio - RF Deactive command with type Discovery*/
2039 ALOGD ("%s: handle=%d", __FUNCTION__, handle);
nxpandroid34627bd2016-05-27 15:52:30 +05302040 if (sCurrentConnectedTargetProtocol == TARGET_TYPE_KOVIO_BARCODE)
nxpandroida9a68ba2016-01-14 21:12:17 +05302041 {
2042 SyncEventGuard guard (sPresenceCheckEvent);
2043 status = NFA_RwPresenceCheck (NfcTag::getInstance().getPresenceCheckAlgorithm());
2044 if (status == NFA_STATUS_OK)
2045 {
2046 sPresenceCheckEvent.wait ();
2047 isPresent = sIsTagPresent ? JNI_TRUE : JNI_FALSE;
2048 }
2049 if (isPresent == JNI_FALSE)
2050 ALOGD ("%s: tag absent", __FUNCTION__);
2051 return isPresent;
2052#if 0
2053 ALOGD ("%s: Kovio, force deactivate handling", __FUNCTION__);
2054 tNFA_DEACTIVATED deactivated = {NFA_DEACTIVATE_TYPE_IDLE};
2055 {
2056 SyncEventGuard g (gDeactivatedEvent);
2057 gActivated = false; //guard this variable from multi-threaded access
2058 gDeactivatedEvent.notifyOne ();
2059 }
2060
2061 NfcTag::getInstance().setDeactivationState (deactivated);
2062 nativeNfcTag_resetPresenceCheck();
2063 NfcTag::getInstance().connectionEventHandler (NFA_DEACTIVATED_EVT, NULL);
2064 nativeNfcTag_abortWaits();
2065 NfcTag::getInstance().abort ();
2066
2067 return JNI_FALSE;
2068#endif
2069 }
2070
nxpandroid64fd68c2015-09-23 16:45:15 +05302071 /*
2072 * This fix is made because NFA_RwPresenceCheck cmd is not woking for ISO-DEP in CEFH mode
2073 * Hence used the Properitary presence check cmd
2074 * */
2075
2076 if (NfcTag::getInstance ().mTechLibNfcTypes[handle] == NFA_PROTOCOL_ISO_DEP)
2077 {
2078 if (sIsReconnecting == true)
2079 {
2080 ALOGD("%s: Reconnecting Tag", __FUNCTION__);
2081 return JNI_TRUE;
2082 }
2083 ALOGD ("%s: presence check for TypeB / TypeA random uid", __FUNCTION__);
2084 sPresenceCheckTimer.set(500, presenceCheckTimerProc);
2085
2086 tNFC_STATUS stat = NFA_RegVSCback (true,nfaVSCNtfCallback); //Register CallBack for VS NTF
2087 if(NFA_STATUS_OK != stat)
2088 {
2089 goto TheEnd;
2090 }
2091
2092 SyncEventGuard guard (sNfaVSCResponseEvent);
2093 stat = NFA_SendVsCommand (0x11,0x00,NULL,nfaVSCCallback);
2094 if(NFA_STATUS_OK == stat)
2095 {
2096 ALOGD ("%s: presence check for TypeB - wait for NFA VS RSP to come", __FUNCTION__);
2097 sNfaVSCResponseEvent.wait(); //wait for NFA VS command to finish
2098 ALOGD ("%s: presence check for TypeB - GOT NFA VS RSP", __FUNCTION__);
2099 }
2100
2101 if(true == sVSCRsp)
2102 {
2103 {
2104 SyncEventGuard guard (sNfaVSCNotificationEvent);
2105 ALOGD ("%s: presence check for TypeB - wait for NFA VS NTF to come", __FUNCTION__);
2106 sNfaVSCNotificationEvent.wait(); //wait for NFA VS NTF to come
2107 ALOGD ("%s: presence check for TypeB - GOT NFA VS NTF", __FUNCTION__);
2108 sPresenceCheckTimer.kill();
2109 }
2110
2111 if(false == sIsTagInField)
2112 {
2113 isPresent = JNI_FALSE;
2114 }
2115 else
2116 {
2117 isPresent = JNI_TRUE;
2118 }
2119 }
2120 NFA_RegVSCback (false,nfaVSCNtfCallback); //DeRegister CallBack for VS NTF
2121 ALOGD ("%s: presence check for TypeB - return", __FUNCTION__);
2122 goto TheEnd;
2123 }
2124
nxpandroid1153eb32015-11-06 18:46:58 +05302125#if (NXP_EXTNS == TRUE)
nxpandroid64fd68c2015-09-23 16:45:15 +05302126 if(NfcTag::getInstance ().mTechLibNfcTypes[handle] == NFA_PROTOCOL_T3BT)
2127 {
2128 UINT8 *pbuf = NULL;
2129 UINT8 bufLen = 0x00;
2130 bool waitOk = false;
nxpandroid281eb922016-08-25 20:27:46 +05302131 int timeout = NfcTag::getInstance ().getTransceiveTimeout (sCurrentConnectedTargetType);
2132 ALOGD ("%s: enter; timeout = %d", __FUNCTION__, timeout);
nxpandroid64fd68c2015-09-23 16:45:15 +05302133
2134 SyncEventGuard g (sTransceiveEvent);
2135 sTransceiveRfTimeout = false;
2136 sWaitingForTransceive = true;
2137 //sTransceiveDataLen = 0;
2138 bufLen = (UINT8) sizeof(Presence_check_TypeB);
2139 pbuf = Presence_check_TypeB;
2140 //memcpy(pbuf, Attrib_cmd_TypeB, bufLen);
2141 status = NFA_SendRawFrame (pbuf, bufLen,NFA_DM_DEFAULT_PRESENCE_CHECK_START_DELAY);
2142 if (status != NFA_STATUS_OK)
2143 {
2144 ALOGE ("%s: fail send; error=%d", __FUNCTION__, status);
2145 }
2146 else
nxpandroid281eb922016-08-25 20:27:46 +05302147 waitOk = sTransceiveEvent.wait (timeout);
nxpandroid64fd68c2015-09-23 16:45:15 +05302148
2149 if (waitOk == false || sTransceiveRfTimeout) //if timeout occurred
2150 {
2151 return JNI_FALSE;;
2152 }
2153 else
2154 {
2155 return JNI_TRUE;
2156 }
2157 }
2158#endif
2159
nxpandroid34627bd2016-05-27 15:52:30 +05302160 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
nxpandroid64fd68c2015-09-23 16:45:15 +05302161 {
nxpandroid34627bd2016-05-27 15:52:30 +05302162 status = EXTNS_MfcPresenceCheck ();
2163 if (status == NFCSTATUS_SUCCESS)
2164 {
2165 return (NFCSTATUS_SUCCESS == EXTNS_GetPresenceCheckStatus ()) ? JNI_TRUE : JNI_FALSE;
2166 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302167 }
nxpandroid34627bd2016-05-27 15:52:30 +05302168
nxpandroid64fd68c2015-09-23 16:45:15 +05302169 {
2170 SyncEventGuard guard (sPresenceCheckEvent);
2171 status = NFA_RwPresenceCheck (NfcTag::getInstance().getPresenceCheckAlgorithm());
2172 if (status == NFA_STATUS_OK)
2173 {
2174 sPresenceCheckEvent.wait ();
2175 isPresent = sIsTagPresent ? JNI_TRUE : JNI_FALSE;
2176 }
2177 }
2178
2179 TheEnd:
2180
2181 if (isPresent == JNI_FALSE)
2182 ALOGD ("%s: tag absent", __FUNCTION__);
2183 return isPresent;
2184}
2185
2186
2187/*******************************************************************************
2188**
2189** Function: nativeNfcTag_doIsNdefFormatable
2190**
2191** Description: Can tag be formatted to store NDEF message?
2192** e: JVM environment.
nxpandroida9a68ba2016-01-14 21:12:17 +05302193** o: Java object.
nxpandroid64fd68c2015-09-23 16:45:15 +05302194** libNfcType: Type of tag.
2195** uidBytes: Tag's unique ID.
2196** pollBytes: Data from activation.
2197** actBytes: Data from activation.
2198**
2199** Returns: True if formattable.
2200**
2201*******************************************************************************/
2202static jboolean nativeNfcTag_doIsNdefFormatable (JNIEnv* e,
2203 jobject o, jint /*libNfcType*/, jbyteArray, jbyteArray,
2204 jbyteArray)
2205{
2206 jboolean isFormattable = JNI_FALSE;
2207
nxpandroid34627bd2016-05-27 15:52:30 +05302208 tNFC_PROTOCOL protocol = NfcTag::getInstance().getProtocol();
2209 if (NFA_PROTOCOL_T1T == protocol || NFA_PROTOCOL_ISO15693 == protocol
2210 || NFA_PROTOCOL_MIFARE == protocol)
nxpandroid64fd68c2015-09-23 16:45:15 +05302211 {
nxpandroid64fd68c2015-09-23 16:45:15 +05302212 isFormattable = JNI_TRUE;
nxpandroid34627bd2016-05-27 15:52:30 +05302213 }
2214 else if(NFA_PROTOCOL_T3T == protocol)
2215 {
nxpandroid64fd68c2015-09-23 16:45:15 +05302216 isFormattable = NfcTag::getInstance().isFelicaLite() ? JNI_TRUE : JNI_FALSE;
nxpandroid34627bd2016-05-27 15:52:30 +05302217 }
2218 else if(NFA_PROTOCOL_T2T == protocol)
2219 {
nxpandroid64fd68c2015-09-23 16:45:15 +05302220 isFormattable = ( NfcTag::getInstance().isMifareUltralight() |
2221 NfcTag::getInstance().isInfineonMyDMove() |
2222 NfcTag::getInstance().isKovioType2Tag() )
2223 ? JNI_TRUE : JNI_FALSE;
nxpandroid34627bd2016-05-27 15:52:30 +05302224 }
2225 else if(NFA_PROTOCOL_ISO_DEP == protocol)
2226 {
nxpandroid64fd68c2015-09-23 16:45:15 +05302227 /**
2228 * Determines whether this is a formatable IsoDep tag - currectly only NXP DESFire
2229 * is supported.
2230 */
2231 uint8_t cmd[] = {0x90, 0x60, 0x00, 0x00, 0x00};
2232
2233 if(NfcTag::getInstance().isMifareDESFire())
2234 {
2235 /* Identifies as DESfire, use get version cmd to be sure */
2236 jbyteArray versionCmd = e->NewByteArray(5);
2237 e->SetByteArrayRegion(versionCmd, 0, 5, (jbyte*)cmd);
2238 jbyteArray respBytes = nativeNfcTag_doTransceive(e, o,
2239 versionCmd, JNI_TRUE, NULL);
2240 if (respBytes != NULL)
2241 {
2242 // Check whether the response matches a typical DESfire
2243 // response.
2244 // libNFC even does more advanced checking than we do
2245 // here, and will only format DESfire's with a certain
2246 // major/minor sw version and NXP as a manufacturer.
2247 // We don't want to do such checking here, to avoid
2248 // having to change code in multiple places.
2249 // A succesful (wrapped) DESFire getVersion command returns
2250 // 9 bytes, with byte 7 0x91 and byte 8 having status
2251 // code 0xAF (these values are fixed and well-known).
2252 int respLength = e->GetArrayLength(respBytes);
2253 uint8_t* resp = (uint8_t*)e->GetByteArrayElements(respBytes, NULL);
2254 if (respLength == 9 && resp[7] == 0x91 && resp[8] == 0xAF)
2255 {
2256 isFormattable = JNI_TRUE;
2257 }
2258 e->ReleaseByteArrayElements(respBytes, (jbyte *)resp, JNI_ABORT);
2259 }
2260 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302261 }
2262 ALOGD("%s: is formattable=%u", __FUNCTION__, isFormattable);
2263 return isFormattable;
2264}
2265
2266
2267/*******************************************************************************
2268**
2269** Function: nativeNfcTag_doIsIsoDepNdefFormatable
2270**
2271** Description: Is ISO-DEP tag formattable?
2272** e: JVM environment.
2273** o: Java object.
2274** pollBytes: Data from activation.
2275** actBytes: Data from activation.
2276**
2277** Returns: True if formattable.
2278**
2279*******************************************************************************/
2280static jboolean nativeNfcTag_doIsIsoDepNdefFormatable (JNIEnv *e, jobject o, jbyteArray pollBytes, jbyteArray actBytes)
2281{
2282 uint8_t uidFake[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
2283 ALOGD ("%s", __FUNCTION__);
2284 jbyteArray uidArray = e->NewByteArray (8);
2285 e->SetByteArrayRegion (uidArray, 0, 8, (jbyte*) uidFake);
2286 return nativeNfcTag_doIsNdefFormatable (e, o, 0, uidArray, pollBytes, actBytes);
2287}
2288
nxpandroid34627bd2016-05-27 15:52:30 +05302289/*******************************************************************************
2290 **
2291 ** Function: nativeNfcTag_makeMifareNdefFormat
2292**
2293** Description: Format a mifare classic tag so it can store NDEF message.
2294** e: JVM environment.
2295** o: Java object.
2296** key: Key to acces tag.
2297** keySize: size of Key.
2298**
2299** Returns: True if ok.
2300**
2301*******************************************************************************/
2302static jboolean nativeNfcTag_makeMifareNdefFormat (JNIEnv *e, jobject o, uint8_t *key, uint32_t keySize)
2303{
2304 ALOGD ("%s: enter", __FUNCTION__);
2305 tNFA_STATUS status = NFA_STATUS_OK;
2306
2307 status = nativeNfcTag_doReconnect (e, o);
2308 if (status != NFA_STATUS_OK)
2309 {
2310 ALOGD ("%s: reconnect error, status=%u", __FUNCTION__, status);
2311 return JNI_FALSE;
2312 }
2313
2314 sem_init (&sFormatSem, 0, 0);
2315 sFormatOk = false;
2316
2317 status = EXTNS_MfcFormatTag (key, keySize);
2318
2319 if (status == NFA_STATUS_OK)
2320 {
2321 ALOGD ("%s: wait for completion", __FUNCTION__);
2322 sem_wait (&sFormatSem);
2323 status = sFormatOk ? NFA_STATUS_OK : NFA_STATUS_FAILED;
2324 }
2325 else
2326 {
2327 ALOGE ("%s: error status=%u", __FUNCTION__, status);
2328 }
2329
2330 sem_destroy (&sFormatSem);
2331 ALOGD ("%s: exit", __FUNCTION__);
2332 return (status == NFA_STATUS_OK) ? JNI_TRUE : JNI_FALSE;
2333}
nxpandroid64fd68c2015-09-23 16:45:15 +05302334
2335/*******************************************************************************
2336**
2337** Function: nativeNfcTag_doNdefFormat
2338**
2339** Description: Format a tag so it can store NDEF message.
2340** e: JVM environment.
2341** o: Java object.
2342** key: Not used.
2343**
2344** Returns: True if ok.
2345**
2346*******************************************************************************/
2347static jboolean nativeNfcTag_doNdefFormat (JNIEnv *e, jobject o, jbyteArray)
2348{
2349 ALOGD ("%s: enter", __FUNCTION__);
2350 tNFA_STATUS status = NFA_STATUS_OK;
2351 int handle = sCurrentConnectedHandle;
nxpandroid64fd68c2015-09-23 16:45:15 +05302352
2353 // Do not try to format if tag is already deactivated.
2354 if (NfcTag::getInstance ().isActivated () == false)
2355 {
2356 ALOGD ("%s: tag already deactivated(no need to format)", __FUNCTION__);
2357 return JNI_FALSE;
2358 }
2359
nxpandroid34627bd2016-05-27 15:52:30 +05302360 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
2361 {
2362 static uint8_t mfc_key1[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2363 static uint8_t mfc_key2[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
2364 jboolean result;
2365
2366 result = nativeNfcTag_makeMifareNdefFormat (e, o, mfc_key1, sizeof(mfc_key1));
2367 if (result == JNI_FALSE)
2368 {
2369 result = nativeNfcTag_makeMifareNdefFormat (e, o, mfc_key2, sizeof(mfc_key2));
2370 }
2371 if(result == JNI_FALSE)
2372 {
2373 ALOGE ("%s: error status=%u", __FUNCTION__, NFA_STATUS_FAILED);
2374 EXTNS_SetConnectFlag (FALSE);
2375 }
2376 return result;
2377 }
2378
nxpandroid64fd68c2015-09-23 16:45:15 +05302379 sem_init (&sFormatSem, 0, 0);
2380 sFormatOk = false;
nxpandroid34627bd2016-05-27 15:52:30 +05302381 status = NFA_RwFormatTag ();
nxpandroid64fd68c2015-09-23 16:45:15 +05302382 if (status == NFA_STATUS_OK)
2383 {
2384 ALOGD ("%s: wait for completion", __FUNCTION__);
2385 sem_wait (&sFormatSem);
2386 status = sFormatOk ? NFA_STATUS_OK : NFA_STATUS_FAILED;
nxpandroid64fd68c2015-09-23 16:45:15 +05302387 }
2388 else
nxpandroid34627bd2016-05-27 15:52:30 +05302389 {
nxpandroid64fd68c2015-09-23 16:45:15 +05302390 ALOGE ("%s: error status=%u", __FUNCTION__, status);
nxpandroid34627bd2016-05-27 15:52:30 +05302391 }
nxpandroid64fd68c2015-09-23 16:45:15 +05302392 sem_destroy (&sFormatSem);
2393
nxpandroid34627bd2016-05-27 15:52:30 +05302394 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_ISO_DEP)
nxpandroid64fd68c2015-09-23 16:45:15 +05302395 {
2396 int retCode = NFCSTATUS_SUCCESS;
2397 retCode = nativeNfcTag_doReconnect (e, o);
2398 }
2399 ALOGD ("%s: exit", __FUNCTION__);
2400 return (status == NFA_STATUS_OK) ? JNI_TRUE : JNI_FALSE;
2401}
2402
2403
2404/*******************************************************************************
2405**
2406** Function: nativeNfcTag_doMakeReadonlyResult
2407**
2408** Description: Receive the result of making a tag read-only. Called by the
2409** NFA_SET_TAG_RO_EVT.
2410** status: Status of the operation.
2411**
2412** Returns: None
2413**
2414*******************************************************************************/
2415void nativeNfcTag_doMakeReadonlyResult (tNFA_STATUS status)
2416{
2417 if (sMakeReadonlyWaitingForComplete != JNI_FALSE)
2418 {
2419 sMakeReadonlyWaitingForComplete = JNI_FALSE;
2420 sMakeReadonlyStatus = status;
2421
2422 sem_post (&sMakeReadonlySem);
2423 }
2424}
2425
nxpandroid34627bd2016-05-27 15:52:30 +05302426/*******************************************************************************
2427 **
2428** Function: nativeNfcTag_makeMifareReadonly
2429**
2430** Description: Make the mifare classic tag read-only.
2431** e: JVM environment.
2432** o: Java object.
2433** key: Key to access the tag.
2434** keySize: size of Key.
2435**
2436** Returns: True if ok.
2437**
2438*******************************************************************************/
2439static jboolean nativeNfcTag_makeMifareReadonly (JNIEnv *e, jobject o, uint8_t *key, int32_t keySize)
2440{
2441 jboolean result = JNI_FALSE;
2442 tNFA_STATUS status = NFA_STATUS_OK;
2443
2444 sMakeReadonlyStatus = NFA_STATUS_FAILED;
2445
2446 ALOGD ("%s", __FUNCTION__);
2447
2448 /* Create the make_readonly semaphore */
2449 if (sem_init (&sMakeReadonlySem, 0, 0) == -1)
2450 {
2451 ALOGE ("%s: Make readonly semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno);
2452 return JNI_FALSE;
2453 }
2454
2455 sMakeReadonlyWaitingForComplete = JNI_TRUE;
2456
2457 status = nativeNfcTag_doReconnect (e, o);
2458 if (status != NFA_STATUS_OK)
2459 {
2460 goto TheEnd;
2461 }
2462
2463 status = EXTNS_MfcSetReadOnly (key, keySize);
2464 if (status != NFA_STATUS_OK)
2465 {
2466 goto TheEnd;
2467 }
2468 sem_wait (&sMakeReadonlySem);
2469
2470 if (sMakeReadonlyStatus == NFA_STATUS_OK)
2471 {
2472 result = JNI_TRUE;
2473 }
2474
2475TheEnd:
2476 /* Destroy semaphore */
2477 if (sem_destroy (&sMakeReadonlySem))
2478 {
2479 ALOGE ("%s: Failed to destroy read_only semaphore (errno=0x%08x)", __FUNCTION__, errno);
2480 }
2481 sMakeReadonlyWaitingForComplete = JNI_FALSE;
2482 return result;
2483}
nxpandroid64fd68c2015-09-23 16:45:15 +05302484
2485/*******************************************************************************
2486**
2487** Function: nativeNfcTag_doMakeReadonly
2488**
2489** Description: Make the tag read-only.
2490** e: JVM environment.
2491** o: Java object.
2492** key: Key to access the tag.
2493**
2494** Returns: True if ok.
2495**
2496*******************************************************************************/
2497static jboolean nativeNfcTag_doMakeReadonly (JNIEnv *e, jobject o, jbyteArray)
2498{
2499 jboolean result = JNI_FALSE;
2500 tNFA_STATUS status = NFA_STATUS_OK;
2501 int handle = sCurrentConnectedHandle;
2502
2503 ALOGD ("%s", __FUNCTION__);
2504
nxpandroid34627bd2016-05-27 15:52:30 +05302505 if (sCurrentConnectedTargetProtocol == NFA_PROTOCOL_MIFARE)
2506 {
2507 static uint8_t mfc_key1[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2508 static uint8_t mfc_key2[6] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7};
2509 result = nativeNfcTag_makeMifareReadonly (e, o, mfc_key1, sizeof(mfc_key1));
2510 if (result == JNI_FALSE)
2511 {
2512 result = nativeNfcTag_makeMifareReadonly (e, o, mfc_key2, sizeof(mfc_key2));
2513 }
2514 return result;
2515 }
2516
nxpandroid64fd68c2015-09-23 16:45:15 +05302517 /* Create the make_readonly semaphore */
2518 if (sem_init (&sMakeReadonlySem, 0, 0) == -1)
2519 {
2520 ALOGE ("%s: Make readonly semaphore creation failed (errno=0x%08x)", __FUNCTION__, errno);
2521 return JNI_FALSE;
2522 }
2523
2524 sMakeReadonlyWaitingForComplete = JNI_TRUE;
2525
nxpandroid34627bd2016-05-27 15:52:30 +05302526 // Hard-lock the tag (cannot be reverted)
2527 status = NFA_RwSetTagReadOnly(TRUE);
2528 if (status == NFA_STATUS_REJECTED)
nxpandroid64fd68c2015-09-23 16:45:15 +05302529 {
nxpandroid34627bd2016-05-27 15:52:30 +05302530 status = NFA_RwSetTagReadOnly (FALSE); //try soft lock
2531 if (status != NFA_STATUS_OK)
nxpandroid64fd68c2015-09-23 16:45:15 +05302532 {
nxpandroid34627bd2016-05-27 15:52:30 +05302533 ALOGE ("%s: fail soft lock, status=%d", __FUNCTION__, status);
2534 goto TheEnd;
nxpandroid64fd68c2015-09-23 16:45:15 +05302535 }
2536 }
nxpandroid34627bd2016-05-27 15:52:30 +05302537 else if(status != NFA_STATUS_OK)
nxpandroid64fd68c2015-09-23 16:45:15 +05302538 {
nxpandroid34627bd2016-05-27 15:52:30 +05302539 ALOGE ("%s: fail hard lock, status=%d", __FUNCTION__, status);
2540 goto TheEnd;
nxpandroid64fd68c2015-09-23 16:45:15 +05302541 }
2542
nxpandroid34627bd2016-05-27 15:52:30 +05302543 /*Wait for check NDEF completion status*/
2544 if (sem_wait (&sMakeReadonlySem))
nxpandroid64fd68c2015-09-23 16:45:15 +05302545 {
nxpandroid34627bd2016-05-27 15:52:30 +05302546 ALOGE ("%s: Failed to wait for make_readonly semaphore (errno=0x%08x)", __FUNCTION__, errno);
2547 goto TheEnd;
nxpandroid64fd68c2015-09-23 16:45:15 +05302548 }
2549
nxpandroid34627bd2016-05-27 15:52:30 +05302550 if(sMakeReadonlyStatus == NFA_STATUS_OK)
nxpandroid64fd68c2015-09-23 16:45:15 +05302551 {
nxpandroid64fd68c2015-09-23 16:45:15 +05302552 result = JNI_TRUE;
2553 }
2554
2555TheEnd:
2556 /* Destroy semaphore */
2557 if (sem_destroy (&sMakeReadonlySem))
2558 {
2559 ALOGE ("%s: Failed to destroy read_only semaphore (errno=0x%08x)", __FUNCTION__, errno);
2560 }
2561 sMakeReadonlyWaitingForComplete = JNI_FALSE;
2562 return result;
2563}
2564
2565
2566/*******************************************************************************
2567**
2568** Function: nativeNfcTag_registerNdefTypeHandler
2569**
2570** Description: Register a callback to receive NDEF message from the tag
2571** from the NFA_NDEF_DATA_EVT.
2572**
2573** Returns: None
2574**
2575*******************************************************************************/
2576//register a callback to receive NDEF message from the tag
2577//from the NFA_NDEF_DATA_EVT;
2578void nativeNfcTag_registerNdefTypeHandler ()
2579{
2580 ALOGD ("%s", __FUNCTION__);
2581 sNdefTypeHandlerHandle = NFA_HANDLE_INVALID;
2582 NFA_RegisterNDefTypeHandler (TRUE, NFA_TNF_DEFAULT, (UINT8 *) "", 0, ndefHandlerCallback);
nxpandroid34627bd2016-05-27 15:52:30 +05302583 EXTNS_MfcRegisterNDefTypeHandler (ndefHandlerCallback);
nxpandroid64fd68c2015-09-23 16:45:15 +05302584}
2585
2586
2587/*******************************************************************************
2588**
2589** Function: nativeNfcTag_deregisterNdefTypeHandler
2590**
2591** Description: No longer need to receive NDEF message from the tag.
2592**
2593** Returns: None
2594**
2595*******************************************************************************/
2596void nativeNfcTag_deregisterNdefTypeHandler ()
2597{
2598 ALOGD ("%s", __FUNCTION__);
2599 NFA_DeregisterNDefTypeHandler (sNdefTypeHandlerHandle);
2600 sNdefTypeHandlerHandle = NFA_HANDLE_INVALID;
2601}
2602
2603
2604/*******************************************************************************
2605**
2606** Function: presenceCheckTimerProc
2607**
2608** Description: Callback function for presence check timer.
2609**
2610** Returns: None
2611**
2612*******************************************************************************/
2613static void presenceCheckTimerProc (union sigval)
2614{
2615 ALOGD ("%s", __FUNCTION__);
2616 sIsTagInField = false;
2617 sIsReconnecting = false;
2618 SyncEventGuard guard (sNfaVSCNotificationEvent);
2619 sNfaVSCNotificationEvent.notifyOne ();
2620}
2621
2622/*******************************************************************************
2623**
2624** Function: sReconnectTimerProc
2625**
2626** Description: Callback function for reconnect timer.
2627**
2628** Returns: None
2629**
2630*******************************************************************************/
2631static void sReconnectTimerProc (union sigval)
2632{
2633 ALOGD ("%s", __FUNCTION__);
2634 SyncEventGuard guard (sNfaVSCNotificationEvent);
2635 sNfaVSCNotificationEvent.notifyOne ();
2636}
2637
2638/*******************************************************************************
2639**
2640** Function: acquireRfInterfaceMutexLock
2641**
2642** Description: acquire lock
2643**
2644** Returns: None
2645**
2646*******************************************************************************/
2647void acquireRfInterfaceMutexLock()
2648{
2649 ALOGD ("%s: try to acquire lock", __FUNCTION__);
2650 sRfInterfaceMutex.lock();
2651 ALOGD ("%s: sRfInterfaceMutex lock", __FUNCTION__);
2652}
2653
2654/*******************************************************************************
2655**
2656** Function: releaseRfInterfaceMutexLock
2657**
2658** Description: release the lock
2659**
2660** Returns: None
2661**
2662*******************************************************************************/
2663void releaseRfInterfaceMutexLock()
2664{
2665 sRfInterfaceMutex.unlock();
2666 ALOGD ("%s: sRfInterfaceMutex unlock", __FUNCTION__);
2667}
2668
2669/*****************************************************************************
2670**
2671** JNI functions for Android 4.0.3
2672**
2673*****************************************************************************/
2674static JNINativeMethod gMethods[] =
2675{
2676 {"doConnect", "(I)I", (void *)nativeNfcTag_doConnect},
2677 {"doDisconnect", "()Z", (void *)nativeNfcTag_doDisconnect},
2678 {"doReconnect", "()I", (void *)nativeNfcTag_doReconnect},
2679 {"doHandleReconnect", "(I)I", (void *)nativeNfcTag_doHandleReconnect},
2680 {"doTransceive", "([BZ[I)[B", (void *)nativeNfcTag_doTransceive},
2681 {"doGetNdefType", "(II)I", (void *)nativeNfcTag_doGetNdefType},
2682 {"doCheckNdef", "([I)I", (void *)nativeNfcTag_doCheckNdef},
2683 {"doRead", "()[B", (void *)nativeNfcTag_doRead},
2684 {"doWrite", "([B)Z", (void *)nativeNfcTag_doWrite},
2685 {"doPresenceCheck", "()Z", (void *)nativeNfcTag_doPresenceCheck},
2686 {"doIsIsoDepNdefFormatable", "([B[B)Z", (void *)nativeNfcTag_doIsIsoDepNdefFormatable},
2687 {"doNdefFormat", "([B)Z", (void *)nativeNfcTag_doNdefFormat},
2688 {"doMakeReadonly", "([B)Z", (void *)nativeNfcTag_doMakeReadonly},
2689};
2690
2691
2692/*******************************************************************************
2693**
2694** Function: register_com_android_nfc_NativeNfcTag
2695**
2696** Description: Regisgter JNI functions with Java Virtual Machine.
2697** e: Environment of JVM.
2698**
2699** Returns: Status of registration.
2700**
2701*******************************************************************************/
2702int register_com_android_nfc_NativeNfcTag (JNIEnv *e)
2703{
2704 ALOGD ("%s", __FUNCTION__);
2705 return jniRegisterNativeMethods (e, gNativeNfcTagClassName, gMethods, NELEM (gMethods));
2706}
2707
2708
2709} /* namespace android */