AusweisApp2/patches/qt-Android-Add-support-for-...

181 lines
7.3 KiB
Diff

From 6483796d9c117a7dee7c2ffcef090600b04bd21c Mon Sep 17 00:00:00 2001
From: Lars Schmertmann <Lars.Schmertmann@governikus.de>
Date: Tue, 13 Dec 2016 15:34:32 +0100
Subject: Android: Add support for sendCommand to QNearFieldTarget
For the communication with a German ID card its required to execute
commands. This change enables support for sendCommand.
Change-Id: I95773c047953b244cd5c3e22bfc7abf7f7eb656e
---
src/nfc/qnearfieldtarget.cpp | 3 +-
src/nfc/qnearfieldtarget.h | 3 +-
src/nfc/qnearfieldtarget_android.cpp | 81 +++++++++++++++++++++++-------------
3 files changed, 56 insertions(+), 31 deletions(-)
diff --git x/qtconnectivity/src/nfc/qnearfieldtarget.cpp y/qtconnectivity/src/nfc/qnearfieldtarget.cpp
index 509160c1..a65b4be2 100644
--- x/qtconnectivity/src/nfc/qnearfieldtarget.cpp
+++ y/qtconnectivity/src/nfc/qnearfieldtarget.cpp
@@ -111,7 +111,7 @@ QT_BEGIN_NAMESPACE
/*!
\enum QNearFieldTarget::Error
- This enum describes the error codes that that a near field target reports.
+ This enum describes the error codes that a near field target reports.
\value NoError No error has occurred.
\value UnknownError An unidentified error occurred.
@@ -123,6 +123,7 @@ QT_BEGIN_NAMESPACE
\value InvalidParametersError Invalid parameters were passed to a tag type specific function.
\value NdefReadError Failed to read NDEF messages from the target.
\value NdefWriteError Failed to write NDEF messages to the target.
+ \value CommandError Failed to send a command to the target.
*/
// Copied from qbytearray.cpp
diff --git x/qtconnectivity/src/nfc/qnearfieldtarget.h y/qtconnectivity/src/nfc/qnearfieldtarget.h
index dc081f5e..dfb474f6 100644
--- x/qtconnectivity/src/nfc/qnearfieldtarget.h
+++ y/qtconnectivity/src/nfc/qnearfieldtarget.h
@@ -91,7 +91,8 @@ public:
ChecksumMismatchError,
InvalidParametersError,
NdefReadError,
- NdefWriteError
+ NdefWriteError,
+ CommandError
};
Q_ENUM(Error)
diff --git x/qtconnectivity/src/nfc/qnearfieldtarget_android.cpp y/qtconnectivity/src/nfc/qnearfieldtarget_android.cpp
index e0c1616d..478f4d8c 100644
--- x/qtconnectivity/src/nfc/qnearfieldtarget_android.cpp
+++ y/qtconnectivity/src/nfc/qnearfieldtarget_android.cpp
@@ -43,6 +43,7 @@
#define NDEFTECHNOLOGY "android.nfc.tech.Ndef"
#define NDEFFORMATABLETECHNOLOGY "android.nfc.tech.NdefFormatable"
+#define ISODEPTECHNOLOGY "android.nfc.tech.IsoDep"
#define NFCATECHNOLOGY "android.nfc.tech.NfcA"
#define NFCBTECHNOLOGY "android.nfc.tech.NfcB"
#define NFCFTECHNOLOGY "android.nfc.tech.NfcF"
@@ -84,7 +85,19 @@ QNearFieldTarget::Type NearFieldTarget::type() const
QNearFieldTarget::AccessMethods NearFieldTarget::accessMethods() const
{
- AccessMethods result = NdefAccess;
+ AccessMethods result = UnknownAccess;
+
+ if (m_techList.contains(QStringLiteral(NDEFTECHNOLOGY))
+ || m_techList.contains(QStringLiteral(NDEFFORMATABLETECHNOLOGY)))
+ result |= NdefAccess;
+
+ if (m_techList.contains(QStringLiteral(ISODEPTECHNOLOGY))
+ || m_techList.contains(QStringLiteral(NFCATECHNOLOGY))
+ || m_techList.contains(QStringLiteral(NFCBTECHNOLOGY))
+ || m_techList.contains(QStringLiteral(NFCFTECHNOLOGY))
+ || m_techList.contains(QStringLiteral(NFCVTECHNOLOGY)))
+ result |= TagTypeSpecificAccess;
+
return result;
}
@@ -157,24 +170,23 @@ QNearFieldTarget::RequestId NearFieldTarget::readNdefMessages()
return requestId;
}
-
QNearFieldTarget::RequestId NearFieldTarget::sendCommand(const QByteArray &command)
{
- Q_UNUSED(command);
- Q_EMIT QNearFieldTarget::error(QNearFieldTarget::UnsupportedError, QNearFieldTarget::RequestId());
- return QNearFieldTarget::RequestId();
-
- //Not supported for now
- /*if (command.size() == 0) {
+ if (command.size() == 0) {
Q_EMIT QNearFieldTarget::error(QNearFieldTarget::InvalidParametersError, QNearFieldTarget::RequestId());
return QNearFieldTarget::RequestId();
}
- AndroidNfc::AttachedJNIEnv aenv;
- JNIEnv *env = aenv.jniEnv;
+ // Making sure that target has commands
+ if (!(accessMethods() & TagTypeSpecificAccess))
+ return QNearFieldTarget::RequestId();
+
+ QAndroidJniEnvironment env;
- jobject tagTech;
- if (m_techList.contains(QStringLiteral(NFCATECHNOLOGY))) {
+ QAndroidJniObject tagTech;
+ if (m_techList.contains(ISODEPTECHNOLOGY)) {
+ tagTech = getTagTechnology(ISODEPTECHNOLOGY);
+ } else if (m_techList.contains(QStringLiteral(NFCATECHNOLOGY))) {
tagTech = getTagTechnology(QStringLiteral(NFCATECHNOLOGY));
} else if (m_techList.contains(QStringLiteral(NFCBTECHNOLOGY))) {
tagTech = getTagTechnology(QStringLiteral(NFCBTECHNOLOGY));
@@ -187,30 +199,41 @@ QNearFieldTarget::RequestId NearFieldTarget::sendCommand(const QByteArray &comma
return QNearFieldTarget::RequestId();
}
- QByteArray ba(ba);
-
- jclass techClass = env->GetObjectClass(tagTech);
- jmethodID tranceiveMID = env->GetMethodID(techClass, "tranceive", "([B)[B");
- Q_ASSERT_X(tranceiveMID != 0, "sendCommand", "could not find tranceive method");
+ // Connecting
+ QNearFieldTarget::RequestId requestId = QNearFieldTarget::RequestId(new QNearFieldTarget::RequestIdPrivate());
+ tagTech.callMethod<void>("connect");
+ if (catchJavaExceptions()) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::TargetOutOfRangeError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+ // Making QByteArray
+ QByteArray ba(command);
jbyteArray jba = env->NewByteArray(ba.size());
env->SetByteArrayRegion(jba, 0, ba.size(), reinterpret_cast<jbyte*>(ba.data()));
- jbyteArray rsp = reinterpret_cast<jbyteArray>(env->CallObjectMethod(tagTech, tranceiveMID, jba));
-
- jsize len = env->GetArrayLength(rsp);
- QByteArray rspQBA;
- rspQBA.resize(len);
-
- env->GetByteArrayRegion(rsp, 0, len, reinterpret_cast<jbyte*>(rspQBA.data()));
-
- qDebug() << "Send command returned QBA size: " << rspQBA.size();
-
-
+ // Writing
+ QAndroidJniObject myNewVal = tagTech.callObjectMethod("transceive", "([B)[B", jba);
+ if (catchJavaExceptions()) {
+ QMetaObject::invokeMethod(this, "error", Qt::QueuedConnection,
+ Q_ARG(QNearFieldTarget::Error, QNearFieldTarget::CommandError),
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+ return requestId;
+ }
+ QByteArray result = jbyteArrayToQByteArray(myNewVal.object<jbyteArray>());
env->DeleteLocalRef(jba);
+ handleResponse(requestId, result);
- return QNearFieldTarget::RequestId();*/
+ // Closing connection, sending signal and exit
+ tagTech.callMethod<void>("close");
+ catchJavaExceptions(); // IOException at this point does not matter anymore.
+ QMetaObject::invokeMethod(this, "requestCompleted", Qt::QueuedConnection,
+ Q_ARG(const QNearFieldTarget::RequestId&, requestId));
+
+ return requestId;
}
QNearFieldTarget::RequestId NearFieldTarget::sendCommands(const QList<QByteArray> &commands)
--
2.11.0