Remove various iOS NFC card edge case problems
* you and ecsec GmbH.
*
***************************************************************************/
-
package org.openecard.scio;
import java.io.ByteArrayOutputStream;
@@ -32,6 +31,7 @@ import org.openecard.common.util.Promise;
import org.robovm.apple.corenfc.NFCISO7816APDU;
import org.robovm.apple.corenfc.NFCISO7816Tag;
import org.robovm.apple.corenfc.NFCPollingOption;
+import org.robovm.apple.corenfc.NFCReaderError;
import org.robovm.apple.corenfc.NFCTagReaderSession;
import org.robovm.apple.corenfc.NFCTagReaderSessionDelegateAdapter;
import org.robovm.apple.dispatch.DispatchQueue;
@@ -43,7 +43,6 @@ import org.robovm.apple.foundation.NSObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-
/**
* NFC implementation of SCIO API card interface.
*
@@ -74,10 +73,12 @@ public final class IOSNFCCard extends AbstractNFCCard {
this.cfg = cfg;
}
- private void setTag(NFCISO7816Tag tag) {
+ private void setTag(NFCISO7816Tag tag, NFCSessionContext givenContext) {
+ if (givenContext == sessionContext || (tag == null && givenContext == null)) {
this.tag = tag;
this.setHistBytes();
}
+ }
private NFCSessionContext initSessionObj() throws SCIOException {
DispatchQueue dspqueue;
@@ -134,8 +135,9 @@ public final class IOSNFCCard extends AbstractNFCCard {
}
}
if (this.error != null) {
- if (this.error.getCode() != 203) {
+ if (this.error.getCode() != NFCReaderError.ReaderSessionInvalidationErrorSystemIsBusy.value()) {
LOG.error("Could not create a new NFC session. {}", this.error);
+ context.session.invalidateSession();
this.error = null;
this.sessionContext = null;
this.terminateTag();
@@ -252,17 +254,33 @@ public final class IOSNFCCard extends AbstractNFCCard {
}
private class NFCTagReaderSessionDelegateAdapterImpl extends NFCTagReaderSessionDelegateAdapter {
+
public NFCSessionContext currentContext = null;
+ private final Object notifyErrorLock = new Object();
+ private volatile boolean hasNotifiedError = false;
@Override
public void didInvalidate(NFCTagReaderSession session, NSError err) {
LOG.debug(".didInvalidate()");
+ notifyError(err);
+ return;
+ }
+
+ private void notifyError(NSError err) {
+
+ synchronized (notifyErrorLock) {
+ if (hasNotifiedError) {
+ return;
+ } else {
+ hasNotifiedError = true;
+ }
+ }
+
synchronized (tagLock) {
error = err;
- setTag(null);
+ setTag(null, currentContext);
tagLock.notifyAll();
}
- return;
}
@Override
@@ -277,16 +295,12 @@ public final class IOSNFCCard extends AbstractNFCCard {
session.connectToTag(t, (NSError err) -> {
if (err != null) {
- synchronized (tagLock) {
- error = err;
- setTag(null);
- tagLock.notifyAll();
- }
+ notifyError(err);
} else {
NFCISO7816Tag tag = session.getConnectedTag().asNFCISO7816Tag();
synchronized (tagLock) {
- setTag(tag);
+ setTag(tag, currentContext);
setDialogMsg(cfg.getDefaultCardRecognizedMSG());
tagLock.notifyAll();
}
